diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 13a0d2ea607..d82cda987cc 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 @@ -665,20 +679,41 @@ 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)) { + 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); - // TODO: set analyzer information + + if (mAnalyzerInformation) { + std::list errors; + mAnalyzerInformation->analyzeFile(mSettings.buildDir, file.spath(), cfgname, hash, errors); + mAnalyzerInformation->setFileInfo("CheckUnusedFunctions", mUnusedFunctionsCheck->analyzerInfo()); + mAnalyzerInformation->close(); + } } return EXIT_SUCCESS; } @@ -745,19 +780,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()) { diff --git a/test/cli/qml_test.py b/test/cli/qml_test.py index 56b04ee9553..de4a8d900af 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__)) @@ -54,8 +53,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)