Skip to content

Commit 5f6aebe

Browse files
authored
Fix #14516 (Review progress messages) (danmar#8241)
1 parent 1a9bdeb commit 5f6aebe

File tree

7 files changed

+115
-16
lines changed

7 files changed

+115
-16
lines changed

.github/workflows/selfcheck.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ jobs:
121121
122122
- name: Self check (unusedFunction / no test / no gui)
123123
run: |
124-
supprs="--suppress=unusedFunction:lib/errorlogger.h:196 --suppress=unusedFunction:lib/importproject.cpp:1531 --suppress=unusedFunction:lib/importproject.cpp:1555"
124+
supprs="--suppress=unusedFunction:lib/errorlogger.h:197 --suppress=unusedFunction:lib/importproject.cpp:1531 --suppress=unusedFunction:lib/importproject.cpp:1555"
125125
./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
126126
env:
127127
DISABLE_VALUEFLOW: 1

lib/cppcheck.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,6 +1316,8 @@ void CppCheck::internalError(const std::string &filename, const std::string &msg
13161316

13171317
void CppCheck::checkNormalTokens(const Tokenizer &tokenizer, AnalyzerInformation* analyzerInformation, const std::string& currentConfig)
13181318
{
1319+
const ProgressReporter progressReporter(mErrorLogger, mSettings.reportProgress, tokenizer.list.getSourceFilePath(), "Run checkers");
1320+
13191321
CheckUnusedFunctions unusedFunctionsChecker;
13201322

13211323
// TODO: this should actually be the behavior if only "--enable=unusedFunction" is specified - see #10648
@@ -1514,6 +1516,8 @@ void CppCheck::executeAddons(const std::vector<std::string>& files, const std::s
15141516
if (isCtuInfo && addonInfo.name != "misra" && !addonInfo.ctu)
15151517
continue;
15161518

1519+
ProgressReporter progressReporter(mErrorLogger, mSettings.reportProgress, files.front(), "addon:" + addonInfo.name + (isCtuInfo ? " (ctu)" : ""));
1520+
15171521
std::vector<picojson::value> results;
15181522

15191523
try {

lib/errorlogger.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include <cstddef>
2828
#include <cstdint>
29+
#include <ctime>
2930
#include <list>
3031
#include <set>
3132
#include <string>
@@ -286,6 +287,41 @@ class CPPCHECKLIB ErrorLogger {
286287
static const std::set<std::string> mCriticalErrorIds;
287288
};
288289

290+
/// RAII class for reporting progress messages
291+
class CPPCHECKLIB ProgressReporter {
292+
public:
293+
ProgressReporter(ErrorLogger& e, int reportProgressInterval, std::string filename, std::string stage) :
294+
mErrorLogger(e),
295+
mReportProgressInterval(reportProgressInterval),
296+
mFilename(std::move(filename)),
297+
mStage(std::move(stage)) {
298+
report(0);
299+
}
300+
301+
~ProgressReporter() {
302+
mErrorLogger.reportProgress(mFilename, mStage.c_str(), 100);
303+
}
304+
305+
void report(int value) {
306+
if (mReportProgressInterval < 0 || value == mLastValue)
307+
return;
308+
const std::time_t t = std::time(nullptr);
309+
if (t >= mLastTime + mReportProgressInterval) {
310+
mErrorLogger.reportProgress(mFilename, mStage.c_str(), value);
311+
mLastTime = t;
312+
mLastValue = value;
313+
}
314+
}
315+
316+
private:
317+
ErrorLogger& mErrorLogger;
318+
const int mReportProgressInterval;
319+
const std::string mFilename;
320+
const std::string mStage;
321+
std::time_t mLastTime{0};
322+
int mLastValue{-1};
323+
};
324+
289325
/** Replace substring. Example replaceStr("1,NR,3", "NR", "2") => "1,2,3" */
290326
std::string replaceStr(std::string s, const std::string &from, const std::string &to);
291327

lib/symboldatabase.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,6 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
174174
// Store current access in each scope (depends on evaluation progress)
175175
std::map<const Scope*, AccessControl> access;
176176

177-
const bool doProgress = (mSettings.reportProgress != -1);
178-
179177
std::map<Scope *, std::set<std::string>> forwardDecls;
180178

181179
const std::function<Scope *(const Token *, Scope *)> findForwardDeclScope = [&](const Token *tok, Scope *startScope) {
@@ -200,13 +198,14 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
200198
return it->second.count(tok->str()) > 0 ? startScope : nullptr;
201199
};
202200

201+
ProgressReporter progressReporter(mErrorLogger, mSettings.reportProgress, mTokenizer.list.getSourceFilePath(), "SymbolDatabase (find all scopes)");
202+
203203
// find all scopes
204204
for (const Token *tok = mTokenizer.tokens(); tok; tok = tok ? tok->next() : nullptr) {
205205
// #5593 suggested to add here:
206-
if (doProgress)
207-
mErrorLogger.reportProgress(mTokenizer.list.getSourceFilePath(),
208-
"SymbolDatabase",
209-
tok->progressValue());
206+
207+
progressReporter.report(tok->progressValue());
208+
210209
// Locate next class
211210
if ((tok->isCpp() && tok->isKeyword() &&
212211
((Token::Match(tok, "class|struct|union|namespace ::| %name% final| {|:|::|<") &&

lib/tokenize.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,11 +1167,10 @@ void Tokenizer::simplifyTypedefCpp()
11671167
std::vector<Space> spaceInfo(1);
11681168

11691169
const std::time_t maxTime = mSettings.typedefMaxTime > 0 ? std::time(nullptr) + mSettings.typedefMaxTime: 0;
1170-
const bool doProgress = (mSettings.reportProgress != -1) && !list.getFiles().empty();
1170+
ProgressReporter progressReporter(mErrorLogger, mSettings.reportProgress, list.getSourceFilePath(), "Tokenize (typedef)");
11711171

11721172
for (Token *tok = list.front(); tok; tok = tok->next()) {
1173-
if (doProgress)
1174-
mErrorLogger.reportProgress(list.getFiles()[0], "Tokenize (typedef)", tok->progressValue());
1173+
progressReporter.report(tok->progressValue());
11751174

11761175
if (Settings::terminated())
11771176
return;
@@ -2932,11 +2931,10 @@ bool Tokenizer::simplifyUsing()
29322931
};
29332932
std::list<Using> usingList;
29342933

2935-
const bool doProgress = (mSettings.reportProgress != -1) && !list.getFiles().empty();
2934+
ProgressReporter progressReporter(mErrorLogger, mSettings.reportProgress, list.getSourceFilePath(), "Tokenize (using)");
29362935

29372936
for (Token *tok = list.front(); tok; tok = tok->next()) {
2938-
if (doProgress)
2939-
mErrorLogger.reportProgress(list.getFiles()[0], "Tokenize (using)", tok->progressValue());
2937+
progressReporter.report(tok->progressValue());
29402938

29412939
if (Settings::terminated())
29422940
return substitute;

lib/valueflow.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7210,7 +7210,9 @@ struct ValueFlowPassRunner {
72107210
std::size_t n = state.settings.vfOptions.maxIterations;
72117211
while (n > 0 && values != getTotalValues()) {
72127212
values = getTotalValues();
7213+
const std::string passnum = std::to_string(state.settings.vfOptions.maxIterations - n + 1);
72137214
if (std::any_of(passes.begin(), passes.end(), [&](const ValuePtr<ValueFlowPass>& pass) {
7215+
ProgressReporter progressReporter(state.errorLogger, state.settings.reportProgress >= 0, state.tokenlist.getSourceFilePath(), std::string("ValueFlow::") + pass->name() + (' ' + passnum));
72147216
return run(pass);
72157217
}))
72167218
return true;
@@ -7354,6 +7356,8 @@ void ValueFlow::setValues(TokenList& tokenlist,
73547356
const Settings& settings,
73557357
TimerResultsIntf* timerResults)
73567358
{
7359+
ProgressReporter progressReporter(errorLogger, settings.reportProgress, tokenlist.getSourceFilePath(), "ValueFlow");
7360+
73577361
for (Token* tok = tokenlist.front(); tok; tok = tok->next())
73587362
tok->clearValueFlow();
73597363

test/cli/other_test.py

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,67 @@ def test_progress(tmpdir):
169169
"progress: Tokenize (typedef) 62%\n"
170170
"progress: Tokenize (typedef) 75%\n"
171171
"progress: Tokenize (typedef) 87%\n"
172-
"progress: SymbolDatabase 0%\n"
173-
"progress: SymbolDatabase 12%\n"
174-
"progress: SymbolDatabase 87%\n"
172+
"progress: Tokenize (typedef) 100%\n"
173+
"progress: SymbolDatabase (find all scopes) 0%\n"
174+
"progress: SymbolDatabase (find all scopes) 12%\n"
175+
"progress: SymbolDatabase (find all scopes) 87%\n"
176+
"progress: SymbolDatabase (find all scopes) 100%\n"
177+
"progress: ValueFlow 0%\n"
178+
"progress: ValueFlow::valueFlowImpossibleValues(tokenlist, settings) 1 0%\n"
179+
"progress: ValueFlow::valueFlowImpossibleValues(tokenlist, settings) 1 100%\n"
180+
"progress: ValueFlow::valueFlowSymbolicOperators(symboldatabase, settings) 1 0%\n"
181+
"progress: ValueFlow::valueFlowSymbolicOperators(symboldatabase, settings) 1 100%\n"
182+
"progress: ValueFlow::valueFlowCondition(SymbolicConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 0%\n"
183+
"progress: ValueFlow::valueFlowCondition(SymbolicConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 100%\n"
184+
"progress: ValueFlow::valueFlowSymbolicInfer(symboldatabase, settings) 1 0%\n"
185+
"progress: ValueFlow::valueFlowSymbolicInfer(symboldatabase, settings) 1 100%\n"
186+
"progress: ValueFlow::valueFlowArrayBool(tokenlist, settings) 1 0%\n"
187+
"progress: ValueFlow::valueFlowArrayBool(tokenlist, settings) 1 100%\n"
188+
"progress: ValueFlow::valueFlowArrayElement(tokenlist, settings) 1 0%\n"
189+
"progress: ValueFlow::valueFlowArrayElement(tokenlist, settings) 1 100%\n"
190+
"progress: ValueFlow::valueFlowRightShift(tokenlist, settings) 1 0%\n"
191+
"progress: ValueFlow::valueFlowRightShift(tokenlist, settings) 1 100%\n"
192+
"progress: ValueFlow::valueFlowCondition(ContainerConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 0%\n"
193+
"progress: ValueFlow::valueFlowCondition(ContainerConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 100%\n"
194+
"progress: ValueFlow::valueFlowAfterAssign(tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 0%\n"
195+
"progress: ValueFlow::valueFlowAfterAssign(tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 100%\n"
196+
"progress: ValueFlow::valueFlowAfterSwap(tokenlist, symboldatabase, errorLogger, settings) 1 0%\n"
197+
"progress: ValueFlow::valueFlowAfterSwap(tokenlist, symboldatabase, errorLogger, settings) 1 100%\n"
198+
"progress: ValueFlow::valueFlowCondition(SimpleConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 0%\n"
199+
"progress: ValueFlow::valueFlowCondition(SimpleConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 100%\n"
200+
"progress: ValueFlow::valueFlowInferCondition(tokenlist, settings) 1 0%\n"
201+
"progress: ValueFlow::valueFlowInferCondition(tokenlist, settings) 1 100%\n"
202+
"progress: ValueFlow::valueFlowSwitchVariable(tokenlist, symboldatabase, errorLogger, settings) 1 0%\n"
203+
"progress: ValueFlow::valueFlowSwitchVariable(tokenlist, symboldatabase, errorLogger, settings) 1 100%\n"
204+
"progress: ValueFlow::valueFlowForLoop(tokenlist, symboldatabase, errorLogger, settings) 1 0%\n"
205+
"progress: ValueFlow::valueFlowForLoop(tokenlist, symboldatabase, errorLogger, settings) 1 100%\n"
206+
"progress: ValueFlow::valueFlowSubFunction(tokenlist, symboldatabase, errorLogger, settings) 1 0%\n"
207+
"progress: ValueFlow::valueFlowSubFunction(tokenlist, symboldatabase, errorLogger, settings) 1 100%\n"
208+
"progress: ValueFlow::valueFlowFunctionReturn(tokenlist, errorLogger, settings) 1 0%\n"
209+
"progress: ValueFlow::valueFlowFunctionReturn(tokenlist, errorLogger, settings) 1 100%\n"
210+
"progress: ValueFlow::valueFlowLifetime(tokenlist, errorLogger, settings) 1 0%\n"
211+
"progress: ValueFlow::valueFlowLifetime(tokenlist, errorLogger, settings) 1 100%\n"
212+
"progress: ValueFlow::valueFlowFunctionDefaultParameter(tokenlist, symboldatabase, errorLogger, settings) 1 0%\n"
213+
"progress: ValueFlow::valueFlowFunctionDefaultParameter(tokenlist, symboldatabase, errorLogger, settings) 1 100%\n"
214+
"progress: ValueFlow::valueFlowUninit(tokenlist, errorLogger, settings) 1 0%\n"
215+
"progress: ValueFlow::valueFlowUninit(tokenlist, errorLogger, settings) 1 100%\n"
216+
"progress: ValueFlow::valueFlowAfterMove(tokenlist, symboldatabase, errorLogger, settings) 1 0%\n"
217+
"progress: ValueFlow::valueFlowAfterMove(tokenlist, symboldatabase, errorLogger, settings) 1 100%\n"
218+
"progress: ValueFlow::valueFlowSmartPointer(tokenlist, errorLogger, settings) 1 0%\n"
219+
"progress: ValueFlow::valueFlowSmartPointer(tokenlist, errorLogger, settings) 1 100%\n"
220+
"progress: ValueFlow::valueFlowIterators(tokenlist, settings) 1 0%\n"
221+
"progress: ValueFlow::valueFlowIterators(tokenlist, settings) 1 100%\n"
222+
"progress: ValueFlow::valueFlowCondition(IteratorConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 0%\n"
223+
"progress: ValueFlow::valueFlowCondition(IteratorConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 100%\n"
224+
"progress: ValueFlow::valueFlowIteratorInfer(tokenlist, settings) 1 0%\n"
225+
"progress: ValueFlow::valueFlowIteratorInfer(tokenlist, settings) 1 100%\n"
226+
"progress: ValueFlow::valueFlowContainerSize(tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 0%\n"
227+
"progress: ValueFlow::valueFlowContainerSize(tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 100%\n"
228+
"progress: ValueFlow::valueFlowSafeFunctions(tokenlist, symboldatabase, errorLogger, settings) 1 0%\n"
229+
"progress: ValueFlow::valueFlowSafeFunctions(tokenlist, symboldatabase, errorLogger, settings) 1 100%\n"
230+
"progress: ValueFlow 100%\n"
231+
"progress: Run checkers 0%\n"
232+
"progress: Run checkers 100%\n"
175233
)
176234
assert stderr == ""
177235

0 commit comments

Comments
 (0)