diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index e2a575533cc3..436edc944d52 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -764,7 +764,14 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) // Report progress else if (std::strcmp(argv[i], "--report-progress") == 0) { - mSettings.reportProgress = true; + mSettings.reportProgress = 10; + } + + else if (std::strncmp(argv[i], "--report-progress=", 18) == 0) { + int tmp; + if (!parseNumberArg(argv[i], 18, tmp, true)) + return false; + mSettings.reportProgress = tmp; } #ifdef HAVE_RULES @@ -1298,7 +1305,7 @@ void CmdLineParser::printHelp() " using e.g. ~ for home folder does not work. It is\n" " currently only possible to apply the base paths to\n" " files that are on a lower level in the directory tree.\n" - " --report-progress Report progress messages while checking a file.\n" + " --report-progress Report progress messages while checking a file (single job only).\n" #ifdef HAVE_RULES " --rule= Match regular expression.\n" " --rule-file= Use given rule file. For more information, see:\n" diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 540619939e22..a0bf72d4b390 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -276,7 +276,7 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck) { Settings& settings = cppcheck.settings(); - if (settings.reportProgress) + if (settings.reportProgress >= 0) mLatestProgressOutputTime = std::time(nullptr); if (!settings.outputFile.empty()) { @@ -399,6 +399,7 @@ void CppCheckExecutor::reportOut(const std::string &outmsg, Color c) std::cout << c << ansiToOEM(outmsg, true) << Color::Reset << std::endl; } +// TODO: remove filename parameter? void CppCheckExecutor::reportProgress(const std::string &filename, const char stage[], const std::size_t value) { (void)filename; @@ -406,9 +407,10 @@ void CppCheckExecutor::reportProgress(const std::string &filename, const char st if (!mLatestProgressOutputTime) return; - // Report progress messages every 10 seconds + // Report progress messages every x seconds const std::time_t currentTime = std::time(nullptr); - if (currentTime >= (mLatestProgressOutputTime + 10)) { + if (mSettings->reportProgress == 0 || (currentTime >= (mLatestProgressOutputTime + mSettings->reportProgress))) + { mLatestProgressOutputTime = currentTime; // format a progress message diff --git a/lib/settings.h b/lib/settings.h index ab27b1dbd4dd..afb7e981f0ed 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -267,7 +267,7 @@ class CPPCHECKLIB WARN_UNUSED Settings { bool relativePaths{}; /** @brief --report-progress */ - bool reportProgress{}; + int reportProgress{-1}; /** Rule */ struct CPPCHECKLIB Rule { diff --git a/test/cli/test-other.py b/test/cli/test-other.py index 5d9af040861a..a630699a1157 100644 --- a/test/cli/test-other.py +++ b/test/cli/test-other.py @@ -91,3 +91,53 @@ def test_message_j(tmpdir): assert stdout == "Checking {} ...\n".format(test_file) # we were adding stray \0 characters at the end # TODO: test missing std.cfg + + +def test_progress(tmpdir): + test_file = os.path.join(tmpdir, 'test.c') + with open(test_file, 'wt') as f: + f.write(""" + int main(int argc) + { + } + """) + + args = ['--report-progress=0', '--enable=all', '--inconclusive', '--platform=native', test_file] + + exitcode, stdout, stderr = cppcheck(args) + assert exitcode == 0 + pos = stdout.find('\n') + assert(pos != -1) + pos += 1 + assert stdout[:pos] == "Checking {} ...\n".format(test_file) + assert (stdout[pos:] == + "progress: Tokenize (typedef) 0%\n" + "progress: Tokenize (typedef) 12%\n" + "progress: Tokenize (typedef) 25%\n" + "progress: Tokenize (typedef) 37%\n" + "progress: Tokenize (typedef) 50%\n" + "progress: Tokenize (typedef) 62%\n" + "progress: Tokenize (typedef) 75%\n" + "progress: Tokenize (typedef) 87%\n" + "progress: SymbolDatabase 0%\n" + "progress: SymbolDatabase 12%\n" + "progress: SymbolDatabase 87%\n" + ) + assert stderr == "" + + +def test_progress_j(tmpdir): + test_file = os.path.join(tmpdir, 'test.c') + with open(test_file, 'wt') as f: + f.write(""" + int main(int argc) + { + } + """) + + args = ['--report-progress=0', '--enable=all', '--inconclusive', '-j2', '--disable=unusedFunction', '--platform=native', test_file] + + exitcode, stdout, stderr = cppcheck(args) + assert exitcode == 0 + assert stdout == "Checking {} ...\n".format(test_file) + assert stderr == "" diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 54e844f899dc..1eede5650e70 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -148,7 +148,11 @@ class TestCmdlineParser : public TestFixture { TEST_CASE(maxConfigsMissingCount); TEST_CASE(maxConfigsInvalid); TEST_CASE(maxConfigsTooSmall); - TEST_CASE(reportProgressTest); // "Test" suffix to avoid hiding the parent's reportProgress + TEST_CASE(reportProgress1); + TEST_CASE(reportProgress2); + TEST_CASE(reportProgress3); + TEST_CASE(reportProgress4); + TEST_CASE(reportProgress5); TEST_CASE(stdc99); TEST_CASE(stdcpp11); TEST_CASE(stdunknown1); @@ -1060,12 +1064,46 @@ class TestCmdlineParser : public TestFixture { ASSERT_EQUALS("cppcheck: error: argument to '--max-configs=' must be greater than 0.\n", GET_REDIRECT_OUTPUT); } - void reportProgressTest() { + void reportProgress1() { REDIRECT; const char * const argv[] = {"cppcheck", "--report-progress", "file.cpp"}; - settings->reportProgress = false; + settings->reportProgress = -1; ASSERT(parser->parseFromArgs(3, argv)); - ASSERT(settings->reportProgress); + ASSERT_EQUALS(10, settings->reportProgress); + ASSERT_EQUALS("", GET_REDIRECT_OUTPUT); + } + + void reportProgress2() { + REDIRECT; + const char * const argv[] = {"cppcheck", "--report-progress=", "file.cpp"}; + settings->reportProgress = -1; + ASSERT(!parser->parseFromArgs(3, argv)); + ASSERT_EQUALS("cppcheck: error: argument to '--report-progress=' is not valid - not an integer.\n", GET_REDIRECT_OUTPUT); + } + + void reportProgress3() { + REDIRECT; + const char * const argv[] = {"cppcheck", "--report-progress=-1", "file.cpp"}; + settings->reportProgress = -1; + ASSERT(!parser->parseFromArgs(3, argv)); + ASSERT_EQUALS("cppcheck: error: argument to '--report-progress=' needs to be a positive integer.\n", GET_REDIRECT_OUTPUT); + } + + void reportProgress4() { + REDIRECT; + const char * const argv[] = {"cppcheck", "--report-progress=0", "file.cpp"}; + settings->reportProgress = -1; + ASSERT(parser->parseFromArgs(3, argv)); + ASSERT_EQUALS(0, settings->reportProgress); + ASSERT_EQUALS("", GET_REDIRECT_OUTPUT); + } + + void reportProgress5() { + REDIRECT; + const char * const argv[] = {"cppcheck", "--report-progress=1", "file.cpp"}; + settings->reportProgress = -1; + ASSERT(parser->parseFromArgs(3, argv)); + ASSERT_EQUALS(1, settings->reportProgress); ASSERT_EQUALS("", GET_REDIRECT_OUTPUT); }