diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index e26f97c6f..c97ef32b3 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -561,6 +561,25 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) } } + // Set maximum number of #ifdef configurations to check + else if (strncmp(argv[i], "--max-configs=", 14) == 0) + { + _settings->_force = false; + + std::istringstream iss(14+argv[i]); + if (!(iss >> _settings->_maxConfigs)) + { + PrintMessage("cppcheck: argument to '--max-configs=' is not a number"); + return false; + } + + if (_settings->_maxConfigs < 1) + { + PrintMessage("cppcheck: argument to '--max-configs=' must be greater than 0"); + return false; + } + } + // Print help else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { _pathnames.clear(); @@ -660,8 +679,9 @@ void CmdLineParser::PrintHelp() " --file-list= Specify the files to check in a text file. Add one\n" " filename per line. When file is -, the file list will\n" " be read from standard input.\n" - " -f, --force Force checking of all configurations in files that have\n" - " \"too many\" configurations.\n" + " -f, --force Force checking of all configurations in files. If used\n" + " together with --max-ifdefs=, the last option is the one\n" + " that is effective.\n" " -h, --help Print this help.\n" " -I Give include path. Give several -I parameters to give\n" " several paths. First given path is checked first. If\n" @@ -674,6 +694,11 @@ void CmdLineParser::PrintHelp() " more comments, like: // cppcheck-suppress warningId\n" " on the lines before the warning to suppress.\n" " -j Start [jobs] threads to do the checking simultaneously.\n" + " --max-configs=\n" + " Maximum number of configurations to check in a file\n" + " before skipping it. Default is 12. If used together\n" + " with --force, the last option is the one that is\n" + " effective.\n" " --platform= Specifies platform specific types and sizes. The\n" " available platforms are:\n" " * unix32\n" diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 7de38609f..e3071c6d0 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -195,9 +195,9 @@ unsigned int CppCheck::processFile() int checkCount = 0; for (std::list::const_iterator it = configurations.begin(); it != configurations.end(); ++it) { - // Check only 12 first configurations, after that bail out, unless --force + // Check only a few configurations (default 12), after that bail out, unless --force // was used. - if (!_settings._force && checkCount > 11) { + if (!_settings._force && checkCount >= _settings._maxConfigs) { const std::string fixedpath = Path::toNativeSeparators(_filename); ErrorLogger::ErrorMessage::FileLocation location; diff --git a/lib/settings.cpp b/lib/settings.cpp index 9ce9aa90a..5c347c919 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -38,6 +38,7 @@ Settings::Settings() _showtime = 0; // TODO: use enum _append = ""; _terminate = false; + _maxConfigs = 12; inconclusive = false; experimental = false; test_2_pass = false; diff --git a/lib/settings.h b/lib/settings.h index 2d26b4655..f33c6801f 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -121,6 +121,10 @@ public: /** @brief get append code (--append) */ std::string append() const; + /** @brief Maximum number of configurations to check before bailing. + Default is 12. (--max-configs=N) */ + int _maxConfigs; + /** * @brief Returns true if given id is in the list of * enabled extra checks (--enable) diff --git a/man/cppcheck.1.xml b/man/cppcheck.1.xml index adc51ff87..bb9884f42 100644 --- a/man/cppcheck.1.xml +++ b/man/cppcheck.1.xml @@ -116,6 +116,7 @@ man(1), man(7), http://www.tldp.org/HOWTO/Man-Page/ + @@ -253,7 +254,7 @@ Example: -DDEBUG=1 -D__cplusplus Force checking of files that have a lot of configurations. Error is printed if such a file is found so there is no reason to use this by -default. +default. If used together with --max-ifdefs=, the last option is the one that is effective. @@ -292,6 +293,13 @@ Directory name is matched to all parts of the path. Start <jobs> threads to do the checking work. + + + + Maximum number of configurations to check in a file before skipping it. Default is 12. If used together with --force, the last option is + the one that is effective. + + diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index c9147c3d2..45df69fda 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -74,6 +74,10 @@ private: TEST_CASE(jobs); TEST_CASE(jobsMissingCount); TEST_CASE(jobsInvalid); + TEST_CASE(maxConfigs); + TEST_CASE(maxConfigsMissingCount); + TEST_CASE(maxConfigsInvalid); + TEST_CASE(maxConfigsTooSmall); TEST_CASE(reportProgressTest); // "Test" suffix to avoid hiding the parent's reportProgress TEST_CASE(stdposix); TEST_CASE(stdc99); @@ -537,6 +541,43 @@ private: ASSERT_EQUALS(false, parser.ParseFromArgs(4, argv)); } + void maxConfigs() { + REDIRECT; + const char *argv[] = {"cppcheck", "-f", "--max-configs=12", "file.cpp"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT(parser.ParseFromArgs(4, argv)); + ASSERT_EQUALS(12, settings._maxConfigs); + ASSERT_EQUALS(false, settings._force); + } + + void maxConfigsMissingCount() { + REDIRECT; + const char *argv[] = {"cppcheck", "--max-configs=", "file.cpp"}; + Settings settings; + CmdLineParser parser(&settings); + // Fails since --max-configs= is missing limit + ASSERT_EQUALS(false, parser.ParseFromArgs(3, argv)); + } + + void maxConfigsInvalid() { + REDIRECT; + const char *argv[] = {"cppcheck", "--max-configs=e", "file.cpp"}; + Settings settings; + CmdLineParser parser(&settings); + // Fails since invalid count given for --max-configs= + ASSERT_EQUALS(false, parser.ParseFromArgs(3, argv)); + } + + void maxConfigsTooSmall() { + REDIRECT; + const char *argv[] = {"cppcheck", "--max-configs=0", "file.cpp"}; + Settings settings; + CmdLineParser parser(&settings); + // Fails since limit must be greater than 0 + ASSERT_EQUALS(false, parser.ParseFromArgs(3, argv)); + } + void reportProgressTest() { REDIRECT; const char *argv[] = {"cppcheck", "--report-progress", "file.cpp"};