From dbc5a829dd3dc85371d9352428c776938c7b5a8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 19 Feb 2026 21:30:52 +0100 Subject: [PATCH 1/7] Fix #14516 (Review progress messages) --- lib/cppcheck.cpp | 2 ++ lib/errorlogger.h | 36 ++++++++++++++++++++++++++++++++++++ lib/symboldatabase.cpp | 11 +++++------ lib/tokenize.cpp | 10 ++++------ lib/valueflow.cpp | 4 ++++ 5 files changed, 51 insertions(+), 12 deletions(-) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index de3bcd1530a..b8f38c16578 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1316,6 +1316,8 @@ void CppCheck::internalError(const std::string &filename, const std::string &msg void CppCheck::checkNormalTokens(const Tokenizer &tokenizer, AnalyzerInformation* analyzerInformation, const std::string& currentConfig) { + ProgressReporter(mErrorLogger, mSettings.reportProgress >= 0, tokenizer.list.getSourceFilePath(), "Run checkers"); + CheckUnusedFunctions unusedFunctionsChecker; // TODO: this should actually be the behavior if only "--enable=unusedFunction" is specified - see #10648 diff --git a/lib/errorlogger.h b/lib/errorlogger.h index f8806bbbdca..9564e4bfd69 100644 --- a/lib/errorlogger.h +++ b/lib/errorlogger.h @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -286,6 +287,41 @@ class CPPCHECKLIB ErrorLogger { static const std::set mCriticalErrorIds; }; +/// RAII class for reporting progress messages +class CPPCHECKLIB ProgressReporter { +public: + ProgressReporter(ErrorLogger& e, bool reportProgress, const std::string& filename, const std::string& stage) : + errorLogger(e), + reportProgress(reportProgress), + filename(filename), + stage(stage) { + if (reportProgress) + errorLogger.reportProgress(filename, stage.c_str(), 0); + } + + ~ProgressReporter() { + if (reportProgress) + errorLogger.reportProgress(filename, stage.c_str(), 100); + } + + void report(int value) { + if (!reportProgress) + return; + const auto t = std::time(nullptr); + if (t != lastTime) { + errorLogger.reportProgress(filename, stage.c_str(), value); + lastTime = t; + } + } + +private: + ErrorLogger& errorLogger; + const bool reportProgress; + const std::string filename; + const std::string stage; + std::time_t lastTime{0}; +}; + /** Replace substring. Example replaceStr("1,NR,3", "NR", "2") => "1,2,3" */ std::string replaceStr(std::string s, const std::string &from, const std::string &to); diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index f5ffa4e1604..548b6a27fdd 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -174,8 +174,6 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() // Store current access in each scope (depends on evaluation progress) std::map access; - const bool doProgress = (mSettings.reportProgress != -1); - std::map> forwardDecls; const std::function findForwardDeclScope = [&](const Token *tok, Scope *startScope) { @@ -200,13 +198,14 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() return it->second.count(tok->str()) > 0 ? startScope : nullptr; }; + ProgressReporter progressReporter(mErrorLogger, (mSettings.reportProgress >= 0), mTokenizer.list.getSourceFilePath(), "SymbolDatabase (find all scopes)"); + // find all scopes for (const Token *tok = mTokenizer.tokens(); tok; tok = tok ? tok->next() : nullptr) { // #5593 suggested to add here: - if (doProgress) - mErrorLogger.reportProgress(mTokenizer.list.getSourceFilePath(), - "SymbolDatabase", - tok->progressValue()); + + progressReporter.report(tok->progressValue()); + // Locate next class if ((tok->isCpp() && tok->isKeyword() && ((Token::Match(tok, "class|struct|union|namespace ::| %name% final| {|:|::|<") && diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 7c15be961bc..352c917f73b 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1167,11 +1167,10 @@ void Tokenizer::simplifyTypedefCpp() std::vector spaceInfo(1); const std::time_t maxTime = mSettings.typedefMaxTime > 0 ? std::time(nullptr) + mSettings.typedefMaxTime: 0; - const bool doProgress = (mSettings.reportProgress != -1) && !list.getFiles().empty(); + ProgressReporter progressReporter(mErrorLogger, (mSettings.reportProgress >= 0), list.getSourceFilePath(), "Tokenize (typedef)"); for (Token *tok = list.front(); tok; tok = tok->next()) { - if (doProgress) - mErrorLogger.reportProgress(list.getFiles()[0], "Tokenize (typedef)", tok->progressValue()); + progressReporter.report(tok->progressValue()); if (Settings::terminated()) return; @@ -2932,11 +2931,10 @@ bool Tokenizer::simplifyUsing() }; std::list usingList; - const bool doProgress = (mSettings.reportProgress != -1) && !list.getFiles().empty(); + ProgressReporter progressReporter(mErrorLogger, (mSettings.reportProgress >= 0), list.getSourceFilePath(), "Tokenize (using)"); for (Token *tok = list.front(); tok; tok = tok->next()) { - if (doProgress) - mErrorLogger.reportProgress(list.getFiles()[0], "Tokenize (using)", tok->progressValue()); + progressReporter.report(tok->progressValue()); if (Settings::terminated()) return substitute; diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 7aa0ce4aac6..c519b7eeafe 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -7202,7 +7202,9 @@ struct ValueFlowPassRunner { std::size_t n = state.settings.vfOptions.maxIterations; while (n > 0 && values != getTotalValues()) { values = getTotalValues(); + const std::string passnum = std::to_string(state.settings.vfOptions.maxIterations - n + 1); if (std::any_of(passes.begin(), passes.end(), [&](const ValuePtr& pass) { + ProgressReporter progressReporter(state.errorLogger, state.settings.reportProgress >= 0, state.tokenlist.getSourceFilePath(), std::string("ValueFlow::") + pass->name() + (' ' + passnum)); return run(pass); })) return true; @@ -7346,6 +7348,8 @@ void ValueFlow::setValues(TokenList& tokenlist, const Settings& settings, TimerResultsIntf* timerResults) { + ProgressReporter progressReporter(errorLogger, settings.reportProgress >= 0, tokenlist.getSourceFilePath(), "ValueFlow"); + for (Token* tok = tokenlist.front(); tok; tok = tok->next()) tok->clearValueFlow(); From d888cbac77af74c17abf43275ecdced06ae78f1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 19 Feb 2026 21:40:27 +0100 Subject: [PATCH 2/7] progress for addons --- lib/cppcheck.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index b8f38c16578..a3e9816953e 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1516,6 +1516,8 @@ void CppCheck::executeAddons(const std::vector& files, const std::s if (isCtuInfo && addonInfo.name != "misra" && !addonInfo.ctu) continue; + ProgressReporter(mErrorLogger, mSettings.reportProgress >= 0, files.front(), "addon:" + addonInfo.name + (isCtuInfo ? " (ctu)" : "")); + std::vector results; try { From f8f35f6dbc06864761cec7005b9c0ddd236c666e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 19 Feb 2026 21:54:38 +0100 Subject: [PATCH 3/7] ci --- .github/workflows/selfcheck.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/selfcheck.yml b/.github/workflows/selfcheck.yml index d0c0f233dd2..804de21a0b4 100644 --- a/.github/workflows/selfcheck.yml +++ b/.github/workflows/selfcheck.yml @@ -121,7 +121,7 @@ jobs: - name: Self check (unusedFunction / no test / no gui) run: | - supprs="--suppress=unusedFunction:lib/errorlogger.h:196 --suppress=unusedFunction:lib/importproject.cpp:1531 --suppress=unusedFunction:lib/importproject.cpp:1555" + supprs="--suppress=unusedFunction:lib/errorlogger.h:197 --suppress=unusedFunction:lib/importproject.cpp:1531 --suppress=unusedFunction:lib/importproject.cpp:1555" ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib -D__CPPCHECK__ -D__GNUC__ --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output.notest_nogui/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr $supprs env: DISABLE_VALUEFLOW: 1 From a6bc1d4d792bc99862b587cf45f823a80103372f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 19 Feb 2026 22:03:39 +0100 Subject: [PATCH 4/7] clang-tidy --- lib/cppcheck.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index a3e9816953e..e61b9a77edc 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1316,7 +1316,7 @@ void CppCheck::internalError(const std::string &filename, const std::string &msg void CppCheck::checkNormalTokens(const Tokenizer &tokenizer, AnalyzerInformation* analyzerInformation, const std::string& currentConfig) { - ProgressReporter(mErrorLogger, mSettings.reportProgress >= 0, tokenizer.list.getSourceFilePath(), "Run checkers"); + const ProgressReporter progressReporter(mErrorLogger, mSettings.reportProgress >= 0, tokenizer.list.getSourceFilePath(), "Run checkers"); CheckUnusedFunctions unusedFunctionsChecker; From 5cdced971034129b0339feb3b2d17e171a1c04d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 19 Feb 2026 22:57:19 +0100 Subject: [PATCH 5/7] ci --- lib/cppcheck.cpp | 4 +-- lib/errorlogger.h | 21 +++++++------- lib/symboldatabase.cpp | 2 +- lib/tokenize.cpp | 4 +-- lib/valueflow.cpp | 2 +- test/cli/other_test.py | 64 ++++++++++++++++++++++++++++++++++++++++-- 6 files changed, 78 insertions(+), 19 deletions(-) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index e61b9a77edc..e2239cf89f3 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1316,7 +1316,7 @@ void CppCheck::internalError(const std::string &filename, const std::string &msg void CppCheck::checkNormalTokens(const Tokenizer &tokenizer, AnalyzerInformation* analyzerInformation, const std::string& currentConfig) { - const ProgressReporter progressReporter(mErrorLogger, mSettings.reportProgress >= 0, tokenizer.list.getSourceFilePath(), "Run checkers"); + const ProgressReporter progressReporter(mErrorLogger, mSettings.reportProgress, tokenizer.list.getSourceFilePath(), "Run checkers"); CheckUnusedFunctions unusedFunctionsChecker; @@ -1516,7 +1516,7 @@ void CppCheck::executeAddons(const std::vector& files, const std::s if (isCtuInfo && addonInfo.name != "misra" && !addonInfo.ctu) continue; - ProgressReporter(mErrorLogger, mSettings.reportProgress >= 0, files.front(), "addon:" + addonInfo.name + (isCtuInfo ? " (ctu)" : "")); + ProgressReporter(mErrorLogger, mSettings.reportProgress, files.front(), "addon:" + addonInfo.name + (isCtuInfo ? " (ctu)" : "")); std::vector results; diff --git a/lib/errorlogger.h b/lib/errorlogger.h index 9564e4bfd69..daeac3618ed 100644 --- a/lib/errorlogger.h +++ b/lib/errorlogger.h @@ -290,36 +290,37 @@ class CPPCHECKLIB ErrorLogger { /// RAII class for reporting progress messages class CPPCHECKLIB ProgressReporter { public: - ProgressReporter(ErrorLogger& e, bool reportProgress, const std::string& filename, const std::string& stage) : + ProgressReporter(ErrorLogger& e, int reportProgressInterval, const std::string& filename, const std::string& stage) : errorLogger(e), - reportProgress(reportProgress), + reportProgressInterval(reportProgressInterval), filename(filename), stage(stage) { - if (reportProgress) - errorLogger.reportProgress(filename, stage.c_str(), 0); + report(0); } ~ProgressReporter() { - if (reportProgress) - errorLogger.reportProgress(filename, stage.c_str(), 100); + lastTime = 0; + errorLogger.reportProgress(filename, stage.c_str(), 100); } void report(int value) { - if (!reportProgress) + if (reportProgressInterval < 0 || value == lastValue) return; - const auto t = std::time(nullptr); - if (t != lastTime) { + const std::time_t t = std::time(nullptr); + if (t >= lastTime + reportProgressInterval) { errorLogger.reportProgress(filename, stage.c_str(), value); lastTime = t; + lastValue = value; } } private: ErrorLogger& errorLogger; - const bool reportProgress; + const int reportProgressInterval; const std::string filename; const std::string stage; std::time_t lastTime{0}; + int lastValue{-1}; }; /** Replace substring. Example replaceStr("1,NR,3", "NR", "2") => "1,2,3" */ diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 548b6a27fdd..3ac133ac716 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -198,7 +198,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() return it->second.count(tok->str()) > 0 ? startScope : nullptr; }; - ProgressReporter progressReporter(mErrorLogger, (mSettings.reportProgress >= 0), mTokenizer.list.getSourceFilePath(), "SymbolDatabase (find all scopes)"); + ProgressReporter progressReporter(mErrorLogger, mSettings.reportProgress, mTokenizer.list.getSourceFilePath(), "SymbolDatabase (find all scopes)"); // find all scopes for (const Token *tok = mTokenizer.tokens(); tok; tok = tok ? tok->next() : nullptr) { diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 352c917f73b..e68f27e619c 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1167,7 +1167,7 @@ void Tokenizer::simplifyTypedefCpp() std::vector spaceInfo(1); const std::time_t maxTime = mSettings.typedefMaxTime > 0 ? std::time(nullptr) + mSettings.typedefMaxTime: 0; - ProgressReporter progressReporter(mErrorLogger, (mSettings.reportProgress >= 0), list.getSourceFilePath(), "Tokenize (typedef)"); + ProgressReporter progressReporter(mErrorLogger, mSettings.reportProgress, list.getSourceFilePath(), "Tokenize (typedef)"); for (Token *tok = list.front(); tok; tok = tok->next()) { progressReporter.report(tok->progressValue()); @@ -2931,7 +2931,7 @@ bool Tokenizer::simplifyUsing() }; std::list usingList; - ProgressReporter progressReporter(mErrorLogger, (mSettings.reportProgress >= 0), list.getSourceFilePath(), "Tokenize (using)"); + ProgressReporter progressReporter(mErrorLogger, mSettings.reportProgress, list.getSourceFilePath(), "Tokenize (using)"); for (Token *tok = list.front(); tok; tok = tok->next()) { progressReporter.report(tok->progressValue()); diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index c519b7eeafe..53b15089975 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -7348,7 +7348,7 @@ void ValueFlow::setValues(TokenList& tokenlist, const Settings& settings, TimerResultsIntf* timerResults) { - ProgressReporter progressReporter(errorLogger, settings.reportProgress >= 0, tokenlist.getSourceFilePath(), "ValueFlow"); + ProgressReporter progressReporter(errorLogger, settings.reportProgress, tokenlist.getSourceFilePath(), "ValueFlow"); for (Token* tok = tokenlist.front(); tok; tok = tok->next()) tok->clearValueFlow(); diff --git a/test/cli/other_test.py b/test/cli/other_test.py index 86a5c023bbc..aca118456b2 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -169,9 +169,67 @@ def test_progress(tmpdir): "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" + "progress: Tokenize (typedef) 100%\n" + "progress: SymbolDatabase (find all scopes) 0%\n" + "progress: SymbolDatabase (find all scopes) 12%\n" + "progress: SymbolDatabase (find all scopes) 87%\n" + "progress: SymbolDatabase (find all scopes) 100%\n" + "progress: ValueFlow 0%\n" + "progress: ValueFlow::valueFlowImpossibleValues(tokenlist, settings) 1 0%\n" + "progress: ValueFlow::valueFlowImpossibleValues(tokenlist, settings) 1 100%\n" + "progress: ValueFlow::valueFlowSymbolicOperators(symboldatabase, settings) 1 0%\n" + "progress: ValueFlow::valueFlowSymbolicOperators(symboldatabase, settings) 1 100%\n" + "progress: ValueFlow::valueFlowCondition(SymbolicConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 0%\n" + "progress: ValueFlow::valueFlowCondition(SymbolicConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 100%\n" + "progress: ValueFlow::valueFlowSymbolicInfer(symboldatabase, settings) 1 0%\n" + "progress: ValueFlow::valueFlowSymbolicInfer(symboldatabase, settings) 1 100%\n" + "progress: ValueFlow::valueFlowArrayBool(tokenlist, settings) 1 0%\n" + "progress: ValueFlow::valueFlowArrayBool(tokenlist, settings) 1 100%\n" + "progress: ValueFlow::valueFlowArrayElement(tokenlist, settings) 1 0%\n" + "progress: ValueFlow::valueFlowArrayElement(tokenlist, settings) 1 100%\n" + "progress: ValueFlow::valueFlowRightShift(tokenlist, settings) 1 0%\n" + "progress: ValueFlow::valueFlowRightShift(tokenlist, settings) 1 100%\n" + "progress: ValueFlow::valueFlowCondition(ContainerConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 0%\n" + "progress: ValueFlow::valueFlowCondition(ContainerConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 100%\n" + "progress: ValueFlow::valueFlowAfterAssign(tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 0%\n" + "progress: ValueFlow::valueFlowAfterAssign(tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 100%\n" + "progress: ValueFlow::valueFlowAfterSwap(tokenlist, symboldatabase, errorLogger, settings) 1 0%\n" + "progress: ValueFlow::valueFlowAfterSwap(tokenlist, symboldatabase, errorLogger, settings) 1 100%\n" + "progress: ValueFlow::valueFlowCondition(SimpleConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 0%\n" + "progress: ValueFlow::valueFlowCondition(SimpleConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 100%\n" + "progress: ValueFlow::valueFlowInferCondition(tokenlist, settings) 1 0%\n" + "progress: ValueFlow::valueFlowInferCondition(tokenlist, settings) 1 100%\n" + "progress: ValueFlow::valueFlowSwitchVariable(tokenlist, symboldatabase, errorLogger, settings) 1 0%\n" + "progress: ValueFlow::valueFlowSwitchVariable(tokenlist, symboldatabase, errorLogger, settings) 1 100%\n" + "progress: ValueFlow::valueFlowForLoop(tokenlist, symboldatabase, errorLogger, settings) 1 0%\n" + "progress: ValueFlow::valueFlowForLoop(tokenlist, symboldatabase, errorLogger, settings) 1 100%\n" + "progress: ValueFlow::valueFlowSubFunction(tokenlist, symboldatabase, errorLogger, settings) 1 0%\n" + "progress: ValueFlow::valueFlowSubFunction(tokenlist, symboldatabase, errorLogger, settings) 1 100%\n" + "progress: ValueFlow::valueFlowFunctionReturn(tokenlist, errorLogger, settings) 1 0%\n" + "progress: ValueFlow::valueFlowFunctionReturn(tokenlist, errorLogger, settings) 1 100%\n" + "progress: ValueFlow::valueFlowLifetime(tokenlist, errorLogger, settings) 1 0%\n" + "progress: ValueFlow::valueFlowLifetime(tokenlist, errorLogger, settings) 1 100%\n" + "progress: ValueFlow::valueFlowFunctionDefaultParameter(tokenlist, symboldatabase, errorLogger, settings) 1 0%\n" + "progress: ValueFlow::valueFlowFunctionDefaultParameter(tokenlist, symboldatabase, errorLogger, settings) 1 100%\n" + "progress: ValueFlow::valueFlowUninit(tokenlist, errorLogger, settings) 1 0%\n" + "progress: ValueFlow::valueFlowUninit(tokenlist, errorLogger, settings) 1 100%\n" + "progress: ValueFlow::valueFlowAfterMove(tokenlist, symboldatabase, errorLogger, settings) 1 0%\n" + "progress: ValueFlow::valueFlowAfterMove(tokenlist, symboldatabase, errorLogger, settings) 1 100%\n" + "progress: ValueFlow::valueFlowSmartPointer(tokenlist, errorLogger, settings) 1 0%\n" + "progress: ValueFlow::valueFlowSmartPointer(tokenlist, errorLogger, settings) 1 100%\n" + "progress: ValueFlow::valueFlowIterators(tokenlist, settings) 1 0%\n" + "progress: ValueFlow::valueFlowIterators(tokenlist, settings) 1 100%\n" + "progress: ValueFlow::valueFlowCondition(IteratorConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 0%\n" + "progress: ValueFlow::valueFlowCondition(IteratorConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 100%\n" + "progress: ValueFlow::valueFlowIteratorInfer(tokenlist, settings) 1 0%\n" + "progress: ValueFlow::valueFlowIteratorInfer(tokenlist, settings) 1 100%\n" + "progress: ValueFlow::valueFlowContainerSize(tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 0%\n" + "progress: ValueFlow::valueFlowContainerSize(tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 100%\n" + "progress: ValueFlow::valueFlowSafeFunctions(tokenlist, symboldatabase, errorLogger, settings) 1 0%\n" + "progress: ValueFlow::valueFlowSafeFunctions(tokenlist, symboldatabase, errorLogger, settings) 1 100%\n" + "progress: ValueFlow 100%\n" + "progress: Run checkers 0%\n" + "progress: Run checkers 100%\n" ) assert stderr == "" From 6a164fc39ef6e4e5b0dbf33e8527d30b87737b0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 19 Feb 2026 23:16:54 +0100 Subject: [PATCH 6/7] clang-tidy --- lib/errorlogger.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/errorlogger.h b/lib/errorlogger.h index daeac3618ed..26cf6b1dbb8 100644 --- a/lib/errorlogger.h +++ b/lib/errorlogger.h @@ -290,11 +290,11 @@ class CPPCHECKLIB ErrorLogger { /// RAII class for reporting progress messages class CPPCHECKLIB ProgressReporter { public: - ProgressReporter(ErrorLogger& e, int reportProgressInterval, const std::string& filename, const std::string& stage) : + ProgressReporter(ErrorLogger& e, int reportProgressInterval, std::string filename, std::string stage) : errorLogger(e), reportProgressInterval(reportProgressInterval), - filename(filename), - stage(stage) { + filename(std::move(filename)), + stage(std::move(stage)) { report(0); } From d7bb76f26dc487cceef1ba9104c4b203cfdd4f80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 20 Feb 2026 07:28:08 +0100 Subject: [PATCH 7/7] ci --- lib/cppcheck.cpp | 2 +- lib/errorlogger.h | 33 ++++++++++++++++----------------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index e2239cf89f3..a3d2bb0f161 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1516,7 +1516,7 @@ void CppCheck::executeAddons(const std::vector& files, const std::s if (isCtuInfo && addonInfo.name != "misra" && !addonInfo.ctu) continue; - ProgressReporter(mErrorLogger, mSettings.reportProgress, files.front(), "addon:" + addonInfo.name + (isCtuInfo ? " (ctu)" : "")); + ProgressReporter progressReporter(mErrorLogger, mSettings.reportProgress, files.front(), "addon:" + addonInfo.name + (isCtuInfo ? " (ctu)" : "")); std::vector results; diff --git a/lib/errorlogger.h b/lib/errorlogger.h index 26cf6b1dbb8..19d423f7f02 100644 --- a/lib/errorlogger.h +++ b/lib/errorlogger.h @@ -291,36 +291,35 @@ class CPPCHECKLIB ErrorLogger { class CPPCHECKLIB ProgressReporter { public: ProgressReporter(ErrorLogger& e, int reportProgressInterval, std::string filename, std::string stage) : - errorLogger(e), - reportProgressInterval(reportProgressInterval), - filename(std::move(filename)), - stage(std::move(stage)) { + mErrorLogger(e), + mReportProgressInterval(reportProgressInterval), + mFilename(std::move(filename)), + mStage(std::move(stage)) { report(0); } ~ProgressReporter() { - lastTime = 0; - errorLogger.reportProgress(filename, stage.c_str(), 100); + mErrorLogger.reportProgress(mFilename, mStage.c_str(), 100); } void report(int value) { - if (reportProgressInterval < 0 || value == lastValue) + if (mReportProgressInterval < 0 || value == mLastValue) return; const std::time_t t = std::time(nullptr); - if (t >= lastTime + reportProgressInterval) { - errorLogger.reportProgress(filename, stage.c_str(), value); - lastTime = t; - lastValue = value; + if (t >= mLastTime + mReportProgressInterval) { + mErrorLogger.reportProgress(mFilename, mStage.c_str(), value); + mLastTime = t; + mLastValue = value; } } private: - ErrorLogger& errorLogger; - const int reportProgressInterval; - const std::string filename; - const std::string stage; - std::time_t lastTime{0}; - int lastValue{-1}; + ErrorLogger& mErrorLogger; + const int mReportProgressInterval; + const std::string mFilename; + const std::string mStage; + std::time_t mLastTime{0}; + int mLastValue{-1}; }; /** Replace substring. Example replaceStr("1,NR,3", "NR", "2") => "1,2,3" */