diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 09009752a..787695f28 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -573,6 +573,12 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) } #endif + // Check configuration + else if (strcmp(argv[i], "--check-includes") == 0) + { + _settings->checkIncludes = true; + } + // Print help else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 8e42a96cf..86ac5dcb0 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -19,6 +19,8 @@ #include "cppcheckexecutor.h" #include "cppcheck.h" #include "threadexecutor.h" +#include "preprocessor.h" +#include "errorlogger.h" #include #include #include // EXIT_SUCCESS and EXIT_FAILURE @@ -131,6 +133,8 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c int CppCheckExecutor::check(int argc, const char* const argv[]) { + Preprocessor::missingIncludeFlag = false; + CppCheck cppCheck(*this, true); if (!parseFromArgs(&cppCheck, argc, argv)) { @@ -181,7 +185,26 @@ int CppCheckExecutor::check(int argc, const char* const argv[]) returnValue = executor.check(); } - reportUnmatchedSuppressions(cppCheck.settings().nomsg.getUnmatchedGlobalSuppressions()); + if (!cppCheck.settings().checkConfiguration()) + { + reportUnmatchedSuppressions(cppCheck.settings().nomsg.getUnmatchedGlobalSuppressions()); + + if (Preprocessor::missingIncludeFlag) + { + const std::list callStack; + ErrorLogger::ErrorMessage msg(callStack, + Severity::information, + "Cppcheck cannot find all the include files (--check-includes)\n" + "Cppcheck cannot find all the include files. Cpppcheck can check the code without the " + "include files found. But the results will probably be more accurate if all the include " + "files are found. Please check your project's include directories and add all of them " + "as include directories for Cppcheck. To see what files Cppcheck cannot find use " + "--check-includes.", + "missingInclude", + false); + reportErr(msg); + } + } if (_settings._xml) { diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index d219870ab..97b0c6c65 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -122,6 +122,11 @@ unsigned int CppCheck::processFile() preprocessor.preprocess(fin, filedata, configurations, _filename, _settings._includePaths); } + if (_settings.checkConfiguration()) + { + return 0; + } + _settings.ifcfg = bool(configurations.size() > 1); if (!_settings.userDefines.empty()) @@ -212,6 +217,11 @@ void CppCheck::analyseFile(std::istream &fin, const std::string &filename) preprocessor.preprocess(fin, filedata, configurations, filename, _settings._includePaths); const std::string code = Preprocessor::getcode(filedata, "", filename, &_settings, &_errorLogger); + if (_settings.checkConfiguration()) + { + return; + } + // Tokenize.. Tokenizer tokenizer(&_settings, this); std::istringstream istr(code); @@ -240,7 +250,7 @@ void CppCheck::analyseFile(std::istream &fin, const std::string &filename) void CppCheck::checkFile(const std::string &code, const char FileName[]) { - if (_settings.terminated()) + if (_settings.terminated() || _settings.checkConfiguration()) return; Tokenizer _tokenizer(&_settings, this); diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index de87dd825..cd22dc2af 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -35,6 +35,8 @@ #include #include +bool Preprocessor::missingIncludeFlag; + Preprocessor::Preprocessor(Settings *settings, ErrorLogger *errorLogger) : _settings(settings), _errorLogger(errorLogger) { @@ -1930,7 +1932,12 @@ void Preprocessor::handleIncludes(std::string &code, const std::string &filePath } else if (!fileOpened) { - if (_errorLogger && _settings && ((headerType == UserHeader && _settings->isEnabled("missingInclude")) || _settings->debugwarnings)) + missingIncludeFlag = true; + + if (_errorLogger && + _settings && + _settings->checkIncludes && + (headerType == UserHeader || _settings->debugwarnings)) { std::string f = filePath; diff --git a/lib/preprocessor.h b/lib/preprocessor.h index 1d670a32e..4f9eefd7f 100644 --- a/lib/preprocessor.h +++ b/lib/preprocessor.h @@ -53,6 +53,8 @@ public: Preprocessor(Settings *settings = 0, ErrorLogger *errorLogger = 0); + static bool missingIncludeFlag; + /** * Extract the code for each configuration * @param istr The (file/string) stream to read from. diff --git a/lib/settings.cpp b/lib/settings.cpp index 1c560321e..d20a81f8f 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -47,6 +47,7 @@ Settings::Settings() test_2_pass = false; reportProgress = false; ifcfg = false; + checkIncludes = false; } std::string Settings::Suppressions::parseFile(std::istream &istr) diff --git a/lib/settings.h b/lib/settings.h index 03da57a65..5646ddce1 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -300,6 +300,15 @@ public: * @brief Extra rules */ std::list rules; + + /** Is the 'configuration checking' wanted? */ + bool checkConfiguration() const + { + return checkIncludes; + } + + /** Check configuration: includes */ + bool checkIncludes; }; /// @}