Compare commits
14 Commits
Author | SHA1 | Date |
---|---|---|
Daniel Marjamäki | 70b3cc7638 | |
Daniel Marjamäki | 220effee6a | |
Daniel Marjamäki | f28be6494c | |
Daniel Marjamäki | ac38e9fdb3 | |
Daniel Marjamäki | 48738c22eb | |
Daniel Marjamäki | c6f7b7db02 | |
Daniel Marjamäki | 731928a3b6 | |
Daniel Marjamäki | 32a0641365 | |
Daniel Marjamäki | a626c2d171 | |
Daniel Marjamäki | 4719e725a1 | |
Daniel Marjamäki | b44a38bf7f | |
Daniel Marjamäki | 61f846073d | |
Daniel Marjamäki | f998703a50 | |
Daniel Marjamäki | 05102aa06e |
6
Makefile
6
Makefile
|
@ -96,7 +96,7 @@ ifeq (clang++, $(findstring clang++,$(CXX)))
|
|||
CPPCHK_GLIBCXX_DEBUG=
|
||||
endif
|
||||
ifndef CXXFLAGS
|
||||
CXXFLAGS=-pedantic -Wall -Wextra -Wcast-qual -Wno-deprecated-declarations -Wfloat-equal -Wmissing-declarations -Wmissing-format-attribute -Wno-long-long -Wpacked -Wredundant-decls -Wundef -Wno-shadow -Wno-missing-field-initializers -Wno-missing-braces -Wno-sign-compare -Wno-multichar $(CPPCHK_GLIBCXX_DEBUG) -g
|
||||
CXXFLAGS=-std=c++0x -O2 -DNDEBUG -Wall -Wno-sign-compare
|
||||
endif
|
||||
|
||||
ifeq (g++, $(findstring g++,$(CXX)))
|
||||
|
@ -213,6 +213,7 @@ CLIOBJ = cli/cmdlineparser.o \
|
|||
|
||||
TESTOBJ = test/options.o \
|
||||
test/test64bit.o \
|
||||
test/testanalyzerinformation.o \
|
||||
test/testassert.o \
|
||||
test/testastutils.o \
|
||||
test/testautovariables.o \
|
||||
|
@ -582,6 +583,9 @@ test/options.o: test/options.cpp test/options.h
|
|||
test/test64bit.o: test/test64bit.cpp lib/check.h lib/check64bit.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/test64bit.o test/test64bit.cpp
|
||||
|
||||
test/testanalyzerinformation.o: test/testanalyzerinformation.cpp lib/analyzerinfo.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/platform.h lib/suppressions.h lib/utils.h test/testsuite.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testanalyzerinformation.o test/testanalyzerinformation.cpp
|
||||
|
||||
test/testassert.o: test/testassert.cpp lib/check.h lib/checkassert.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testassert.o test/testassert.cpp
|
||||
|
||||
|
|
|
@ -1391,7 +1391,10 @@ def get_path_premium_addon():
|
|||
|
||||
|
||||
def cmd_output(cmd):
|
||||
try:
|
||||
return subprocess.check_output(cmd).strip().decode('ascii')
|
||||
except subprocess.CalledProcessError as e:
|
||||
return e.output
|
||||
with subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as p:
|
||||
comm = p.communicate()
|
||||
out = comm[0]
|
||||
if p.returncode == 1 and len(comm[1]) > 2:
|
||||
out = comm[1]
|
||||
return out.decode(encoding='utf-8', errors='ignore')
|
||||
|
||||
|
|
|
@ -4062,8 +4062,9 @@ class MisraChecker:
|
|||
errmsg = 'misra violation (use --rule-texts=<file> to get proper output)'
|
||||
if self.path_premium_addon:
|
||||
for line in cppcheckdata.cmd_output([self.path_premium_addon, '--cli', '--get-rule-text=' + errorId]).split('\n'):
|
||||
if not line.startswith('{'):
|
||||
errmsg = line
|
||||
if len(line) > 1 and not line.startswith('{'):
|
||||
errmsg = line.strip()
|
||||
break
|
||||
else:
|
||||
errmsg = 'misra violation %s with no text in the supplied rule-texts-file' % (ruleNum)
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
|
|||
|
||||
if (parser.getShowErrorMessages()) {
|
||||
mShowAllErrors = true;
|
||||
std::cout << ErrorMessage::getXMLHeader();
|
||||
std::cout << ErrorMessage::getXMLHeader(settings.cppcheckCfgProductName);
|
||||
cppcheck->getErrorMessages();
|
||||
std::cout << ErrorMessage::getXMLFooter() << std::endl;
|
||||
}
|
||||
|
@ -908,7 +908,7 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck)
|
|||
}
|
||||
|
||||
if (settings.xml) {
|
||||
reportErr(ErrorMessage::getXMLHeader());
|
||||
reportErr(ErrorMessage::getXMLHeader(settings.cppcheckCfgProductName));
|
||||
}
|
||||
|
||||
if (!settings.buildDir.empty()) {
|
||||
|
@ -979,7 +979,12 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck)
|
|||
|
||||
cppcheck.analyseWholeProgram(mSettings->buildDir, mFiles);
|
||||
|
||||
if (settings.severity.isEnabled(Severity::information) || settings.checkConfiguration) {
|
||||
bool suppressUnmatchedSuppressions = false;
|
||||
for (const Suppressions::Suppression& suppression: settings.nomsg.getSuppressions()) {
|
||||
if (suppression.errorId == "unmatchedSuppression" && suppression.fileName.empty() && suppression.lineNumber == Suppressions::Suppression::NO_LINE)
|
||||
suppressUnmatchedSuppressions = true;
|
||||
}
|
||||
if (!suppressUnmatchedSuppressions && (settings.severity.isEnabled(Severity::information) || settings.checkConfiguration)) {
|
||||
const bool enableUnusedFunctionCheck = cppcheck.isUnusedFunctionCheckEnabled();
|
||||
|
||||
if (settings.jointSuppressionReport) {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
/**
|
||||
*
|
||||
* @mainpage Cppcheck
|
||||
* @version 2.7
|
||||
* @version 2.8
|
||||
*
|
||||
* @section overview_sec Overview
|
||||
* Cppcheck is a simple tool for static analysis of C/C++ code.
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
# Version for libraries CPP
|
||||
SET(VERSION "2.7")
|
||||
SET(VERSION "2.8.2")
|
||||
STRING(REGEX MATCHALL "[0-9]" VERSION_PARTS "${VERSION}")
|
||||
LIST(GET VERSION_PARTS 0 VERSION_MAJOR)
|
||||
LIST(GET VERSION_PARTS 1 VERSION_MINOR)
|
||||
SET(SOVERSION "${VERSION_MAJOR}.${VERSION_MINOR}")
|
||||
LIST(GET VERSION_PARTS 2 VERSION_BUILD)
|
||||
SET(SOVERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_BUILD}")
|
||||
|
||||
# Postfix of so's:
|
||||
SET(DLLVERSION "")
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
# git checkout -b 2.6.x ; git push -u origin 2.6.x
|
||||
#
|
||||
# Update version numbers in:
|
||||
# sed -i -r "s/version 2[.][0-9]+([.]99)*/2.7/" cli/main.cpp
|
||||
# sed -i -r "s/version 2[.][0-9]+([.]99)*/version 2.7/" cli/main.cpp
|
||||
# sed -i -r "s|2[.][0-9]+([.]99)*|2.7|" cmake/versions.cmake
|
||||
# sed -i -r "s/MINOR [0-9]+/MINOR 7/" lib/version.h
|
||||
# sed -i -r "s/2[.][0-9]+([.]99)*/2.7/" win_installer/productInfo.wxi
|
||||
|
|
|
@ -95,34 +95,36 @@ static bool skipAnalysis(const std::string &analyzerInfoFile, unsigned long long
|
|||
return true;
|
||||
}
|
||||
|
||||
std::string AnalyzerInformation::getAnalyzerInfoFileFromFilesTxt(std::istream& filesTxt, const std::string &sourcefile, const std::string &cfg)
|
||||
{
|
||||
std::string line;
|
||||
const std::string end(':' + cfg + ':' + Path::simplifyPath(sourcefile));
|
||||
while (std::getline(filesTxt,line)) {
|
||||
if (line.size() <= end.size() + 2U)
|
||||
continue;
|
||||
if (!endsWith(line, end.c_str(), end.size()))
|
||||
continue;
|
||||
return line.substr(0,line.find(':'));
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string AnalyzerInformation::getAnalyzerInfoFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg)
|
||||
{
|
||||
const std::string files(buildDir + "/files.txt");
|
||||
std::ifstream fin(files);
|
||||
std::ifstream fin(Path::join(buildDir, "files.txt"));
|
||||
if (fin.is_open()) {
|
||||
std::string line;
|
||||
const std::string end(':' + cfg + ':' + sourcefile);
|
||||
while (std::getline(fin,line)) {
|
||||
if (line.size() <= end.size() + 2U)
|
||||
continue;
|
||||
if (!endsWith(line, end.c_str(), end.size()))
|
||||
continue;
|
||||
std::ostringstream ostr;
|
||||
ostr << buildDir << '/' << line.substr(0,line.find(':'));
|
||||
return ostr.str();
|
||||
}
|
||||
const std::string& ret = getAnalyzerInfoFileFromFilesTxt(fin, sourcefile, cfg);
|
||||
if (!ret.empty())
|
||||
return Path::join(buildDir, ret);
|
||||
}
|
||||
|
||||
std::string filename = Path::fromNativeSeparators(buildDir);
|
||||
if (!endsWith(filename, '/'))
|
||||
filename += '/';
|
||||
const std::string::size_type pos = sourcefile.rfind('/');
|
||||
if (pos == std::string::npos)
|
||||
filename += sourcefile;
|
||||
std::string filename;
|
||||
if (pos != std::string::npos)
|
||||
filename = sourcefile;
|
||||
else
|
||||
filename += sourcefile.substr(pos+1);
|
||||
filename += ".analyzerinfo";
|
||||
return filename;
|
||||
filename = sourcefile.substr(pos + 1);
|
||||
return Path::join(buildDir, filename) + ".analyzerinfo";
|
||||
}
|
||||
|
||||
bool AnalyzerInformation::analyzeFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg, unsigned long long checksum, std::list<ErrorMessage> *errors)
|
||||
|
|
|
@ -58,6 +58,8 @@ public:
|
|||
void reportErr(const ErrorMessage &msg, bool verbose);
|
||||
void setFileInfo(const std::string &check, const std::string &fileInfo);
|
||||
static std::string getAnalyzerInfoFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg);
|
||||
protected:
|
||||
static std::string getAnalyzerInfoFileFromFilesTxt(std::istream& filesTxt, const std::string &sourcefile, const std::string &cfg);
|
||||
private:
|
||||
std::ofstream mOutputStream;
|
||||
std::string mAnalyzerInfoFile;
|
||||
|
|
|
@ -1435,7 +1435,12 @@ void CppCheck::executeAddonsWholeProgram(const std::map<std::string, std::size_t
|
|||
ctuInfoFiles.push_back(getCtuInfoFileName(dumpFileName));
|
||||
}
|
||||
|
||||
executeAddons(ctuInfoFiles);
|
||||
try {
|
||||
executeAddons(ctuInfoFiles);
|
||||
} catch (const InternalError& e) {
|
||||
internalError("", "Internal error during whole program analysis: " + e.errorMessage);
|
||||
mExitCode = 1;
|
||||
}
|
||||
|
||||
for (const std::string &f: ctuInfoFiles) {
|
||||
std::remove(f.c_str());
|
||||
|
|
|
@ -368,7 +368,7 @@ bool ErrorMessage::deserialize(const std::string &data)
|
|||
return true;
|
||||
}
|
||||
|
||||
std::string ErrorMessage::getXMLHeader()
|
||||
std::string ErrorMessage::getXMLHeader(const std::string& productName)
|
||||
{
|
||||
tinyxml2::XMLPrinter printer;
|
||||
|
||||
|
@ -380,6 +380,8 @@ std::string ErrorMessage::getXMLHeader()
|
|||
|
||||
printer.PushAttribute("version", 2);
|
||||
printer.OpenElement("cppcheck", false);
|
||||
if (!productName.empty())
|
||||
printer.PushAttribute("product-name", productName.c_str());
|
||||
printer.PushAttribute("version", CppCheck::version());
|
||||
printer.CloseElement(false);
|
||||
printer.OpenElement("errors", false);
|
||||
|
@ -489,7 +491,7 @@ static std::string readCode(const std::string &file, int linenr, int column, con
|
|||
std::string::size_type pos = 0;
|
||||
while ((pos = line.find('\t', pos)) != std::string::npos)
|
||||
line[pos] = ' ';
|
||||
return line + endl + std::string((column>0 ? column-1 : column), ' ') + '^';
|
||||
return line + endl + std::string((column>0 ? column-1 : 0), ' ') + '^';
|
||||
}
|
||||
|
||||
static void replaceColors(std::string& source)
|
||||
|
|
|
@ -160,7 +160,7 @@ public:
|
|||
*/
|
||||
std::string toXML() const;
|
||||
|
||||
static std::string getXMLHeader();
|
||||
static std::string getXMLHeader(const std::string& productName);
|
||||
static std::string getXMLFooter();
|
||||
|
||||
/**
|
||||
|
|
|
@ -242,3 +242,11 @@ bool Path::fileExists(const std::string &file)
|
|||
std::ifstream f(file.c_str());
|
||||
return f.is_open();
|
||||
}
|
||||
|
||||
std::string Path::join(std::string path1, std::string path2) {
|
||||
if (path1.empty() || path2.empty())
|
||||
return path1 + path2;
|
||||
if (path2.front() == '/')
|
||||
return path2;
|
||||
return ((path1.back() == '/') ? path1 : (path1 + "/")) + path2;
|
||||
}
|
||||
|
|
|
@ -179,6 +179,11 @@ public:
|
|||
* @return true if given path is a File
|
||||
*/
|
||||
static bool fileExists(const std::string &file);
|
||||
|
||||
/**
|
||||
* join 2 paths with '/' separators
|
||||
*/
|
||||
static std::string join(std::string path1, std::string path2);
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
// After a release the DEVMINOR is incremented. MAJOR=x MINOR=y, DEVMINOR=y+1
|
||||
|
||||
#define CPPCHECK_MAJOR 2
|
||||
#define CPPCHECK_MINOR 7
|
||||
#define CPPCHECK_DEVMINOR 7
|
||||
#define CPPCHECK_MINOR 8
|
||||
#define CPPCHECK_DEVMINOR 8
|
||||
|
||||
#define STRINGIFY(x) STRING(x)
|
||||
#define STRING(VER) #VER
|
||||
#if CPPCHECK_MINOR == CPPCHECK_DEVMINOR
|
||||
#define CPPCHECK_VERSION_STRING STRINGIFY(CPPCHECK_MAJOR) "." STRINGIFY(CPPCHECK_DEVMINOR)
|
||||
#define CPPCHECK_VERSION CPPCHECK_MAJOR,CPPCHECK_MINOR,0,0
|
||||
#define CPPCHECK_VERSION_STRING STRINGIFY(CPPCHECK_MAJOR) "." STRINGIFY(CPPCHECK_DEVMINOR) ".2"
|
||||
#define CPPCHECK_VERSION CPPCHECK_MAJOR,CPPCHECK_MINOR,1,0
|
||||
#else
|
||||
#define CPPCHECK_VERSION_STRING STRINGIFY(CPPCHECK_MAJOR) "." STRINGIFY(CPPCHECK_DEVMINOR) " dev"
|
||||
#define CPPCHECK_VERSION CPPCHECK_MAJOR,CPPCHECK_MINOR,99,0
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
title: Cppcheck manual
|
||||
subtitle: Version 2.7
|
||||
subtitle: Version 2.8
|
||||
author: Cppcheck team
|
||||
lang: en
|
||||
documentclass: report
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Cppcheck - A tool for static C/C++ code analysis
|
||||
* Copyright (C) 2007-2022 Cppcheck team.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "analyzerinfo.h"
|
||||
#include "testsuite.h"
|
||||
#include <sstream>
|
||||
|
||||
class TestAnalyzerInformation : public TestFixture, private AnalyzerInformation {
|
||||
public:
|
||||
TestAnalyzerInformation() : TestFixture("TestAnalyzerInformation") {}
|
||||
|
||||
private:
|
||||
|
||||
void run() override {
|
||||
TEST_CASE(getAnalyzerInfoFile);
|
||||
}
|
||||
|
||||
void getAnalyzerInfoFile() const {
|
||||
const char filesTxt[] = "file1.a4::file1.c\n";
|
||||
std::istringstream f1(filesTxt);
|
||||
ASSERT_EQUALS("file1.a4", getAnalyzerInfoFileFromFilesTxt(f1, "file1.c", ""));
|
||||
std::istringstream f2(filesTxt);
|
||||
ASSERT_EQUALS("file1.a4", getAnalyzerInfoFileFromFilesTxt(f2, "./file1.c", ""));
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestAnalyzerInformation)
|
|
@ -192,7 +192,7 @@ private:
|
|||
header += " <cppcheck version=\"";
|
||||
header += CppCheck::version();
|
||||
header += "\"/>\n <errors>";
|
||||
ASSERT_EQUALS(header, ErrorMessage::getXMLHeader());
|
||||
ASSERT_EQUALS(header, ErrorMessage::getXMLHeader(""));
|
||||
ASSERT_EQUALS(" </errors>\n</results>", ErrorMessage::getXMLFooter());
|
||||
std::string message(" <error id=\"errorId\" severity=\"error\"");
|
||||
message += " msg=\"Programming error.\" verbose=\"Verbose error\">\n";
|
||||
|
@ -208,7 +208,7 @@ private:
|
|||
header += " <cppcheck version=\"";
|
||||
header += CppCheck::version();
|
||||
header += "\"/>\n <errors>";
|
||||
ASSERT_EQUALS(header, ErrorMessage::getXMLHeader());
|
||||
ASSERT_EQUALS(header, ErrorMessage::getXMLHeader(""));
|
||||
ASSERT_EQUALS(" </errors>\n</results>", ErrorMessage::getXMLFooter());
|
||||
std::string message(" <error id=\"errorId\" severity=\"error\"");
|
||||
message += " msg=\"Programming error.\" verbose=\"Verbose error\">\n";
|
||||
|
|
|
@ -37,6 +37,7 @@ private:
|
|||
TEST_CASE(is_c);
|
||||
TEST_CASE(is_cpp);
|
||||
TEST_CASE(get_path_from_filename);
|
||||
TEST_CASE(join);
|
||||
}
|
||||
|
||||
void removeQuotationMarks() const {
|
||||
|
@ -141,6 +142,14 @@ private:
|
|||
ASSERT_EQUALS("a/b/c/", Path::getPathFromFilename("a/b/c/index.h"));
|
||||
ASSERT_EQUALS("a/b/c/", Path::getPathFromFilename("a/b/c/"));
|
||||
}
|
||||
|
||||
void join() const {
|
||||
ASSERT_EQUALS("a", Path::join("a", ""));
|
||||
ASSERT_EQUALS("a", Path::join("", "a"));
|
||||
ASSERT_EQUALS("a/b", Path::join("a", "b"));
|
||||
ASSERT_EQUALS("a/b", Path::join("a/", "b"));
|
||||
ASSERT_EQUALS("/b", Path::join("a", "/b"));
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestPath)
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
<ClCompile Include="..\lib\astutils.cpp" />
|
||||
<ClCompile Include="options.cpp" />
|
||||
<ClCompile Include="test64bit.cpp" />
|
||||
<ClCompile Include="testanalyzerinformation.cpp" />
|
||||
<ClCompile Include="testassert.cpp" />
|
||||
<ClCompile Include="testastutils.cpp" />
|
||||
<ClCompile Include="testautovariables.cpp" />
|
||||
|
@ -313,4 +314,4 @@
|
|||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Include>
|
||||
<?define ProductName = "Cppcheck $(var.Platform) 2.7" ?>
|
||||
<?define ProductName = "Cppcheck $(var.Platform) 2.8" ?>
|
||||
<?define ProductNameShort = "Cppcheck" ?>
|
||||
<?define ProductVersion = "2.7" ?>
|
||||
<?define ProductVersion = "2.8" ?>
|
||||
|
||||
<?define ProductManufacturer = "The Cppcheck team" ?>
|
||||
<?define ProductDescription = "Cppcheck is a tool for static analysis of C/C++ code" ?>
|
||||
|
|
Loading…
Reference in New Issue