Added --cppcheck-build-dir flag
This commit is contained in:
parent
324f68ca36
commit
9ff3e85899
24
Makefile
24
Makefile
|
@ -128,7 +128,8 @@ MAN_SOURCE=man/cppcheck.1.xml
|
|||
|
||||
###### Object Files
|
||||
|
||||
LIBOBJ = $(SRCDIR)/astutils.o \
|
||||
LIBOBJ = $(SRCDIR)/analyzerinfo.o \
|
||||
$(SRCDIR)/astutils.o \
|
||||
$(SRCDIR)/check.o \
|
||||
$(SRCDIR)/check64bit.o \
|
||||
$(SRCDIR)/checkassert.o \
|
||||
|
@ -299,6 +300,9 @@ endif
|
|||
|
||||
###### Build
|
||||
|
||||
$(SRCDIR)/analyzerinfo.o: lib/analyzerinfo.cpp lib/cxx11emu.h lib/analyzerinfo.h lib/config.h
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(SRCDIR)/analyzerinfo.o $(SRCDIR)/analyzerinfo.cpp
|
||||
|
||||
$(SRCDIR)/astutils.o: lib/astutils.cpp lib/cxx11emu.h lib/astutils.h lib/symboldatabase.h lib/config.h lib/token.h lib/valueflow.h lib/mathlib.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(SRCDIR)/astutils.o $(SRCDIR)/astutils.cpp
|
||||
|
||||
|
@ -380,10 +384,10 @@ $(SRCDIR)/checkunusedvar.o: lib/checkunusedvar.cpp lib/cxx11emu.h lib/checkunuse
|
|||
$(SRCDIR)/checkvaarg.o: lib/checkvaarg.cpp lib/cxx11emu.h lib/checkvaarg.h lib/config.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h lib/settings.h lib/library.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h lib/symboldatabase.h
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(SRCDIR)/checkvaarg.o $(SRCDIR)/checkvaarg.cpp
|
||||
|
||||
$(SRCDIR)/cppcheck.o: lib/cppcheck.cpp lib/cxx11emu.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/preprocessor.h lib/path.h lib/version.h
|
||||
$(SRCDIR)/cppcheck.o: lib/cppcheck.cpp lib/cxx11emu.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/analyzerinfo.h lib/preprocessor.h lib/path.h lib/version.h
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(SRCDIR)/cppcheck.o $(SRCDIR)/cppcheck.cpp
|
||||
|
||||
$(SRCDIR)/errorlogger.o: lib/errorlogger.cpp lib/cxx11emu.h lib/errorlogger.h lib/config.h lib/suppressions.h lib/path.h lib/cppcheck.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/utils.h
|
||||
$(SRCDIR)/errorlogger.o: lib/errorlogger.cpp lib/cxx11emu.h lib/errorlogger.h lib/config.h lib/suppressions.h lib/path.h lib/cppcheck.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/analyzerinfo.h lib/utils.h
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(SRCDIR)/errorlogger.o $(SRCDIR)/errorlogger.cpp
|
||||
|
||||
$(SRCDIR)/importproject.o: lib/importproject.cpp lib/cxx11emu.h lib/importproject.h lib/config.h lib/platform.h lib/path.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/token.h lib/valueflow.h
|
||||
|
@ -434,10 +438,10 @@ $(SRCDIR)/tokenlist.o: lib/tokenlist.cpp lib/cxx11emu.h lib/tokenlist.h lib/conf
|
|||
$(SRCDIR)/valueflow.o: lib/valueflow.cpp lib/cxx11emu.h lib/valueflow.h lib/config.h lib/astutils.h lib/errorlogger.h lib/suppressions.h lib/mathlib.h lib/settings.h lib/library.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h lib/symboldatabase.h lib/token.h lib/tokenlist.h
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(SRCDIR)/valueflow.o $(SRCDIR)/valueflow.cpp
|
||||
|
||||
cli/cmdlineparser.o: cli/cmdlineparser.cpp lib/cxx11emu.h cli/cmdlineparser.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h cli/cppcheckexecutor.h cli/filelister.h lib/path.h cli/threadexecutor.h
|
||||
cli/cmdlineparser.o: cli/cmdlineparser.cpp lib/cxx11emu.h cli/cmdlineparser.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/analyzerinfo.h cli/cppcheckexecutor.h cli/filelister.h lib/path.h cli/threadexecutor.h
|
||||
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o cli/cmdlineparser.o cli/cmdlineparser.cpp
|
||||
|
||||
cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp lib/cxx11emu.h cli/cppcheckexecutor.h lib/errorlogger.h lib/config.h lib/suppressions.h cli/cmdlineparser.h lib/cppcheck.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h cli/filelister.h lib/path.h lib/pathmatch.h lib/preprocessor.h cli/threadexecutor.h lib/utils.h
|
||||
cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp lib/cxx11emu.h cli/cppcheckexecutor.h lib/errorlogger.h lib/config.h lib/suppressions.h cli/cmdlineparser.h lib/cppcheck.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/analyzerinfo.h cli/filelister.h lib/path.h lib/pathmatch.h lib/preprocessor.h cli/threadexecutor.h lib/utils.h
|
||||
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o cli/cppcheckexecutor.o cli/cppcheckexecutor.cpp
|
||||
|
||||
cli/filelister.o: cli/filelister.cpp lib/cxx11emu.h cli/filelister.h lib/path.h lib/config.h lib/pathmatch.h
|
||||
|
@ -446,7 +450,7 @@ cli/filelister.o: cli/filelister.cpp lib/cxx11emu.h cli/filelister.h lib/path.h
|
|||
cli/main.o: cli/main.cpp lib/cxx11emu.h cli/cppcheckexecutor.h lib/errorlogger.h lib/config.h lib/suppressions.h
|
||||
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o cli/main.o cli/main.cpp
|
||||
|
||||
cli/threadexecutor.o: cli/threadexecutor.cpp lib/cxx11emu.h cli/threadexecutor.h lib/errorlogger.h lib/config.h lib/suppressions.h lib/importproject.h lib/platform.h lib/cppcheck.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h cli/cppcheckexecutor.h
|
||||
cli/threadexecutor.o: cli/threadexecutor.cpp lib/cxx11emu.h cli/threadexecutor.h lib/errorlogger.h lib/config.h lib/suppressions.h lib/importproject.h lib/platform.h lib/cppcheck.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/analyzerinfo.h cli/cppcheckexecutor.h
|
||||
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o cli/threadexecutor.o cli/threadexecutor.cpp
|
||||
|
||||
test/options.o: test/options.cpp lib/cxx11emu.h test/options.h
|
||||
|
@ -488,10 +492,10 @@ test/testcondition.o: test/testcondition.cpp lib/cxx11emu.h lib/tokenize.h lib/e
|
|||
test/testconstructors.o: test/testconstructors.cpp lib/cxx11emu.h lib/tokenize.h lib/errorlogger.h lib/config.h lib/suppressions.h lib/tokenlist.h lib/checkclass.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/settings.h lib/library.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h test/testsuite.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testconstructors.o test/testconstructors.cpp
|
||||
|
||||
test/testcppcheck.o: test/testcppcheck.cpp lib/cxx11emu.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h test/testsuite.h lib/path.h
|
||||
test/testcppcheck.o: test/testcppcheck.cpp lib/cxx11emu.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/analyzerinfo.h test/testsuite.h lib/path.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testcppcheck.o test/testcppcheck.cpp
|
||||
|
||||
test/testerrorlogger.o: test/testerrorlogger.cpp lib/cxx11emu.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h test/testsuite.h
|
||||
test/testerrorlogger.o: test/testerrorlogger.cpp lib/cxx11emu.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/analyzerinfo.h test/testsuite.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testerrorlogger.o test/testerrorlogger.cpp
|
||||
|
||||
test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/cxx11emu.h lib/tokenize.h lib/errorlogger.h lib/config.h lib/suppressions.h lib/tokenlist.h lib/checkexceptionsafety.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/settings.h lib/library.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h lib/utils.h test/testsuite.h
|
||||
|
@ -578,13 +582,13 @@ test/teststring.o: test/teststring.cpp lib/cxx11emu.h lib/tokenize.h lib/errorlo
|
|||
test/testsuite.o: test/testsuite.cpp lib/cxx11emu.h test/testsuite.h lib/errorlogger.h lib/config.h lib/suppressions.h test/options.h test/redirect.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testsuite.o test/testsuite.cpp
|
||||
|
||||
test/testsuppressions.o: test/testsuppressions.cpp lib/cxx11emu.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h test/testsuite.h
|
||||
test/testsuppressions.o: test/testsuppressions.cpp lib/cxx11emu.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/analyzerinfo.h test/testsuite.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testsuppressions.o test/testsuppressions.cpp
|
||||
|
||||
test/testsymboldatabase.o: test/testsymboldatabase.cpp lib/cxx11emu.h test/testsuite.h lib/errorlogger.h lib/config.h lib/suppressions.h test/testutils.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/symboldatabase.h lib/token.h lib/valueflow.h lib/utils.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testsymboldatabase.o test/testsymboldatabase.cpp
|
||||
|
||||
test/testthreadexecutor.o: test/testthreadexecutor.cpp lib/cxx11emu.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h test/testsuite.h
|
||||
test/testthreadexecutor.o: test/testthreadexecutor.cpp lib/cxx11emu.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/analyzerinfo.h test/testsuite.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testthreadexecutor.o test/testthreadexecutor.cpp
|
||||
|
||||
test/testtimer.o: test/testtimer.cpp lib/cxx11emu.h lib/timer.h lib/config.h test/testsuite.h lib/errorlogger.h lib/suppressions.h
|
||||
|
|
|
@ -120,6 +120,9 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
|||
return true;
|
||||
}
|
||||
|
||||
else if (std::strncmp(argv[i], "--cppcheck-build-dir=", 21) == 0)
|
||||
_settings->buildDir = argv[i] + 21;
|
||||
|
||||
// Flag used for various purposes during debugging
|
||||
else if (std::strcmp(argv[i], "--debug") == 0)
|
||||
_settings->debug = _settings->debugwarnings = true;
|
||||
|
@ -797,6 +800,9 @@ void CmdLineParser::PrintHelp()
|
|||
"If a directory is given instead of a filename, *.cpp, *.cxx, *.cc, *.c++, *.c,\n"
|
||||
"*.tpp, and *.txx files are checked recursively from the given directory.\n\n"
|
||||
"Options:\n"
|
||||
" --analyze-dir=<dir> Analysis output directory. Useful for various data.\n"
|
||||
" Some possible usages are; whole program analysis,\n"
|
||||
" incremental analysis, distributed analysis.\n"
|
||||
" --check-config Check cppcheck configuration. The normal code\n"
|
||||
" analysis is disabled by this flag.\n"
|
||||
" --check-library Show information messages when library files have\n"
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Cppcheck - A tool for static C/C++ code analysis
|
||||
* Copyright (C) 2007-2016 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 "path.h"
|
||||
#include <tinyxml2.h>
|
||||
|
||||
AnalyzerInformation::AnalyzerInformation() {}
|
||||
AnalyzerInformation::~AnalyzerInformation()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void AnalyzerInformation::close()
|
||||
{
|
||||
analyzerInfoFile.clear();
|
||||
if (fout.is_open()) {
|
||||
fout << "</analyzerinfo>\n";
|
||||
fout.close();
|
||||
}
|
||||
}
|
||||
|
||||
static bool skipAnalysis(const std::string &analyzerInfoFile, std::size_t checksum, std::list<ErrorLogger::ErrorMessage> *errors)
|
||||
{
|
||||
tinyxml2::XMLDocument doc;
|
||||
tinyxml2::XMLError error = doc.LoadFile(analyzerInfoFile.c_str());
|
||||
if (error != tinyxml2::XML_SUCCESS)
|
||||
return false;
|
||||
|
||||
const tinyxml2::XMLElement * const rootNode = doc.FirstChildElement();
|
||||
if (rootNode == nullptr)
|
||||
return false;
|
||||
|
||||
const char *attr = rootNode->Attribute("checksum");
|
||||
if (!attr || attr != std::to_string(checksum))
|
||||
return false;
|
||||
|
||||
for (const tinyxml2::XMLElement *e = rootNode->FirstChildElement(); e; e = e->NextSiblingElement()) {
|
||||
if (std::strcmp(e->Name(), "error") == 0)
|
||||
errors->push_back(ErrorLogger::ErrorMessage(e));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AnalyzerInformation::analyzeFile(const std::string &buildDir, const std::string &sourcefile, std::size_t checksum, std::list<ErrorLogger::ErrorMessage> *errors)
|
||||
{
|
||||
if (buildDir.empty() || sourcefile.empty())
|
||||
return true;
|
||||
close();
|
||||
|
||||
analyzerInfoFile = Path::fromNativeSeparators(buildDir);
|
||||
if (analyzerInfoFile.back() != '/')
|
||||
analyzerInfoFile += '/';
|
||||
const std::string::size_type pos = sourcefile.rfind("/");
|
||||
if (pos == std::string::npos)
|
||||
analyzerInfoFile += sourcefile;
|
||||
else
|
||||
analyzerInfoFile += sourcefile.substr(pos+1);
|
||||
analyzerInfoFile += ".analyzerinfo";
|
||||
|
||||
const std::string start = "<analyzerinfo checksum=\"" + std::to_string(checksum) + "\">";
|
||||
|
||||
if (skipAnalysis(analyzerInfoFile, checksum, errors)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fout.open(analyzerInfoFile);
|
||||
if (fout.is_open()) {
|
||||
fout << "<?xml version=\"1.0\"?>\n";
|
||||
fout << start << '\n';
|
||||
} else {
|
||||
analyzerInfoFile.clear();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AnalyzerInformation::reportErr(const ErrorLogger::ErrorMessage &msg, bool verbose)
|
||||
{
|
||||
if (fout.is_open())
|
||||
fout << msg.toXML(verbose,2) << '\n';
|
||||
}
|
||||
|
||||
void AnalyzerInformation::setFileInfo(const std::string &check, const std::string &fileInfo)
|
||||
{
|
||||
if (fout.is_open() && !fileInfo.empty())
|
||||
fout << " <FileInfo check=\"" << check << "\">\n" << fileInfo << " </FileInfo>\n";
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Cppcheck - A tool for static C/C++ code analysis
|
||||
* Copyright (C) 2007-2016 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/>.
|
||||
*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef analyzerinfoH
|
||||
#define analyzerinfoH
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "config.h"
|
||||
#include "errorlogger.h"
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
|
||||
/// @addtogroup Core
|
||||
/// @{
|
||||
|
||||
/**
|
||||
* @brief Analyzer information
|
||||
*
|
||||
* Store various analysis information:
|
||||
* - checksum
|
||||
* - error messages
|
||||
* - whole program analysis data
|
||||
*
|
||||
* The information can be used for various purposes. It allows:
|
||||
* - 'make' - only analyze TUs that are changed and generate full report
|
||||
* - should be possible to add distributed analysis later
|
||||
* - multi-threaded whole program analysis
|
||||
*/
|
||||
class CPPCHECKLIB AnalyzerInformation {
|
||||
public:
|
||||
AnalyzerInformation();
|
||||
~AnalyzerInformation();
|
||||
|
||||
/** Close current TU.analyzerinfo file */
|
||||
void close();
|
||||
bool analyzeFile(const std::string &buildDir, const std::string &sourcefile, std::size_t checksum, std::list<ErrorLogger::ErrorMessage> *errors);
|
||||
void reportErr(const ErrorLogger::ErrorMessage &msg, bool verbose);
|
||||
void setFileInfo(const std::string &check, const std::string &fileInfo);
|
||||
private:
|
||||
std::ofstream fout;
|
||||
std::string analyzerInfoFile;
|
||||
};
|
||||
|
||||
/// @}
|
||||
//---------------------------------------------------------------------------
|
||||
#endif // analyzerinfoH
|
|
@ -90,6 +90,9 @@ public:
|
|||
public:
|
||||
FileInfo() {}
|
||||
virtual ~FileInfo() {}
|
||||
virtual std::string toString() const {
|
||||
return std::string();
|
||||
}
|
||||
};
|
||||
|
||||
virtual FileInfo * getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const {
|
||||
|
|
|
@ -1896,6 +1896,24 @@ void CheckBufferOverrun::arrayIndexThenCheckError(const Token *tok, const std::s
|
|||
"not be accessed if the index is out of limits.", CWE398, false);
|
||||
}
|
||||
|
||||
std::string CheckBufferOverrun::MyFileInfo::toString() const
|
||||
{
|
||||
std::ostringstream ret;
|
||||
for (std::map<std::string, struct CheckBufferOverrun::MyFileInfo::ArrayUsage>::const_iterator it = arrayUsage.begin(); it != arrayUsage.end(); ++it) {
|
||||
ret << " <ArrayUsage"
|
||||
<< " array=\"" << ErrorLogger::toxml(it->first) << '\"'
|
||||
<< " index=\"" << it->second.index << '\"'
|
||||
<< " fileName=\"" << ErrorLogger::toxml(it->second.fileName) << '\"'
|
||||
<< " linenr=\"" << it->second.linenr << "\"/>\n";
|
||||
}
|
||||
for (std::map<std::string, MathLib::bigint>::const_iterator it = arraySize.begin(); it != arraySize.end(); ++it) {
|
||||
ret << " <ArraySize"
|
||||
<< " array=\"" << ErrorLogger::toxml(it->first) << '\"'
|
||||
<< " size=\"" << it->second << "\"/>\n";
|
||||
}
|
||||
return ret.str();
|
||||
}
|
||||
|
||||
Check::FileInfo* CheckBufferOverrun::getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const
|
||||
{
|
||||
(void)settings;
|
||||
|
|
|
@ -209,6 +209,8 @@ public:
|
|||
/* data for multifile checking */
|
||||
class MyFileInfo : public Check::FileInfo {
|
||||
public:
|
||||
std::string toString() const;
|
||||
|
||||
struct ArrayUsage {
|
||||
MathLib::bigint index;
|
||||
std::string fileName;
|
||||
|
|
|
@ -272,3 +272,19 @@ void CheckUnusedFunctions::analyseWholeProgram(const std::list<Check::FileInfo*>
|
|||
(void)fileInfo;
|
||||
check(&errorLogger, settings);
|
||||
}
|
||||
|
||||
std::string CheckUnusedFunctions::analyzerInfo(const std::string &filename) const
|
||||
{
|
||||
std::ostringstream ret;
|
||||
for (std::map<std::string, FunctionUsage>::const_iterator it = _functions.begin(); it != _functions.end(); ++it) {
|
||||
if (it->second.filename != filename)
|
||||
continue;
|
||||
ret << " <functionusage"
|
||||
<< " function=\"" << ErrorLogger::toxml(it->first) << '\"'
|
||||
<< " lineNumber=\"" << it->second.lineNumber << '\"'
|
||||
<< " usedSameFile=\"" << (it->second.usedSameFile?1:0) << '\"'
|
||||
<< " usedOtherFile=\"" << (it->second.usedOtherFile?1:0) << "\"/>\n";
|
||||
}
|
||||
return ret.str();
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,8 @@ public:
|
|||
|
||||
static CheckUnusedFunctions instance;
|
||||
|
||||
std::string analyzerInfo(const std::string &filename) const;
|
||||
|
||||
private:
|
||||
|
||||
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const {
|
||||
|
@ -72,9 +74,7 @@ private:
|
|||
/**
|
||||
* Dummy implementation, just to provide error for --errorlist
|
||||
*/
|
||||
void runSimplifiedChecks(const Tokenizer *, const Settings *, ErrorLogger *) {
|
||||
|
||||
}
|
||||
void runSimplifiedChecks(const Tokenizer *, const Settings *, ErrorLogger *) {}
|
||||
|
||||
static std::string myName() {
|
||||
return "Unused functions";
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include "check.h"
|
||||
#include "path.h"
|
||||
|
||||
#include "checkunusedfunctions.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
@ -135,6 +137,18 @@ unsigned int CppCheck::processFile(const std::string& filename, const std::strin
|
|||
tokens1.removeComments();
|
||||
preprocessor.removeComments();
|
||||
|
||||
if (!_settings.buildDir.empty()) {
|
||||
std::list<ErrorLogger::ErrorMessage> errors;
|
||||
unsigned int checksum = preprocessor.calculateChecksum(tokens1);
|
||||
if (!analyzerInformation.analyzeFile(_settings.buildDir, filename, checksum, &errors)) {
|
||||
while (!errors.empty()) {
|
||||
reportErr(errors.front());
|
||||
errors.pop_front();
|
||||
}
|
||||
return exitcode; // known results => no need to reanalyze file
|
||||
}
|
||||
}
|
||||
|
||||
// Get directives
|
||||
preprocessor.setDirectives(tokens1);
|
||||
|
||||
|
@ -343,6 +357,9 @@ unsigned int CppCheck::processFile(const std::string& filename, const std::strin
|
|||
exitcode=1; // e.g. reflect a syntax error
|
||||
}
|
||||
|
||||
analyzerInformation.setFileInfo("CheckUnusedFunctions", CheckUnusedFunctions::instance.analyzerInfo(filename));
|
||||
analyzerInformation.close();
|
||||
|
||||
// In jointSuppressionReport mode, unmatched suppressions are
|
||||
// collected after all files are processed
|
||||
if (!_settings.jointSuppressionReport && (_settings.isEnabled("information") || _settings.checkConfiguration)) {
|
||||
|
@ -411,8 +428,10 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer)
|
|||
// Analyse the tokens..
|
||||
for (std::list<Check *>::const_iterator it = Check::instances().begin(); it != Check::instances().end(); ++it) {
|
||||
Check::FileInfo *fi = (*it)->getFileInfo(&tokenizer, &_settings);
|
||||
if (fi != nullptr)
|
||||
if (fi != nullptr) {
|
||||
fileInfo.push_back(fi);
|
||||
analyzerInformation.setFileInfo((*it)->name(), fi->toString());
|
||||
}
|
||||
}
|
||||
|
||||
executeRules("normal", tokenizer);
|
||||
|
@ -635,6 +654,7 @@ void CppCheck::reportErr(const ErrorLogger::ErrorMessage &msg)
|
|||
_errorList.push_back(errmsg);
|
||||
|
||||
_errorLogger.reportErr(msg);
|
||||
analyzerInformation.reportErr(msg, _settings.verbose);
|
||||
}
|
||||
|
||||
void CppCheck::reportOut(const std::string &outmsg)
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "settings.h"
|
||||
#include "errorlogger.h"
|
||||
#include "check.h"
|
||||
#include "analyzerinfo.h"
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
@ -214,6 +215,8 @@ private:
|
|||
|
||||
/** File info used for whole program analysis */
|
||||
std::list<Check::FileInfo*> fileInfo;
|
||||
|
||||
AnalyzerInformation analyzerInformation;
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
|
|
@ -111,6 +111,23 @@ ErrorLogger::ErrorMessage::ErrorMessage(const std::list<const Token*>& callstack
|
|||
setmsg(msg);
|
||||
}
|
||||
|
||||
ErrorLogger::ErrorMessage::ErrorMessage(const tinyxml2::XMLElement * const errmsg) : _cwe(0U)
|
||||
{
|
||||
_id = errmsg->Attribute("id");
|
||||
_severity = Severity::fromString(errmsg->Attribute("severity"));
|
||||
const char *attr = errmsg->Attribute("cwe");
|
||||
std::istringstream(attr ? attr : "0") >> _cwe.id;
|
||||
attr = errmsg->Attribute("inconclusive");
|
||||
_inconclusive = attr && (std::strcmp(attr, "true") == 0);
|
||||
_shortMessage = errmsg->Attribute("msg");
|
||||
_verboseMessage = errmsg->Attribute("verbose");
|
||||
for (const tinyxml2::XMLElement *e = errmsg->FirstChildElement(); e; e = e->NextSiblingElement()) {
|
||||
if (std::strcmp(e->Name(),"location")==0) {
|
||||
_callStack.push_back(ErrorLogger::ErrorMessage::FileLocation(e->Attribute("file"), std::atoi(e->Attribute("line"))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ErrorLogger::ErrorMessage::setmsg(const std::string &msg)
|
||||
{
|
||||
// If a message ends to a '\n' and contains only a one '\n'
|
||||
|
|
|
@ -40,6 +40,9 @@ struct CWE {
|
|||
|
||||
class Token;
|
||||
class TokenList;
|
||||
namespace tinyxml2 {
|
||||
class XMLElement;
|
||||
}
|
||||
|
||||
/// @addtogroup Core
|
||||
/// @{
|
||||
|
@ -213,6 +216,7 @@ public:
|
|||
ErrorMessage(const std::list<const Token*>& callstack, const TokenList* list, Severity::SeverityType severity, const std::string& id, const std::string& msg, bool inconclusive);
|
||||
ErrorMessage(const std::list<const Token*>& callstack, const TokenList* list, Severity::SeverityType severity, const std::string& id, const std::string& msg, const CWE &cwe, bool inconclusive);
|
||||
ErrorMessage();
|
||||
ErrorMessage(const tinyxml2::XMLElement * const errmsg);
|
||||
|
||||
/**
|
||||
* Format the error message in XML format
|
||||
|
|
|
@ -4,6 +4,7 @@ include($$PWD/pcrerules.pri)
|
|||
include($$PWD/../externals/externals.pri)
|
||||
INCLUDEPATH += $$PWD
|
||||
HEADERS += $${PWD}/check.h \
|
||||
$${PWD}/analyzerinfo.h \
|
||||
$${PWD}/astutils.h \
|
||||
$${PWD}/check.h \
|
||||
$${PWD}/check64bit.h \
|
||||
|
@ -51,7 +52,8 @@ HEADERS += $${PWD}/check.h \
|
|||
$${PWD}/valueflow.h \
|
||||
|
||||
|
||||
SOURCES += $${PWD}/astutils.cpp \
|
||||
SOURCES += $${PWD}/analyzerinfo.cpp \
|
||||
$${PWD}/astutils.cpp \
|
||||
$${PWD}/check.cpp \
|
||||
$${PWD}/check64bit.cpp \
|
||||
$${PWD}/checkassert.cpp \
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "simplecpp.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <sstream>
|
||||
#include <cstdlib>
|
||||
#include <cctype>
|
||||
|
@ -806,3 +807,19 @@ void Preprocessor::dump(std::ostream &out) const
|
|||
}
|
||||
out << " </directivelist>" << std::endl;
|
||||
}
|
||||
|
||||
std::size_t Preprocessor::calculateChecksum(const simplecpp::TokenList &tokens1) const
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
for (const simplecpp::Token *tok = tokens1.cfront(); tok; tok = tok->next) {
|
||||
if (!tok->comment)
|
||||
ostr << tok->str;
|
||||
}
|
||||
for (std::map<std::string, simplecpp::TokenList *>::const_iterator it = tokenlists.begin(); it != tokenlists.end(); ++it) {
|
||||
for (const simplecpp::Token *tok = it->second->cfront(); tok; tok = tok->next) {
|
||||
if (!tok->comment)
|
||||
ostr << tok->str;
|
||||
}
|
||||
}
|
||||
return std::hash<std::string> {}(ostr.str());
|
||||
}
|
||||
|
|
|
@ -160,6 +160,8 @@ public:
|
|||
bool validateCfg(const std::string &cfg, const std::list<simplecpp::MacroUsage> ¯oUsageList);
|
||||
void validateCfgError(const std::string &file, const unsigned int line, const std::string &cfg, const std::string ¯o);
|
||||
|
||||
std::size_t calculateChecksum(const simplecpp::TokenList &tokens1) const;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
|
|
|
@ -56,6 +56,9 @@ private:
|
|||
public:
|
||||
Settings();
|
||||
|
||||
/** @brief --cppcheck-build-dir */
|
||||
std::string buildDir;
|
||||
|
||||
/** @brief Is --debug given? */
|
||||
bool debug;
|
||||
|
||||
|
|
Loading…
Reference in New Issue