From a3c6266b992177c32c2683e4b594987c4d750d74 Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 4 Jul 2024 14:35:47 +0200 Subject: [PATCH 1/4] CppCheck: set missing file info in analyzer information for markup files --- lib/cppcheck.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 13a0d2ea607..77bcbd032f0 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -665,7 +665,10 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string try { if (mSettings.library.markupFile(file.spath())) { - if (mUnusedFunctionsCheck && (mSettings.useSingleJob() || !mSettings.buildDir.empty())) { + if (!mSettings.buildDir.empty()) + mAnalyzerInformation.reset(new AnalyzerInformation); + + if (mUnusedFunctionsCheck && (mSettings.useSingleJob() || mAnalyzerInformation)) { // this is not a real source file - we just want to tokenize it. treat it as C anyways as the language needs to be determined. Tokenizer tokenizer(mSettings, *this); // enforce the language since markup files are special and do not adhere to the enforced language @@ -678,7 +681,11 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string tokenizer.list.createTokens(in, file.spath()); } mUnusedFunctionsCheck->parseTokens(tokenizer, mSettings); - // TODO: set analyzer information + + if (mAnalyzerInformation) { + // TODO: open file so we can set the fileinfo + mAnalyzerInformation->setFileInfo("CheckUnusedFunctions", mUnusedFunctionsCheck->analyzerInfo()); + } } return EXIT_SUCCESS; } From 54750e0591f4158f987157fcd3b49a4a5b79475c Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 24 Oct 2024 04:11:59 +0200 Subject: [PATCH 2/4] CppCheck: extracted hash calculation into helper --- lib/cppcheck.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 77bcbd032f0..6bae8d4e9f8 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -624,6 +624,20 @@ static simplecpp::TokenList createTokenList(const std::string& filename, std::ve return {filename, files, outputList}; } +static std::size_t calculateHash(const Preprocessor& preprocessor, const simplecpp::TokenList& tokens, const Settings& settings) +{ + std::ostringstream toolinfo; + toolinfo << CPPCHECK_VERSION_STRING; + toolinfo << (settings.severity.isEnabled(Severity::warning) ? 'w' : ' '); + toolinfo << (settings.severity.isEnabled(Severity::style) ? 's' : ' '); + toolinfo << (settings.severity.isEnabled(Severity::performance) ? 'p' : ' '); + toolinfo << (settings.severity.isEnabled(Severity::portability) ? 'p' : ' '); + toolinfo << (settings.severity.isEnabled(Severity::information) ? 'i' : ' '); + toolinfo << settings.userDefines; + settings.supprs.nomsg.dump(toolinfo); + return preprocessor.calculateHash(tokens, toolinfo.str()); +} + unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string &cfgname, std::istream* fileStream) { // TODO: move to constructor when CppCheck no longer owns the settings @@ -752,19 +766,8 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string mAnalyzerInformation.reset(new AnalyzerInformation); if (mAnalyzerInformation) { - // Get toolinfo - std::ostringstream toolinfo; - toolinfo << CPPCHECK_VERSION_STRING; - toolinfo << (mSettings.severity.isEnabled(Severity::warning) ? 'w' : ' '); - toolinfo << (mSettings.severity.isEnabled(Severity::style) ? 's' : ' '); - toolinfo << (mSettings.severity.isEnabled(Severity::performance) ? 'p' : ' '); - toolinfo << (mSettings.severity.isEnabled(Severity::portability) ? 'p' : ' '); - toolinfo << (mSettings.severity.isEnabled(Severity::information) ? 'i' : ' '); - toolinfo << mSettings.userDefines; - mSettings.supprs.nomsg.dump(toolinfo); - // Calculate hash so it can be compared with old hash / future hashes - const std::size_t hash = preprocessor.calculateHash(tokens1, toolinfo.str()); + const std::size_t hash = calculateHash(preprocessor, tokens1, mSettings); std::list errors; if (!mAnalyzerInformation->analyzeFile(mSettings.buildDir, file.spath(), cfgname, hash, errors)) { while (!errors.empty()) { From 47b3e62d965b0d5f979ba7b81079e67acf117f1d Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 24 Oct 2024 04:19:18 +0200 Subject: [PATCH 3/4] CppCheck: actually generate analyzer information for markup files --- lib/cppcheck.cpp | 6 +++++- test/cli/qml_test.py | 3 --- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 6bae8d4e9f8..a1ba63c7ca4 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -697,8 +697,12 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string mUnusedFunctionsCheck->parseTokens(tokenizer, mSettings); if (mAnalyzerInformation) { - // TODO: open file so we can set the fileinfo + // TODO: how to get the proper tokenlist to generate the proper hash? + const std::size_t hash = time(nullptr); // calculateHash(tokenizer.list, mSettings); + std::list errors; + mAnalyzerInformation->analyzeFile(mSettings.buildDir, file.spath(), cfgname, hash, errors); mAnalyzerInformation->setFileInfo("CheckUnusedFunctions", mUnusedFunctionsCheck->analyzerInfo()); + mAnalyzerInformation->close(); } } return EXIT_SUCCESS; diff --git a/test/cli/qml_test.py b/test/cli/qml_test.py index 7e09d5360e2..9b64f1d01a4 100644 --- a/test/cli/qml_test.py +++ b/test/cli/qml_test.py @@ -2,7 +2,6 @@ # python3 -m pytest test-qml.py import os -import pytest from testutils import cppcheck __script_dir = os.path.dirname(os.path.abspath(__file__)) @@ -53,8 +52,6 @@ def test_unused_functions_j(): assert ret == 0, stdout -# TODO: fillSampleData is not unused -@pytest.mark.xfail(strict=True) def test_unused_functions_builddir(tmpdir): build_dir = os.path.join(tmpdir, 'b1') os.mkdir(build_dir) From 48283a40658094e480a3525cece35865d2b80bbc Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 26 Oct 2024 22:42:36 +0200 Subject: [PATCH 4/4] CppCheck: calculate proper hash for markup file analyzer information --- lib/cppcheck.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index a1ba63c7ca4..d82cda987cc 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -683,22 +683,32 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string mAnalyzerInformation.reset(new AnalyzerInformation); if (mUnusedFunctionsCheck && (mSettings.useSingleJob() || mAnalyzerInformation)) { + std::size_t hash = 0; // this is not a real source file - we just want to tokenize it. treat it as C anyways as the language needs to be determined. Tokenizer tokenizer(mSettings, *this); // enforce the language since markup files are special and do not adhere to the enforced language tokenizer.list.setLang(Standards::Language::C, true); if (fileStream) { - tokenizer.list.createTokens(*fileStream, file.spath()); + std::vector files{file.spath()}; + simplecpp::TokenList tokens(*fileStream, files); + if (mAnalyzerInformation) { + const Preprocessor preprocessor(mSettings, *this); + hash = calculateHash(preprocessor, tokens, mSettings); + } + tokenizer.list.createTokens(std::move(tokens)); } else { - std::ifstream in(file.spath()); - tokenizer.list.createTokens(in, file.spath()); + std::vector files{file.spath()}; + simplecpp::TokenList tokens(file.spath(), files); + if (mAnalyzerInformation) { + const Preprocessor preprocessor(mSettings, *this); + hash = calculateHash(preprocessor, tokens, mSettings); + } + tokenizer.list.createTokens(std::move(tokens)); } mUnusedFunctionsCheck->parseTokens(tokenizer, mSettings); if (mAnalyzerInformation) { - // TODO: how to get the proper tokenlist to generate the proper hash? - const std::size_t hash = time(nullptr); // calculateHash(tokenizer.list, mSettings); std::list errors; mAnalyzerInformation->analyzeFile(mSettings.buildDir, file.spath(), cfgname, hash, errors); mAnalyzerInformation->setFileInfo("CheckUnusedFunctions", mUnusedFunctionsCheck->analyzerInfo());