From 9b9dd99226941fb72f8e955895b18480adfa1d00 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 22 Oct 2026 14:49:36 +0200 Subject: [PATCH 01/32] Update tokenize.cpp --- lib/tokenize.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 1d5b7436405..4adf43e1195 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -9427,7 +9427,7 @@ void Tokenizer::simplifyFunctionTryCatch() if (!Token::Match(tok, "try {|:")) continue; const Token* par = tok->previous(); - while (par && par->isKeyword()) + while (par && (par->isKeyword() || Token::Match(par, "final|override"))) par = par->previous(); if (!TokenList::isFunctionHead(par, "try")) // TODO: this is supposed to a list of characters and not strings continue; From aa91b3a3c299e53f2a717fece51f0d90049558f5 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 22 Oct 2026 14:50:47 +0200 Subject: [PATCH 02/32] Update testtokenize.cpp --- test/testtokenize.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 75a94c26aec..d864b342428 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -2028,6 +2028,15 @@ class TestTokenizer : public TestFixture { "void S::func() const\n" "try { f(); }\n" "catch (...) { g(); }\n")); + + ASSERT_EQUALS("struct D : B {\n" // #15126 + "void f ( ) override { try { } catch ( ... ) { } }\n" + "void g ( ) final { try { } catch ( ... ) { } }\n" + "} ;", + tokenizeAndStringify("struct D : B {\n" + " void f() override try {} catch (...) {}\n" + " void g() final try {} catch (...) {}\n" + "};\n")); } // Simplify "((..))" into "(..)" From b4102413e97b015b0ff6e8bbd76dde18d5dcdf09 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 26 Oct 2026 08:26:44 +0100 Subject: [PATCH 03/32] Update testtokenize.cpp [skip ci] --- test/testtokenize.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index d864b342428..cb5812e05b0 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -2032,11 +2032,18 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS("struct D : B {\n" // #15126 "void f ( ) override { try { } catch ( ... ) { } }\n" "void g ( ) final { try { } catch ( ... ) { } }\n" + "void i ( ) & override { try { } catch ( ... ) { } }\n" + "void j ( ) const && override { try { } catch ( ... ) { } }\n" + "auto k ( ) . std :: nullptr_t override { try { } catch ( ... ) { } }\n" "} ;", tokenizeAndStringify("struct D : B {\n" " void f() override try {} catch (...) {}\n" " void g() final try {} catch (...) {}\n" + " void i() & override try {} catch (...) {}\n" + " void j() const && override try {} catch (...) {}\n" + " auto k() -> std::nullptr_t override try {} catch (...) {}\n" "};\n")); + ASSERT_EQUALS("[test.cpp:6:5]: (debug) auto token with no type. [autoNoType]\n", errout_str()); } // Simplify "((..))" into "(..)" From cf6eb155a024ce620573a56e6a50a66dca12c53a Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 26 Oct 2026 08:28:03 +0100 Subject: [PATCH 04/32] Update tokenlist.cpp [skip ci] --- lib/tokenlist.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 26b24d649c8..ee10b8b4887 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -2379,7 +2379,7 @@ const Token * TokenList::isFunctionHead(const Token *tok, const std::string &suf tok = tok->linkAt(1)->next(); if (Token::Match(tok, "%name% (") && tok->isUpperCaseName()) tok = tok->linkAt(1)->next(); - if (tok && tok->originalName() == "->") { // trailing return type + if (tok && (tok->str() == "->" || tok->originalName() == "->")) { // trailing return type for (tok = tok->next(); tok && !Token::Match(tok, ";|{|override|final|}|)|]"); tok = tok->next()) if (tok->link() && Token::Match(tok, "<|[|(")) tok = tok->link(); From bb851aff57dd525206fc9e976e42e88627488f9b Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 26 Oct 2026 08:28:45 +0100 Subject: [PATCH 05/32] Update tokenize.cpp --- lib/tokenize.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 4adf43e1195..1249bc2efe3 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -9427,7 +9427,7 @@ void Tokenizer::simplifyFunctionTryCatch() if (!Token::Match(tok, "try {|:")) continue; const Token* par = tok->previous(); - while (par && (par->isKeyword() || Token::Match(par, "final|override"))) + while (par && (par->isKeyword() || Token::Match(par, "%name%|&|&&|->|::"))) par = par->previous(); if (!TokenList::isFunctionHead(par, "try")) // TODO: this is supposed to a list of characters and not strings continue; From 33f15a28235640fd1eef6778821a880e229f5158 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 26 Oct 2026 12:36:50 +0100 Subject: [PATCH 06/32] Update tokenize.cpp --- lib/tokenize.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 1249bc2efe3..b861283fc56 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -9427,7 +9427,7 @@ void Tokenizer::simplifyFunctionTryCatch() if (!Token::Match(tok, "try {|:")) continue; const Token* par = tok->previous(); - while (par && (par->isKeyword() || Token::Match(par, "%name%|&|&&|->|::"))) + while (par && !Token::Match(par, "[);]"))) par = par->previous(); if (!TokenList::isFunctionHead(par, "try")) // TODO: this is supposed to a list of characters and not strings continue; From c10d38f455197c978d78580dd60ab6f805bdd615 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 26 Oct 2026 13:15:08 +0100 Subject: [PATCH 07/32] Update tokenize.cpp --- lib/tokenize.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index b861283fc56..7e9b80454ef 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -9427,7 +9427,7 @@ void Tokenizer::simplifyFunctionTryCatch() if (!Token::Match(tok, "try {|:")) continue; const Token* par = tok->previous(); - while (par && !Token::Match(par, "[);]"))) + while (par && !Token::Match(par, "[);]")) par = par->previous(); if (!TokenList::isFunctionHead(par, "try")) // TODO: this is supposed to a list of characters and not strings continue; From 796e5927b63f6666b543662180b8647f7c9a97dd Mon Sep 17 00:00:00 2001 From: William Jakobsson <50847546+wjakobsson@users.noreply.github.com> Date: Fri, 23 Oct 2026 16:24:32 +0200 Subject: [PATCH 08/32] Fix #15132 build dir: cached results are discarded on the second run when includes are not in order (#8957) --- lib/preprocessor.cpp | 27 ++++++++++++++++---------- test/cli/other_test.py | 41 +++++++++++++++++++++++++++++++++++++++ test/testpreprocessor.cpp | 20 +++++++++++++++++++ 3 files changed, 78 insertions(+), 10 deletions(-) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 0a0acecab1a..c14eaf813ad 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -1114,22 +1114,29 @@ void Preprocessor::dump(std::ostream &out) const std::size_t Preprocessor::calculateHash(const std::string &toolinfo) const { std::string hashData = toolinfo; - for (const simplecpp::Token *tok = mTokens.cfront(); tok; tok = tok->next) { - if (!tok->comment) { - hashData += tok->str(); - hashData += static_cast(tok->location.line); - hashData += static_cast(tok->location.col); - } - } - for (const auto &filedata : mFileCache) { - for (const simplecpp::Token *tok = filedata->tokens.cfront(); tok; tok = tok->next) { + const auto addTokens = [&hashData](const simplecpp::TokenList &tokens) { + for (const simplecpp::Token *tok = tokens.cfront(); tok; tok = tok->next) { if (!tok->comment) { hashData += tok->str(); hashData += static_cast(tok->location.line); hashData += static_cast(tok->location.col); } } - } + }; + addTokens(mTokens); + + // Hash the included files in a fixed order, the order they are loaded in differs between runs + std::vector fileData; + fileData.reserve(mFileCache.size()); + std::transform(mFileCache.cbegin(), mFileCache.cend(), std::back_inserter(fileData), [](const std::unique_ptr &data) { + return data.get(); + }); + std::sort(fileData.begin(), fileData.end(), [](const simplecpp::FileData *a, const simplecpp::FileData *b) { + return a->filename < b->filename; + }); + for (const simplecpp::FileData *data : fileData) + addTokens(data->tokens); + return (std::hash{})(hashData); } diff --git a/test/cli/other_test.py b/test/cli/other_test.py index aad4fec264e..c86d8cd5a81 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -4575,6 +4575,47 @@ def run_and_assert_cppcheck(stdout_exp): # - internalError +def test_analyzerinfo_include_order(tmp_path): # #15132 + with open(tmp_path / 'z.h', 'wt') as f: + f.write('int z;\n') + with open(tmp_path / 'a.h', 'wt') as f: + f.write('int a;\n') + test_file = tmp_path / 'test.c' + with open(test_file, 'wt') as f: + f.write( +"""#include "z.h" +#include "a.h" +int f(void) { return a + z; } +""") + + build_dir = tmp_path / 'b1' + os.makedirs(build_dir) + + args = [ + '-q', + '--debug-analyzerinfo', + '--cppcheck-build-dir={}'.format(build_dir), + str(test_file) + ] + + test_file_s = str(test_file).replace('\\', '/') + test_a1_file_s = str(build_dir / 'test.a1').replace('\\', '/') + + exitcode, stdout, stderr = cppcheck(args) + assert exitcode == 0, stdout + assert stdout.splitlines() == [ + "no cached result '{}' for '{}' found".format(test_a1_file_s, test_file_s) + ] + assert stderr.splitlines() == [] + + exitcode, stdout, stderr = cppcheck(args) + assert exitcode == 0, stdout + assert stdout.splitlines() == [ + "skipping analysis - loaded 0 cached finding(s) from '{}' for '{}'".format(test_a1_file_s, test_file_s) + ] + assert stderr.splitlines() == [] + + def test_ctu_function_call_path_slash(tmp_path): # #14591 test_file = tmp_path / 'test.cpp' with open(test_file, "w") as f: diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 9aad97b2c99..faa1d9ce01b 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -382,6 +382,7 @@ class TestPreprocessor : public TestFixture { TEST_CASE(limitsDefines); TEST_CASE(hashCalculation); + TEST_CASE(hashCalculationIncludeOrder); TEST_CASE(standard); @@ -3182,6 +3183,25 @@ class TestPreprocessor : public TestFixture { ASSERT(getHash(code2) != getHash(code3)); } + void hashCalculationIncludeOrder() { + // #15132 - the load order of the includes must not change the hash + const ScopedFile headerA("hash_a.h", "int a;\n"); + const ScopedFile headerZ("hash_z.h", "int z;\n"); + const char code[] = "#include \"hash_z.h\"\n" + "#include \"hash_a.h\"\n"; + + const auto getHashLoadOrder = [&](const std::vector &loadOrder) { + std::vector files; + simplecpp::TokenList tokens(code, files, "test.c"); + Preprocessor preprocessor(tokens, settingsDefault, *this, Standards::Language::C); + for (const std::string &header : loadOrder) + ASSERT(preprocessor.loadFile(files, header)); + return preprocessor.calculateHash(""); + }; + + ASSERT_EQUALS(getHashLoadOrder({"hash_z.h", "hash_a.h"}), getHashLoadOrder({"hash_a.h", "hash_z.h"})); + } + void standard() { const char code[] = "int a;\n"; From bccafc80a848c448ddecf39a094b1810a5016ddc Mon Sep 17 00:00:00 2001 From: William Jakobsson <50847546+wjakobsson@users.noreply.github.com> Date: Fri, 23 Oct 2026 16:24:55 +0200 Subject: [PATCH 09/32] Fix #14893 recheck removes unselected files results (#8699) --- gui/checkthread.cpp | 7 +- gui/checkthread.h | 8 +- gui/mainwindow.cpp | 102 ++++++++++++++++++----- gui/mainwindow.h | 34 +++++++- gui/resultstree.cpp | 23 ++++- gui/resultstree.h | 11 ++- gui/test/resultstree/testresultstree.cpp | 25 ++++++ gui/test/resultstree/testresultstree.h | 1 + gui/threadhandler.cpp | 6 +- gui/threadhandler.h | 7 ++ lib/analyzerinfo.cpp | 4 +- test/testanalyzerinformation.cpp | 35 ++++++++ 12 files changed, 224 insertions(+), 39 deletions(-) diff --git a/gui/checkthread.cpp b/gui/checkthread.cpp index 07ca4e77ed2..2b4c9ba654f 100644 --- a/gui/checkthread.cpp +++ b/gui/checkthread.cpp @@ -113,13 +113,15 @@ CheckThread::CheckThread(ThreadResult &result, int threadIndex) void CheckThread::setSettings(const Settings &settings, std::shared_ptr supprs) { mFiles.clear(); + mFileSettings.clear(); mSettings = settings; // this is a copy mSuppressions = std::move(supprs); } -void CheckThread::analyseWholeProgram(const std::list &files, const std::string& ctuInfo) +void CheckThread::analyseWholeProgram(const std::list &files, const std::list &fileSettings, const std::string& ctuInfo) { mFiles = files; + mFileSettings = fileSettings; mAnalyseWholeProgram = true; mCtuInfo = ctuInfo; start(); @@ -136,8 +138,9 @@ void CheckThread::run() std::string ctuInfo; ctuInfo.swap(mCtuInfo); qDebug() << "Whole program analysis"; - cppcheck.analyseWholeProgram(mSettings.buildDir, mFiles, {}, ctuInfo); + cppcheck.analyseWholeProgram(mSettings.buildDir, mFiles, mFileSettings, ctuInfo); mFiles.clear(); + mFileSettings.clear(); emit done(); return; } diff --git a/gui/checkthread.h b/gui/checkthread.h index a630ef7fc13..74eb292e6e2 100644 --- a/gui/checkthread.h +++ b/gui/checkthread.h @@ -69,10 +69,11 @@ class CheckThread : public QThread { /** * @brief Run whole program analysis - * @param files All files - * @param ctuInfo Ctu info for addons + * @param files All files + * @param fileSettings All files of the project + * @param ctuInfo Ctu info for addons */ - void analyseWholeProgram(const std::list &files, const std::string& ctuInfo); + void analyseWholeProgram(const std::list &files, const std::list &fileSettings, const std::string& ctuInfo); void setAddonsAndTools(const QStringList &addonsAndTools) { mAddonsAndTools = addonsAndTools; @@ -153,6 +154,7 @@ class CheckThread : public QThread { bool isSuppressed(const SuppressionList::ErrorMessage &errorMessage) const; std::list mFiles; + std::list mFileSettings; bool mAnalyseWholeProgram{}; std::string mCtuInfo; QStringList mAddonsAndTools; diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 3ed37eb7b25..5ddb790b77b 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -59,6 +59,7 @@ #include #include +#include #include #include #include @@ -96,6 +97,7 @@ #include #include #include +#include #include #include #include @@ -118,6 +120,18 @@ static QString fromNativePath(const QString& p) { #endif } +// The files selected in the results view are not necessarily spelled the same way as the +// project or files.txt spells them, compare them as absolute paths +static QString comparablePath(const QString& path) { + return QDir::cleanPath(QFileInfo(path).absoluteFilePath()); +} + +static QSet comparablePaths(const QStringList& paths) { + QSet ret; + std::transform(paths.cbegin(), paths.cend(), std::inserter(ret, ret.end()), comparablePath); + return ret; +} + template> static T toStdStringList(const QStringList& stringList) { T ret; @@ -568,21 +582,31 @@ void MainWindow::saveSettings() const mUI->mResults->saveSettings(mSettings); } -void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLib, const bool checkConfig, const QStringList& recheckFiles) +void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLib, const bool checkConfig, const QStringList& selectedFiles, const Recheck recheck) { Settings checkSettings; auto supprs = std::make_shared(); if (!getCppcheckSettings(checkSettings, *supprs)) return; - // filter requested files - if (!recheckFiles.isEmpty()) { + // Filter the selected files + if (recheck == Recheck::Selected) { + const QSet selected = comparablePaths(selectedFiles); p.fileSettings.remove_if([&](const FileSettings& fs) { - return !recheckFiles.contains(QString::fromStdString(fs.filename())); + return !selected.contains(comparablePath(QString::fromStdString(fs.filename()))); }); + if (p.fileSettings.empty()) { + QMessageBox msg(QMessageBox::Information, + "Cppcheck", + tr("None of the selected files is part of the project, nothing to analyze."), + QMessageBox::Ok, + this); + msg.exec(); + return; + } } - clearResults(); + clearResultsForAnalysis(checkSettings.buildDir, selectedFiles, recheck); mIsLogfileLoaded = false; if (mProjectFile) { @@ -647,7 +671,7 @@ void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLib, const bo mUI->mResults->setCheckSettings(checkSettings); } -void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLib, const bool checkConfig) +void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLib, const bool checkConfig, const QStringList& selectedFiles, const Recheck recheck) { if (files.isEmpty()) return; @@ -657,7 +681,7 @@ void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLib, c if (!getCppcheckSettings(checkSettings, *supprs)) return; - clearResults(); + clearResultsForAnalysis(checkSettings.buildDir, selectedFiles, recheck); mIsLogfileLoaded = false; FileList pathList; @@ -669,7 +693,6 @@ void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLib, c } QStringList fileNames = pathList.getFileList(); - mUI->mResults->clear(true); mUI->mResults->setResultsSource(ResultsTree::ResultsSource::Analysis); mThread->clearFiles(); @@ -1379,11 +1402,6 @@ void MainWindow::reAnalyzeSelected(const QStringList& files) return; if (mProjectFile) { - // Clear details, statistics and progress - mUI->mResults->clear(false); - for (int i = 0; i < files.size(); ++i) - mUI->mResults->clearRecheckFile(files[i]); - analyzeProject(mProjectFile, files); return; } @@ -1393,10 +1411,7 @@ void MainWindow::reAnalyzeSelected(const QStringList& files) if (!getCppcheckSettings(checkSettings, *supprs)) return; - // Clear details, statistics and progress - mUI->mResults->clear(false); - for (int i = 0; i < files.size(); ++i) - mUI->mResults->clearRecheckFile(files[i]); + clearResultsForAnalysis(checkSettings.buildDir, files, Recheck::Selected); mCurrentDirectory = mUI->mResults->getCheckDirectory(); FileList pathList; @@ -1451,7 +1466,7 @@ void MainWindow::reAnalyze(bool all) void MainWindow::clearResults() { if (mProjectFile && !mProjectFile->getBuildDir().isEmpty()) { - QDir dir(QFileInfo(mProjectFile->getFilename()).absolutePath() + '/' + mProjectFile->getBuildDir()); + QDir dir(QDir(QFileInfo(mProjectFile->getFilename()).absolutePath()).filePath(mProjectFile->getBuildDir())); for (const QString& f: dir.entryList(QDir::Files)) { if (!f.endsWith("files.txt")) { static const QRegularExpression rx("^.*.s[0-9]+$"); @@ -1465,6 +1480,42 @@ void MainWindow::clearResults() enableResultsButtons(); } +void MainWindow::clearResultsForAnalysis(const std::string& buildDir, const QStringList& selectedFiles, const Recheck recheck) +{ + switch (recheck) { + case Recheck::None: + clearResults(); + break; + case Recheck::Selected: + // Only the selected files are analyzed, the results of the other files are kept + mUI->mResults->clear(false); + for (const QString& f : selectedFiles) + mUI->mResults->clearRecheckFile(f); + enableResultsButtons(); + break; + case Recheck::Cached: { + // Every file reports its results again, either analyzed or replayed from the analyzer + // information. Remove the analyzer information of the selected files so that they really + // are analyzed again, also by the clang tools that keep their results next to it. + const QSet selected = comparablePaths(selectedFiles); + QDir dir(QString::fromStdString(buildDir)); + std::ifstream filesTxt(buildDir + "/files.txt"); + std::string line; + while (std::getline(filesTxt, line)) { + AnalyzerInformation::Info info; + if (!info.parse(line) || !selected.contains(comparablePath(QString::fromStdString(info.sourceFile)))) + continue; + const QString afile = QString::fromStdString(info.afile); + for (const QString& f : dir.entryList({afile, afile + ".*"}, QDir::Files)) + dir.remove(f); + } + mUI->mResults->clear(true); + enableResultsButtons(); + break; + } + } +} + void MainWindow::openResults() { if (mUI->mResults->hasResults()) { @@ -1863,10 +1914,17 @@ bool MainWindow::loadLastResults() return true; } -void MainWindow::analyzeProject(const ProjectFile *projectFile, const QStringList& recheckFiles, const bool checkLib, const bool checkConfig) +void MainWindow::analyzeProject(const ProjectFile *projectFile, const QStringList& selectedFiles, const bool checkLib, const bool checkConfig) { Settings::terminate(false); + // With a build directory the whole project is analyzed: the analyzer information cache skips + // the unchanged files, and files.txt stays complete so whole program analysis sees every file. + // Without a build directory there is no cache, so only the selected files are analyzed. + Recheck recheck = Recheck::None; + if (!selectedFiles.isEmpty()) + recheck = projectFile->getBuildDir().isEmpty() ? Recheck::Selected : Recheck::Cached; + QFileInfo inf(projectFile->getFilename()); const QString& rootpath = projectFile->getRootPath(); @@ -1968,11 +2026,11 @@ void MainWindow::analyzeProject(const ProjectFile *projectFile, const QStringLis msg.exec(); return; } - doAnalyzeProject(p, checkLib, checkConfig, recheckFiles); // TODO: avoid copy + doAnalyzeProject(p, checkLib, checkConfig, selectedFiles, recheck); // TODO: avoid copy return; } - QStringList paths = recheckFiles.isEmpty() ? projectFile->getCheckPaths() : recheckFiles; + QStringList paths = recheck == Recheck::Selected ? selectedFiles : projectFile->getCheckPaths(); // If paths not given then check the root path (which may be the project // file's location, see above). This is to keep the compatibility with @@ -1981,7 +2039,7 @@ void MainWindow::analyzeProject(const ProjectFile *projectFile, const QStringLis if (paths.isEmpty()) { paths << mCurrentDirectory; } - doAnalyzeFiles(paths, checkLib, checkConfig); + doAnalyzeFiles(paths, checkLib, checkConfig, selectedFiles, recheck); } void MainWindow::newProjectFile() diff --git a/gui/mainwindow.h b/gui/mainwindow.h index c654a2c94f0..a92476a8c20 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -249,6 +250,19 @@ private slots: void changeReportType(); private: + /** @brief How an analysis treats the files selected for a recheck */ + enum class Recheck : std::uint8_t { + /** Not a recheck, everything is analyzed from scratch */ + None, + /** Only the selected files are analyzed, the results of the other files are kept */ + Selected, + /** + * Everything is analyzed. The analyzer information in the build directory is kept, + * except for the selected files, so the unchanged files are not analyzed again. + */ + Cached + }; + bool isCppcheckPremium() const; /** Get filename for last results */ @@ -266,11 +280,11 @@ private slots: /** * @brief Analyze the project. * @param projectFile Pointer to the project to analyze. - * @param recheckFiles files to recheck, empty => check all files + * @param selectedFiles files to recheck, empty => check all files * @param checkLib Flag to indicate if the library should be checked. * @param checkConfig Flag to indicate if the configuration should be checked. */ - void analyzeProject(const ProjectFile *projectFile, const QStringList& recheckFiles, bool checkLib = false, bool checkConfig = false); + void analyzeProject(const ProjectFile *projectFile, const QStringList& selectedFiles, bool checkLib = false, bool checkConfig = false); /** * @brief Set current language @@ -308,8 +322,10 @@ private slots: * @param p imported project * @param checkLib Flag to indicate if library should be checked * @param checkConfig Flag to indicate if the configuration should be checked. + * @param selectedFiles Files selected for a recheck + * @param recheck How the selected files are rechecked */ - void doAnalyzeProject(ImportProject p, bool checkLib = false, bool checkConfig = false, const QStringList& recheckFiles = QStringList()); + void doAnalyzeProject(ImportProject p, bool checkLib = false, bool checkConfig = false, const QStringList& selectedFiles = QStringList(), Recheck recheck = Recheck::None); /** * @brief Analyze all files specified in parameter files @@ -317,8 +333,18 @@ private slots: * @param files List of files and/or directories to analyze * @param checkLib Flag to indicate if library should be checked * @param checkConfig Flag to indicate if the configuration should be checked. + * @param selectedFiles Files selected for a recheck + * @param recheck How the selected files are rechecked + */ + void doAnalyzeFiles(const QStringList &files, bool checkLib = false, bool checkConfig = false, const QStringList& selectedFiles = QStringList(), Recheck recheck = Recheck::None); + + /** + * @brief Clear the results that a new analysis replaces + * @param buildDir Build directory of the analysis + * @param selectedFiles Files selected for a recheck + * @param recheck How the selected files are rechecked */ - void doAnalyzeFiles(const QStringList &files, bool checkLib = false, bool checkConfig = false); + void clearResultsForAnalysis(const std::string& buildDir, const QStringList& selectedFiles, Recheck recheck); /** * @brief Get our default cppcheck settings and read project file. diff --git a/gui/resultstree.cpp b/gui/resultstree.cpp index ed8b3c7412e..2c99ecf3ed1 100644 --- a/gui/resultstree.cpp +++ b/gui/resultstree.cpp @@ -246,7 +246,7 @@ bool ResultsTree::addErrorItem(const ErrorItem& errorItem) const QString s = errorItem.toString(); if (mErrorList.contains(s)) return false; - mErrorList.append(s); + mErrorList.insert(s); QSharedPointer errorItemPtr{new ErrorItem(errorItem)}; @@ -427,7 +427,7 @@ void ResultsTree::clear(const QString &filename) if (stripped == fileItem->text() || filename == fileItem->errorItem->file0) { - mErrorList.removeAll(fileItem->errorItem->toString()); + removeFileErrorsFromErrorList(fileItem); mModel->removeRow(i); break; } @@ -445,7 +445,7 @@ void ResultsTree::clearRecheckFile(const QString &filename) QString storedfile = fileItem->getErrorPathItem().file; storedfile = ((!mCheckPath.isEmpty() && storedfile.startsWith(mCheckPath)) ? storedfile.mid(mCheckPath.length() + 1) : storedfile); if (actualfile == storedfile) { - mErrorList.removeAll(fileItem->errorItem->toString()); + removeFileErrorsFromErrorList(fileItem); mModel->removeRow(i); break; } @@ -1132,6 +1132,15 @@ void ResultsTree::saveErrors(Report *report, const ResultItem *fileItem) const } } +void ResultsTree::removeFileErrorsFromErrorList(const ResultItem *fileItem) +{ + for (int i{0}; i < fileItem->rowCount(); ++i) { + const auto *errorItem = dynamic_cast(fileItem->child(i, COLUMN_FILE)); + if (errorItem && errorItem->errorItem) + mErrorList.remove(errorItem->errorItem->toString()); + } +} + void ResultsTree::updateFromOldReport(const QString &filename) { showColumn(COLUMN_SINCE_DATE); @@ -1194,7 +1203,15 @@ void ResultsTree::updateSettings(bool showFullPath, void ResultsTree::setCheckDirectory(const QString &dir) { + if (mCheckPath == dir) + return; + mCheckPath = dir; + + // A partial recheck keeps results whose displayed paths are relative to the check path, so + // they are recalculated. Not without a check path, QDir("") would turn absolute paths into "../..". + if (!mCheckPath.isEmpty()) + refreshFilePaths(); } const QString& ResultsTree::getCheckDirectory() const diff --git a/gui/resultstree.h b/gui/resultstree.h index 23fe5567ed9..c829c21fc6a 100644 --- a/gui/resultstree.h +++ b/gui/resultstree.h @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -356,6 +357,12 @@ protected slots: */ void saveErrors(Report *report, const ResultItem *fileItem) const; + /** + * @brief Remove all errors of a file item from the duplicate-check list + * @param fileItem Item whose errors to remove + */ + void removeFileErrorsFromErrorList(const ResultItem *fileItem); + /** * @brief Convert a severity string to a icon filename * @@ -566,8 +573,8 @@ protected slots: QStringList mHiddenMessageId; - // List of existing errors so we can avoid duplicates - QStringList mErrorList; + // Set of existing errors so we can avoid duplicates + QSet mErrorList; QItemSelectionModel* mSelectionModel{}; ThreadHandler *mThread{}; diff --git a/gui/test/resultstree/testresultstree.cpp b/gui/test/resultstree/testresultstree.cpp index 31520f3e6d9..e2e40517f69 100644 --- a/gui/test/resultstree/testresultstree.cpp +++ b/gui/test/resultstree/testresultstree.cpp @@ -265,6 +265,31 @@ void TestResultsTree::resultsInSameFile() const } } +void TestResultsTree::clearRecheckFile() const +{ + // #14893 - rechecking a file removes its results, the results of the other files are kept + ResultsTree tree(nullptr); + QVERIFY(tree.addErrorItem(createErrorItem("file1.c", 10, Severity::style, "test", "bugId"))); + QVERIFY(tree.addErrorItem(createErrorItem("file1.c", 20, Severity::style, "test", "bugId"))); + QVERIFY(tree.addErrorItem(createErrorItem("file2.c", 10, Severity::style, "test", "bugId"))); + + const auto* model = dynamic_cast(tree.model()); + QVERIFY(model != nullptr); + QCOMPARE(model->rowCount(), 2); + + tree.clearRecheckFile("file1.c"); + QCOMPARE(model->rowCount(), 1); + QCOMPARE(model->item(0,0)->text(), "file2.c"); + + // the recheck reports the results of the rechecked file again, they must not be treated as duplicates + QVERIFY(tree.addErrorItem(createErrorItem("file1.c", 10, Severity::style, "test", "bugId"))); + QVERIFY(tree.addErrorItem(createErrorItem("file1.c", 20, Severity::style, "test", "bugId"))); + QCOMPARE(model->rowCount(), 2); + + // the results of the other files are still known + QVERIFY(!tree.addErrorItem(createErrorItem("file2.c", 10, Severity::style, "test", "bugId"))); +} + void TestResultsTree::testReportType() const { TestReport report("{id},{classification},{guideline}"); diff --git a/gui/test/resultstree/testresultstree.h b/gui/test/resultstree/testresultstree.h index add0390c456..dcce568b4ba 100644 --- a/gui/test/resultstree/testresultstree.h +++ b/gui/test/resultstree/testresultstree.h @@ -26,6 +26,7 @@ private slots: void duplicateResults() const; void multiLineResult() const; void resultsInSameFile() const; + void clearRecheckFile() const; void testReportType() const; void testReportTypeIcon() const; void testGetGuidelineError() const; diff --git a/gui/threadhandler.cpp b/gui/threadhandler.cpp index 3f89d58b558..577dcdc3375 100644 --- a/gui/threadhandler.cpp +++ b/gui/threadhandler.cpp @@ -21,6 +21,7 @@ #include "checkthread.h" #include "common.h" #include "filesettings.h" +#include "importproject.h" #include "resultsview.h" #include "settings.h" #include "utils.h" @@ -53,6 +54,7 @@ ThreadHandler::~ThreadHandler() void ThreadHandler::clearFiles() { mLastFiles.clear(); + mLastFileSettings.clear(); mResults.clearFiles(); mAnalyseWholeProgram = false; mCtuInfo.clear(); @@ -63,6 +65,7 @@ void ThreadHandler::clearFiles() void ThreadHandler::setFiles(std::list files) { mLastFiles = files; + mLastFileSettings.clear(); mResults.setFiles(std::move(files)); } @@ -70,6 +73,7 @@ void ThreadHandler::setProject(const ImportProject &prj) { mResults.setProject(prj); mLastFiles.clear(); + mLastFileSettings = prj.fileSettings; } void ThreadHandler::setCheckFiles(bool all) @@ -190,7 +194,7 @@ void ThreadHandler::threadDone() createThreads(1); mRunningThreadCount = 1; setupCheckThread(*mThreads[0]); - mThreads[0]->analyseWholeProgram(mLastFiles, mCtuInfo); + mThreads[0]->analyseWholeProgram(mLastFiles, mLastFileSettings, mCtuInfo); mAnalyseWholeProgram = false; mCtuInfo.clear(); return; diff --git a/gui/threadhandler.h b/gui/threadhandler.h index 17f011c32ac..879da0db8da 100644 --- a/gui/threadhandler.h +++ b/gui/threadhandler.h @@ -20,6 +20,7 @@ #ifndef THREADHANDLER_H #define THREADHANDLER_H +#include "filesettings.h" #include "settings.h" #include "suppressions.h" #include "threadresult.h" @@ -238,6 +239,12 @@ protected slots: */ std::list mLastFiles; + /** + * @brief Files of the project checked last time (used by the whole program analysis) + * + */ + std::list mLastFileSettings; + /** @brief date and time when current checking started */ QDateTime mCheckStartTime; diff --git a/lib/analyzerinfo.cpp b/lib/analyzerinfo.cpp index aa8d82c27fa..3bdc6875e63 100644 --- a/lib/analyzerinfo.cpp +++ b/lib/analyzerinfo.cpp @@ -21,7 +21,6 @@ #include "errorlogger.h" #include "filesettings.h" #include "path.h" -#include "utils.h" #include #include @@ -197,12 +196,13 @@ std::string AnalyzerInformation::skipAnalysis(const tinyxml2::XMLDocument &analy std::string AnalyzerInformation::getAnalyzerInfoFileFromFilesTxt(std::istream& filesTxt, const std::string &sourcefile, const std::string &cfg, size_t fsFileId) { + const std::string simplifiedSourcefile = Path::simplifyPath(sourcefile); std::string line; while (std::getline(filesTxt,line)) { AnalyzerInformation::Info filesTxtInfo; if (!filesTxtInfo.parse(line)) continue; // TODO: report error? - if (endsWith(sourcefile, filesTxtInfo.sourceFile) && filesTxtInfo.cfg == cfg && filesTxtInfo.fsFileId == fsFileId) + if (filesTxtInfo.sourceFile == simplifiedSourcefile && filesTxtInfo.cfg == cfg && filesTxtInfo.fsFileId == fsFileId) return filesTxtInfo.afile; } return ""; diff --git a/test/testanalyzerinformation.cpp b/test/testanalyzerinformation.cpp index 2174f7d4676..0356630686c 100644 --- a/test/testanalyzerinformation.cpp +++ b/test/testanalyzerinformation.cpp @@ -53,6 +53,41 @@ class TestAnalyzerInformation : public TestFixture { ASSERT_EQUALS("file1.a4", AnalyzerInformationTest::getAnalyzerInfoFileFromFilesTxt(f, "file1.c", "", 0)); f.str(filesTxt); ASSERT_EQUALS("file1.a4", AnalyzerInformationTest::getAnalyzerInfoFileFromFilesTxt(f, "./file1.c", "", 0)); + + // only an exact match is used - "executor.cpp" is a suffix of "processexecutor.cpp" + // so both used to resolve to the same analyzer info file + { + constexpr char suffixTxt[] = "executor.a1:::executor.cpp\n" + "processexecutor.a2:::processexecutor.cpp\n"; + std::istringstream f1(suffixTxt); + ASSERT_EQUALS("executor.a1", AnalyzerInformationTest::getAnalyzerInfoFileFromFilesTxt(f1, "executor.cpp", "", 0)); + std::istringstream f2(suffixTxt); + ASSERT_EQUALS("processexecutor.a2", AnalyzerInformationTest::getAnalyzerInfoFileFromFilesTxt(f2, "processexecutor.cpp", "", 0)); + } + + // the same, with the exact match on the first line + { + constexpr char suffixTxt[] = "processexecutor.a1:::processexecutor.cpp\n" + "executor.a2:::executor.cpp\n"; + std::istringstream f1(suffixTxt); + ASSERT_EQUALS("processexecutor.a1", AnalyzerInformationTest::getAnalyzerInfoFileFromFilesTxt(f1, "processexecutor.cpp", "", 0)); + std::istringstream f2(suffixTxt); + ASSERT_EQUALS("executor.a2", AnalyzerInformationTest::getAnalyzerInfoFileFromFilesTxt(f2, "executor.cpp", "", 0)); + } + + // a path that only ends with the path in files.txt is not a match + { + constexpr char relTxt[] = "a.a1:::src/a.c\n"; + std::istringstream f1(relTxt); + ASSERT_EQUALS("", AnalyzerInformationTest::getAnalyzerInfoFileFromFilesTxt(f1, "/home/proj/src/a.c", "", 0)); + } + + // no match at all + { + constexpr char noneTxt[] = "a.a1:::a.c\n"; + std::istringstream f1(noneTxt); + ASSERT_EQUALS("", AnalyzerInformationTest::getAnalyzerInfoFileFromFilesTxt(f1, "b.c", "", 0)); + } } void getAnalyzerInfoFile() const { From 5a6c769e68f09fb4d4c85b797b509b19c59836ee Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 23 Oct 2026 19:08:31 +0200 Subject: [PATCH 10/32] Fix #15063 FP knownArgument when there is function pointer call (#8935) --- lib/vf_settokenvalue.cpp | 2 +- test/testother.cpp | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/vf_settokenvalue.cpp b/lib/vf_settokenvalue.cpp index 21bfbbe2da2..c4d32691422 100644 --- a/lib/vf_settokenvalue.cpp +++ b/lib/vf_settokenvalue.cpp @@ -256,7 +256,7 @@ namespace ValueFlow // Ensure that the comma isn't a function call if (!callParent || (!Token::Match(callParent->previous(), "%name%|> (") && !Token::simpleMatch(callParent, "{") && (!Token::Match(callParent, "( %name%") || settings.library.isNotLibraryFunction(callParent->next())) && - !(callParent->str() == "(" && (Token::simpleMatch(callParent->astOperand1(), "*") || Token::Match(callParent->astOperand1(), "%name%|("))))) { + !(callParent->str() == "(" && Token::Match(callParent->astOperand1(), "%name%|(|[|*|.")))) { setTokenValue(parent, std::move(value), settings); return; } diff --git a/test/testother.cpp b/test/testother.cpp index f1d06182184..ac0d3d5040e 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -13734,6 +13734,18 @@ class TestOther : public TestFixture { " return MACRO(true);\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("struct S {\n" // #15063 + " int (*f)(int, int);\n" + " int (*a[2])(int, int);\n" + "};\n" + "int g1(struct S* p, int x) {\n" + " return (p->f)(x, 10);\n" + "}\n" + "int g2(struct S s, int x) {\n" + " return s.a[0](x, 10);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void knownArgumentHiddenVariableExpression() { From 992ed7e8aa8cabfe49d65c493afc776a8f3c4702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 25 Oct 2026 11:20:08 +0100 Subject: [PATCH 11/32] Fix #15134 (gui: tests through AT-SPI) (#8958) --- .github/workflows/codeql-analysis.yml | 3 + gui/cppcheck_de.ts | 507 ++++++-- gui/cppcheck_es.ts | 507 ++++++-- gui/cppcheck_fi.ts | 507 ++++++-- gui/cppcheck_fr.ts | 507 ++++++-- gui/cppcheck_it.ts | 507 ++++++-- gui/cppcheck_ja.ts | 507 ++++++-- gui/cppcheck_ka.ts | 507 ++++++-- gui/cppcheck_ko.ts | 507 ++++++-- gui/cppcheck_nl.ts | 507 ++++++-- gui/cppcheck_ru.ts | 507 ++++++-- gui/cppcheck_sr.ts | 507 ++++++-- gui/cppcheck_sv.ts | 507 ++++++-- gui/cppcheck_zh_CN.ts | 507 ++++++-- gui/cppcheck_zh_TW.ts | 507 ++++++-- gui/manualtest/docs/handbook.html | 453 +++++++ gui/manualtest/docs/report.png | Bin 0 -> 149022 bytes gui/manualtest/gen.py | 234 ++++ gui/manualtest/guitest.py | 715 +++++++++++ gui/manualtest/mainwindow.md | 21 - gui/manualtest/projectfiledialog.md | 52 - gui/manualtest/report.py | 408 ++++++ gui/manualtest/run.py | 230 ++++ gui/manualtest/runner.py | 232 ++++ gui/manualtest/testfile.py | 743 +++++++++++ gui/manualtest/tests/analysis.feature | 55 + gui/manualtest/tests/analysis.scripts.json | 399 ++++++ gui/manualtest/tests/application.feature | 59 + gui/manualtest/tests/application.scripts.json | 548 ++++++++ gui/manualtest/tests/preferences.feature | 42 + gui/manualtest/tests/preferences.scripts.json | 306 +++++ gui/manualtest/tests/project_dialog.feature | 40 + .../tests/project_dialog.scripts.json | 371 ++++++ gui/manualtest/tests/projects.feature | 72 ++ gui/manualtest/tests/projects.scripts.json | 771 +++++++++++ .../projects/basic-project/basic.cppcheck | 9 + .../projects/basic-project/include/util.h | 5 + .../tests/projects/basic-project/src/a.c | 18 + .../tests/projects/basic-project/src/b.c | 5 + gui/manualtest/tests/projects/custom-cfg/a.c | 4 + .../tests/projects/custom-cfg/aa.cfg | 402 ++++++ .../tests/projects/custom-cfg/p.cppcheck | 6 + .../tests/projects/embedded/board.h | 10 + .../tests/projects/embedded/embedded.cppcheck | 9 + gui/manualtest/tests/projects/embedded/gpio.c | 6 + gui/manualtest/tests/projects/embedded/main.c | 10 + .../projects/embedded/rules with spaces.txt | 7 + .../tests/projects/embedded/rules.txt | 7 + gui/manualtest/tests/projects/embedded/uart.c | 6 + gui/manualtest/tests/projects/recheck/a.c | 5 + gui/manualtest/tests/projects/recheck/a_v2.c | 5 + gui/manualtest/tests/projects/recheck/b.c | 5 + .../tests/projects/recheck/p.cppcheck | 7 + .../relative-paths/compile_commands.json | 4 + .../tests/projects/relative-paths/inc/util.h | 1 + .../tests/projects/relative-paths/skip/b.c | 4 + .../tests/projects/relative-paths/src/a.c | 6 + .../tests/projects/switch-project/one/a.c | 5 + .../projects/switch-project/one/p1.cppcheck | 6 + .../tests/projects/switch-project/two/b.c | 5 + .../projects/switch-project/two/p2.cppcheck | 6 + .../tests/projects/syntax-error/binary.c | Bin 0 -> 4096 bytes .../projects/syntax-error/binary.cppcheck | 7 + .../tests/projects/syntax-error/braces.c | 3 + .../projects/syntax-error/braces.cppcheck | 7 + .../tests/projects/syntax-error/empty.c | 0 .../projects/syntax-error/empty.cppcheck | 7 + .../tests/projects/syntax-error/latin1.c | 6 + .../projects/syntax-error/latin1.cppcheck | 7 + .../tests/projects/syntax-error/long_line.c | 1 + .../projects/syntax-error/long_line.cppcheck | 7 + .../tests/projects/syntax-error/ok.c | 5 + .../projects/syntax-error/unclosed_nesting.c | 4 + .../syntax-error/unclosed_nesting.cppcheck | 7 + gui/manualtest/tests/projects/xml-results/a.c | 5 + .../tests/projects/xml-results/results.xml | 9 + gui/manualtest/tests/result_list.feature | 91 ++ gui/manualtest/tests/result_list.scripts.json | 1127 +++++++++++++++++ gui/manualtest/tests/xml_results.feature | 45 + gui/manualtest/tests/xml_results.scripts.json | 466 +++++++ gui/manualtest/web.py | 464 +++++++ gui/manualtest/web/index.html | 677 ++++++++++ 82 files changed, 15167 insertions(+), 1193 deletions(-) create mode 100644 gui/manualtest/docs/handbook.html create mode 100644 gui/manualtest/docs/report.png create mode 100755 gui/manualtest/gen.py create mode 100755 gui/manualtest/guitest.py delete mode 100644 gui/manualtest/mainwindow.md delete mode 100644 gui/manualtest/projectfiledialog.md create mode 100644 gui/manualtest/report.py create mode 100755 gui/manualtest/run.py create mode 100644 gui/manualtest/runner.py create mode 100644 gui/manualtest/testfile.py create mode 100644 gui/manualtest/tests/analysis.feature create mode 100644 gui/manualtest/tests/analysis.scripts.json create mode 100644 gui/manualtest/tests/application.feature create mode 100644 gui/manualtest/tests/application.scripts.json create mode 100644 gui/manualtest/tests/preferences.feature create mode 100644 gui/manualtest/tests/preferences.scripts.json create mode 100644 gui/manualtest/tests/project_dialog.feature create mode 100644 gui/manualtest/tests/project_dialog.scripts.json create mode 100644 gui/manualtest/tests/projects.feature create mode 100644 gui/manualtest/tests/projects.scripts.json create mode 100644 gui/manualtest/tests/projects/basic-project/basic.cppcheck create mode 100644 gui/manualtest/tests/projects/basic-project/include/util.h create mode 100644 gui/manualtest/tests/projects/basic-project/src/a.c create mode 100644 gui/manualtest/tests/projects/basic-project/src/b.c create mode 100644 gui/manualtest/tests/projects/custom-cfg/a.c create mode 100644 gui/manualtest/tests/projects/custom-cfg/aa.cfg create mode 100644 gui/manualtest/tests/projects/custom-cfg/p.cppcheck create mode 100644 gui/manualtest/tests/projects/embedded/board.h create mode 100644 gui/manualtest/tests/projects/embedded/embedded.cppcheck create mode 100644 gui/manualtest/tests/projects/embedded/gpio.c create mode 100644 gui/manualtest/tests/projects/embedded/main.c create mode 100644 gui/manualtest/tests/projects/embedded/rules with spaces.txt create mode 100644 gui/manualtest/tests/projects/embedded/rules.txt create mode 100644 gui/manualtest/tests/projects/embedded/uart.c create mode 100644 gui/manualtest/tests/projects/recheck/a.c create mode 100644 gui/manualtest/tests/projects/recheck/a_v2.c create mode 100644 gui/manualtest/tests/projects/recheck/b.c create mode 100644 gui/manualtest/tests/projects/recheck/p.cppcheck create mode 100644 gui/manualtest/tests/projects/relative-paths/compile_commands.json create mode 100644 gui/manualtest/tests/projects/relative-paths/inc/util.h create mode 100644 gui/manualtest/tests/projects/relative-paths/skip/b.c create mode 100644 gui/manualtest/tests/projects/relative-paths/src/a.c create mode 100644 gui/manualtest/tests/projects/switch-project/one/a.c create mode 100644 gui/manualtest/tests/projects/switch-project/one/p1.cppcheck create mode 100644 gui/manualtest/tests/projects/switch-project/two/b.c create mode 100644 gui/manualtest/tests/projects/switch-project/two/p2.cppcheck create mode 100644 gui/manualtest/tests/projects/syntax-error/binary.c create mode 100644 gui/manualtest/tests/projects/syntax-error/binary.cppcheck create mode 100644 gui/manualtest/tests/projects/syntax-error/braces.c create mode 100644 gui/manualtest/tests/projects/syntax-error/braces.cppcheck create mode 100644 gui/manualtest/tests/projects/syntax-error/empty.c create mode 100644 gui/manualtest/tests/projects/syntax-error/empty.cppcheck create mode 100644 gui/manualtest/tests/projects/syntax-error/latin1.c create mode 100644 gui/manualtest/tests/projects/syntax-error/latin1.cppcheck create mode 100644 gui/manualtest/tests/projects/syntax-error/long_line.c create mode 100644 gui/manualtest/tests/projects/syntax-error/long_line.cppcheck create mode 100644 gui/manualtest/tests/projects/syntax-error/ok.c create mode 100644 gui/manualtest/tests/projects/syntax-error/unclosed_nesting.c create mode 100644 gui/manualtest/tests/projects/syntax-error/unclosed_nesting.cppcheck create mode 100644 gui/manualtest/tests/projects/xml-results/a.c create mode 100644 gui/manualtest/tests/projects/xml-results/results.xml create mode 100644 gui/manualtest/tests/result_list.feature create mode 100644 gui/manualtest/tests/result_list.scripts.json create mode 100644 gui/manualtest/tests/xml_results.feature create mode 100644 gui/manualtest/tests/xml_results.scripts.json create mode 100644 gui/manualtest/web.py create mode 100644 gui/manualtest/web/index.html diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 84d37423d2e..4fe5620680d 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -42,6 +42,9 @@ jobs: uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} + config: | + paths-ignore: + - gui/manualtest - name: Build cppcheck if: matrix.language == 'cpp' diff --git a/gui/cppcheck_de.ts b/gui/cppcheck_de.ts index f89eb60e4a8..ee401f8c2a4 100644 --- a/gui/cppcheck_de.ts +++ b/gui/cppcheck_de.ts @@ -5,27 +5,32 @@ About + About Cppcheck Über Cppcheck + Version %1 Version %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - Ein Werkzeug zur statischen C/C++-Code-Analyse. + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. Copyright © 2007-%1 Cppcheck-Team. + This program is licensed under the terms of the GNU General Public License version 3 Dieses Programm ist unter den Bedingungen @@ -33,11 +38,13 @@ der GNU General Public License Version 3 lizenziert + Visit Cppcheck homepage at %1 Besuchen Sie die Cppcheck-Homepage unter %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> <html><head/><body><p>Vielen Dank den Bibliotheken die wir nutzen:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> @@ -47,11 +54,13 @@ der GNU General Public License Version 3 lizenziert ApplicationDialog + Add an application Anwendung hinzufügen + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -78,21 +87,25 @@ Parameter: -l(line) (file) + &Name: &Name: + &Executable: &Ausführbare Datei: + &Parameters: &Parameter: + Browse Suchen @@ -188,16 +201,19 @@ Parameter: -l(line) (file) HelpDialog + Cppcheck GUI help Cppcheck GUI Hilfe + Contents Inhalt + Index Index @@ -215,16 +231,19 @@ Parameter: -l(line) (file) LibraryAddFunctionDialog + Add function Funktion hinzufügen + Function name(s) Funktionsname(n) + Number of arguments Anzahl Argumente @@ -233,86 +252,103 @@ Parameter: -l(line) (file) LibraryDialog + Library Editor Bibliothekseditor + Open Öffnen + Save Speichern + Save as Speichern unter + Functions Funktionen + Sort Sortiere + Add Hinzufügen + Filter: Filter: + Comments Kommentare + noreturn Zurückkehrend + False Ja + True Nein + Unknown Unbekannt + return value must be used Rückgabewert muss genutzt werden + ignore function in leaks checking Ignoriere Funktion in Speicherleck-Prüfung + Arguments Argumente + Edit Bearbeiten @@ -356,11 +392,13 @@ Parameter: -l(line) (file) LibraryEditArgDialog + Edit argument Argument bearbeiten + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -376,11 +414,13 @@ Parameter: -l(line) (file) + Not bool Nicht boolsch + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -396,78 +436,99 @@ Parameter: -l(line) (file) + Not null Nicht Null + Not uninit Nicht uninitialisiert + String String + Format string Formatstring + Min size of buffer Minimale Puffergröße + + Type Typ + + None Keine + + argvalue Argumentwert + + mul Multiplikation + + strlen strlen + + Arg Argument 1 + + Arg2 Argument 2 + and und + Valid values Zulässige Werte @@ -480,506 +541,611 @@ Parameter: -l(line) (file) + Standard Standard + &File &Datei + &View &Ansicht + &Toolbars &Symbolleisten + A&nalyze A&nalysieren + C++ standard C++-Standard + &C standard &C-Standard + &Edit &Bearbeiten + &License... &Lizenz... + A&uthors... &Autoren... + &About... Ü&ber... + &Files... &Dateien... + + Analyze files Analysiere Dateien + Ctrl+F Strg+F + &Directory... &Verzeichnis... + + Analyze directory Analysiere Verzeichnis + Ctrl+D Strg+D + Ctrl+R Strg+R + &Stop &Stoppen + + Stop analysis Analyse abbrechen + Esc Esc + &Save results to file... &Ergebnisse in Datei speichern... + Ctrl+S Strg+S + &Quit &Beenden + &Clear results Ergebnisse &löschen + &Preferences &Einstellungen - + + + Show errors Zeige Fehler - + + + Show warnings Zeige Warnungen + + Show performance warnings Zeige Performance-Warnungen + Show &hidden Zeige &versteckte - - + + Information Information + Show information messages Zeige Informationsmeldungen + Show portability warnings Zeige Portabilitätswarnungen + Show Cppcheck results Zeige Cppcheck-Ergebnisse + Clang Clang + Show Clang results Zeige Clang-Ergebnisse + &Filter &Filter + Filter results Gefilterte Ergebnisse + Windows 32-bit ANSI Windows 32-bit, ANSI + Windows 32-bit Unicode Windows 32-bit, Unicode + Unix 32-bit Unix 32-bit + Unix 64-bit Unix 64-bit + Windows 64-bit Windows 64-bit + &Print... Drucken... + Print the Current Report Aktuellen Bericht ausdrucken + Print Pre&view... Druckvorschau + Open a Print Preview Dialog for the Current Results Druckvorschaudialog für aktuelle Ergebnisse öffnen + Open library editor Bibliothekseditor öffnen + &Check all Alle &auswählen + Checking for updates + Hide Verstecken + + Report + Filter Filter + &Reanalyze modified files Veränderte Dateien neu analysieren + Reanal&yze all files Alle Dateien erneut anal&ysieren + Ctrl+Q + Style war&nings Stilwar&nungen + E&rrors F&ehler + &Uncheck all Alle a&bwählen + Collapse &all Alle &reduzieren + &Expand all Alle &erweitern + &Standard &Standard + Standard items Standardeinträge + Toolbar Symbolleiste + &Categories &Kategorien + Error categories Fehler-Kategorien + &Open XML... Öffne &XML... + Open P&roject File... Pr&ojektdatei öffnen... + Ctrl+Shift+O + Sh&ow Scratchpad... &Zeige Schmierzettel... + &New Project File... &Neue Projektdatei... + Ctrl+Shift+N + &Log View &Loganzeige + Log View Loganzeige + C&lose Project File Projektdatei &schließen + &Edit Project File... Projektdatei &bearbeiten... + &Statistics &Statistik + &Warnings &Warnungen + Per&formance warnings Per&formance-Warnungen + &Information &Information + &Portability &Portabilität + P&latforms P&lattformen + C++&11 C++&11 + C&99 C&99 + &Posix Posix + C&11 C&11 + &C89 &C89 + &C++03 &C++03 + &Library Editor... &Bibliothekseditor + &Auto-detect language Sprache &automatisch erkennen + &Enforce C++ C++ &erzwingen + E&nforce C C e&rzwingen + C++14 C++14 + Reanalyze and check library Neu analysieren und Bibliothek prüfen + Check configuration (defines, includes) Prüfe Konfiguration (Definitionen, Includes) + C++17 C++17 + C++20 C++20 + Compliance report... + Normal @@ -997,68 +1163,84 @@ Parameter: -l(line) (file) + Autosar + EULA... + Thread Details + Show thread details + &Contents &Inhalte + Categories Kategorien + + Show style warnings Zeige Stilwarnungen + Open the help contents Öffnet die Hilfe-Inhalte + F1 F1 + &Help &Hilfe - - + + Quick Filter: Schnellfilter: - + + None of the selected files is part of the project, nothing to analyze. + + + + Select configuration Konfiguration wählen - + Found project file: %1 Do you want to load this project file instead? @@ -1067,102 +1249,102 @@ Do you want to load this project file instead? Möchten Sie stattdessen diese öffnen? - + File not found Datei nicht gefunden - + Bad XML Fehlerhaftes XML - + Missing attribute Fehlendes Attribut - + Bad attribute value Falscher Attributwert - + Duplicate platform type Plattformtyp doppelt - + Platform type redefined Plattformtyp neu definiert - + Duplicate define - + Failed to load the selected library '%1'. %2 Laden der ausgewählten Bibliothek '%1' schlug fehl. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Lizenz - + Authors Autoren - + Save the report file Speichert die Berichtdatei - - + + XML files (*.xml) XML-Dateien (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -1171,32 +1353,32 @@ This is probably because the settings were changed between the Cppcheck versions Dies wurde vermutlich durch einen Wechsel der Cppcheck-Version hervorgerufen. Bitte prüfen (und korrigieren) Sie die Einstellungen, andernfalls könnte die Editor-Anwendung nicht korrekt starten. - + You must close the project file before selecting new files or directories! Sie müssen die Projektdatei schließen, bevor Sie neue Dateien oder Verzeichnisse auswählen! - + The library '%1' contains unknown elements: %2 Die Bibliothek '%1' enthält unbekannte Elemente: %2 - + Unsupported format Nicht unterstütztes Format - + Unknown element Unbekanntes Element - - - - + + + + Error Fehler @@ -1205,50 +1387,50 @@ Dies wurde vermutlich durch einen Wechsel der Cppcheck-Version hervorgerufen. Bi Laden von %1 fehlgeschlagen. Ihre Cppcheck-Installation ist defekt. Sie können --data-dir=<Verzeichnis> als Kommandozeilenparameter verwenden, um anzugeben, wo die Datei sich befindet. Bitte beachten Sie, dass --data-dir in Installationsroutinen genutzt werden soll, und die GUI bei dessen Nutzung nicht startet, sondern die Einstellungen konfiguriert. - + Open the report file Berichtdatei öffnen - + Text files (*.txt) Textdateien (*.txt) - + CSV files (*.csv) CSV-Dateien (*.csv) - + Project files (*.cppcheck);;All files(*.*) Projektdateien (*.cppcheck);;Alle Dateien(*.*) - + Select Project File Projektdatei auswählen - - - - + + + + Project: Projekt: - + No suitable files found to analyze! Keine passenden Dateien für Analyse gefunden! - + C/C++ Source C/C++-Quellcode - + Compile database Compilerdatenbank @@ -1261,22 +1443,22 @@ Dies wurde vermutlich durch einen Wechsel der Cppcheck-Version hervorgerufen. Bi Borland C++-Builder 6 - + Select files to analyze Dateien für Analyse auswählen - + Select directory to analyze Verzeichnis für Analyse auswählen - + Select the configuration that will be analyzed Zu analysierende Konfiguration auswählen - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1285,7 +1467,7 @@ Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1296,7 +1478,7 @@ Eine neue XML-Datei zu öffnen wird die aktuellen Ergebnisse löschen Möchten sie fortfahren? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1305,104 +1487,104 @@ Do you want to stop the analysis and exit Cppcheck? Wollen sie die Analyse abbrechen und Cppcheck beenden? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML-Dateien (*.xml);;Textdateien (*.txt);;CSV-Dateien (*.csv) - + Build dir '%1' does not exist, create it? Erstellungsverzeichnis '%1' existiert nicht. Erstellen? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1411,22 +1593,22 @@ Analysis is stopped. Import von '%1' fehlgeschlagen; Analyse wurde abgebrochen. - + Project files (*.cppcheck) Projektdateien (*.cppcheck) - + Select Project Filename Projektnamen auswählen - + No project file loaded Keine Projektdatei geladen - + The project file %1 @@ -1443,12 +1625,12 @@ Do you want to remove the file from the recently used projects -list? Möchten Sie die Datei von der Liste der zuletzt benutzten Projekte entfernen? - + Install - + New version available: %1. %2 @@ -1493,26 +1675,31 @@ Options: NewSuppressionDialog + New suppression Neue Fehlerunterdrückung + Error ID Fehler-ID + File name Dateiname + Line number Zeilennummer + Symbol name Symbolname @@ -1554,26 +1741,31 @@ Options: ProjectFile + Project File Projektdatei + Paths and Defines Pfade und Definitionen + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Importiere Projekt (Visual Studio / Compile-Datenbank / Borland C++-Builder 6) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Definitionen müssen mit einem Semikolon getrennt werden. Beispiel: DEF1;DEF2=5;DEF3=int + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. Hinweis: Legen Sie eigene .cfg-Dateien in den Ordner der Projektdatei. Dann sollten sie oben sichtbar werden. @@ -1583,48 +1775,59 @@ Options: + MISRA rule texts MISRA-Regeltexte + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> <html><head/><body><p>Text aus Anhang A &quot;Summary of guidelines&quot; aus der MISRA-C-2012-PDF in eine Textdatei einfügen.</p></body></html> + ... ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> <html><head/><body><p>Sie haben die Auswahl:</p><p> * Alle Debug- und Release-Konfigurationen analysieren</p><p> * Nur die erste passende Debug-Konfiguration analysieren</p><p><br/></p></body></html> + + Browse... Durchsuchen... + Analyze all Visual Studio configurations Alle Visual-Studio-Konfigurationen analysieren + Selected VS Configurations Ausgewählte VS-Konfiguration + Paths: Pfade: + + Add... Hinzufügen... @@ -1632,6 +1835,9 @@ Options: + + + Edit Bearbeiten @@ -1640,300 +1846,365 @@ Options: + + + + Remove Entfernen + Undefines: Un-Definitionen: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 Un-Definitionen müssen Semikolon-getrennt sein. Beispiel: UNDEF1;UNDEF2;UNDEF3 + Include Paths: Includepfade: + Up Auf + Down Ab + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Platform Plattform + + Analysis Analyse + This is a workfolder that Cppcheck will use for various purposes. + Clang (experimental) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) Prüfe Code in ungenutzten Templates (normalerweise AN, theoretisch können Warnungen in ungenutzten Templates gefahrlos ignoriert werden) + Max CTU depth Maximale CTU-Tiefe + Max recursion in template instantiation + Warning options Warnoptionen + Root path: Wurzelverzeichnis: + Filepaths in warnings will be relative to this path + Warning tags (separated by semicolon) Warnungs-Tags (Semikolon-getrennt) + Enable inline suppressions Inline-Fehlerunterdrückung aktivieren + 2025 + Misra C++ + 2008 + Cert C Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Safety profiles (defined in C++ core guidelines) + Bug hunting + External tools Externe Werkzeuge + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) Cppcheck-Arbeitsverzeichnis (Vollständige Programmanalyse, inkrementelle Analyse, Statistiken, etc.) + Types and Functions + Libraries Bibliotheken + Parser + Cppcheck (built in) + Check that each class has a safe public interface + Limit analysis + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files + Exclude folder... + Exclude file... + Suppressions Fehlerunterdrückungen + Add Hinzufügen + + Addons Add-Ons + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 Y2038 + Thread safety Threadsicherheit + Coding standards Programmierstandards + Misra C Misra C + 2012 + + 2023 + Cert C++ Cert C++ + Bug hunting (Premium) @@ -1947,6 +2218,7 @@ Options: + Defines: Definitionen: @@ -2565,21 +2837,25 @@ Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werde + Results Berichte + Critical errors Kritische Fehler + Analysis Log Analyseprotokoll + Warning Details Warnungs-Details @@ -2588,26 +2864,31 @@ Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werde ScratchPad + Scratchpad Schmierzettel + Copy or write some C/C++ code here: Kopieren oder schreiben Sie C/C++-Code hierher: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": Optional einen Dateinamen (hauptsächlich für automatische Spracherkennung) eingeben und auf "Prüfe" klicken: + filename Dateiname + Check Prüfe @@ -2616,21 +2897,25 @@ Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werde Settings + Preferences Einstellungen + General Allgemein + Add... Hinzufügen... + Number of threads: Anzahl der Threads: @@ -2640,56 +2925,67 @@ Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werde + Force checking all #ifdef configurations Erzwinge Prüfung aller #ifdef-Konfigurationen + Show full path of files Vollständigen Dateipfad anzeigen + Show "No errors found" message when no errors found "Keine Fehler gefunden"-Meldung anzeigen, wenn keine Fehler gefunden werden + Display error Id in column "Id" Zeige Meldungs-Id in Spalte "Id" + Enable inline suppressions Inline-Fehlerunterdrückung aktivieren + Check for inconclusive errors also Auch nach unklaren Fehlern suchen + Show statistics on check completion Zeige Statistiken nach Prüfungsabschluss + Check for updates Auf Updates prüfen + Show internal warnings in log Interne Warnungen im Log anzeigen + Addons Add-Ons + Python binary (leave this empty to use python in the PATH) Python-Binärdatei (Python aus PATH wird genutzt, wenn leer) @@ -2697,117 +2993,143 @@ Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werde + + + ... ... + MISRA addon MISRA-Addon + MISRA rule texts file MISRA-Regeltext-Datei + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> <html><head/><body><p>Text aus Anhang A &quot;Summary of guidelines&quot; aus der MISRA-C-2012-PDF in eine Textdatei einfügen.</p></body></html> + Clang Clang + Clang path (leave empty to use system PATH) Clang-Verzeichnis (PATH wird genutzt, wenn leer) + Visual Studio headers Visual-Studio-Header + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> <html><head/><body><p>Pfade zu Visual-Studio-Headern, Semikolon-getrennt.</p><p>Sie können eine Visual-Studio-Kommandozeile öffnen, &quot;SET INCLUDE&quot; eingeben und dann die Pfade hier reinkopieren.</p></body></html> + Code Editor Code-Editor + Code Editor Style Code-Editor-Stil + System Style Systemstil + Default Light Style Heller Standardstil + Default Dark Style Dunkler Standardstil + Custom Benutzerdefiniert + Remove Entfernen + Max count: Maximalzahl: + Applications Anwendungen + + Edit... Bearbeiten... + Set as default Als Standard festlegen + Reports Berichte + Save all errors when creating report Alle Fehler beim Erstellen von Berichten speichern + Save full path to files in reports Vollständigen Dateipfad in Berichten speichern + Language Sprache @@ -2864,6 +3186,8 @@ Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werde + + Statistics @@ -2871,113 +3195,135 @@ Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werde + Project Projekt + Project: Projekt: + Paths: Pfade: + Include paths: Include-Pfade: + Defines: Definitionen: + Undefines: Un-Definitionen: + Previous Scan Vorherige Prüfung + Path Selected: Ausgewählte Pfade: + Number of Files Scanned: Anzahl der geprüften Dateien: + Scan Duration: Prüfungsdauer: + Errors: Fehler: + Warnings: Warnungen: + Stylistic warnings: Stilwarnungen: + Portability warnings: Portabilitätswarnungen: + Performance issues: Performance-Probleme: + Information messages: Informationsmeldungen: + Active checkers: Aktive Checker: + Checkers Checker + History Verlauf + File: Datei: + Copy to Clipboard In die Zwischenablage kopieren + Pdf Export PDF-Export @@ -3127,6 +3473,7 @@ Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werde ThreadDetails + Thread Details diff --git a/gui/cppcheck_es.ts b/gui/cppcheck_es.ts index 0230aaa69e4..b2080055651 100644 --- a/gui/cppcheck_es.ts +++ b/gui/cppcheck_es.ts @@ -5,38 +5,45 @@ About + About Cppcheck Acerca de Cppcheck + Version %1 Versión %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - Una utilidad para el análisis estático de código C/C++. + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. Copyright © 2007-2021 el equipo de cppcheck. + This program is licensed under the terms of the GNU General Public License version 3 Este programa está licenciado bajo los términos de GNU General Public License versión 3 + Visit Cppcheck homepage at %1 Visita el sitio de Cppcheck en %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> @@ -46,11 +53,13 @@ of the GNU General Public License version 3 ApplicationDialog + Add an application Añade una aplicación + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -66,21 +75,25 @@ Parameters: -l(line) (file) + &Name: &Nombre: + &Executable: &Ejecutable: + &Parameters: &Parámetros: + Browse Buscar @@ -125,16 +138,19 @@ Parameters: -l(line) (file) HelpDialog + Cppcheck GUI help + Contents + Index @@ -152,16 +168,19 @@ Parameters: -l(line) (file) LibraryAddFunctionDialog + Add function Añadir función + Function name(s) Nombre(s) de la función + Number of arguments Número de argumentos @@ -170,86 +189,103 @@ Parameters: -l(line) (file) LibraryDialog + Library Editor Editor de bibliotecas + Open Abrir + Save Guardar + Save as + Functions Funciones + Sort + Add Añadir + Filter: + Comments + noreturn + False Falso + True Verdadero + Unknown Desconocido + return value must be used + ignore function in leaks checking + Arguments Argumentos + Edit Editar @@ -295,11 +331,13 @@ Parameters: -l(line) (file) LibraryEditArgDialog + Edit argument Editar argumento + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -310,11 +348,13 @@ Parameters: -l(line) (file) + Not bool No bool + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -325,78 +365,99 @@ Parameters: -l(line) (file) + Not null No null + Not uninit No uninit + String String + Format string + Min size of buffer + + Type Tipo + + None Ninguno + + argvalue + + mul + + strlen + + Arg + + Arg2 + and + Valid values Valores válidos @@ -409,684 +470,800 @@ Parameters: -l(line) (file) + &File &Archivo + &View &Ver + &Toolbars &Herramientas + &Help &Ayuda + C++ standard C++ estándar + &C standard C standard C estándar + &Edit &Editar + Standard Estándar + Categories Categorías + &License... &Licencia... + A&uthors... A&utores... + &About... &Acerca de... + &Files... &Ficheros... + + Analyze files Check files Comprobar archivos + Ctrl+F Ctrl+F + &Directory... &Carpeta... + + Analyze directory Check directory Comprobar carpeta + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop &Detener + + Stop analysis Stop checking Detener comprobación + Esc Esc + &Save results to file... &Guardar los resultados en el fichero... + Ctrl+S Ctrl+S + &Quit &Salir + &Clear results &Limpiar resultados + &Preferences &Preferencias + + Show style warnings Mostrar advertencias de estilo - + + + Show errors Mostrar errores - - + + Information Información + Show information messages Mostrar mensajes de información + Show portability warnings Mostrar advertencias de portabilidad + Show Cppcheck results + Clang + Show Clang results + &Filter &Filtro + Filter results Resultados del filtro + Windows 32-bit ANSI Windows 32-bit ANSI + Windows 32-bit Unicode Windows 32-bit Unicode + Unix 32-bit Unix 32-bit + Unix 64-bit Unix 64-bit + Windows 64-bit Windows 64-bit + &Print... Im&primir... + Print the Current Report Imprimir el informe actual + Print Pre&view... Pre&visualización de impresión... + Open a Print Preview Dialog for the Current Results Abre el diálogo de previsualización de impresión para el informe actual + Open library editor Abrir el editor de bibliotecas + &Check all &Seleccionar todo + Checking for updates + Hide Ocultar + + Report + A&nalyze + Filter Filtro + &Reanalyze modified files &Recheck modified files + Reanal&yze all files + Ctrl+Q + Style war&nings + E&rrors + &Uncheck all &Deseleccionar todo + Collapse &all Contraer &todo + &Expand all &Expandir todo + &Standard &Estándar + Standard items Elementos estándar + &Contents &Contenidos + Open the help contents Abrir la ayuda de contenidos + F1 F1 + Toolbar Barra de herramientas + &Categories &Categorías + Error categories Categorías de error + &Open XML... &Abrir XML... + Open P&roject File... Abrir P&royecto... + Ctrl+Shift+O + Sh&ow Scratchpad... + &New Project File... &Nuevo Proyecto... + Ctrl+Shift+N + &Log View &Visor del log + Log View Visor del log + C&lose Project File C&errar Proyecto + &Edit Project File... &Editar Proyecto... + &Statistics &Estadísticas + &Warnings + Per&formance warnings + &Information + &Portability + P&latforms + C++&11 + C&99 + &Posix + C&11 + &C89 + &C++03 + &Library Editor... + &Auto-detect language + &Enforce C++ + E&nforce C + C++14 C++14 + Reanalyze and check library + Check configuration (defines, includes) + C++17 C++17 + C++20 C++20 + Compliance report... + Normal + Autosar + EULA... + Thread Details + Show thread details - + + + Show warnings Mostrar advertencias + + Show performance warnings Mostrar advertencias de rendimiento + Show &hidden Mostrar &ocultos - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. - + You must close the project file before selecting new files or directories! ¡Tienes que cerrar el proyecto antes de seleccionar nuevos ficheros o carpetas! - + Select configuration - + File not found Archivo no encontrado - + Bad XML XML malformado - + Missing attribute Falta el atributo - + Bad attribute value - + Unsupported format Formato no soportado - + Duplicate define - + Failed to load the selected library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - - + + XML files (*.xml) Archivos XML (*.xml) - + Open the report file Abrir informe - + License Licencia - + Authors Autores - + Save the report file Guardar informe - - + + Quick Filter: Filtro rápido: - + Found project file: %1 Do you want to load this project file instead? @@ -1095,102 +1272,107 @@ Do you want to load this project file instead? ¿Quiere cargar este fichero de proyecto en su lugar? - + The library '%1' contains unknown elements: %2 La biblioteca '%1' contiene elementos deconocidos: %2 - + Duplicate platform type - + Platform type redefined - + Unknown element - - - - + + + + Error Error - + Text files (*.txt) Ficheros de texto (*.txt) - + CSV files (*.csv) Ficheros CVS (*.cvs) - + Project files (*.cppcheck);;All files(*.*) Ficheros de proyecto (*.cppcheck;;Todos los ficheros (*.*) - + Select Project File Selecciona el archivo de proyecto - - - - + + + + Project: Proyecto: - + + None of the selected files is part of the project, nothing to analyze. + + + + No suitable files found to analyze! - + C/C++ Source - + Compile database - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1198,76 +1380,76 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Build dir '%1' does not exist, create it? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Project files (*.cppcheck) - + Select Project Filename Selecciona el nombre del proyecto - + No project file loaded No hay ningún proyecto cargado - + The project file %1 @@ -1284,67 +1466,67 @@ Do you want to remove the file from the recently used projects -list? ¿Quiere eliminar el fichero de la lista de proyectos recientes? - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1388,26 +1570,31 @@ Options: NewSuppressionDialog + New suppression + Error ID + File name + Line number + Symbol name @@ -1449,111 +1636,135 @@ Options: ProjectFile + Project File Archivo de proyecto + Paths and Defines + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Import Project (Visual studio / compile database) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Defines must be separated by a semicolon ';' + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. Nota: Ponga sus propios archivos .cfg en la misma carpeta que el proyecto. Debería verlos arriba. + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files + Exclude folder... + Exclude file... + Misra C + 2012 + + 2023 + MISRA rule texts + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> + + Browse... + Analyze all Visual Studio configurations + Selected VS Configurations + Paths: Rutas: + + Add... Añadir... @@ -1561,6 +1772,9 @@ Options: + + + Edit Editar @@ -1569,269 +1783,327 @@ Options: + + + + Remove Eliminar + Undefines: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 + Include Paths: + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Types and Functions + + Analysis + This is a workfolder that Cppcheck will use for various purposes. + Parser + Cppcheck (built in) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + Check that each class has a safe public interface + Limit analysis + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) + Max CTU depth + Enable inline suppressions Habilitar supresiones inline + 2025 + Misra C++ + 2008 + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Safety profiles (defined in C++ core guidelines) + Bug hunting + External tools + Up Subir + Down Bajar + Platform + Clang (experimental) + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + Max recursion in template instantiation + Warning options + Root path: + Filepaths in warnings will be relative to this path + Warning tags (separated by semicolon) + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) + Libraries + Suppressions Supresiones + Add Añadir + + Addons + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 + Thread safety + Coding standards + Cert C++ + Bug hunting (Premium) + Defines: Definiciones: @@ -2354,21 +2626,25 @@ Por favor comprueba que la ruta a la aplicación y los parámetros son correctos ResultsView + Results Resultados + Critical errors + Analysis Log + Warning Details @@ -2475,26 +2751,31 @@ Para cambiar el tipo de comportamiento, abra el menú Ver. ScratchPad + Scratchpad Scratchpad + Copy or write some C/C++ code here: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": + filename nombre de archivo + Check Comprobar @@ -2503,11 +2784,13 @@ Para cambiar el tipo de comportamiento, abra el menú Ver. Settings + Preferences Preferencias + General General @@ -2517,46 +2800,55 @@ Para cambiar el tipo de comportamiento, abra el menú Ver. + Force checking all #ifdef configurations Forzar comprobación de todas las configuraciones #ifdef + Display error Id in column "Id" Mostrar el Id del error en la columna "Id" + Enable inline suppressions Habilitar supresiones inline + Check for inconclusive errors also + Show statistics on check completion + Check for updates + Show internal warnings in log + Addons + Python binary (leave this empty to use python in the PATH) @@ -2564,137 +2856,167 @@ Para cambiar el tipo de comportamiento, abra el menú Ver. + + + ... + MISRA addon + MISRA rule texts file + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Clang + Clang path (leave empty to use system PATH) + Visual Studio headers + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> + Code Editor + Code Editor Style + System Style + Default Light Style + Default Dark Style + Custom + Add... Añadir... + Max count: + + Edit... Editar... + Set as default Definir por defecto + Language Idioma + Number of threads: Número de hilos: + Show full path of files Mostrar la ruta completa de los ficheros + Show "No errors found" message when no errors found Mostrar el mensaje "No se han encontrado errores" + Remove Eliminar + Applications Aplicaciones + Reports Informes + Save all errors when creating report Guardar todos los errores cuando se cree el informe + Save full path to files in reports Guardar la ruta completa en los ficheros de informes @@ -2751,6 +3073,8 @@ Para cambiar el tipo de comportamiento, abra el menú Ver. + + Statistics @@ -2758,113 +3082,135 @@ Para cambiar el tipo de comportamiento, abra el menú Ver. + Project Proyecto + Project: Proyecto: + Paths: Rutas: + Include paths: Incluye las rutas: + Defines: Definiciones: + Undefines: + Previous Scan Análisis anterior + Path Selected: Ruta seleccionada: + Number of Files Scanned: Número de archivos analizados: + Scan Duration: Duración del análisis: + Errors: Errores: + Warnings: Advertencias: + Stylistic warnings: Advertencias de estilo: + Portability warnings: Advertencias de portabilidad: + Performance issues: Problemas de rendimiento: + Information messages: Mensajes de información: + Active checkers: + Checkers + History + File: + Copy to Clipboard Copiar al portapapeles + Pdf Export @@ -3014,6 +3360,7 @@ Para cambiar el tipo de comportamiento, abra el menú Ver. ThreadDetails + Thread Details diff --git a/gui/cppcheck_fi.ts b/gui/cppcheck_fi.ts index 8bdd6fd1671..0600febbd04 100644 --- a/gui/cppcheck_fi.ts +++ b/gui/cppcheck_fi.ts @@ -5,27 +5,32 @@ About + About Cppcheck Tietoa ohjelmasta Cppcheck + Version %1 Versio %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - Työkalu C/C++ koodin staattiseen analysointiin. + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. Copyright (C) 2007-2021 Daniel Marjamäki ja cppcheck tiimi. + This program is licensed under the terms of the GNU General Public License version 3 Tämä ohjelma on lisensoitu GNU General @@ -33,11 +38,13 @@ Public lisenssin version 3 alaisuuteen + Visit Cppcheck homepage at %1 Cppcheckin kotisivu löytyy osoitteesta %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> @@ -47,11 +54,13 @@ Public lisenssin version 3 alaisuuteen ApplicationDialog + Add an application Lisää uusi ohjelma + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -67,21 +76,25 @@ Parameters: -l(line) (file) + &Name: + &Executable: + &Parameters: + Browse Selaa @@ -128,16 +141,19 @@ Parameters: -l(line) (file) HelpDialog + Cppcheck GUI help + Contents + Index @@ -155,16 +171,19 @@ Parameters: -l(line) (file) LibraryAddFunctionDialog + Add function + Function name(s) + Number of arguments @@ -173,86 +192,103 @@ Parameters: -l(line) (file) LibraryDialog + Library Editor + Open + Save + Save as + Functions + Sort + Add + Filter: + Comments + noreturn + False + True + Unknown + return value must be used + ignore function in leaks checking + Arguments + Edit @@ -298,11 +334,13 @@ Parameters: -l(line) (file) LibraryEditArgDialog + Edit argument + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -313,11 +351,13 @@ Parameters: -l(line) (file) + Not bool + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -328,78 +368,99 @@ Parameters: -l(line) (file) + Not null + Not uninit + String + Format string + Min size of buffer + + Type + + None + + argvalue + + mul + + strlen + + Arg + + Arg2 + and + Valid values @@ -412,785 +473,906 @@ Parameters: -l(line) (file) + A&nalyze + Standard Vakio + &File &Tiedosto + &View &Näytä + &Toolbars + C++ standard + &C standard C standard + &Edit &Muokkaa + &License... &Lisenssi... + A&uthors... &Tekijät... + &About... &Tietoa ohjelmasta Cppcheck... + &Files... &Tiedostot... + + Analyze files Check files + Ctrl+F Ctrl+F + &Directory... &Hakemisto... + + Analyze directory Check directory + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop &Pysäytä + + Stop analysis Stop checking + Esc Esc + &Save results to file... &Tallenna tulokset tiedostoon... + Ctrl+S Ctrl+S + &Quit &Lopeta + &Clear results &Tyhjennä tulokset + &Preferences &Asetukset - + + + Show errors - + + + Show warnings + + Show performance warnings + Show &hidden - - + + Information + Show information messages + Show portability warnings + Show Cppcheck results + Clang + Show Clang results + &Filter + Filter results + Windows 32-bit ANSI + Windows 32-bit Unicode + Unix 32-bit + Unix 64-bit + Windows 64-bit + &Print... + Print the Current Report + Print Pre&view... + Open a Print Preview Dialog for the Current Results + Open library editor + &Check all &Valitse kaikki + Checking for updates + Hide + + Report + Filter + &Reanalyze modified files &Recheck modified files + Reanal&yze all files + Ctrl+Q + Style war&nings + E&rrors + &Uncheck all &Poista kaikista valinta + Collapse &all &Pienennä kaikki + &Expand all &Laajenna kaikki + &Standard + Standard items + Toolbar + &Categories + Error categories + &Open XML... + Open P&roject File... + Ctrl+Shift+O + Sh&ow Scratchpad... + &New Project File... + Ctrl+Shift+N + &Log View + Log View + C&lose Project File + &Edit Project File... + &Statistics + &Warnings + Per&formance warnings + &Information + &Portability + P&latforms + C++&11 + C&99 + &Posix + C&11 + &C89 + &C++03 + &Library Editor... + &Auto-detect language + &Enforce C++ + E&nforce C + C++14 + Reanalyze and check library + Check configuration (defines, includes) + C++17 + C++20 + Compliance report... + Normal + Autosar + EULA... + Thread Details + Show thread details + &Contents + Categories + + Show style warnings + Open the help contents + F1 + &Help &Ohje - - + + Quick Filter: - + Select configuration - + Found project file: %1 Do you want to load this project file instead? - + File not found - + Bad XML - + Missing attribute - + Bad attribute value - + Duplicate define - + Failed to load the selected library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Lisenssi - + Authors Tekijät - + Save the report file Tallenna raportti - - + + XML files (*.xml) XML-tiedostot (*xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. - + You must close the project file before selecting new files or directories! - + The library '%1' contains unknown elements: %2 - + Unsupported format - + Duplicate platform type - + Platform type redefined - + Unknown element - - - - + + + + Error - + Open the report file - + Text files (*.txt) Tekstitiedostot (*.txt) - + CSV files (*.csv) - + Project files (*.cppcheck);;All files(*.*) - + Select Project File - - - - + + + + Project: - + + None of the selected files is part of the project, nothing to analyze. + + + + No suitable files found to analyze! - + C/C++ Source - + Compile database - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1198,76 +1380,76 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Build dir '%1' does not exist, create it? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Project files (*.cppcheck) - + Select Project Filename - + No project file loaded - + The project file %1 @@ -1278,67 +1460,67 @@ Do you want to remove the file from the recently used projects -list? - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1382,26 +1564,31 @@ Options: NewSuppressionDialog + New suppression + Error ID + File name + Line number + Symbol name @@ -1423,75 +1610,91 @@ Options: ProjectFile + Project File + Paths and Defines + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Import Project (Visual studio / compile database) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Defines must be separated by a semicolon ';' + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. + MISRA rule texts + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> + + Browse... + Analyze all Visual Studio configurations + Selected VS Configurations + Paths: + + Add... @@ -1499,6 +1702,9 @@ Options: + + + Edit @@ -1507,305 +1713,371 @@ Options: + + + + Remove + Undefines: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 + Include Paths: + Up + Down + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Platform + + Analysis + This is a workfolder that Cppcheck will use for various purposes. + Clang (experimental) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) + Max CTU depth + Max recursion in template instantiation + Warning options + Root path: + Filepaths in warnings will be relative to this path + Warning tags (separated by semicolon) + Enable inline suppressions + 2025 + Misra C++ + 2008 + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Safety profiles (defined in C++ core guidelines) + Bug hunting + External tools + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) + Types and Functions + Libraries + Parser + Cppcheck (built in) + Check that each class has a safe public interface + Limit analysis + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files + Exclude folder... + Exclude file... + Suppressions + Add + + Addons + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 + Thread safety + Coding standards + Misra C + 2012 + + 2023 + Cert C++ + Bug hunting (Premium) + Defines: @@ -2412,21 +2684,25 @@ Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valik + Results Tulokset + Critical errors + Analysis Log + Warning Details @@ -2435,26 +2711,31 @@ Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valik ScratchPad + Scratchpad + Copy or write some C/C++ code here: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": + filename + Check @@ -2463,77 +2744,92 @@ Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valik Settings + Preferences Asetukset + General Yleiset + Add... + Number of threads: Säikeiden lukumäärä: + Force checking all #ifdef configurations Check all #ifdef configurations Tarkista kaikki #ifdef kombinaatiot + Show full path of files Näytä tiedostojen täysi polku + Show "No errors found" message when no errors found Näytä "virheitä ei löytynyt"-viesti jos virheitä ei löydy + Display error Id in column "Id" + Enable inline suppressions + Check for inconclusive errors also + Show statistics on check completion + Check for updates + Show internal warnings in log + Addons + Python binary (leave this empty to use python in the PATH) @@ -2541,117 +2837,143 @@ Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valik + + + ... + MISRA addon + MISRA rule texts file + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Clang + Clang path (leave empty to use system PATH) + Visual Studio headers + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> + Code Editor + Code Editor Style + System Style + Default Light Style + Default Dark Style + Custom + Remove + Max count: + Applications Ohjelmat + + Edit... + Set as default + Reports Raportit + Save all errors when creating report Tallenna kaikki virheet raporttia luodessa + Save full path to files in reports Tallenna tiedostojen koko polku raportteihin + Language @@ -2704,6 +3026,8 @@ Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valik + + Statistics @@ -2711,113 +3035,135 @@ Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valik + Project + Project: + Paths: + Include paths: + Defines: + Undefines: + Previous Scan + Path Selected: + Number of Files Scanned: + Scan Duration: + Errors: + Warnings: + Stylistic warnings: + Portability warnings: + Performance issues: + Information messages: + Active checkers: + Checkers + History + File: + Copy to Clipboard + Pdf Export @@ -2967,6 +3313,7 @@ Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valik ThreadDetails + Thread Details diff --git a/gui/cppcheck_fr.ts b/gui/cppcheck_fr.ts index ca25352e60c..7ac6f3ae89a 100644 --- a/gui/cppcheck_fr.ts +++ b/gui/cppcheck_fr.ts @@ -5,21 +5,25 @@ About + About Cppcheck A propos + Version %1 Version %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - Un outil d'analyse statique de code C/C++. + This program is licensed under the terms of the GNU General Public License version 3 Ce programme est sous licence GNU @@ -27,17 +31,20 @@ General Public License version 3 + Visit Cppcheck homepage at %1 Visitez le site Cppcheck : %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. @@ -47,11 +54,13 @@ General Public License version 3 ApplicationDialog + Add an application Ajouter une application + Browse Parcourir @@ -67,16 +76,19 @@ General Public License version 3 + &Executable: &Exécutable : + &Parameters: &Paramètres : + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -102,6 +114,7 @@ Paramètres : -l(ligne) (fichier) + &Name: &Nom : @@ -128,16 +141,19 @@ Paramètres : -l(ligne) (fichier) HelpDialog + Cppcheck GUI help + Contents + Index @@ -151,16 +167,19 @@ Paramètres : -l(ligne) (fichier) LibraryAddFunctionDialog + Add function Ajouter une fonction + Function name(s) Nom(s) de la fonction + Number of arguments Nombre d'arguments @@ -169,66 +188,79 @@ Paramètres : -l(ligne) (fichier) LibraryDialog + Library Editor + Open + Save Sauvegarder + Functions + Add Ajouter + noreturn + False + True + Unknown + return value must be used + ignore function in leaks checking + Arguments + Edit Editer @@ -245,21 +277,25 @@ Paramètres : -l(ligne) (fichier) + Sort + Filter: + Comments + Save as @@ -288,11 +324,13 @@ Paramètres : -l(ligne) (fichier) LibraryEditArgDialog + Edit argument + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -303,11 +341,13 @@ Paramètres : -l(ligne) (fichier) + Not bool + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -318,78 +358,99 @@ Paramètres : -l(ligne) (fichier) + Not null + Not uninit + String + Format string + Min size of buffer + + Type + + None + + argvalue + + mul + + strlen + + Arg + + Arg2 + and + Valid values @@ -398,472 +459,535 @@ Paramètres : -l(ligne) (fichier) MainWindow + Checking for updates + Hide Cacher + &File &Fichier + &View &Affichage + + Report + &Help &Aide + &Edit &Édition + Standard Standard + &License... &Licence... + A&uthors... A&uteurs... + &About... À &Propos... + &Files... &Fichiers... + Ctrl+F + &Directory... &Répertoires... + Ctrl+D + Ctrl+R + &Stop &Arrêter + Esc + &Save results to file... &Sauvegarder les résultats dans un fichier... + Ctrl+S + &Quit &Quitter + &Clear results &Effacer les résultats + &Preferences &Préférences + &Check all &Tout cocher + &Uncheck all &Tout décocher + Collapse &all &Tout réduire + &Expand all &Tout dérouler + &Contents &Contenus + Open the help contents Ouvir l'aide + F1 + Compliance report... + Normal + Autosar + EULA... + Thread Details + Show thread details - + License Licence - + Authors Auteurs - + Save the report file Sauvegarder le rapport - - + + XML files (*.xml) Fichiers XML (*.xml) - + About - + Text files (*.txt) Fichiers Texte (*.txt) - + CSV files (*.csv) Fichiers CSV (*.csv) + &Toolbars &Boite à outils + Categories Catégories + + Show style warnings Afficher les avertissements de style - + + + Show errors Afficher les erreurs + &Standard + Standard items + Toolbar + &Categories + Error categories + &Open XML... &Ouvrir un fichier XML... + Open P&roject File... Ouvrir un P&rojet... + &New Project File... &Nouveau Projet... + &Log View &Journal + Log View Journal + C&lose Project File F&ermer le projet + &Edit Project File... &Editer le projet + &Statistics Statistiques - + + + Show warnings Afficher les avertissements + + Show performance warnings Afficher les avertissements de performance + Show &hidden - - + + Information Information + Show information messages Afficher les messages d'information + Show portability warnings Afficher les problèmes de portabilité - + You must close the project file before selecting new files or directories! Vous devez d'abord fermer le projet avant de choisir des fichiers/répertoires - + Open the report file Ouvrir le rapport - + Project files (*.cppcheck);;All files(*.*) - + Select Project File - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Select Project Filename - + No project file loaded - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -871,37 +995,39 @@ This is probably because the settings were changed between the Cppcheck versions + &Filter &Filtre + Filter results - - + + Quick Filter: Filtre rapide : - + Found project file: %1 Do you want to load this project file instead? - - - - + + + + Project: Projet : - + The project file %1 @@ -913,31 +1039,37 @@ Do you want to remove the file from the recently used projects -list? + Filter Filtre + Windows 32-bit ANSI + Windows 32-bit Unicode + Unix 32-bit + Unix 64-bit + Windows 64-bit @@ -948,98 +1080,104 @@ Do you want to remove the file from the recently used projects -list? + C++ standard - - - - + + + + Error Erreur - + File not found Fichier introuvable - + Bad XML Mauvais fichier XML - + Missing attribute Attribut manquant - + Bad attribute value Mauvaise valeur d'attribut - + Failed to load the selected library '%1'. %2 Echec lors du chargement de la bibliothèque '%1'. %2 - + Unsupported format Format non supporté - + The library '%1' contains unknown elements: %2 La bibliothèque '%1' contient des éléments inconnus: %2 - + Duplicate platform type - + Platform type redefined + &Print... &Imprimer... + Print the Current Report Imprimer le rapport + Print Pre&view... Apercu d'impression... + Open a Print Preview Dialog for the Current Results + Open library editor - + Unknown element - + Select configuration @@ -1062,104 +1200,116 @@ Options: - + Build dir '%1' does not exist, create it? + + Analyze files + + Analyze directory + &Reanalyze modified files + + Stop analysis - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + No suitable files found to analyze! - + + None of the selected files is part of the project, nothing to analyze. + + + + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Duplicate define - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1167,181 +1317,213 @@ Do you want to stop the analysis and exit Cppcheck? + A&nalyze + &C standard + Reanal&yze all files + Ctrl+Q + Style war&nings + E&rrors + Ctrl+Shift+O + Sh&ow Scratchpad... + Ctrl+Shift+N + &Warnings + Per&formance warnings + &Information + &Portability + Show Cppcheck results + Clang + Show Clang results + P&latforms + C++&11 + C&99 + &Posix + C&11 + &C89 + &C++03 + &Library Editor... + &Auto-detect language + &Enforce C++ + E&nforce C + C++14 - + Project files (*.cppcheck) + Reanalyze and check library + Check configuration (defines, includes) + C++17 + C++20 - + C/C++ Source - + Compile database - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1353,26 +1535,31 @@ Do you want to proceed? NewSuppressionDialog + New suppression + Error ID + File name + Line number + Symbol name @@ -1394,22 +1581,27 @@ Do you want to proceed? ProjectFile + Project File Fichier Projet + Paths: Chemins : + Defines: + + Add... Ajouter... @@ -1417,6 +1609,9 @@ Do you want to proceed? + + + Edit Editer @@ -1425,356 +1620,433 @@ Do you want to proceed? + + + + Remove Supprimer + Up Monter + Down Descendre + Suppressions Suppressions + Add Ajouter + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. + ... + Include Paths: + Paths and Defines + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> + Analyze all Visual Studio configurations + Root path: + Warning tags (separated by semicolon) + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) + Selected VS Configurations + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Types and Functions + Libraries + Parser + Cppcheck (built in) + Check that each class has a safe public interface + Limit analysis + + Addons + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 + Thread safety + Coding standards + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Bug hunting + + Browse... + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int + Platform + This is a workfolder that Cppcheck will use for various purposes. + Clang (experimental) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + Max recursion in template instantiation + Warning options + Filepaths in warnings will be relative to this path + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files + Exclude folder... + Exclude file... + Enable inline suppressions + Misra C + 2012 + + 2023 + 2025 + MISRA rule texts + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Misra C++ + 2008 + Cert C++ + Safety profiles (defined in C++ core guidelines) + Bug hunting (Premium) + External tools + Import Project (Visual studio / compile database/ Borland C++ Builder 6) + Undefines: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 + + Analysis + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) + Max CTU depth @@ -2291,6 +2563,7 @@ Please select the default editor application in preferences/Applications.ResultsView + Results Résultats @@ -2375,16 +2648,19 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage. + Critical errors + Analysis Log + Warning Details @@ -2408,26 +2684,31 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage.ScratchPad + Scratchpad + filename + Check + Copy or write some C/C++ code here: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": @@ -2436,122 +2717,147 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage.Settings + Preferences Préférences + General Général + Number of threads: Nombre de fils : + Max count: + Show full path of files Montrer le chemin complet des fichiers + Show "No errors found" message when no errors found Afficher un message "Pas d'erreur trouvée" lorsque aucune erreur est trouvée + Check for updates + Applications Applications + Reports Rapports + Save all errors when creating report Sauvegarder toutes les erreurs lorsqu'un rapport est créé + Save full path to files in reports Sauvegarder le chemin complet des fichiers dans les rapports + Add... Ajouter... + Force checking all #ifdef configurations + Enable inline suppressions + Language Langue + Remove Supprimer + + Edit... Editer... + Set as default + Display error Id in column "Id" Afficher l'identifiant d'erreur Id dans la colonne "Id" + Check for inconclusive errors also + Show internal warnings in log Montrer les avertissements internes dans le journal + Show statistics on check completion + Addons + Python binary (leave this empty to use python in the PATH) @@ -2559,71 +2865,87 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage. + + + ... + Clang + Clang path (leave empty to use system PATH) + Visual Studio headers + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> + MISRA addon + MISRA rule texts file + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Code Editor + Code Editor Style + Default Light Style + Default Dark Style + Custom + System Style @@ -2676,6 +2998,8 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage. + + Statistics @@ -2683,93 +3007,111 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage. + Project Projet + Project: Projet : + Paths: Chemins : + Include paths: Inclure les chemins : + Defines: + Previous Scan Analyse précédente + Path Selected: Chemin sélectionné : + Number of Files Scanned: Nombre de fichiers analysés : + Scan Duration: Durée de l'analyse : + Errors: Erreurs : + Warnings: Avertissements + Stylistic warnings: Avertissements de style + Portability warnings: Avertissements de portabilité + Performance issues: Problème de performance + Information messages: Messages d'information : + Active checkers: + Checkers + Copy to Clipboard Copier vers le presse-papier @@ -2896,6 +3238,7 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage. + Pdf Export @@ -2906,11 +3249,13 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage. + History + File: @@ -2926,6 +3271,7 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage. + Undefines: @@ -2939,6 +3285,7 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage.ThreadDetails + Thread Details diff --git a/gui/cppcheck_it.ts b/gui/cppcheck_it.ts index 243b0be7d51..4d0823a7053 100644 --- a/gui/cppcheck_it.ts +++ b/gui/cppcheck_it.ts @@ -5,27 +5,32 @@ About + About Cppcheck Informazioni su Cppcheck + Version %1 Versione %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - Uno strumento per l'analisi statica di codice C/C++ + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. Copyright © 2007-2021 il team Cppcheck. + This program is licensed under the terms of the GNU General Public License version 3 Questo programma è rilasciato sotto i termini @@ -33,11 +38,13 @@ della GNU General Public License versione 3 + Visit Cppcheck homepage at %1 Visita la pagina iniziale di Cppcheck all'indirizzo: %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> @@ -47,11 +54,13 @@ della GNU General Public License versione 3 ApplicationDialog + Add an application Aggiungi un'applicazione + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -78,21 +87,25 @@ Parametri: -l(line) (file) + &Name: &Nome: + &Executable: &Eseguibile: + &Parameters: &Parametri: + Browse Esplora @@ -137,16 +150,19 @@ Parametri: -l(line) (file) HelpDialog + Cppcheck GUI help + Contents + Index @@ -164,16 +180,19 @@ Parametri: -l(line) (file) LibraryAddFunctionDialog + Add function + Function name(s) + Number of arguments @@ -182,86 +201,103 @@ Parametri: -l(line) (file) LibraryDialog + Library Editor + Open + Save + Save as + Functions + Sort + Add + Filter: + Comments + noreturn + False + True + Unknown + return value must be used + ignore function in leaks checking + Arguments + Edit Modifica @@ -307,11 +343,13 @@ Parametri: -l(line) (file) LibraryEditArgDialog + Edit argument + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -322,11 +360,13 @@ Parametri: -l(line) (file) + Not bool + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -337,78 +377,99 @@ Parametri: -l(line) (file) + Not null + Not uninit + String + Format string + Min size of buffer + + Type + + None + + argvalue + + mul + + strlen + + Arg + + Arg2 + and + Valid values @@ -421,578 +482,694 @@ Parametri: -l(line) (file) + A&nalyze + Standard Standard + &File &File + &View &Visualizza + &Toolbars &Barre degli strumenti + C++ standard + &C standard C standard + &Edit &Modifica + &License... &Licenza... + A&uthors... A&utori... + &About... I&nformazioni su... + &Files... &File... + + Analyze files Check files Scansiona i file + Ctrl+F Ctrl+F + &Directory... &Cartella... + + Analyze directory Check directory Scansiona la cartella + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop &Ferma + + Stop analysis Stop checking Ferma la scansione + Esc Esc + &Save results to file... &Salva i risultati nel file... + Ctrl+S Ctrl+S + &Quit &Esci + &Clear results &Cancella i risultati + &Preferences &Preferenze - + + + Show errors Mostra gli errori - + + + Show warnings Mostra gli avvisi + + Show performance warnings Mostra gli avvisi sulle prestazioni + Show &hidden Mostra &i nascosti - - + + Information Informazione + Show information messages Mostra messaggi di informazione + Show portability warnings Mostra gli avvisi sulla portabilità + Show Cppcheck results + Clang + Show Clang results + &Filter &Filtro + Filter results Filtra i risultati + Windows 32-bit ANSI Windows 32-bit, ANSI + Windows 32-bit Unicode Windows 32-bit, Unicode + Unix 32-bit Unix 32-bit + Unix 64-bit Unix 64-bit + Windows 64-bit Windows 64-bit + &Print... + Print the Current Report + Print Pre&view... + Open a Print Preview Dialog for the Current Results + Open library editor + &Check all &Seleziona tutto + Checking for updates + Hide Nascondi + + Report + Filter Filtro + &Reanalyze modified files &Recheck modified files + Reanal&yze all files + Ctrl+Q + Style war&nings + E&rrors + &Uncheck all &Deseleziona tutto + Collapse &all Riduci &tutto + &Expand all &Espandi tutto + &Standard &Standard + Standard items Oggetti standard + Toolbar Barra degli strumenti + &Categories &Categorie + Error categories Categorie di errore + &Open XML... &Apri XML... + Open P&roject File... Apri file di p&rogetto... + Ctrl+Shift+O + Sh&ow Scratchpad... + &New Project File... &Nuovo file di progetto... + Ctrl+Shift+N + &Log View &Visualizza il rapporto + Log View Visualizza il rapporto + C&lose Project File C&hiudi il file di progetto + &Edit Project File... &Modifica il file di progetto... + &Statistics &Statistiche + &Warnings + Per&formance warnings + &Information + &Portability + P&latforms + C++&11 + C&99 + &Posix + C&11 + &C89 + &C++03 + &Library Editor... + &Auto-detect language + &Enforce C++ + E&nforce C + C++14 C++14 + Reanalyze and check library + Check configuration (defines, includes) + C++17 C++17 + C++20 C++20 + Compliance report... + Normal + Autosar + EULA... + Thread Details + Show thread details + &Contents &Contenuti + Categories Categorie + + Show style warnings Mostra gli avvisi sullo stile + Open the help contents Apri i contenuti di aiuto + F1 F1 + &Help &Aiuto - - + + Quick Filter: Rapido filtro: - + Select configuration - + Found project file: %1 Do you want to load this project file instead? @@ -1001,96 +1178,96 @@ Do you want to load this project file instead? Vuoi piuttosto caricare questo file di progetto? - + File not found - + Bad XML - + Missing attribute - + Bad attribute value - + Unsupported format - + Duplicate define - + Failed to load the selected library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Licenza - + Authors Autori - + Save the report file Salva il file di rapporto - - + + XML files (*.xml) File XML (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -1099,111 +1276,116 @@ This is probably because the settings were changed between the Cppcheck versions Probabilmente ciò è avvenuto perché le impostazioni sono state modificate tra le versioni di Cppcheck. Per favore controlla (e sistema) le impostazioni delle applicazioni editor, altrimenti il programma editor può non partire correttamente. - + You must close the project file before selecting new files or directories! Devi chiudere il file di progetto prima di selezionare nuovi file o cartelle! - + The library '%1' contains unknown elements: %2 - + Duplicate platform type - + Platform type redefined - + Unknown element - - - - + + + + Error - + Open the report file Apri il file di rapporto - + Text files (*.txt) File di testo (*.txt) - + CSV files (*.csv) Files CSV (*.csv) - + Project files (*.cppcheck);;All files(*.*) Files di progetto (*.cppcheck);;Tutti i files(*.*) - + Select Project File Seleziona il file di progetto - - - - + + + + Project: Progetto: - + + None of the selected files is part of the project, nothing to analyze. + + + + No suitable files found to analyze! - + C/C++ Source - + Compile database - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1211,76 +1393,76 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Build dir '%1' does not exist, create it? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Project files (*.cppcheck) - + Select Project Filename Seleziona il nome del file di progetto - + No project file loaded Nessun file di progetto caricato - + The project file %1 @@ -1297,67 +1479,67 @@ Do you want to remove the file from the recently used projects -list? Vuoi rimuovere il file dalla lista dei progetti recentemente usati? - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1401,26 +1583,31 @@ Options: NewSuppressionDialog + New suppression + Error ID + File name + Line number + Symbol name @@ -1462,111 +1649,135 @@ Options: ProjectFile + Project File File di progetto + Paths and Defines + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Import Project (Visual studio / compile database) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Defines must be separated by a semicolon ';' + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files + Exclude folder... + Exclude file... + Misra C + 2012 + + 2023 + MISRA rule texts + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> + + Browse... + Analyze all Visual Studio configurations + Selected VS Configurations + Paths: Percorsi: + + Add... Aggiungi... @@ -1574,6 +1785,9 @@ Options: + + + Edit Modifica @@ -1582,269 +1796,327 @@ Options: + + + + Remove Rimuovi + Undefines: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 + Include Paths: + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Types and Functions + + Analysis + This is a workfolder that Cppcheck will use for various purposes. + Parser + Cppcheck (built in) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + Check that each class has a safe public interface + Limit analysis + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) + Max CTU depth + Enable inline suppressions Abilita le soppressioni + 2025 + Misra C++ + 2008 + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Safety profiles (defined in C++ core guidelines) + Bug hunting + External tools + Up Su + Down Giù + Platform + Clang (experimental) + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + Max recursion in template instantiation + Warning options + Root path: + Filepaths in warnings will be relative to this path + Warning tags (separated by semicolon) + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) + Libraries + Suppressions + Add + + Addons + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 + Thread safety + Coding standards + Cert C++ + Bug hunting (Premium) + Defines: Definizioni: @@ -2464,21 +2736,25 @@ Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza. + Results Risultati + Critical errors + Analysis Log + Warning Details @@ -2487,26 +2763,31 @@ Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza.ScratchPad + Scratchpad Blocchetto per appunti + Copy or write some C/C++ code here: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": + filename Nome file + Check Scansiona @@ -2515,21 +2796,25 @@ Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza.Settings + Preferences Preferenze + General Generale + Add... Aggiungi... + Number of threads: Numero di threads: @@ -2539,56 +2824,67 @@ Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza. + Force checking all #ifdef configurations Forza la scansione di tutte le configurazioni #ifdef + Show full path of files Mostra tutto il percorso dei files + Show "No errors found" message when no errors found Mostra il messaggio "Nessun errore trovato" quando nessun errore è stato trovato + Display error Id in column "Id" Mostra l'id dell'errore nella colonna "Id" + Enable inline suppressions Abilita le soppressioni + Check for inconclusive errors also + Show statistics on check completion + Check for updates + Show internal warnings in log + Addons + Python binary (leave this empty to use python in the PATH) @@ -2596,117 +2892,143 @@ Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza. + + + ... + MISRA addon + MISRA rule texts file + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Clang + Clang path (leave empty to use system PATH) + Visual Studio headers + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> + Code Editor + Code Editor Style + System Style + Default Light Style + Default Dark Style + Custom + Remove Rimuovi + Max count: + Applications Applicazioni + + Edit... Modifica... + Set as default Imposta come predefinito + Reports Rapporti + Save all errors when creating report Salva tutti gli errori quando viene creato il rapporto + Save full path to files in reports Salva tutto il percorso ai files nei rapporti + Language Lingua @@ -2763,6 +3085,8 @@ Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza. + + Statistics @@ -2770,113 +3094,135 @@ Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza. + Project Progetto + Project: Progetto: + Paths: Percorsi: + Include paths: Percorsi di inclusione: + Defines: Definizioni: + Undefines: + Previous Scan Precedente Scansione + Path Selected: Selezionato percorso: + Number of Files Scanned: Numero di Files Scansionati: + Scan Duration: Durata della scansione: + Errors: Errori: + Warnings: Avvisi: + Stylistic warnings: Avvisi sullo stile: + Portability warnings: Avvisi sulla portabilità: + Performance issues: Casi sulla performance: + Information messages: Messaggi di informazione: + Active checkers: + Checkers + History + File: + Copy to Clipboard Copia negli Appunti + Pdf Export @@ -3026,6 +3372,7 @@ Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza.ThreadDetails + Thread Details diff --git a/gui/cppcheck_ja.ts b/gui/cppcheck_ja.ts index dcbe8418942..75b2bad9985 100644 --- a/gui/cppcheck_ja.ts +++ b/gui/cppcheck_ja.ts @@ -5,38 +5,45 @@ About + About Cppcheck cppcheckについて + Version %1 Version %1 + Cppcheck - A tool for static C/C++ code analysis. CppcheckはC/C++ 静的コード解析ツールです. + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. Copyright © 2007-%1 Cppcheck team. + This program is licensed under the terms of the GNU General Public License version 3 本ソフトウェアはGNU General Public License Version3 ライセンスの元で配布されます + Visit Cppcheck homepage at %1 Cppcheckのホームページはこちら %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> <html><head/><body><p>ライブラリの開発者に感謝を捧げます:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> @@ -46,11 +53,13 @@ of the GNU General Public License version 3 ApplicationDialog + Add an application アプリケーションの追加 + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -77,21 +86,25 @@ Parameters: -l(line) (file) + &Name: 表示名(&N): + &Executable: 実行ファイルのパス(&E): + &Parameters: パラメータ(&P): + Browse 参照 @@ -191,16 +204,19 @@ Parameters: -l(line) (file) HelpDialog + Cppcheck GUI help Cppcheck GUI ヘルプ + Contents 目次 + Index インデックス @@ -218,16 +234,19 @@ Parameters: -l(line) (file) LibraryAddFunctionDialog + Add function 関数の追加 + Function name(s) 関数の名称 + Number of arguments 引数の数 @@ -236,86 +255,103 @@ Parameters: -l(line) (file) LibraryDialog + Library Editor ライブラリエディタ + Open 開く + Save 保存する + Save as 別名で保存する + Functions 関数 + Sort ソート + Add 追加 + Filter: フィルタ: + Comments コメント + noreturn noreturn(返り値なし) + False False(偽) + True True(真) + Unknown Unknown(不明) + return value must be used 返り値は使用されなければならない + ignore function in leaks checking リークの解析中に無視する関数 + Arguments Arguments(引数) + Edit 編集 @@ -361,11 +397,13 @@ Parameters: -l(line) (file) LibraryEditArgDialog + Edit argument 引数の編集 + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -381,12 +419,14 @@ Parameters: -l(line) (file) + Not bool 非ブール型 非bool値 + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -402,78 +442,99 @@ Parameters: -l(line) (file) + Not null 非NULL + Not uninit 未初期化 + String 文字列 + Format string フォーマット文字列 + Min size of buffer バッファの最小サイズ + + Type Type(型) + + None None(無) + + argvalue argvalue(引数の値) + + mul mul(積) + + strlen strlen(文字数) + + Arg Arg(引数) + + Arg2 Arg2(第二引数) + and and(和) + Valid values 妥当な値 @@ -486,542 +547,654 @@ Parameters: -l(line) (file) + &File ファイル(&F) + &View 表示(&V) + &Toolbars ツールバー(&T) + &Help ヘルプ(&H) + C++ standard C++標準 + &C standard C standard &C標準 + &Edit 編集(&E) + Standard 言語規格 + Categories カテゴリ + &License... ライセンス(&L)... + A&uthors... 作者(&u)... + &About... Cppcheckについて(&A)... + &Files... ファイル選択(&F)... + + Analyze files Check files ファイルをチェックする + Ctrl+F Ctrl+F + &Directory... ディレクトリ選択(&D)... + + Analyze directory Check directory ディレクトリをチェックする + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop 停止(&S) + + Stop analysis Stop checking チェックを停止する + Esc Esc + &Save results to file... 結果をファイルに保存(&S)... + Ctrl+S Ctrl+S + &Quit 終了(&Q) + &Clear results 結果をクリア(&C) + &Preferences 設定(&P) + + Show style warnings スタイル警告を表示 - + + + Show errors エラーを表示 - - + + Information 情報 + Show information messages 情報メッセージを表示 + Show portability warnings 移植可能性の問題を表示 + Show Cppcheck results Cppcheck結果を表示する + Clang Clang + Show Clang results Clangの結果を表示 + &Filter フィルター(&F) + Filter results フィルタ結果 + Windows 32-bit ANSI Windows 32-bit ANSIエンコード + Windows 32-bit Unicode Windows 32-bit Unicode + Unix 32-bit Unix 32-bit + Unix 64-bit Unix 64-bit + Windows 64-bit Windows 64-bit + &Print... 印刷(&P)... + Print the Current Report 現在のレポートを印刷 + Print Pre&view... 印刷プレビュー(&v)... + Open a Print Preview Dialog for the Current Results 現在のレポートをプレビュー表示 + Open library editor ライブラリエディタを開く + C&lose Project File プロジェクトを閉じる(&l) + &Edit Project File... プロジェクトの編集(&E)... + &Statistics 統計情報(&S) - + + + Show warnings 警告を表示 + + Show performance warnings パフォーマンス警告を表示 + Show &hidden 非表示を表示(&h) + &Check all すべてのエラーを表示(&C) + Checking for updates 更新の確認 + Hide 非表示 + + Report レポート + A&nalyze チェック(&n) + Filter フィルター + &Reanalyze modified files &Recheck modified files 変更ありファイルを再解析(&R) + Reanal&yze all files 全ファイル再解析(&y) + Ctrl+Q Ctrl+Q + Style war&nings スタイル警告(&n) + E&rrors エラー(&r) + &Uncheck all すべてのエラーを非表示(&U) + Collapse &all ツリーを折り畳む(&a) + &Expand all ツリーを展開(&E) + &Standard 言語規格(&S) + Standard items 標準項目 + &Contents コンテンツ(&C) + Open the help contents ヘルプファイルを開く + F1 F1 + Toolbar ツールバー + &Categories カテゴリ(&C) + Error categories エラーカテゴリ + &Open XML... XMLを開く(&O)... + Open P&roject File... プロジェクトを開く(&R)... + Ctrl+Shift+O Ctrl+Shift+O + Sh&ow Scratchpad... スクラッチパッドを表示(&o)... + &New Project File... 新規プロジェクト(&N)... + Ctrl+Shift+N Ctrl+Shift+N + &Log View ログを表示(&L) + Log View ログ表示 + &Warnings 警告(&W) + Per&formance warnings パフォーマンス警告(&f) + &Information 情報(&I) + &Portability 移植可能性(&P) + P&latforms プラットフォーム(&l) + C++&11 C++11(&1) + C&99 C99(&9) + &Posix Posix(&P) + C&11 C11(&1) + &C89 C89(&C) + &C++03 C++03(&C) + &Library Editor... ライブラリエディタ(&L)... + &Auto-detect language 自動言語検出(&A) + &Enforce C++ C++ 強制(&E) + E&nforce C C 強制(&n) + C++14 C++14 + Reanalyze and check library ライブラリを再チェックする + Check configuration (defines, includes) チェックの設定(define、インクルード) + C++17 C++17 + C++20 C++20 + Compliance report... コンプライアンスレポート... + Normal ノーマル @@ -1047,26 +1220,30 @@ Parameters: -l(line) (file) + Autosar AUTOSAR + EULA... EULA... + Thread Details スレッド詳細 + Show thread details スレッド詳細を表示 - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -1075,23 +1252,28 @@ This is probably because the settings were changed between the Cppcheck versions Cppcheckの古いバージョンの設定には互換性がありません。エディタアプリケーションの設定を確認して修正してください、そうしないと正しく起動できないかもしれません。 - + You must close the project file before selecting new files or directories! 新しいファイル/ディレクトリをチェックするには現在のプロジェクトを閉じてください! - - + + Quick Filter: クイックフィルタ: - + + None of the selected files is part of the project, nothing to analyze. + + + + Select configuration コンフィグレーションの選択 - + Found project file: %1 Do you want to load this project file instead? @@ -1100,64 +1282,64 @@ Do you want to load this project file instead? 現在のプロジェクトの代わりにこのプロジェクトファイルを読み込んでもかまいませんか? - + The library '%1' contains unknown elements: %2 このライブラリ '%1' には次の不明な要素が含まれています。 %2 - + File not found ファイルがありません - + Bad XML 不正なXML - + Missing attribute 属性がありません - + Bad attribute value 不正な属性があります - + Unsupported format サポートされていないフォーマット - + Duplicate platform type プラットフォームの種類が重複しています - + Platform type redefined プラットフォームの種類が再定義されました - + Unknown element 不明な要素 - + Failed to load the selected library '%1'. %2 選択したライブラリの読み込みに失敗しました '%1' %2 - - - - + + + + Error エラー @@ -1170,38 +1352,38 @@ Do you want to load this project file instead? %1 - %2 の読み込みに失敗 - - + + XML files (*.xml) XML ファイル (*.xml) - + Open the report file レポートを開く - + License ライセンス - + Authors 作者 - + Save the report file レポートを保存 - + Text files (*.txt) テキストファイル (*.txt) - + CSV files (*.csv) CSV形式ファイル (*.csv) @@ -1210,32 +1392,32 @@ Do you want to load this project file instead? コンプライアンスレポートをすぐに生成できません。解析が完了し成功していなければなりません。コードを再解析して、致命的なエラーがないことを確認してください。 - + Project files (*.cppcheck);;All files(*.*) プロジェクトファイル (*.cppcheck);;すべてのファイル(*.*) - + Select Project File プロジェクトファイルを選択 - + Failed to open file ファイルを開くのに失敗しました - + Unknown project file format プロジェクトファイルの形式が不明です - + Failed to import project file プロジェクトファイルのインポートに失敗しました - + Failed to import '%1': %2 Analysis is stopped. @@ -1244,40 +1426,40 @@ Analysis is stopped. 解析を停止しました。 - + Failed to import '%1' (%2), analysis is stopped '%1' (%2) のインポートに失敗しました。解析は停止 - + Install インストール - + New version available: %1. %2 新しいバージョンが利用可能です。: %1. %2 - - - - + + + + Project: プロジェクト: - + No suitable files found to analyze! チェック対象のファイルがみつかりません! - + C/C++ Source C/C++のソースコード - + Compile database コンパイルデータベース @@ -1290,22 +1472,22 @@ Analysis is stopped. Borland C++ Builder 6 - + Select files to analyze チェック対象のファイルを選択 - + Select directory to analyze チェックするディレクトリを選択してください - + Select the configuration that will be analyzed チェックの設定を選択 - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1314,37 +1496,37 @@ Do you want to proceed analysis without using any of these project files? - + Duplicate define 重複した定義 - + File not found: '%1' ファイルがありません: '%1' - + Failed to load/setup addon %1: %2 アドオンの読み込みまたは設定に失敗 %1 - %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. %1のロードに失敗しました。あなたの Cppcheck は正しくインストールされていません。あなたは --data-dir=<directory> コマンドラインオプションを使ってこのファイルの場所を指定できます。ただし、この --data-dir はインストールスクリプトによって使用されていなければなりません。またGUI版はこれを使用しません。さらに、全ての設定は調整済みでなければなりません。 - + Failed to load %1 - %2 Analysis is aborted. 読み込みに失敗 %1 - %2 - - + + %1 Analysis is aborted. @@ -1353,7 +1535,7 @@ Analysis is aborted. 解析は中止した。 - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1363,7 +1545,7 @@ Do you want to proceed? 新しくXMLファイルを開くと現在の結果が削除されます。実行しますか? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1372,77 +1554,77 @@ Do you want to stop the analysis and exit Cppcheck? チェックを中断して、Cppcheckを終了しますか? - + About CppCheckについて - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML ファイル (*.xml);;テキストファイル (*.txt);;CSVファイル (*.csv) - + Build dir '%1' does not exist, create it? ビルドディレクトリ'%1'がありません。作成しますか? - + To check the project using addons, you need a build directory. アドオンを使用してプロジェクトをチェックするためには、ビルドディレクトリが必要です。 - + Show Mandatory 必須を表示 - + Show Required 要求を表示 - + Show Advisory 推奨を表示 - + Show Document ドキュメントを表示 - + Show L1 L1を表示 - + Show L2 L2を表示 - + Show L3 L3を表示 - + Show style スタイルを表示 - + Show portability 移植可能性を表示 - + Show performance パフォーマンスを表示 - + Show information 情報を表示 @@ -1451,22 +1633,22 @@ Do you want to stop the analysis and exit Cppcheck? '%1'のインポートに失敗しました。(チェック中断) - + Project files (*.cppcheck) プロジェクトファイル (*.cppcheck) - + Select Project Filename プロジェクトファイル名を選択 - + No project file loaded プロジェクトファイルが読み込まれていません - + The project file %1 @@ -1528,26 +1710,31 @@ Options: NewSuppressionDialog + New suppression 新しい指摘の抑制 + Error ID エラーID + File name ファイル名 + Line number 行数 + Symbol name シンボル名 @@ -1589,28 +1776,33 @@ Options: ProjectFile + Project File プロジェクトファイル + Paths and Defines パスと定義 + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Import Project (Visual studio / compile database) プロジェクトのインポート(Visual studio / compile database Borland C++ Builder 6)) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Defines must be separated by a semicolon ';' 定義(Define)はセミコロン';'で区切る必要があります。 例: DEF1;DEF2=5;DEF3=int + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. カスタマイズした cfgファイルを同じフォルダにプロジェクトファイルとして保存してください。ここに表示できるようになります。 @@ -1620,48 +1812,59 @@ Options: + MISRA rule texts MISRA ルールテキスト + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> <html><head/><body><p>MISRA C 2012 pdfのAppendix A &quot;Summary of guidelines&quot; からテキストをコピーペーストしてください。</p></body></html> + ... ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> <html><head/><body><p>選択済み:</p><p> * 全Debug と Release設定をチェックする</p><p> * 最初にマッチした Debug 設定のみチェックする</p><p><br/></p></body></html> + + Browse... 参照... + Analyze all Visual Studio configurations Visual Studioの全ての設定をチェックする + Selected VS Configurations 選択したVS設定 + Paths: パス: + + Add... 追加... @@ -1669,6 +1872,9 @@ Options: + + + Edit 編集 @@ -1677,87 +1883,108 @@ Options: + + + + Remove 取り除く + Undefines: 定義取り消し(Undefines): + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 定義の取り消しはセミコロンで区切ります。例: UNDEF1;UNDEF2;UNDEF3 + Include Paths: インクルードパス: + Include file インクルードファイル + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">ヘッダファイルを強制的にインクルードします</span></p></body></html> + Browse.. ブラウズ.. + Types and Functions 型と関数 + + Analysis チェック + This is a workfolder that Cppcheck will use for various purposes. Cppcheckがさまざまな目的で使用するワークディレクトリ。 + Parser パーサー + Cppcheck (built in) Cppcheckビルトイン + Check level チェックレベル + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. #R 限定的 -- 開発者が直接的に結果を得るための解析を意味します。解析は限定的で高速ですがより少ない結果になります。 + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. #N 通常 -- CIでの通常の解析を意味します。解析が合理的な時間内に完了すべきです。 + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). #E 徹底的 -- ナイトリービルド等を意味します。解析時間はより長くなることがあります (コンパイルの10倍以上時間がかかってもよい)。 + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) ヘッダファイルのコードもチェック (通常はONにしてください、制限するときのみOFF) @@ -1767,194 +1994,234 @@ Options: + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. タグが追加された場合、警告上で右クリックしてそれらのタグの中の一つを設定できます。警告を分類できます。 + Exclude source files 除外するソースファイル + Exclude folder... フォルダで除外... + Exclude file... ファイルで除外... + Check that each class has a safe public interface クラスが安全で公開されたインターフェースをもっているか確認 + Limit analysis 解析の制限 + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) 未使用テンプレートのコードもチェック (解析に時間がかかり、また正確性は低い) + Max CTU depth CTUの最大深さ + Enable inline suppressions inline抑制を有効にする + Misra C MISRA C + 2012 2012 + + 2023 2023 + 2025 2025 + Misra C++ MISRA C++ + 2008 2008 + Cert C++ Cert C++ + Safety profiles (defined in C++ core guidelines) 安全性プロファイル(C++コアガイドラインで定義) + Bug hunting (Premium) バグハンティング(プレミアム) + External tools 外部ツール + Up 上 + Down 下 + Platform プラットフォーム + Clang (experimental) Clang (実験的) + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. 可能な限りクラスが柔軟であり堅牢であることを望む場合、公開されたインターフェースが非常に堅牢です。Cppcheckは引数があらゆる値をとりうると仮定します。 + Max recursion in template instantiation テンプレートインスタンス化の最大再帰回数 + Warning options 警告オプション + Root path: ルートパス: + Filepaths in warnings will be relative to this path 警告中のファイルパスはこのパスからの相対パスになります + Warning tags (separated by semicolon) 警告タグ(セミコロン区切り) + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) Cppcheck ビルドディレクトリ (全プログラムチェック, 差分チェック, 統計等) + Libraries ライブラリ + Suppressions 指摘の抑制 + Add 追加 + + Addons アドオン + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. 注意: アドオンには<a href="https://www.python.org/">Python</a>が必要です。 + Y2038 Y2038 + Thread safety スレッドセーフ + Coding standards コーディング標準 @@ -1964,11 +2231,13 @@ Options: + Cert C CERT C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) CERT-INT35-C: int型の精度 (もしサイズが精度と一致する場合空のままにしてください) @@ -1978,11 +2247,13 @@ Options: + Autosar AUTOSAR + Bug hunting バグハント @@ -1996,6 +2267,7 @@ Options: + Defines: 定義(Defines): @@ -2550,21 +2822,25 @@ Please check the application path and parameters are correct. ResultsView + Results 結果 + Critical errors 致命的なエラー + Analysis Log チェックログ + Warning Details 警告の詳細 @@ -2674,26 +2950,31 @@ To toggle what kind of errors are shown, open view menu. ScratchPad + Scratchpad スクラッチパッド + Copy or write some C/C++ code here: ここに C/C++のコードをコピーペーストまたは記入してください: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": オプション: ファイル名を入力(言語は自動判定)して"チェック"をクリックしてください: + filename ファイル名 + Check チェック @@ -2702,21 +2983,25 @@ To toggle what kind of errors are shown, open view menu. Settings + Preferences 設定 + General 全般 + Add... 追加... + Number of threads: 解析用のスレッド数: @@ -2726,57 +3011,68 @@ To toggle what kind of errors are shown, open view menu. + Force checking all #ifdef configurations Check all #ifdef configurations すべての #ifdef をチェックする + Show full path of files ファイルのフルパスを表示 + Show "No errors found" message when no errors found エラーが無いときは"エラーなし"を表示 + Display error Id in column "Id" エラーIDを "Id" に表示する + Enable inline suppressions inline抑制を有効にする + Check for inconclusive errors also 結論のでない指摘もチェックする + Show statistics on check completion チェック完了時に統計情報を表示する + Check for updates 更新の確認 + Show internal warnings in log ログの内部警告も表示する + Addons アドオン + Python binary (leave this empty to use python in the PATH) Pythonインタプリタの場所(空白の場合システムのPATHから検索) @@ -2784,117 +3080,143 @@ To toggle what kind of errors are shown, open view menu. + + + ... ... + MISRA addon MISRAアドオン + MISRA rule texts file MISRA ルールテキストファイル + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> <html><head/><body><p>Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdfのテキストをテキストファイルにコピー</p></body></html> + Clang Clang + Clang path (leave empty to use system PATH) Clangの場所(空白の場合システムのPATHから検索) + Visual Studio headers Visual Studioのヘッダ + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> <html><head/><body><p>Visual Studioのヘッダーファイル(セミコロン区切り';')。</p><p>Visual Studio コマンドプロンプトを開き、 &quot;SET INCLUDE&quot;. と入力後、そのパスをコピーペーストしてください。</p></body></html> + Code Editor コードエディタ + Code Editor Style コードエディタスタイル + System Style システムのデフォルトのスタイル + Default Light Style ライトスタイルをデフォルトに + Default Dark Style ダークスタイルをデフォルトに + Custom カスタム + Remove 削除 + Max count: #M 最大数: + Applications アプリケーション + + Edit... 編集... + Set as default デフォルトとして設定 + Reports レポート + Save all errors when creating report レポート作成時にすべての警告/エラーを保存 + Save full path to files in reports レポートにファイルのフルパスを保存 + Language 言語 @@ -2951,6 +3273,8 @@ To toggle what kind of errors are shown, open view menu. + + Statistics @@ -2958,113 +3282,135 @@ To toggle what kind of errors are shown, open view menu. + Project プロジェクト + Project: プロジェクト: + Paths: パス: + Include paths: インクルードパス: + Defines: 定義(define): + Undefines: 定義取り消し(undef): + Previous Scan 前回の解析 + Path Selected: ディレクトリ選択: + Number of Files Scanned: 解析済みファイル数: + Scan Duration: 解析にかかった時間: + Errors: エラー: + Warnings: 警告: + Stylistic warnings: スタイル警告: + Portability warnings: 移植可能性の警告: + Performance issues: パフォーマンス警告: + Information messages: 情報メッセージ: + Active checkers: 有効なチェッカー: + Checkers チェッカー + History ヒストリー + File: ファイル: + Copy to Clipboard クリップボードにコピー + Pdf Export PDF エクスポート @@ -3214,6 +3560,7 @@ To toggle what kind of errors are shown, open view menu. ThreadDetails + Thread Details スレッド詳細 diff --git a/gui/cppcheck_ka.ts b/gui/cppcheck_ka.ts index 7464052e694..97fe21d6f96 100644 --- a/gui/cppcheck_ka.ts +++ b/gui/cppcheck_ka.ts @@ -5,27 +5,32 @@ About + About Cppcheck Cppcheck-ის შესახებ + Version %1 ვერსია %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - ხელსაწყო სტატიკური C/C++ კოდის ანალიზისთვის. + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. Copyright © 2007-%1 Cppcheck-ის გუნდი. ყველა უფლება დაცულია. + This program is licensed under the terms of the GNU General Public License version 3 ვრცელდება GNU-ის საჯარო ლიცენზიის, @@ -33,11 +38,13 @@ of the GNU General Public License version 3 + Visit Cppcheck homepage at %1 ეწვიეთ Cppcheck-ის ვებგვერდს მისამართზე %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> <html><head/><body><p>დიდი მადლობა ამ ბიბლიოთეკებს, რომლებსაც ვიყენებთ::</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> @@ -47,11 +54,13 @@ of the GNU General Public License version 3 ApplicationDialog + Add an application აპლიკაციის დამატება + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -67,21 +76,25 @@ Parameters: -l(line) (file) + &Name: &სახელი: + &Executable: &გამშვები ფაილი: + &Parameters: &პარამეტრები: + Browse დათვალიერება @@ -179,16 +192,19 @@ Parameters: -l(line) (file) HelpDialog + Cppcheck GUI help Cppcheck-ის გრაფიკული ინტერფეისის დახმარება + Contents შემცველობა + Index ინდექსი @@ -206,16 +222,19 @@ Parameters: -l(line) (file) LibraryAddFunctionDialog + Add function ფუნქციის დამატება + Function name(s) ფუნქციის სახელ(ებ)-ი + Number of arguments არგუმენტების რაოდენობა @@ -224,86 +243,103 @@ Parameters: -l(line) (file) LibraryDialog + Library Editor ბიბლიოთეკის რედაქტორი + Open გახსნა + Save შენახვა + Save as შენახვა, როგორც + Functions ფუნქციები + Sort დალაგება + Add დამატება + Filter: ფილტრი: + Comments კომენტარები + noreturn noreturn + False მცდარი + True სიმართლე + Unknown უცნობი + return value must be used უნდა გამოიყენოთ დაბრუნებული მნიშვნელობა + ignore function in leaks checking ფუნქციების გამოტოვება გაჟონვები შემოწმებისას + Arguments არგუმენტები + Edit ჩასწორება @@ -348,11 +384,13 @@ Parameters: -l(line) (file) LibraryEditArgDialog + Edit argument არგუმენტის ჩასწორება + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -363,11 +401,13 @@ Parameters: -l(line) (file) + Not bool ლოგიკური მნ. არაა + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -378,78 +418,99 @@ Parameters: -l(line) (file) + Not null ნულოვანი არაა + Not uninit Uninit არაა + String სტრიქონი + Format string სტრიქონის ფორმატი + Min size of buffer ბუფერის მინ. ზომა + + Type ტიპი + + None არაფერი + + argvalue argvalue + + mul mul + + strlen strlen + + Arg არგ + + Arg2 Arg2 + and და + Valid values სწორი მნიშვნელობები @@ -462,511 +523,616 @@ Parameters: -l(line) (file) + A&nalyze ა&ნალიზი + Standard სტანდარტული + &File &ფაილი + &View &ხედი + &Toolbars &ხელსაწყოთა ზოლები + C++ standard C++-ის სტანდარტი + &C standard C standard &C-ის სტანდარტი + &Edit &ჩასწორება + &License... &ლიცენზია... + A&uthors... &ავტორები... + &About... &შესახებ... + &Files... ფაილ&ები... + + Analyze files Check files ფაილების ანალიზი + Ctrl+F Ctrl+F + &Directory... &საქაღალდე.... + + Analyze directory Check directory საქაღალდის ანალიზი + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop &გაჩერება + + Stop analysis Stop checking ანალიზის გაჩერება + Esc Esc + &Save results to file... შედეგები&ს შენახვა ფაილში.... + Ctrl+S Ctrl+S + &Quit გამოსვლა + &Clear results შედეგების &გასუფთავება + &Preferences &გამართვა - + + + Show errors შეცდომების ჩვენება - + + + Show warnings გაფრთხილების ჩვენება + + Show performance warnings წარმადობის გაფრთხილებების ჩვენება + Show &hidden დამალულის &ჩვენება - - + + Information ინფორმაცია + Show information messages ინფორმაციის შეტყობინებების ჩვენება + Show portability warnings გადატანადობის გაფრთხილებების ჩვენება + Show Cppcheck results Cppcheck-ის შედეგები ჩვენება + Clang Clang + Show Clang results Clang-ის შედეგები ჩვენება + &Filter &ფილტრი + Filter results შედეგების გაფილტვრა + Windows 32-bit ANSI Windows 32-bit ANSI + Windows 32-bit Unicode Windows 32-bit Unicode + Unix 32-bit Unix 32-bit + Unix 64-bit Unix 64-bit + Windows 64-bit Windows 64-bit + &Print... &ბეჭდვა… + Print the Current Report მიმდინარე ანგარიშის დაბეჭდვა + Print Pre&view... საბეჭდის &გადახედვა... + Open a Print Preview Dialog for the Current Results მიმდინარე შედეგების დაბეჭდვის მინიატურის დიალოგის ჩვენება + Open library editor ბიბლიოთეკის რედაქტორის გახსნა + &Check all &ყველას ჩართვა + Checking for updates განახლებების შემოწმება + Hide დამალვა + + Report + Filter ფილტრი + &Reanalyze modified files &Recheck modified files ყველა შეცვლილი ფაილის თავიდან ანალი&ზი + Reanal&yze all files &ყველა ფაილის თავიდან ანალიზი + Ctrl+Q Ctrl+Q + Style war&nings ს&ტილის გაფრთხილებები + E&rrors &შეცდომები + &Uncheck all ყველას ჩამოყ&რა + Collapse &all ყველას ჩაკეცვ&ა + &Expand all &ყველას ამოკეცვა + &Standard &სტანდარტული + Standard items სტანდარტული ელემენტები + Toolbar ხელსაწყოთა ზოლი + &Categories &კატეგორიები + Error categories შეცდომის კატეგორიები + &Open XML... &XML-ის გახსნა... + Open P&roject File... პ&პროექტის ფაილის გახსნა... + Ctrl+Shift+O Ctrl+Shift+O + Sh&ow Scratchpad... ბლ&ოკნოტის ჩვენება... + &New Project File... &ახალი პროექტის ფაილი... + Ctrl+Shift+N Ctrl+Shift+N + &Log View ჟურნა&ლის ხედი + Log View ჟურნალის ხედი + C&lose Project File პროექტის ფაი&ლის დახურვა + &Edit Project File... პროექტის ფაილის ჩასწორ&ება... + &Statistics &სტატისტიკა + &Warnings &გაფრთხილებები + Per&formance warnings წარმატების გა&ფრთხილებები + &Information &ინფორმაცია + &Portability &გადატანადობა + P&latforms პ&ლატფორმები + C++&11 C++&11 + C&99 C&99 + &Posix &Posix + C&11 C&11 + &C89 &C89 + &C++03 &C++03 + &Library Editor... ბიბ&ლიოთეკის რედაქტორი... + &Auto-detect language ენის &ავტოდადგენა + &Enforce C++ ძ&ალით C++ + E&nforce C ძა&ლით C + C++14 C++14 + Reanalyze and check library ბიბლიოთეკის თავიდან ანალიზი და შემოწმება + Check configuration (defines, includes) კონფიგურაციის შემოწმება (defines, includes) + C++17 C++17 + C++20 C++20 + Compliance report... შესაბამისობის ანგარიში... + Normal ნორმალური @@ -984,68 +1150,84 @@ Parameters: -l(line) (file) + Autosar + EULA... + Thread Details + Show thread details + &Contents &შემცველობა + Categories კატეგორიები + + Show style warnings სტილის გაფრთხილების ჩვენება + Open the help contents დახმარების შემცველობის გახსნა + F1 F1 + &Help &დახმარება - - + + Quick Filter: სწრაფი ფილტრი: - + + None of the selected files is part of the project, nothing to analyze. + + + + Select configuration აირჩიეთ კონფიგურაცია - + Found project file: %1 Do you want to load this project file instead? @@ -1054,61 +1236,61 @@ Do you want to load this project file instead? გნებავთ, სამაგიეროდ, ეს პროექტის ფაილი ჩატვირთოთ? - + File not found ფაილი ნაპოვნი არაა - + Bad XML არასწორი XML - + Missing attribute აკლია ატრიბუტი - + Bad attribute value არასწორი ატრიბუტის მნიშვნელობა - + Unsupported format მხარდაუჭერელი ფორმატი - + Duplicate define გამეორებული აღწერა - + Failed to load the selected library '%1'. %2 ჩავარდა ჩატვირთვა მონიშნული ბიბლიოთეკისთვის '%1'. %2 - + File not found: '%1' ფაილი ვერ ვიპოვე: '%1' - + Failed to load/setup addon %1: %2 დამატების (%1) ჩატვირთვა/მორგება ჩავარდა: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. @@ -1117,8 +1299,8 @@ Analysis is aborted. ანალიზი შეწყდა. - - + + %1 Analysis is aborted. @@ -1127,113 +1309,113 @@ Analysis is aborted. ანალიზი შეწყვეტილია. - + License ლიცენზია - + Authors ავტორები - + Save the report file ანგარიშის ფაილში ჩაწერა - - + + XML files (*.xml) XML ფაილები (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. - + You must close the project file before selecting new files or directories! ახალი ფაილების ან საქაღალდეების არჩევამდე პრორექტის ფაილი უნდა დახუროთ! - + The library '%1' contains unknown elements: %2 ბიბლიოთეკა '%1' უცნობ ელემენტებს შეიცავს: %2 - + Duplicate platform type გამეორებული პლატფორმის ტიპი - + Platform type redefined პლატფორმის ტიპი თავდან აღიწერა - + Unknown element უცნობი ელემენტი - - - - + + + + Error შეცდომა - + Open the report file ანგარიშის ფაილის გახსნა - + Text files (*.txt) ტექსტური ფაილები (*.txt) - + CSV files (*.csv) CSV ფაილები (*.csv) - + Project files (*.cppcheck);;All files(*.*) პროექტის ფაილები (*.cppcheck);;ყველა ფაილი(*.*) - + Select Project File აირჩიეთ პროექტის ფაილი - - - - + + + + Project: პროექტი: - + No suitable files found to analyze! ანალიზისათვის შესაფერისი ფაილები აღმოჩენილი არაა! - + C/C++ Source C/C++ საწყისი კოდი - + Compile database მონაცემთა ბაზის კომპილაცია @@ -1246,22 +1428,22 @@ This is probably because the settings were changed between the Cppcheck versions Borland C++ Builder 6 - + Select files to analyze აირჩეთ ფაილები ანალიზისთვის - + Select directory to analyze აირჩიეთ საქაღალდე ანალიზისთვის - + Select the configuration that will be analyzed აირჩიეთ კონფიგურაცია ანალიზისთვის - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1270,7 +1452,7 @@ Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1281,7 +1463,7 @@ Do you want to proceed? გნებავთ, გააგრძელოთ? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1290,12 +1472,12 @@ Do you want to stop the analysis and exit Cppcheck? გნებავთ, გააჩეროთ ანალიზი და გახვიდეთ Cppcheck-დან? - + About შესახებ - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML ფაილები (*.xml);;ტექსტური ფაილები (*.txt);;CSV ფაილები (*.csv) @@ -1304,32 +1486,32 @@ Do you want to stop the analysis and exit Cppcheck? შესაბამისობის ანგარიშის გენერაცია ახლა შეუძლებელია, რადგან ჯერ ანალიზი წარმატებით უნდა დასრულდეს. სცადეთ, კოდის ანალიზი თავიდან გაუშვათ და დარწმუნდეთ, რომ კრიტიკული შეცდომები არ არსებობს. - + Build dir '%1' does not exist, create it? აგების საქაღალდე (%1) არ არსებობს. შევქმნა? - + To check the project using addons, you need a build directory. პროექტის დამატებებით შესამოწმებლად აგების საქაღალდე გჭირდებათ. - + Failed to open file ფაილის გახსნის შეცდომა - + Unknown project file format უცნობი პროექტის ფაილის ფორმატი - + Failed to import project file პროექტის ფაილის შემოტანა ჩავარდა - + Failed to import '%1': %2 Analysis is stopped. @@ -1338,27 +1520,27 @@ Analysis is stopped. ანალიზი შეწყდა. - + Failed to import '%1' (%2), analysis is stopped '%1'-ის (%2) შემოტანა ჩავარდა. ანალიზი შეწყდა - + Project files (*.cppcheck) პროექტის ფაილები (*.cppcheck) - + Select Project Filename აირჩიეთ პროექტის ფაილის სახელი - + No project file loaded პროექტის ფაილი ჩატვირთული არაა - + The project file %1 @@ -1375,67 +1557,67 @@ Do you want to remove the file from the recently used projects -list? გნებავთ წაშალოთ ეს ფაილი ახლახან გამოყენებული პროექტების სიიდან? - + Install დაყენება - + New version available: %1. %2 ხელმისაწვდომია ახალი ვერსია: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1492,26 +1674,31 @@ Options: NewSuppressionDialog + New suppression ახალი ჩახშობა + Error ID შეცდომის ID + File name ფაილის სახელი + Line number ხაზის ნომერი + Symbol name სიმბოლოს სახელი @@ -1553,120 +1740,145 @@ Options: ProjectFile + Project File პროექტის ფაილი + Paths and Defines ბილიკები და აღწერები + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Import Project (Visual studio / compile database) პროექტის შემოტანა (Visual studio / მონაცემთა ბაზი კომპილაცია / Borland C++ Builder 6) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Defines must be separated by a semicolon ';' აღწერები წერტილმძიმით უნდა იყოს გამოყოფილი. მაგ: DEF1;DEF2=5;DEF3=int + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. შენიშვნა: ჩადეთ თქვენი .cfg ფაილები იგივე საქაღალდეში, სადაც პროექტის ფაილია. მათ ზემოთ დაინახავთ. + Clang (experimental) Clang (ექსპერიმენტული) + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) თავსართის ფაილებში არსებული კოდის შეწმება (ნაგულისხმევად, ეს ჩართულია. თუ გნებავთ შეზღუდული სწრაფი ანალიზი, მაშინ გამორთეთ ეს) + Max recursion in template instantiation + Filepaths in warnings will be relative to this path ფაილის ბილიკები ამ ბილიკის ფარდობითი იქნება + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. თუ ჭდეები დამატებულია, შეგიძლიათ, გაფრთხილებებზე მარჯვენა ღილაკით დააწკაპუნოთ და დააყენოთ ერთ-ერთი ჭდე. გაფრთხილებების კატეგორიებად დალაგება ხელით შეგიძლიათ. + Exclude source files კოდის ფაილების ამოღება + Exclude folder... საქაღალდის ამოღება... + Exclude file... ფაილის ამოღება... + MISRA rule texts MISRA-ის წესის ტექსტები + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + ... ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> + + Browse... ნუსხა... + Analyze all Visual Studio configurations ყველა Visual Studio-ის კონფიგურაციის ანალიზი + Selected VS Configurations არჩეული VS-ის კონფიგურაციები + Paths: ბილიკები: + + Add... დამატება... @@ -1674,6 +1886,9 @@ Options: + + + Edit ჩასწორება @@ -1682,255 +1897,311 @@ Options: + + + + Remove წაშლა + Undefines: წაშლილი მაკროაღწერები: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 წაშლილი მაკროაღწერები წერტილმძიმით უნდა იყოს გამოყოფილი. მაგ: UNDEF1;UNDEF2;UNDEF3 + Include Paths: ჩასმის ბილიკები: + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Types and Functions ტიპები და ფუნქციები + + Analysis ანალიზი + This is a workfolder that Cppcheck will use for various purposes. ეს სამუშაო საქაღალდეა, რომელსაც Cppcheck სხვადასხვა მიზნებისთვის გამოიყენებს. + Parser ანალიზატორი + Cppcheck (built in) Cppcheck (ჩაშენებული) + Check level შემოწმების დონე + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. ნორმალური -- ნიშნავს ნორმალურ ანალიზს CI-ში. ანალიზი მისაღებ დროში დასრულდება. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). ამომწურავი -- განკუთვნილია ღამის აგებებისთვის და ა.შ. ანალიზის დრო, შეიძლება, უფრო მეტიც იყოს (კომპილაციაზე 10x მეტი დრო ჩვეულებრივი ამბავია). + Check that each class has a safe public interface შემოწმება, აქვს თუ არა ყველა კლასს უსაფრთხო საჯარო ინტერფეისი + Limit analysis ანალიზის შეზღუდვა + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) + Max CTU depth CTU-ის მაქსიმალური სიღრმე + Enable inline suppressions შეცდომების ხაზშივე ჩახშობის ჩართვა + 2025 2025 + Misra C++ Misra C++ + 2008 2008 + Cert C Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) CERT-INT35-C: მთელი რიცხვის სიზუსტე (თუ ზომა სიზუსტეს ემთხვევა, შეგიძლიათ, ცარიელი დატოვოთ) + Autosar + Safety profiles (defined in C++ core guidelines) + Bug hunting შეცდომებზე ნადირობა + External tools გარე ხელსაწყოები + Up მაღლა + Down ქვემოთ + Platform პლატფორმა + Warning options გაფრთხილების მორგება + Root path: Root ბილიკი: + Warning tags (separated by semicolon) გაფრთხილების ჭდეები (წერტილმძიმით გამოყოფილი) + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) Cppcheck-ის აგების საქაღალდე (მთელი პროგრამის ანალიზი, ინკრემენტული ანალიზი, სტატისტიკა და ა.შ.) + Libraries ბიბლიოთეკები + Suppressions ჩახშობები + Add დამატება + + Addons დამატებები + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. შენიშვნა: დამატებას დაყენებული <a href="https://www.python.org/">Python</a> სჭირდება. + Y2038 Y2038 + Thread safety ნაკადების უსაფრთხოება + Coding standards კოდირების სტანდარტები + Misra C Misra C + 2012 2012 + + 2023 2023 + Cert C++ Cert C++ + Bug hunting (Premium) შეცდომებზე ნადირობა (ფასიანი) @@ -1944,6 +2215,7 @@ Options: + Defines: მაკროაღწრები: @@ -2590,21 +2862,25 @@ To toggle what kind of errors are shown, open view menu. + Results შედეგები + Critical errors კრიტიკული შეცდომები + Analysis Log ანალიზის ჟურნალი + Warning Details გაფრთხილების დეტალები @@ -2613,26 +2889,31 @@ To toggle what kind of errors are shown, open view menu. ScratchPad + Scratchpad მონახაზი + Copy or write some C/C++ code here: დააკოპირეთ ან დაწერეთ C/C++ კოდი აქ: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": შეიყვანეთ არასავალდებულო ფაილის სახელი (ძირითადად ავტომატური ენის დადგენისთვის) და დააწკაპუნეთ ღილაკზე "შემოწმება": + filename ფაილის სახელი + Check შემოწმება @@ -2641,21 +2922,25 @@ To toggle what kind of errors are shown, open view menu. Settings + Preferences მორგება + General ზოგადი + Add... დამატება... + Number of threads: ნაკადების რაოდენობა: @@ -2665,57 +2950,68 @@ To toggle what kind of errors are shown, open view menu. + Force checking all #ifdef configurations Check all #ifdef configurations ყველა #ifdef კონფიგურაციის ნაძალადევი შემოწმება + Show full path of files ფაილების სრული ბილიკის ჩვენება + Show "No errors found" message when no errors found "შეცდომები ნაპოვნი არაა" შეტყობინების ჩვენება, როცა შეცდომები აღმოჩენილი არა + Display error Id in column "Id" სვეტში "Id" შეცდომის Id-ის ჩვენება + Enable inline suppressions შეცდომების ხაზშივე ჩახშობის ჩართვა + Check for inconclusive errors also ასევე, ნაჩვენები იქნება საკამათო შეცდომებიც + Show statistics on check completion სტატისტიკის ჩვენება შემოწმების დასრულებისას + Check for updates განახლებების შემოწმება + Show internal warnings in log ჟურნალში შიდა გაფრთხილებების ჩვენება + Addons დამატებები + Python binary (leave this empty to use python in the PATH) ბილიკი python-ის ინტერპრეტატორამდე. (PATH-ში არსებული python-ის გამოსაყენებლად ცარიელი დატოვეთ) @@ -2723,117 +3019,143 @@ To toggle what kind of errors are shown, open view menu. + + + ... ... + MISRA addon MISRA-ის დამატება + MISRA rule texts file MISRA-ის წესის ტექსტების ფაილი + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Clang Clang + Clang path (leave empty to use system PATH) ბილიკი Clang-ის ინტერპრეტატორამდე. (PATH-ში არსებულის გამოსაყენებლად ცარიელი დატოვეთ) + Visual Studio headers Visual Studio-ის თავსართები + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> + Code Editor კოდის რედაქტორი + Code Editor Style კოდის რედაქტორის სტილი + System Style სისტემის მიყოლა + Default Light Style ნაგულისხმევი ღია სტილი + Default Dark Style ნაგულისხმევი მუქი სტილი + Custom მომხმარებლის + Remove წაშლა + Max count: + Applications აპლიკაციები + + Edit... რედაქტირება... + Set as default ნაგულისხმებად დაყენება + Reports ანგარიში + Save all errors when creating report ყველა შეცდომის შენახვა ანგარიშის შექმნისას + Save full path to files in reports ფაილების სრული ბილიკის ჩვენება ანგარიშებში + Language ენა @@ -2890,6 +3212,8 @@ To toggle what kind of errors are shown, open view menu. + + Statistics @@ -2897,113 +3221,135 @@ To toggle what kind of errors are shown, open view menu. + Project პროექტი + Project: პროექტი: + Paths: ბილიკები: + Include paths: თავსართის ფაილის ბილიკები: + Defines: მაკროაღწრები: + Undefines: წაშლილი მაკროაღწერები: + Previous Scan წინა სკანირება + Path Selected: არჩეული ბილიკი: + Number of Files Scanned: დასკანერებულია ფაილების რაოდენობა: + Scan Duration: სკანირების ხანგრძლივობა: + Errors: შეცდომები: + Warnings: გაფრთხილებები: + Stylistic warnings: სტილისტური გაფრთხილებები: + Portability warnings: გადატანადობის გაფრთხილებები: + Performance issues: წარმადობის პრობლემები: + Information messages: ინფორმაციის შეტყობინებები: + Active checkers: აქტიური შემმოწმებლები: + Checkers შაში + History ისტორია + File: ფაილი: + Copy to Clipboard ბუფერში კოპირება + Pdf Export PDF-ად გატანა @@ -3153,6 +3499,7 @@ To toggle what kind of errors are shown, open view menu. ThreadDetails + Thread Details diff --git a/gui/cppcheck_ko.ts b/gui/cppcheck_ko.ts index a7bae5f31f4..09f564e6380 100644 --- a/gui/cppcheck_ko.ts +++ b/gui/cppcheck_ko.ts @@ -5,21 +5,25 @@ About + About Cppcheck Cppcheck 정보 + Version %1 버전 %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - 정적 C/C++ 코드 분석 도구. + This program is licensed under the terms of the GNU General Public License version 3 이 프로그램은 GNU General Public License version 3을 @@ -27,17 +31,20 @@ of the GNU General Public License version 3 + Visit Cppcheck homepage at %1 Cppcheck 홈페이지(%1)를 방문해보세요 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. @@ -47,11 +54,13 @@ of the GNU General Public License version 3 ApplicationDialog + Add an application 응용 프로그램 추가 + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -77,21 +86,25 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: + &Name: 이름(&N): + &Executable: 실행 파일(&E): + &Parameters: 명령행 인자(&P): + Browse 찾기 @@ -136,16 +149,19 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: HelpDialog + Cppcheck GUI help + Contents + Index @@ -163,16 +179,19 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: LibraryAddFunctionDialog + Add function + Function name(s) + Number of arguments @@ -181,66 +200,79 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: LibraryDialog + Library Editor + Open + Save + Functions + Add + noreturn + False + True + Unknown + return value must be used + ignore function in leaks checking + Arguments + Edit 편집 @@ -257,21 +289,25 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: + Sort + Filter: + Comments + Save as @@ -304,11 +340,13 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: LibraryEditArgDialog + Edit argument + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -319,11 +357,13 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: + Not bool + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -334,78 +374,99 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: + Not null + Not uninit + String + Format string + Min size of buffer + + Type + + None + + argvalue + + mul + + strlen + + Arg + + Arg2 + and + Valid values @@ -418,355 +479,426 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: + Checking for updates + Hide 숨기기 + &File 파일(&F) + &View 보기(&V) + &Toolbars 도구바(&T) + + Report + &Help 도움말(&H) + &Edit 편집(&E) + Standard 표준 도구 + Categories 분류 도구 + Filter 필터 도구 + &License... 저작권(&L)... + A&uthors... 제작자(&u)... + &About... 정보(&A)... + &Files... 파일(&F)... + Ctrl+F Ctrl+F + &Directory... 디렉토리(&D)... + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop 중지(&S) + Esc Esc + &Save results to file... 결과를 파일에 저장(&S)... + Ctrl+S Ctrl+S + &Quit 종료(&Q) + &Clear results 결과 지우기(&C) + &Preferences 설정(&P) + + Show style warnings 스타일 경고 표시 - + + + Show errors 애러 표시 + &Check all 전체 선택(&C) + &Uncheck all 전체 해제(&U) + Collapse &all 전체 접기(&A) + &Expand all 전체 펼치기(&E) + &Standard 표준 도구(&S) + Standard items 표준 아이템 + &Contents 내용(&C) + Open the help contents 도움말을 엽니다 + F1 F1 + Toolbar 도구바 + &Categories 분류 도구(&C) + Error categories 에러 종류 + &Open XML... XML 열기(&O)... + Open P&roject File... 프로젝트 파일 열기(&R)... + &New Project File... 새 프로젝트 파일(&N)... + &Log View 로그 보기(&L) + Log View 로그 보기 + C&lose Project File 프로젝트 파일 닫기(&L) + &Edit Project File... 프로젝트 파일 편집(&E)... + &Statistics 통계 보기(&S) - + + + Show warnings 경고 표시 + + Show performance warnings 성능 경고 표시 + Show &hidden 숨기기 보기(&H) + Compliance report... + Normal + Autosar + EULA... + Thread Details + Show thread details - - + + Information 정보 + Show information messages 정보 표시 + Show portability warnings 이식성 경고 표시 + &Filter 필터 도구(&F) + Filter results 필터링 결과 + Windows 32-bit ANSI Windows 32-bit ANSI + Windows 32-bit Unicode Windows 32-bit Unicode + Unix 32-bit Unix 32-bit + Unix 64-bit Unix 64-bit + Windows 64-bit Windows 64-bit - - + + Quick Filter: 빠른 필터: - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -775,12 +907,17 @@ This is probably because the settings were changed between the Cppcheck versions Cppcheck 버전간 설정 방법 차이때문인 것으로 보입니다. 편집기 설정을 검사(및 수정)해주세요, 그렇지 않으면 편집기가 제대로 시작하지 않습니다. - + + None of the selected files is part of the project, nothing to analyze. + + + + You must close the project file before selecting new files or directories! 새로운 파일이나 디렉토리를 선택하기 전에 프로젝트 파일을 닫으세요! - + Found project file: %1 Do you want to load this project file instead? @@ -789,210 +926,210 @@ Do you want to load this project file instead? 이 프로젝트 파일을 불러오겠습니까? - - + + XML files (*.xml) XML 파일 (*.xml) - + Open the report file 보고서 파일 열기 - + License 저작권 - + Authors 제작자 - + Save the report file 보고서 파일 저장 - + Text files (*.txt) 텍스트 파일 (*.txt) - + CSV files (*.csv) CSV 파일 (*.csv) - + Project files (*.cppcheck);;All files(*.*) 프로젝트 파일 (*.cppcheck);;모든 파일(*.*) - + Select Project File 프로젝트 파일 선택 - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information - - - - + + + + Project: 프로젝트: - + Duplicate define - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + About - + To check the project using addons, you need a build directory. - + Select Project Filename 프로젝트 파일이름 선택 - + No project file loaded 프로젝트 파일 불러오기 실패 - + The project file %1 @@ -1015,96 +1152,102 @@ Do you want to remove the file from the recently used projects -list? + C++ standard - - - - + + + + Error - + File not found - + Bad XML - + Missing attribute - + Bad attribute value - + Failed to load the selected library '%1'. %2 - + Unsupported format - + The library '%1' contains unknown elements: %2 - + Duplicate platform type - + Platform type redefined + &Print... + Print the Current Report + Print Pre&view... + Open a Print Preview Dialog for the Current Results + Open library editor - + Unknown element - + Select configuration @@ -1127,67 +1270,74 @@ Options: - + Build dir '%1' does not exist, create it? + + Analyze files + + Analyze directory + &Reanalyze modified files + + Stop analysis - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + No suitable files found to analyze! - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1195,181 +1345,213 @@ Do you want to stop the analysis and exit Cppcheck? + A&nalyze + &C standard + Reanal&yze all files + Ctrl+Q + Style war&nings + E&rrors + Ctrl+Shift+O + Sh&ow Scratchpad... + Ctrl+Shift+N + &Warnings + Per&formance warnings + &Information + &Portability + Show Cppcheck results + Clang + Show Clang results + P&latforms + C++&11 + C&99 + &Posix + C&11 + &C89 + &C++03 + &Library Editor... + &Auto-detect language + &Enforce C++ + E&nforce C + C++14 C++14 - + Project files (*.cppcheck) + Reanalyze and check library + Check configuration (defines, includes) + C++17 C++17 + C++20 C++20 - + C/C++ Source - + Compile database - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1381,26 +1563,31 @@ Do you want to proceed? NewSuppressionDialog + New suppression + Error ID + File name + Line number + Symbol name @@ -1442,22 +1629,27 @@ Do you want to proceed? ProjectFile + Project File 프로젝트 파일 + Defines: Defines: + Paths: 경로: + + Add... 추가... @@ -1465,6 +1657,9 @@ Do you want to proceed? + + + Edit 편집 @@ -1473,356 +1668,433 @@ Do you want to proceed? + + + + Remove 제거 + Up 위로 + Down 아래로 + Suppressions + Add + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. + ... + Include Paths: + Paths and Defines + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> + Analyze all Visual Studio configurations + Root path: + Warning tags (separated by semicolon) + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) + Selected VS Configurations + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Types and Functions + Libraries + Parser + Cppcheck (built in) + Check that each class has a safe public interface + Limit analysis + + Addons + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 + Thread safety + Coding standards + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Bug hunting + + Browse... + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int + Platform + This is a workfolder that Cppcheck will use for various purposes. + Clang (experimental) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + Max recursion in template instantiation + Warning options + Filepaths in warnings will be relative to this path + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files + Exclude folder... + Exclude file... + Enable inline suppressions Inline suppression 사용 + Misra C + 2012 + + 2023 + 2025 + MISRA rule texts + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Misra C++ + 2008 + Cert C++ + Safety profiles (defined in C++ core guidelines) + Bug hunting (Premium) + External tools + Import Project (Visual studio / compile database/ Borland C++ Builder 6) + Undefines: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 + + Analysis + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) + Max CTU depth @@ -2339,6 +2611,7 @@ Please check the application path and parameters are correct. ResultsView + Results 결과 @@ -2427,16 +2700,19 @@ To toggle what kind of errors are shown, open view menu. + Critical errors + Analysis Log + Warning Details @@ -2460,26 +2736,31 @@ To toggle what kind of errors are shown, open view menu. ScratchPad + Scratchpad + filename + Check 검사 + Copy or write some C/C++ code here: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": @@ -2488,16 +2769,19 @@ To toggle what kind of errors are shown, open view menu. Settings + Preferences 설정 + General 일반 + Number of threads: 쓰레드 수: @@ -2507,107 +2791,129 @@ To toggle what kind of errors are shown, open view menu. + Force checking all #ifdef configurations 모든 #ifdef 설정을 강제로 검사 + Show full path of files 파일의 전체 경로 표시 + Show "No errors found" message when no errors found 에러가 발견되지 않는 경우 "에러가 없습니다." 메시지 표시 + Enable inline suppressions Inline suppression 사용 + Check for updates + Add... 추가... + Remove 제거 + Applications 응용 프로그램 + + Edit... 편집... + Set as default 기본으로 지정 + Reports 보고서 + Save all errors when creating report 보고서 생성 시 모든 에러 저장 + Save full path to files in reports 보고서에 파일의 전체 경로 저장 + Language 언어 + Display error Id in column "Id" + Check for inconclusive errors also + Show internal warnings in log + Show statistics on check completion + Max count: + Addons + Python binary (leave this empty to use python in the PATH) @@ -2615,71 +2921,87 @@ To toggle what kind of errors are shown, open view menu. + + + ... + Clang + Clang path (leave empty to use system PATH) + Visual Studio headers + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> + MISRA addon + MISRA rule texts file + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Code Editor + Code Editor Style + Default Light Style + Default Dark Style + Custom + System Style @@ -2736,6 +3058,8 @@ To toggle what kind of errors are shown, open view menu. + + Statistics @@ -2743,93 +3067,111 @@ To toggle what kind of errors are shown, open view menu. + Project 프로젝트 + Project: 프로젝트: + Paths: 경로: + Include paths: Include 경로: + Defines: Defines: + Previous Scan 직전 검사 + Path Selected: 선택된 경로: + Number of Files Scanned: 검사된 파일 수: + Scan Duration: 검사 시간: + Errors: 에러: + Warnings: 경고: + Stylistic warnings: 스타일 경고: + Portability warnings: 이식성 경고: + Performance issues: 성능 경고: + Information messages: 정보 메시지: + Active checkers: + Checkers + Copy to Clipboard 클립보드에 복사 @@ -2956,6 +3298,7 @@ To toggle what kind of errors are shown, open view menu. + Pdf Export @@ -2966,11 +3309,13 @@ To toggle what kind of errors are shown, open view menu. + History + File: @@ -2986,6 +3331,7 @@ To toggle what kind of errors are shown, open view menu. + Undefines: @@ -2999,6 +3345,7 @@ To toggle what kind of errors are shown, open view menu. ThreadDetails + Thread Details diff --git a/gui/cppcheck_nl.ts b/gui/cppcheck_nl.ts index 0c390ff245c..3bab077e6e3 100644 --- a/gui/cppcheck_nl.ts +++ b/gui/cppcheck_nl.ts @@ -5,27 +5,32 @@ About + About Cppcheck Over Cppcheck + Version %1 Versie %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - Een tool voor statische C/C++ code analyse. + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. Copyright © 2007-2021 het cppcheck team. + This program is licensed under the terms of the GNU General Public License version 3 Dit programma is beschikbaar onder te termen @@ -33,11 +38,13 @@ van de GNU General Public License versie 3 + Visit Cppcheck homepage at %1 Bezoek de Cppcheck homepage op %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> @@ -47,11 +54,13 @@ van de GNU General Public License versie 3 ApplicationDialog + Add an application Voeg een nieuwe applicatie toe + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -77,21 +86,25 @@ Parameters: -l(lijn) (bestand) + &Name: &Naam: + &Executable: &Uitvoerbaar: + &Parameters: + Browse Bladeren @@ -138,16 +151,19 @@ Parameters: -l(lijn) (bestand) HelpDialog + Cppcheck GUI help + Contents + Index @@ -165,16 +181,19 @@ Parameters: -l(lijn) (bestand) LibraryAddFunctionDialog + Add function + Function name(s) + Number of arguments @@ -183,86 +202,103 @@ Parameters: -l(lijn) (bestand) LibraryDialog + Library Editor + Open + Save Opslaan + Save as + Functions + Sort + Add + Filter: + Comments + noreturn + False + True + Unknown + return value must be used + ignore function in leaks checking + Arguments + Edit Bewerk @@ -308,11 +344,13 @@ Parameters: -l(lijn) (bestand) LibraryEditArgDialog + Edit argument + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -323,11 +361,13 @@ Parameters: -l(lijn) (bestand) + Not bool + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -338,78 +378,99 @@ Parameters: -l(lijn) (bestand) + Not null + Not uninit + String + Format string + Min size of buffer + + Type + + None + + argvalue + + mul + + strlen + + Arg + + Arg2 + and + Valid values @@ -422,578 +483,694 @@ Parameters: -l(lijn) (bestand) + A&nalyze + Standard Standaard + &File &Bestand + &View &Weergave + &Toolbars &Werkbalken + C++ standard C++standaard + &C standard C standard C standaard + &Edit Be&werken + &License... &Licentie... + A&uthors... A&uteurs... + &About... &Over... + &Files... &Bestanden... + + Analyze files Check files Controleer bestanden + Ctrl+F Ctrl+F + &Directory... &Mappen... + + Analyze directory Check directory Controleer Map + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop &Stop + + Stop analysis Stop checking Stop controle + Esc Esc + &Save results to file... &Resultaten opslaan... + Ctrl+S Ctrl+S + &Quit &Afsluiten + &Clear results &Resultaten wissen + &Preferences &Voorkeuren - + + + Show errors Toon fouten - + + + Show warnings Toon waarschuwingen + + Show performance warnings Toon presentatie waarschuwingen + Show &hidden Toon &verborgen - - + + Information Informatie + Show information messages Toon informatie bericht + Show portability warnings Toon portabiliteit waarschuwingen + Show Cppcheck results + Clang + Show Clang results + &Filter &Filter + Filter results Filter resultaten + Windows 32-bit ANSI Windows 32-bit ANSI + Windows 32-bit Unicode + Unix 32-bit + Unix 64-bit + Windows 64-bit + &Print... + Print the Current Report + Print Pre&view... + Open a Print Preview Dialog for the Current Results + Open library editor + &Check all &Controleer alles + Checking for updates + Hide Verberg + + Report + Filter + &Reanalyze modified files &Recheck modified files + Reanal&yze all files + Ctrl+Q + Style war&nings + E&rrors + &Uncheck all Selecteer &niets + Collapse &all Alles Inkl&appen + &Expand all Alles &Uitklappen + &Standard &Standaard + Standard items Standaard items + Toolbar Werkbalk + &Categories &Categorieën + Error categories Foute Categorieën + &Open XML... + Open P&roject File... Open P&oject bestand... + Ctrl+Shift+O + Sh&ow Scratchpad... + &New Project File... &Nieuw Project Bestand... + Ctrl+Shift+N + &Log View &Log weergave + Log View Log weergave + C&lose Project File &Sluit Project Bestand + &Edit Project File... &Bewerk Project Bestand... + &Statistics &Statistieken + &Warnings + Per&formance warnings + &Information + &Portability + P&latforms + C++&11 + C&99 + &Posix + C&11 + &C89 + &C++03 + &Library Editor... + &Auto-detect language + &Enforce C++ + E&nforce C + C++14 + Reanalyze and check library + Check configuration (defines, includes) + C++17 + C++20 + Compliance report... + Normal + Autosar + EULA... + Thread Details + Show thread details + &Contents &Inhoud + Categories Categorieën + + Show style warnings Toon stijl waarschuwingen + Open the help contents Open de help inhoud + F1 + &Help &Help - - + + Quick Filter: Snel Filter: - + Select configuration - + Found project file: %1 Do you want to load this project file instead? @@ -1001,91 +1178,91 @@ Do you want to load this project file instead? Wilt u dit project laden in plaats van? - + File not found - + Bad XML - + Missing attribute - + Bad attribute value - + Duplicate define - + Failed to load the selected library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Licentie - + Authors Auteurs - + Save the report file Rapport opslaan - - + + XML files (*.xml) XML bestanden (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -1094,116 +1271,121 @@ This is probably because the settings were changed between the Cppcheck versions Dit is waarschijnlijk omdat de instellingen zijn gewijzigd tussen de versies van cppcheck. Controleer (en maak) de bewerker instellingen, anders zal de bewerker niet correct starten. - + You must close the project file before selecting new files or directories! Je moet project bestanden sluiten voordat je nieuwe bestanden of mappen selekteerd! - + The library '%1' contains unknown elements: %2 - + Unsupported format - + Duplicate platform type - + Platform type redefined - + Unknown element - - - - + + + + Error - + Open the report file Open het rapport bestand - + Text files (*.txt) Tekst bestanden (*.txt) - + CSV files (*.csv) CSV bestanden (*.csv) - + Project files (*.cppcheck);;All files(*.*) Project bestanden (*.cppcheck);;Alle bestanden(*.*) - + Select Project File Selecteer project bestand - - - - + + + + Project: Project: - + + None of the selected files is part of the project, nothing to analyze. + + + + No suitable files found to analyze! - + C/C++ Source - + Compile database - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1211,76 +1393,76 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Build dir '%1' does not exist, create it? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Project files (*.cppcheck) - + Select Project Filename Selecteer project bestandsnaam - + No project file loaded Geen project bestand geladen - + The project file %1 @@ -1296,67 +1478,67 @@ Kan niet worden gevonden! Wilt u het bestand van de onlangs gebruikte project verwijderen -lijst? - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1400,26 +1582,31 @@ Options: NewSuppressionDialog + New suppression + Error ID + File name + Line number + Symbol name @@ -1441,111 +1628,135 @@ Options: ProjectFile + Project File Project Bestand + Paths and Defines + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Import Project (Visual studio / compile database) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Defines must be separated by a semicolon ';' + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files + Exclude folder... + Exclude file... + Misra C + 2012 + + 2023 + MISRA rule texts + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> + + Browse... + Analyze all Visual Studio configurations + Selected VS Configurations + Paths: Paden: + + Add... Toevoegen... @@ -1553,6 +1764,9 @@ Options: + + + Edit Bewerk @@ -1561,269 +1775,327 @@ Options: + + + + Remove Verwijder + Undefines: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 + Include Paths: + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Types and Functions + + Analysis + This is a workfolder that Cppcheck will use for various purposes. + Parser + Cppcheck (built in) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + Check that each class has a safe public interface + Limit analysis + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) + Max CTU depth + Enable inline suppressions Schakel inline suppressies in + 2025 + Misra C++ + 2008 + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Safety profiles (defined in C++ core guidelines) + Bug hunting + External tools + Up Omhoog + Down Omlaag + Platform + Clang (experimental) + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + Max recursion in template instantiation + Warning options + Root path: + Filepaths in warnings will be relative to this path + Warning tags (separated by semicolon) + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) + Libraries + Suppressions + Add + + Addons + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 + Thread safety + Coding standards + Cert C++ + Bug hunting (Premium) + Defines: Omschrijft: @@ -2445,21 +2717,25 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden. + Results Resultaten + Critical errors + Analysis Log + Warning Details @@ -2468,26 +2744,31 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden.ScratchPad + Scratchpad Scratchpad + Copy or write some C/C++ code here: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": + filename bestandsnaam + Check Controleer @@ -2496,21 +2777,25 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden.Settings + Preferences Instellingen + General Algemeen + Add... Toevoegen... + Number of threads: Aantal threads: @@ -2520,57 +2805,68 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden. + Force checking all #ifdef configurations Check all #ifdef configurations Controleer alle #ifdef combinaties + Show full path of files Toon het volledige pad van bestanden + Show "No errors found" message when no errors found Toon "Geen fouten gevonden" indien geen fouten gevonden werden + Display error Id in column "Id" Toon fout ld in kolom "Id" + Enable inline suppressions Schakel inline suppressies in + Check for inconclusive errors also + Show statistics on check completion + Check for updates + Show internal warnings in log + Addons + Python binary (leave this empty to use python in the PATH) @@ -2578,117 +2874,143 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden. + + + ... + MISRA addon + MISRA rule texts file + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Clang + Clang path (leave empty to use system PATH) + Visual Studio headers + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> + Code Editor + Code Editor Style + System Style + Default Light Style + Default Dark Style + Custom + Remove Verwijder + Max count: + Applications Applicaties + + Edit... Bewerk... + Set as default Instellen als standaard + Reports Rapporten + Save all errors when creating report Alle fouten opslaan + Save full path to files in reports Volledig pad opslaan + Language Taal @@ -2741,6 +3063,8 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden. + + Statistics @@ -2748,113 +3072,135 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden. + Project Project + Project: Project: + Paths: Paden: + Include paths: Bevat paden: + Defines: Omschrijft: + Undefines: + Previous Scan Vorige scan + Path Selected: Pad Geselekteerd: + Number of Files Scanned: Aantal bestanden gescanned: + Scan Duration: Scan tijd: + Errors: Fouten: + Warnings: Waarschuwingen: + Stylistic warnings: Stilistisch waarschuwingen: + Portability warnings: Portabiliteit waarschuwingen: + Performance issues: Presentatie problemen: + Information messages: Informatie bericht: + Active checkers: + Checkers + History + File: + Copy to Clipboard Kopieer naar Clipbord + Pdf Export @@ -3004,6 +3350,7 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden.ThreadDetails + Thread Details diff --git a/gui/cppcheck_ru.ts b/gui/cppcheck_ru.ts index 2eec05aa1b6..d9a1a27c0a2 100644 --- a/gui/cppcheck_ru.ts +++ b/gui/cppcheck_ru.ts @@ -5,27 +5,32 @@ About + About Cppcheck О Cppcheck + Version %1 Версия %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - программа для статического анализа кода на языках С/С++. + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. Copyright © 2007-2021 Cppcheck team. + This program is licensed under the terms of the GNU General Public License version 3 Эта программа распространяется на @@ -33,11 +38,13 @@ of the GNU General Public License version 3 + Visit Cppcheck homepage at %1 Посетите домашнюю страницу: %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> @@ -47,11 +54,13 @@ of the GNU General Public License version 3 ApplicationDialog + Add an application Добавление приложения + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -77,21 +86,25 @@ Parameters: -l(line) (file) + &Name: &Название: + &Executable: &Программа: + &Parameters: &Параметры: + Browse Просмотреть @@ -138,16 +151,19 @@ Parameters: -l(line) (file) HelpDialog + Cppcheck GUI help + Contents + Index @@ -165,16 +181,19 @@ Parameters: -l(line) (file) LibraryAddFunctionDialog + Add function Добавить функцию + Function name(s) Имя(имена) функции + Number of arguments Количество аргументов @@ -183,86 +202,103 @@ Parameters: -l(line) (file) LibraryDialog + Library Editor Редактор библиотек + Open Открыть + Save Сохранить + Save as Сохранить как + Functions Функции + Sort Сортировать + Add Добавить + Filter: Фильтр: + Comments Комментарии + noreturn + False + True + Unknown + return value must be used должно быть использовано возвращаемое значение + ignore function in leaks checking пропускать функцию при проверке на утечки + Arguments Аргументы + Edit Изменить @@ -308,11 +344,13 @@ Parameters: -l(line) (file) LibraryEditArgDialog + Edit argument Редактировать аргумент + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -323,11 +361,13 @@ Parameters: -l(line) (file) + Not bool + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -338,78 +378,99 @@ Parameters: -l(line) (file) + Not null + Not uninit + String + Format string + Min size of buffer + + Type + + None + + argvalue + + mul + + strlen + + Arg + + Arg2 + and + Valid values @@ -422,578 +483,699 @@ Parameters: -l(line) (file) + A&nalyze Анализ + Standard Стандартные + &File &Файл + &View &Вид + &Toolbars &Панель инструментов + C++ standard Стандарт C++ + &C standard C standard &Стандарт C + &Edit &Правка + &License... &Лицензия... + A&uthors... &Авторы... + &About... &О программе... + &Files... &Файлы... + + Analyze files Check files Проверить файлы + Ctrl+F Ctrl+F + &Directory... &Каталог... + + Analyze directory Check directory Проверка каталога + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop Остановить + + Stop analysis Stop checking Остановить проверку + Esc Esc + &Save results to file... Сохранить отчёт в файл... + Ctrl+S Ctrl+S + &Quit Выход + &Clear results Очистить отчёт + &Preferences Параметры - + + + Show errors Показать ошибки - + + + Show warnings Показать предупреждения + + Show performance warnings Показать предупреждения производительности + Show &hidden Показать скрытые - - + + Information Информационные сообщения + Show information messages Показать информационные сообщения + Show portability warnings Показать предупреждения переносимости + Show Cppcheck results Просмотр результатов Cppcheck + Clang Clang + Show Clang results Просмотр результатов Clang + &Filter Фильтр + Filter results Результаты фильтрации + Windows 32-bit ANSI Windows 32-bit ANSI + Windows 32-bit Unicode Windows 32-bit Unicode + Unix 32-bit Unix 32-bit + Unix 64-bit Unix 64-bit + Windows 64-bit Windows 64-bit + &Print... Печать... + Print the Current Report Напечатать текущий отчет + Print Pre&view... Предварительный просмотр... + Open a Print Preview Dialog for the Current Results Открыть диалог печати для текущих результатов + Open library editor Открыть редактор библиотек + &Check all Отметить все + Checking for updates + Hide Скрыть + + Report + Filter Фильтр + &Reanalyze modified files &Recheck modified files Заново проверить измененные файлы + Reanal&yze all files Заново проверить все файлы + Ctrl+Q + Style war&nings Стилистические предупреждения + E&rrors Ошибки + &Uncheck all Сбросить все + Collapse &all Свернуть все + &Expand all Развернуть все + &Standard Стандартные + Standard items Стандартные элементы + Toolbar Панель инструментов + &Categories Категории + Error categories Категории ошибок + &Open XML... &Открыть XML... + Open P&roject File... Открыть файл &проекта... + Ctrl+Shift+O + Sh&ow Scratchpad... Показать Блокнот + &New Project File... &Новый файл проекта... + Ctrl+Shift+N + &Log View Посмотреть &лог + Log View Посмотреть лог + C&lose Project File &Закрыть файл проекта + &Edit Project File... &Изменить файл проекта... + &Statistics &Статистика + &Warnings Предупреждения + Per&formance warnings Предупреждения производительности + &Information Информационные предупреждения + &Portability Предупреждения переносимости + P&latforms Платформы + C++&11 + C&99 + &Posix + C&11 + &C89 + &C++03 + &Library Editor... Редактор библиотеки + &Auto-detect language Автоматическое определение языка + &Enforce C++ Принудительно C++ + E&nforce C Принудительно C + C++14 C++14 + Reanalyze and check library Повторный анализ библиотеки + Check configuration (defines, includes) Проверить конфигурацию (defines, includes) + C++17 C++17 + C++20 C++20 + Compliance report... + Normal + Autosar + EULA... + Thread Details + Show thread details + &Contents Помощь + Categories Категории + + Show style warnings Показать стилистические предупреждения + Open the help contents Открыть помощь + F1 F1 + &Help Помощь - - + + Quick Filter: Быстрый фильтр: - + + None of the selected files is part of the project, nothing to analyze. + + + + Select configuration Выбор конфигурации - + Found project file: %1 Do you want to load this project file instead? @@ -1002,97 +1184,97 @@ Do you want to load this project file instead? Вы хотите загрузить этот проект? - + File not found Файл не найден - + Bad XML Некорректный XML - + Missing attribute Пропущен атрибут - + Bad attribute value Некорректное значение атрибута - + Unsupported format Неподдерживаемый формат - + Duplicate define - + Failed to load the selected library '%1'. %2 Не удалось загрузить выбранную библиотеку '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Лицензия - + Authors Авторы - + Save the report file Сохранить файл с отчетом - - + + XML files (*.xml) XML-файлы (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -1101,37 +1283,37 @@ This is probably because the settings were changed between the Cppcheck versions Возможно, это связано с изменениями в версии программы. Пожалуйста, проверьте (и исправьте) настройки приложения. - + You must close the project file before selecting new files or directories! Вы должны закрыть проект перед выбором новых файлов или каталогов! - + The library '%1' contains unknown elements: %2 Библиотека '%1' содержит неизвестные элементы: %2 - + Duplicate platform type Дубликат типа платформы - + Platform type redefined Переобъявление типа платформы - + Unknown element Неизвестный элемент - - - - + + + + Error Ошибка @@ -1140,50 +1322,50 @@ This is probably because the settings were changed between the Cppcheck versions Невозможно загрузить %1. Cppcheck установлен некорректно. Вы можете использовать --data-dir=<directory> в командной строке для указания расположения файлов конфигурации. Обратите внимание, что --data-dir предназначен для использования сценариями установки. При включении данной опции, графический интерфейс пользователя не запускается. - + Open the report file Открыть файл с отчетом - + Text files (*.txt) Текстовые файлы (*.txt) - + CSV files (*.csv) CSV файлы(*.csv) - + Project files (*.cppcheck);;All files(*.*) Файлы проекта (*.cppcheck);;Все файлы(*.*) - + Select Project File Выберите файл проекта - - - - + + + + Project: Проект: - + No suitable files found to analyze! Не найдено подходящих файлов для анализа - + C/C++ Source Исходный код C/C++ - + Compile database @@ -1196,22 +1378,22 @@ This is probably because the settings were changed between the Cppcheck versions Borland C++ Builder 6 - + Select files to analyze Выбор файлов для анализа - + Select directory to analyze Выбор каталога для анализа - + Select the configuration that will be analyzed Выбор используемой конфигурации - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1220,7 +1402,7 @@ Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1231,7 +1413,7 @@ Do you want to proceed? Вы хотите продолжить? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1240,104 +1422,104 @@ Do you want to stop the analysis and exit Cppcheck? Вы хотите остановить анализ и выйти из Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML файлы (*.xml);;Текстовые файлы (*.txt);;CSV файлы (*.csv) - + Build dir '%1' does not exist, create it? Директория для сборки '%1' не существует, создать? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1346,22 +1528,22 @@ Analysis is stopped. Невозможно импортировать '%1', анализ остановлен - + Project files (*.cppcheck) Файлы проекта (*.cppcheck) - + Select Project Filename Выберите имя файла для проекта - + No project file loaded Файл с проектом не загружен - + The project file %1 @@ -1377,12 +1559,12 @@ Do you want to remove the file from the recently used projects -list? Хотите удалить его из списка проектов? - + Install - + New version available: %1. %2 @@ -1439,26 +1621,31 @@ Options: NewSuppressionDialog + New suppression Новое подавление + Error ID ID + File name Имя файла + Line number Номер строки + Symbol name Имя символа @@ -1500,73 +1687,87 @@ Options: ProjectFile + Project File Файл проекта + Paths and Defines Каталоги и определения + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Import Project (Visual studio / compile database) Импорт проекта (Visual studio / compile database/ Borland C++ Builder 6) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Defines must be separated by a semicolon ';' Defines должны быть разделены точкой с запятой ';' + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. Положите свои .cfg-файлы в один каталог с файлом проекта. Вы увидите их сверху. + Clang (experimental) + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + Max recursion in template instantiation + Filepaths in warnings will be relative to this path + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files + Exclude folder... + Exclude file... @@ -1576,48 +1777,59 @@ Options: + MISRA rule texts Файл с текстами правил MISRA + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> <html><head/><body><p>Скопируйте текст из Appendix A &quot;Summary of guidelines&quot; из фала правил MISRA C 2012 pdf в текстовый файл.</p></body></html> + ... ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> <html><head/><body><p>Выберите:</p><p> * Анализ всех конфигураций Debug и Release</p><p> * Анализ только первой подходящей конфигурации Debug</p><p><br/></p></body></html> + + Browse... Обзор... + Analyze all Visual Studio configurations Анализировать все конфигурации Visual Studio + Selected VS Configurations + Paths: Пути: + + Add... Добавить... @@ -1625,6 +1837,9 @@ Options: + + + Edit Изменить @@ -1633,260 +1848,317 @@ Options: + + + + Remove Удалить + Undefines: Удаленные макроопределения: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 Удаленные макроопределения должны быть разделены точкой с запятой, например: UNDEF1;UNDEF2;UNDEF3 + Include Paths: Пути заголовочных файлов: + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Types and Functions + + Analysis Анализ + This is a workfolder that Cppcheck will use for various purposes. + Parser + Cppcheck (built in) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + Check that each class has a safe public interface + Limit analysis + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) Проверить код в неиспользуемых шаблонах + Max CTU depth Максимальная глубина CTU + Enable inline suppressions Включить inline-подавление ошибок + 2025 + Misra C++ + 2008 + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Safety profiles (defined in C++ core guidelines) + Bug hunting + External tools Внешние инструменты + Up Вверх + Down Вниз + Platform Платформа + Warning options Опции предупреждений + Root path: Корневой каталог: + Warning tags (separated by semicolon) Теги предупреждений (через ';') + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) Каталог сборки Cppcheck + Libraries Библиотеки + Suppressions Подавления + Add Добавить + + Addons Дополнения + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 + Thread safety + Coding standards Стандарты кодирования + Misra C + 2012 + + 2023 + Cert C++ + Bug hunting (Premium) + Defines: Объявленные макроопределения: @@ -2526,21 +2798,25 @@ To toggle what kind of errors are shown, open view menu. + Results Результаты + Critical errors + Analysis Log Лог анализа + Warning Details Детали предупреждения @@ -2549,26 +2825,31 @@ To toggle what kind of errors are shown, open view menu. ScratchPad + Scratchpad Блокнот + Copy or write some C/C++ code here: Исходный код C/C++: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": При необходимости введите имя файла и нажмите "Проверить": + filename имя файла + Check Проверить @@ -2577,21 +2858,25 @@ To toggle what kind of errors are shown, open view menu. Settings + Preferences Параметры + General Общие + Add... Добавить... + Number of threads: Количество потоков исполнения: @@ -2601,57 +2886,68 @@ To toggle what kind of errors are shown, open view menu. + Force checking all #ifdef configurations Check all #ifdef configurations Проверять все варианты #ifdef конфигураций + Show full path of files Показывать полные пути к файлам + Show "No errors found" message when no errors found Показывать сообщение, если ошибок не найдено + Display error Id in column "Id" Отображать номер ошибки в колонке "id" + Enable inline suppressions Включить inline-подавление ошибок + Check for inconclusive errors also Показывать также спорные ошибки + Show statistics on check completion Показывать статистику после завершения проверки + Check for updates + Show internal warnings in log Показывать внутренние предупреждения в логе + Addons Дополнения + Python binary (leave this empty to use python in the PATH) Python (оставьте пустым для использования python из PATH) @@ -2659,117 +2955,143 @@ To toggle what kind of errors are shown, open view menu. + + + ... ... + MISRA addon Дополнение MISRA + MISRA rule texts file Файл с текстами правил MISRA: + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> <html><head/><body><p>Скопируйте текст из Appendix A &quot;Summary of guidelines&quot; из фала правил MISRA C 2012 pdf в текстовый файл.</p></body></html> + Clang Clang + Clang path (leave empty to use system PATH) Clang (оставьте пустым для использования clang из PATH) + Visual Studio headers Заголовочные файлы Visual Studio + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> <html><head/><body><p>Путь до заголовочных файлов Visual Studio headers, разделенных символом ';'.</p><p>Вы можете открыть командную строку Visual Studio, ввести &quot;SET INCLUDE&quot; и скопировать пути.</p></body></html> + Code Editor Редактор + Code Editor Style Оформление + System Style + Default Light Style + Default Dark Style + Custom + Remove Удалить + Max count: + Applications Приложения + + Edit... Изменить... + Set as default Установить по умолчанию + Reports Отчёты + Save all errors when creating report Сохранять все ошибки при создании отчёта + Save full path to files in reports Сохранять полные пути к файлам в отчётах + Language Язык @@ -2826,6 +3148,8 @@ To toggle what kind of errors are shown, open view menu. + + Statistics @@ -2833,113 +3157,135 @@ To toggle what kind of errors are shown, open view menu. + Project Проект + Project: Проект: + Paths: Пути: + Include paths: Включенные пути: + Defines: Объявленные макроопределения: + Undefines: Удаленные макроопределения: + Previous Scan Последнее сканирование + Path Selected: Выбранный путь: + Number of Files Scanned: Количество просканированных файлов: + Scan Duration: Продолжительность сканирования: + Errors: Ошибки: + Warnings: Предупреждения: + Stylistic warnings: Стилистические предупреждения: + Portability warnings: Предупреждения переносимости: + Performance issues: Проблемы с производительностью: + Information messages: Информационные сообщения: + Active checkers: + Checkers + History История + File: Файл: + Copy to Clipboard Скопировать в буфер обмена + Pdf Export Экспорт PDF @@ -3089,6 +3435,7 @@ To toggle what kind of errors are shown, open view menu. ThreadDetails + Thread Details diff --git a/gui/cppcheck_sr.ts b/gui/cppcheck_sr.ts index 9579d88b695..81da0d77edf 100644 --- a/gui/cppcheck_sr.ts +++ b/gui/cppcheck_sr.ts @@ -5,27 +5,32 @@ About + About Cppcheck About Cppcheck + Version %1 Version %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - A tool for static C/C++ code analysis. + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. + This program is licensed under the terms of the GNU General Public License version 3 This program is licensed under the terms @@ -33,11 +38,13 @@ of the GNU General Public License version 3 + Visit Cppcheck homepage at %1 Visit Cppcheck homepage at %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> @@ -47,11 +54,13 @@ of the GNU General Public License version 3 ApplicationDialog + Add an application Add a new application + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -67,21 +76,25 @@ Parameters: -l(line) (file) + &Name: + &Executable: + &Parameters: + Browse Browse @@ -126,16 +139,19 @@ Parameters: -l(line) (file) HelpDialog + Cppcheck GUI help + Contents + Index @@ -153,16 +169,19 @@ Parameters: -l(line) (file) LibraryAddFunctionDialog + Add function + Function name(s) + Number of arguments @@ -171,86 +190,103 @@ Parameters: -l(line) (file) LibraryDialog + Library Editor + Open + Save + Save as + Functions + Sort + Add + Filter: + Comments + noreturn + False + True + Unknown + return value must be used + ignore function in leaks checking + Arguments + Edit @@ -296,11 +332,13 @@ Parameters: -l(line) (file) LibraryEditArgDialog + Edit argument + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -311,11 +349,13 @@ Parameters: -l(line) (file) + Not bool + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -326,78 +366,99 @@ Parameters: -l(line) (file) + Not null + Not uninit + String + Format string + Min size of buffer + + Type + + None + + argvalue + + mul + + strlen + + Arg + + Arg2 + and + Valid values @@ -410,785 +471,906 @@ Parameters: -l(line) (file) + A&nalyze + Standard Standard + &File &File + &View &View + &Toolbars + C++ standard + &C standard C standard + &Edit &Edit + &License... &License... + A&uthors... A&uthors... + &About... &About... + &Files... &Files... + + Analyze files Check files + Ctrl+F Ctrl+F + &Directory... &Directory... + + Analyze directory Check directory + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop &Stop + + Stop analysis Stop checking + Esc Esc + &Save results to file... &Save results to file... + Ctrl+S Ctrl+S + &Quit &Quit + &Clear results &Clear results + &Preferences &Preferences - + + + Show errors - + + + Show warnings + + Show performance warnings + Show &hidden - - + + Information + Show information messages + Show portability warnings + Show Cppcheck results + Clang + Show Clang results + &Filter + Filter results + Windows 32-bit ANSI Windows 32-bit ANSI + Windows 32-bit Unicode Windows 32-bit Unicode + Unix 32-bit Unix 32-bit + Unix 64-bit Unix 64-bit + Windows 64-bit Windows 64-bit + &Print... + Print the Current Report + Print Pre&view... + Open a Print Preview Dialog for the Current Results + Open library editor + &Check all &Check all + Checking for updates + Hide + + Report + Filter + &Reanalyze modified files &Recheck modified files + Reanal&yze all files + Ctrl+Q + Style war&nings + E&rrors + &Uncheck all &Uncheck all + Collapse &all Collapse &all + &Expand all &Expand all + &Standard + Standard items + Toolbar + &Categories + Error categories + &Open XML... + Open P&roject File... + Ctrl+Shift+O + Sh&ow Scratchpad... + &New Project File... + Ctrl+Shift+N + &Log View + Log View + C&lose Project File + &Edit Project File... + &Statistics + &Warnings + Per&formance warnings + &Information + &Portability + P&latforms + C++&11 + C&99 + &Posix + C&11 + &C89 + &C++03 + &Library Editor... + &Auto-detect language + &Enforce C++ + E&nforce C + C++14 C++14 + Reanalyze and check library + Check configuration (defines, includes) + C++17 C++17 + C++20 C++20 + Compliance report... + Normal + Autosar + EULA... + Thread Details + Show thread details + &Contents + Categories + + Show style warnings + Open the help contents + F1 F1 + &Help &Help - - + + Quick Filter: - + Select configuration - + Found project file: %1 Do you want to load this project file instead? - + File not found - + Bad XML - + Missing attribute - + Bad attribute value - + Duplicate define - + Failed to load the selected library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License License - + Authors Authors - + Save the report file Save the report file - - + + XML files (*.xml) XML files (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. - + You must close the project file before selecting new files or directories! - + The library '%1' contains unknown elements: %2 - + Unsupported format - + Duplicate platform type - + Platform type redefined - + Unknown element - - - - + + + + Error - + Open the report file - + Text files (*.txt) Text files (*.txt) - + CSV files (*.csv) - + Project files (*.cppcheck);;All files(*.*) - + Select Project File - - - - + + + + Project: - + + None of the selected files is part of the project, nothing to analyze. + + + + No suitable files found to analyze! - + C/C++ Source - + Compile database - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1196,76 +1378,76 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Build dir '%1' does not exist, create it? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Project files (*.cppcheck) - + Select Project Filename - + No project file loaded - + The project file %1 @@ -1276,67 +1458,67 @@ Do you want to remove the file from the recently used projects -list? - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1380,26 +1562,31 @@ Options: NewSuppressionDialog + New suppression + Error ID + File name + Line number + Symbol name @@ -1441,75 +1628,91 @@ Options: ProjectFile + Project File + Paths and Defines + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Import Project (Visual studio / compile database) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Defines must be separated by a semicolon ';' + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. + MISRA rule texts + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> + + Browse... + Analyze all Visual Studio configurations + Selected VS Configurations + Paths: + + Add... @@ -1517,6 +1720,9 @@ Options: + + + Edit @@ -1525,305 +1731,371 @@ Options: + + + + Remove + Undefines: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 + Include Paths: + Up + Down + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Platform + + Analysis + This is a workfolder that Cppcheck will use for various purposes. + Clang (experimental) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) + Max CTU depth + Max recursion in template instantiation + Warning options + Root path: + Filepaths in warnings will be relative to this path + Warning tags (separated by semicolon) + Enable inline suppressions + 2025 + Misra C++ + 2008 + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Safety profiles (defined in C++ core guidelines) + Bug hunting + External tools + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) + Types and Functions + Libraries + Parser + Cppcheck (built in) + Check that each class has a safe public interface + Limit analysis + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files + Exclude folder... + Exclude file... + Suppressions + Add + + Addons + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 + Thread safety + Coding standards + Misra C + 2012 + + 2023 + Cert C++ + Bug hunting (Premium) + Defines: @@ -2427,21 +2699,25 @@ To toggle what kind of errors are shown, open view menu. + Results Results + Critical errors + Analysis Log + Warning Details @@ -2450,26 +2726,31 @@ To toggle what kind of errors are shown, open view menu. ScratchPad + Scratchpad + Copy or write some C/C++ code here: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": + filename + Check @@ -2478,76 +2759,91 @@ To toggle what kind of errors are shown, open view menu. Settings + Preferences Preferences + General General + Add... + Number of threads: Number of threads: + Force checking all #ifdef configurations Check all #ifdef configurations + Show full path of files Show full path of files + Show "No errors found" message when no errors found Show "No errors found" message when no errors found + Display error Id in column "Id" + Enable inline suppressions + Check for inconclusive errors also + Show statistics on check completion + Check for updates + Show internal warnings in log + Addons + Python binary (leave this empty to use python in the PATH) @@ -2555,117 +2851,143 @@ To toggle what kind of errors are shown, open view menu. + + + ... + MISRA addon + MISRA rule texts file + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Clang + Clang path (leave empty to use system PATH) + Visual Studio headers + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> + Code Editor + Code Editor Style + System Style + Default Light Style + Default Dark Style + Custom + Remove + Max count: + Applications Applications + + Edit... + Set as default + Reports Reports + Save all errors when creating report Save all errors when creating report + Save full path to files in reports Save full path to files in reports + Language @@ -2718,6 +3040,8 @@ To toggle what kind of errors are shown, open view menu. + + Statistics @@ -2725,113 +3049,135 @@ To toggle what kind of errors are shown, open view menu. + Project + Project: + Paths: + Include paths: + Defines: + Undefines: + Previous Scan + Path Selected: + Number of Files Scanned: + Scan Duration: + Errors: + Warnings: + Stylistic warnings: + Portability warnings: + Performance issues: + Information messages: + Active checkers: + Checkers + History + File: + Copy to Clipboard + Pdf Export @@ -2981,6 +3327,7 @@ To toggle what kind of errors are shown, open view menu. ThreadDetails + Thread Details diff --git a/gui/cppcheck_sv.ts b/gui/cppcheck_sv.ts index 79bc48d06fc..80726023e09 100644 --- a/gui/cppcheck_sv.ts +++ b/gui/cppcheck_sv.ts @@ -5,27 +5,32 @@ About + About Cppcheck Om Cppcheck + Version %1 Version %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - Ett verktyg för statisk analys av C/C++ kod. + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. Copyright © 2007-2021 Cppcheck team. + This program is licensed under the terms of the GNU General Public License version 3 This program is licensed under the terms @@ -33,11 +38,13 @@ of the GNU General Public License version 3 + Visit Cppcheck homepage at %1 Hemsida: %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> @@ -47,11 +54,13 @@ of the GNU General Public License version 3 ApplicationDialog + Add an application Lägg till program + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -77,21 +86,25 @@ Parametrar: -l(line) (file) + &Name: Namn: + &Executable: Körbar fil: + &Parameters: Parametrar: + Browse Bläddra @@ -138,16 +151,19 @@ Parametrar: -l(line) (file) HelpDialog + Cppcheck GUI help + Contents + Index @@ -165,16 +181,19 @@ Parametrar: -l(line) (file) LibraryAddFunctionDialog + Add function Lägg till funktion + Function name(s) Funktion namn + Number of arguments Antal argument @@ -183,86 +202,103 @@ Parametrar: -l(line) (file) LibraryDialog + Library Editor Library Editor + Open Öppna + Save Spara + Save as Spara som + Functions Funktioner + Sort Sortera + Add Lägg till + Filter: Filter: + Comments Kommentar + noreturn noreturn + False False + True True + Unknown Vet ej + return value must be used retur värde måste användas + ignore function in leaks checking Ignorera funktionen när cppcheck letar efter läckor + Arguments Argument + Edit Redigera @@ -308,11 +344,13 @@ Parametrar: -l(line) (file) LibraryEditArgDialog + Edit argument Konfigurera argument + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -326,11 +364,13 @@ Exempel: + Not bool Ej bool + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -344,78 +384,99 @@ Exempel: + Not null Ej null + Not uninit Ej uninit + String Sträng + Format string Format sträng + Min size of buffer Minsta storlek för buffer + + Type Typ + + None Ingen + + argvalue argvalue + + mul mul + + strlen strlen + + Arg Arg + + Arg2 Arg2 + and och + Valid values Tillåtna värden @@ -428,579 +489,700 @@ Exempel: + A&nalyze Analysera + Standard Standard + &File &Arkiv + &View &Visa + &Toolbars Verktygsfält + C++ standard C++ standard + &C standard C standard C standard + &Edit &Redigera + &License... &Licens... + A&uthors... &Utvecklat av... + &About... &Om... + &Files... &Filer... + + Analyze files Check files Analysera filer + Ctrl+F Ctrl+F + &Directory... &Katalog... + + Analyze directory Check directory Analysera mapp + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop &Stoppa + + Stop analysis Stop checking Stoppa analys + Esc Esc + &Save results to file... &Spara resultat till fil... + Ctrl+S Ctrl+S + &Quit &Avsluta + &Clear results &Töm resultat + &Preferences &Inställningar - + + + Show errors Visa fel - + + + Show warnings Visa varningar + + Show performance warnings Visa prestanda varningar + Show &hidden Visa dolda - - + + Information Information + Show information messages Visa informations meddelanden + Show portability warnings Visa portabilitets varningar + Show Cppcheck results Visa Cppcheck resultat + Clang Clang + Show Clang results Visa Clang resultat + &Filter &Filter + Filter results Filtrera resultat + Windows 32-bit ANSI Windows 32-bit ANSI + Windows 32-bit Unicode Windows 32-bit Unicode + Unix 32-bit Unix 32-bit + Unix 64-bit Unix 64-bit + Windows 64-bit Windows 64-bit + &Print... Skriv ut... + Print the Current Report Skriv ut aktuell rapport + Print Pre&view... Förhandsgranska utskrift... + Open a Print Preview Dialog for the Current Results Öppnar förhandsgranskning för nuvarande resultat + Open library editor Öppna library editor + &Check all &Kryssa alla + Checking for updates + Hide Dölj + + Report + Filter Filter + &Reanalyze modified files &Recheck modified files Analysera om ändrade filer + Reanal&yze all files Analysera om alla filer + Ctrl+Q + Style war&nings Style varningar + E&rrors Fel + &Uncheck all Kryssa &ur alla + Collapse &all Ingen bra översättning! &Fäll ihop alla + &Expand all &Expandera alla + &Standard &Standard + Standard items Standard poster + Toolbar Verktygsfält + &Categories &Kategorier + Error categories Fel kategorier + &Open XML... &Öppna XML... + Open P&roject File... Öppna Projektfil... + Ctrl+Shift+O + Sh&ow Scratchpad... Visa Scratchpad... + &New Project File... Ny projektfil... + Ctrl+Shift+N + &Log View + Log View Logg vy + C&lose Project File Stäng projektfil + &Edit Project File... Redigera projektfil... + &Statistics Statistik + &Warnings Varningar + Per&formance warnings Optimerings varningar + &Information Information + &Portability Portabilitet + P&latforms Plattformar + C++&11 C++11 + C&99 C99 + &Posix Posix + C&11 C11 + &C89 C89 + &C++03 C++03 + &Library Editor... Library Editor... + &Auto-detect language Detektera språk automatiskt + &Enforce C++ Tvinga C++ + E&nforce C Tvinga C + C++14 C++14 + Reanalyze and check library + Check configuration (defines, includes) + C++17 C++17 + C++20 C++20 + Compliance report... + Normal + Autosar + EULA... + Thread Details + Show thread details + &Contents &Innehåll + Categories Kategorier + + Show style warnings Visa stil varningar + Open the help contents Öppna hjälp + F1 F1 + &Help &Hjälp - - + + Quick Filter: Snabbfilter: - + + None of the selected files is part of the project, nothing to analyze. + + + + Select configuration Välj konfiguration - + Found project file: %1 Do you want to load this project file instead? @@ -1009,97 +1191,97 @@ Do you want to load this project file instead? Vill du ladda denna projektfil istället? - + File not found Filen hittades ej - + Bad XML Ogiltig XML - + Missing attribute Attribut finns ej - + Bad attribute value Ogiltigt attribut värde - + Unsupported format Format stöds ej - + Duplicate define - + Failed to load the selected library '%1'. %2 Misslyckades att ladda valda library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Licens - + Authors Utvecklare - + Save the report file Spara rapport - - + + XML files (*.xml) XML filer (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -1108,37 +1290,37 @@ This is probably because the settings were changed between the Cppcheck versions En trolig orsak är att inställningarna ändrats för olika Cppcheck versioner. Kontrollera programinställningarna. - + You must close the project file before selecting new files or directories! Du måste stänga projektfilen innan nya filer eller sökvägar kan väljas! - + The library '%1' contains unknown elements: %2 Library filen '%1' har element som ej hanteras: %2 - + Duplicate platform type Dubbel plattformstyp - + Platform type redefined Plattformstyp definieras igen - + Unknown element Element hanteras ej - - - - + + + + Error Fel @@ -1147,50 +1329,50 @@ En trolig orsak är att inställningarna ändrats för olika Cppcheck versioner. Misslyckades att ladda %1. Din Cppcheck installation är ej komplett. Du kan använda --data-dir<directory> på kommandoraden för att specificera var denna fil finns. Det är meningen att --data-dir kommandot skall köras under installationen,så GUIt kommer ej visas när --data-dir används allt som händer är att en inställning görs. - + Open the report file Öppna rapportfilen - + Text files (*.txt) Text filer (*.txt) - + CSV files (*.csv) CSV filer (*.csv) - + Project files (*.cppcheck);;All files(*.*) Projektfiler (*.cppcheck);;Alla filer(*.*) - + Select Project File Välj projektfil - - - - + + + + Project: Projekt: - + No suitable files found to analyze! Inga filer hittades att analysera! - + C/C++ Source - + Compile database @@ -1199,22 +1381,22 @@ En trolig orsak är att inställningarna ändrats för olika Cppcheck versioner. Visual Studio - + Select files to analyze Välj filer att analysera - + Select directory to analyze Välj mapp att analysera - + Select the configuration that will be analyzed Välj konfiguration som kommer analyseras - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1223,7 +1405,7 @@ Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1231,7 +1413,7 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1240,104 +1422,104 @@ Do you want to stop the analysis and exit Cppcheck? Vill du stoppa analysen och avsluta Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML filer (*.xml);;Text filer (*.txt);;CSV filer (*.csv) - + Build dir '%1' does not exist, create it? Build dir '%1' existerar ej, skapa den? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1346,22 +1528,22 @@ Analysis is stopped. Misslyckades att importera '%1', analysen stoppas - + Project files (*.cppcheck) Projekt filer (*.cppcheck) - + Select Project Filename Välj Projektfil - + No project file loaded Inget projekt laddat - + The project file %1 @@ -1378,12 +1560,12 @@ Do you want to remove the file from the recently used projects -list? Vill du ta bort filen från 'senast använda projekt'-listan? - + Install - + New version available: %1. %2 @@ -1440,26 +1622,31 @@ Options: NewSuppressionDialog + New suppression + Error ID + File name + Line number + Symbol name @@ -1501,65 +1688,79 @@ Options: ProjectFile + Project File Projektfil + Paths and Defines Sökvägar och defines + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Import Project (Visual studio / compile database) Importera Projekt (Visual Studio / compile database) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Defines must be separated by a semicolon ';' Defines separeras med semicolon ';' + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. Obs: Lägg dina egna .cfg filer i samma folder som projekt filen. De skall isåfall visas ovan. + ... ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> <html><head/><body><p>Du har ett val:</p><p> * Analysera alla Debug och Release konfigurationer</p><p> * Analysera bara den första matchande Debug konfigurationen</p><p><br/></p></body></html> + + Browse... + Analyze all Visual Studio configurations Analysera alla Visual Studio konfigurationer + Selected VS Configurations + Paths: Sökvägar: + + Add... Lägg till... @@ -1567,6 +1768,9 @@ Options: + + + Edit Redigera @@ -1575,310 +1779,377 @@ Options: + + + + Remove Ta bort + Undefines: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 + Include Paths: Include sökvägar: + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + This is a workfolder that Cppcheck will use for various purposes. + Clang (experimental) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + Max recursion in template instantiation + Filepaths in warnings will be relative to this path + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files + Exclude folder... + Exclude file... + Enable inline suppressions Använd inline suppressions + Misra C + 2012 + + 2023 + 2025 + MISRA rule texts + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Misra C++ + 2008 + Cert C++ + Safety profiles (defined in C++ core guidelines) + Bug hunting (Premium) + External tools + Up Upp + Down Ned + Platform + + Analysis + Parser + Cppcheck (built in) + Check that each class has a safe public interface + Limit analysis + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) + Max CTU depth + Warning options + Root path: Bas sökväg: + Warning tags (separated by semicolon) Varnings taggar (separerade med semikolon) + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) Cppcheck build dir (whole program analys, incremental analys, statistik, etc) + Types and Functions + Libraries Libraries + Suppressions Suppressions + Add Lägg till + + Addons Addons + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 Y2038 + Thread safety Tråd säkerhet + Coding standards Kodstandarder + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Bug hunting @@ -1892,6 +2163,7 @@ Options: + Defines: Defines: @@ -2530,21 +2802,25 @@ För att ställa in vilka fel som skall visas använd visa menyn. + Results Resultat + Critical errors + Analysis Log Analys Log + Warning Details Varningsdetaljer @@ -2553,26 +2829,31 @@ För att ställa in vilka fel som skall visas använd visa menyn. ScratchPad + Scratchpad Scratchpad + Copy or write some C/C++ code here: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": + filename Filnamn + Check Analysera @@ -2581,21 +2862,25 @@ För att ställa in vilka fel som skall visas använd visa menyn. Settings + Preferences Inställningar + General Allmänt + Add... Lägg till... + Number of threads: Antal trådar: @@ -2605,57 +2890,68 @@ För att ställa in vilka fel som skall visas använd visa menyn. + Force checking all #ifdef configurations Check all #ifdef configurations Kontrollera alla #ifdef konfigurationer + Show full path of files Visa den fulla sökvägen för filer + Show "No errors found" message when no errors found Visa "Inga fel hittades" meddelande när inga fel hittas + Display error Id in column "Id" Visa meddelande id i kolumn "Id" + Enable inline suppressions Använd inline suppressions + Check for inconclusive errors also Kör inconclusive analys + Show statistics on check completion Visa statistik när analys är klar + Check for updates + Show internal warnings in log Visa interna fel i loggen + Addons Addons + Python binary (leave this empty to use python in the PATH) Python binär fil (lämna tom för att använda python i PATH) @@ -2663,117 +2959,143 @@ För att ställa in vilka fel som skall visas använd visa menyn. + + + ... ... + MISRA addon + MISRA rule texts file + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Clang Clang + Clang path (leave empty to use system PATH) Clang sökväg (lämna tom för att använda PATH) + Visual Studio headers Visual Studio headers + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> <html><head/><body><p>Sökvägar till Visual Studio headers, separerade med semikolon ';'.</p><p>Du kan öppna en Visual Studio command prompt, och skriva &quot;SET INCLUDE&quot;. Sedan kopiera och klistra in sökvägarna.</p></body></html> + Code Editor + Code Editor Style + System Style + Default Light Style + Default Dark Style + Custom + Remove Ta bort + Max count: + Applications Program + + Edit... Redigera... + Set as default Sätt förvald + Reports Rapporter + Save all errors when creating report Spara alla fel + Save full path to files in reports Spara fulla sökvägar + Language Språk @@ -2830,6 +3152,8 @@ För att ställa in vilka fel som skall visas använd visa menyn. + + Statistics @@ -2837,113 +3161,135 @@ För att ställa in vilka fel som skall visas använd visa menyn. + Project Projekt + Project: Projekt: + Paths: Sökvägar: + Include paths: Include sökvägar: + Defines: Defines: + Undefines: + Previous Scan Föregående analys + Path Selected: Vald sökväg: + Number of Files Scanned: Antal analyserade filer: + Scan Duration: Analys tid: + Errors: Fel: + Warnings: Varningar: + Stylistic warnings: Stil varningar: + Portability warnings: Portabilitets varningar: + Performance issues: Prestanda varningar: + Information messages: Informations meddelanden: + Active checkers: + Checkers + History Historik + File: Fil: + Copy to Clipboard Kopiera + Pdf Export Pdf Export @@ -3093,6 +3439,7 @@ För att ställa in vilka fel som skall visas använd visa menyn. ThreadDetails + Thread Details diff --git a/gui/cppcheck_zh_CN.ts b/gui/cppcheck_zh_CN.ts index 17a85231255..3bc2a493818 100644 --- a/gui/cppcheck_zh_CN.ts +++ b/gui/cppcheck_zh_CN.ts @@ -5,38 +5,45 @@ About + About Cppcheck 关于 Cppcheck + Version %1 版本 %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - C/C++ 静态代码分析工具。 + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. 版权所有 © 2007-%1 Cppcheck 团队。 + This program is licensed under the terms of the GNU General Public License version 3 该程序在 GNU 通用公共授权版本 3 的条款下发布 + Visit Cppcheck homepage at %1 访问 Cppcheck 主页: %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> @@ -46,11 +53,13 @@ of the GNU General Public License version 3 ApplicationDialog + Add an application 添加应用程序 + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -76,21 +85,25 @@ Parameters: -l(line) (file) + &Name: 名称(&N): + &Executable: 可执行文件(&E): + &Parameters: 参数(&P): + Browse 浏览 @@ -135,16 +148,19 @@ Parameters: -l(line) (file) HelpDialog + Cppcheck GUI help Cppcheck GUI 帮助 + Contents 内容 + Index 索引 @@ -162,16 +178,19 @@ Parameters: -l(line) (file) LibraryAddFunctionDialog + Add function 添加函数 + Function name(s) 函数名 + Number of arguments 参数个数 @@ -180,86 +199,103 @@ Parameters: -l(line) (file) LibraryDialog + Library Editor 库编辑器 + Open 打开 + Save 保存 + Save as 另存为 + Functions 函数 + Sort 排序 + Add 添加 + Filter: 过滤: + Comments 注释 + noreturn 无返回 + False 否 + True 是 + Unknown 未知 + return value must be used 返回值必须被使用 + ignore function in leaks checking 在泄漏检查中忽略函数 + Arguments 参数 + Edit 编辑 @@ -305,11 +341,13 @@ Parameters: -l(line) (file) LibraryEditArgDialog + Edit argument 编辑参数 + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -325,11 +363,13 @@ Parameters: -l(line) (file) + Not bool 非布尔值 + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -345,78 +385,99 @@ Parameters: -l(line) (file) + Not null 非空 + Not uninit 非未初始化 + String 字符串 + Format string 格式化字符串 + Min size of buffer 最小缓冲区大小 + + Type 类型 + + None 无 + + argvalue argvalue + + mul mul + + strlen strlen + + Arg 参数1 + + Arg2 参数2 + and 并且 + Valid values 有效值 @@ -429,567 +490,683 @@ Parameters: -l(line) (file) + &File 文件(&F) + &View 查看(&V) + &Toolbars 工具栏(&T) + &Help 帮助(&H) + C++ standard C++ 标准 + &C standard C standard &C 标准 + &Edit 编辑(&E) + Standard 标准 + Categories 分类 + &License... 许可证(&L)... + A&uthors... 作者(&U)... + &About... 关于(&A)... + &Files... 文件(&F)... + + Analyze files Check files 分析文件 + Ctrl+F Ctrl+F + &Directory... 目录(&D)... + + Analyze directory Check directory 分析目录 + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop 停止(&S) + + Stop analysis Stop checking 停止分析 + Esc Esc + &Save results to file... 保存结果到文件(&S)... + Ctrl+S Ctrl+S + &Quit 退出(&Q) + &Clear results 清空结果(&C) + &Preferences 首选项(&P) + + Show style warnings 显示风格警告 - + + + Show errors 显示错误 - - + + Information 信息 + Show information messages 显示信息消息 + Show portability warnings 显示可移植性警告 + Show Cppcheck results 显示 Cppcheck 结果 + Clang Clang + Show Clang results 显示 Clang 结果 + &Filter 滤器(&F) + Filter results 过滤结果 + Windows 32-bit ANSI + Windows 32-bit Unicode + Unix 32-bit + Unix 64-bit + Windows 64-bit + &Print... 打印(&P)... + Print the Current Report 打印当前报告 + Print Pre&view... 打印预览(&v)... + Open a Print Preview Dialog for the Current Results 打开当前结果的打印预览窗口 + Open library editor 打开库编辑器 + C&lose Project File 关闭项目文件(&L) + &Edit Project File... 编辑项目文件(&E)... + &Statistics 统计(&S) - + + + Show warnings 显示警告 + + Show performance warnings 显示性能警告 + Show &hidden 显示隐藏项(&H) + &Check all 全部选中(&C) + Checking for updates + Hide 隐藏 + + Report + A&nalyze 分析(&A) + Filter 滤器 + &Reanalyze modified files &Recheck modified files 重新分析已修改的文件(&R) + Reanal&yze all files 重新分析全部文件(&y) + Ctrl+Q Ctrl+Q + Style war&nings 风格警告(&n) + E&rrors 编辑(&r) + &Uncheck all 全部取消选中(&U) + Collapse &all 全部折叠(&A) + &Expand all 全部展开(&E) + &Standard 标准(&S) + Standard items 标准项 + &Contents 内容(&C) + Open the help contents 打开帮助内容 + F1 F1 + Toolbar 工具栏 + &Categories 分类(&C) + Error categories 错误分类 + &Open XML... 打开 XML (&O)... + Open P&roject File... 打开项目文件(&R)... + Ctrl+Shift+O Ctrl+Shift+O + Sh&ow Scratchpad... 显示便条(&o)... + &New Project File... 新建项目文件(&N)... + Ctrl+Shift+N Ctrl+Shift+N + &Log View 日志视图(&L) + Log View 日志视图 + &Warnings 警告(&W) + Per&formance warnings 性能警告(&f) + &Information 信息(&I) + &Portability 可移植性(&P) + P&latforms 平台(&l) + C++&11 C++&11 + C&99 C&99 + &Posix &Posix + C&11 C&11 + &C89 &C89 + &C++03 &C++03 + &Library Editor... 库编辑器(&L)... + &Auto-detect language 自动检测语言(&A) + &Enforce C++ &Enforce C++ + E&nforce C E&nforce C + C++14 C++14 + Reanalyze and check library 重新分析并检查库 + Check configuration (defines, includes) 检查配置(defines, includes) + C++17 C++17 + C++20 C++20 + Compliance report... + Normal 常规 + Autosar + EULA... + Thread Details + Show thread details - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -998,23 +1175,28 @@ This is probably because the settings were changed between the Cppcheck versions 这可能是因为 Cppcheck 不同版本间的设置有所不同。请检查(并修复)编辑器应用程序设置,否则编辑器程序可能不会正确启动。 - + You must close the project file before selecting new files or directories! 在选择新的文件或目录之前,你必须先关闭此项目文件! - - + + Quick Filter: 快速滤器: - + + None of the selected files is part of the project, nothing to analyze. + + + + Select configuration 选择配置 - + Found project file: %1 Do you want to load this project file instead? @@ -1023,64 +1205,64 @@ Do you want to load this project file instead? 你是否想加载该项目文件? - + The library '%1' contains unknown elements: %2 库 '%1' 包含未知元素: %2 - + File not found 文件未找到 - + Bad XML 无效的 XML - + Missing attribute 缺失属性 - + Bad attribute value 无效的属性值 - + Unsupported format 不支持的格式 - + Duplicate platform type 重复的平台类型 - + Platform type redefined 平台类型重定义 - + Unknown element 位置元素 - + Failed to load the selected library '%1'. %2 选择的库 '%1' 加载失败。 %2 - - - - + + + + Error 错误 @@ -1089,108 +1271,108 @@ Do you want to load this project file instead? 加载 %1 失败。您的 Cppcheck 安装已损坏。您可以在命令行添加 --data-dir=<目录> 参数来指定文件位置。请注意,'--data-dir' 参数应当由安装脚本使用,因此,当使用此参数时,GUI不会启动,所发生的一切只是配置了设置。 - - + + XML files (*.xml) XML 文件(*.xml) - + Open the report file 打开报告文件 - + License 许可证 - + Authors 作者 - + Save the report file 保存报告文件 - + Text files (*.txt) 文本文件(*.txt) - + CSV files (*.csv) CSV 文件(*.csv) - + Project files (*.cppcheck);;All files(*.*) 项目文件(*.cppcheck);;所有文件(*.*) - + Select Project File 选择项目文件 - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Install - + New version available: %1. %2 - - - - + + + + Project: 项目: - + No suitable files found to analyze! 没有找到合适的文件来分析! - + C/C++ Source C/C++ 源码 - + Compile database Compile database @@ -1203,22 +1385,22 @@ Analysis is stopped. Borland C++ Builder 6 - + Select files to analyze 选择要分析的文件 - + Select directory to analyze 选择要分析的目录 - + Select the configuration that will be analyzed 选择要分析的配置 - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1227,44 +1409,44 @@ Do you want to proceed analysis without using any of these project files? - + Duplicate define - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1275,7 +1457,7 @@ Do you want to proceed? 你想继续吗? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1284,77 +1466,77 @@ Do you want to stop the analysis and exit Cppcheck? 您想停止分析并退出 Cppcheck 吗? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML 文件 (*.xml);;文本文件 (*.txt);;CSV 文件 (*.csv) - + Build dir '%1' does not exist, create it? 构建文件夹 '%1' 不能存在,创建它吗? - + To check the project using addons, you need a build directory. 要使用插件检查项目,您需要一个构建目录。 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1363,22 +1545,22 @@ Do you want to stop the analysis and exit Cppcheck? 导入 '%1' 失败,分析已停止 - + Project files (*.cppcheck) 项目文件 (*.cppcheck) - + Select Project Filename 选择项目文件名 - + No project file loaded 项目文件未加载 - + The project file %1 @@ -1446,26 +1628,31 @@ Options: NewSuppressionDialog + New suppression 新建抑制 + Error ID 错误 ID + File name 文件名 + Line number 行号 + Symbol name 符号名 @@ -1487,48 +1674,57 @@ Options: ProjectFile + Project File 项目文件 + Paths and Defines 路径和定义 + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Import Project (Visual studio / compile database) 导入项目 (Visual studio / compile database/ Borland C++ Builder 6) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Defines must be separated by a semicolon ';' 定义必须用分号分隔。例如:DEF1;DEF2=5;DEF3=int + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. 注意:把你自己的 .cfg 文件放在和项目文件相同的文件夹中。你应该在上面看到它们。 + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. 如果添加了标记,您将能够右键单击警告并设置其中一个标记。您可以手动对警告进行分类。 + Exclude source files 排除源文件 + Exclude folder... 排除文件夹... + Exclude file... 排除文件... @@ -1538,48 +1734,59 @@ Options: + MISRA rule texts MISRA 规则文本 + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> <html><head/><body><p>从 MISRA C 2012 PDF 的附录 A &quot;指南摘要&quot; 复制/粘贴文本到一个文本文件。</p></body></html> + ... ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> <html><head/><body><p>您有一个选择:</p><p> * 分析所有的 Debug 和 Release 配置</p><p> * 只分析第一个匹配的 Debug 配置</p><p><br/></p></body></html> + + Browse... 浏览... + Analyze all Visual Studio configurations 分析全部 Visual Studio 配置 + Selected VS Configurations 已选择的 VS 配置 + Paths: 路径: + + Add... 添加... @@ -1587,6 +1794,9 @@ Options: + + + Edit 编辑 @@ -1595,280 +1805,341 @@ Options: + + + + Remove 移除 + Undefines: 未定义: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 未定义必须用分号分隔。例如:UNDEF1;UNDEF2;UNDEF3 + Include Paths: 包含目录: + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Types and Functions 类型和函数 + + Analysis 分析 + This is a workfolder that Cppcheck will use for various purposes. 这是一个 Cppcheck 将用于各种目的的工作文件夹。 + Parser 解析器 + Cppcheck (built in) Cppcheck (内建) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + Check that each class has a safe public interface 检查每个类是否有一个安全的公共接口 + Limit analysis 极限分析 + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) 检查未使用模板中的代码(正常情况下应该是打开,但理论上可以忽略未使用模板中的警告) + Max CTU depth 最大 CTU 深度 + Enable inline suppressions 启用内联方案 + 2025 + Misra C++ + 2008 + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Safety profiles (defined in C++ core guidelines) + Bug hunting + External tools 外部工具 + Up 向上 + Down 向下 + Platform 平台 + Clang (experimental) Clang (实验性的) + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. 如果你想要设计你的类尽可能的灵活和健壮,那么公共接口必须非常健壮。Cppcheck 将假设参数可以取 *任何* 值。 + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) 检查头文件中的代码(通常应该是打开的。如果您想要一个有限的快速分析,那么关掉它)) + Max recursion in template instantiation 模板实例化中的最大递归 + Warning options 警告选项 + Root path: 根路径: + Filepaths in warnings will be relative to this path 警告中的文件路径将相对于此路径 + Warning tags (separated by semicolon) 警告标志(用分号隔开) + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) Cppcheck 构建目录 (整个程序分析、增量分析、统计数据等) + Libraries 库 + Suppressions 抑制 + Add 添加 + + Addons 插件 + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. 注意:插件需要安装 <a href="https://www.python.org/">Python</a>。 + Y2038 Y2038 + Thread safety 线程安全 + Coding standards 编码标准 + Misra C + 2012 + + 2023 + Cert C++ + Bug hunting (Premium) @@ -1882,6 +2153,7 @@ Options: + Defines: 定义: @@ -2424,21 +2696,25 @@ Please check the application path and parameters are correct. ResultsView + Results 结果 + Critical errors + Analysis Log 分析日志 + Warning Details 警告详情 @@ -2549,26 +2825,31 @@ To toggle what kind of errors are shown, open view menu. ScratchPad + Scratchpad 便条 + Copy or write some C/C++ code here: 在这里复制或输入一些 C/C++ 代码: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": 可选择输入文件名 (主要用来自动语言检测) 然后点击 "检查": + filename 文件名 + Check 检查 @@ -2577,21 +2858,25 @@ To toggle what kind of errors are shown, open view menu. Settings + Preferences 首选项 + General 常规 + Add... 添加... + Number of threads: 线程个数: @@ -2601,57 +2886,68 @@ To toggle what kind of errors are shown, open view menu. + Force checking all #ifdef configurations Check all #ifdef configurations 强制检查所有 #ifdef 配置 + Show full path of files 显示文件的完整路径 + Show "No errors found" message when no errors found 当未找到错误,显示“未发现错误”消息 + Display error Id in column "Id" 在列“Id”中显示错误 Id + Enable inline suppressions 启用内联方案 + Check for inconclusive errors also 检查不确定的错误 + Show statistics on check completion 检查完成后显示统计数据 + Check for updates + Show internal warnings in log 在日志中显示内建警告 + Addons 插件 + Python binary (leave this empty to use python in the PATH) Python 二进制 (留空将使用 PATH 路径中的 python) @@ -2659,117 +2955,143 @@ To toggle what kind of errors are shown, open view menu. + + + ... ... + MISRA addon MISRA 插件 + MISRA rule texts file MISRA 规则文本文件 + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> <html><head/><body><p>从 MISRA C 2012 PDF 的附录 A &quot;指南摘要&quot; 复制/粘贴文本到一个文本文件。</p></body></html> + Clang Clang + Clang path (leave empty to use system PATH) Clang 路径 (留空将使用系统 PATH 路径) + Visual Studio headers Visual Studio 头文件 + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> <html><head/><body><p>Visual Studio 头文件路径,用分号 ';' 分割。</p><p>你可以打开一个 Visual Studio 命令提示符,输入 &quot;SET INCLUDE&quot;。然后复制/粘贴路径。</p></body></html> + Code Editor 代码编辑器 + Code Editor Style 代码编辑器风格 + System Style 系统风格 + Default Light Style 默认浅色风格 + Default Dark Style 默认深色风格 + Custom 自定义 + Remove 移除 + Max count: + Applications 应用程序 + + Edit... 编辑... + Set as default 设为默认 + Reports 报告 + Save all errors when creating report 创建报告时,保存所有错误 + Save full path to files in reports 在报告中保存文件的完整路径 + Language 语言 @@ -2826,6 +3148,8 @@ To toggle what kind of errors are shown, open view menu. + + Statistics @@ -2833,113 +3157,135 @@ To toggle what kind of errors are shown, open view menu. + Project 项目 + Project: 项目: + Paths: 路径: + Include paths: 包含路径: + Defines: 定义: + Undefines: 未定义: + Previous Scan 上一次扫描 + Path Selected: 选中的路径: + Number of Files Scanned: 扫描的文件数: + Scan Duration: 扫描时间: + Errors: 错误: + Warnings: 警告: + Stylistic warnings: Stylistic 警告: + Portability warnings: 可移植性警告: + Performance issues: 性能警告: + Information messages: 信息: + Active checkers: + Checkers + History 历史 + File: 文件: + Copy to Clipboard 复制到剪贴板 + Pdf Export 导出 PDF @@ -3089,6 +3435,7 @@ To toggle what kind of errors are shown, open view menu. ThreadDetails + Thread Details diff --git a/gui/cppcheck_zh_TW.ts b/gui/cppcheck_zh_TW.ts index 6be1247835e..b1951e9f29f 100644 --- a/gui/cppcheck_zh_TW.ts +++ b/gui/cppcheck_zh_TW.ts @@ -5,26 +5,31 @@ About + About Cppcheck 關於 Cppcheck + Version %1 版本 %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - 一款靜態 C/C++ 程式碼分析工具。 + Copyright © 2007-%1 Cppcheck team. 著作權 © 2007-%1 Cppcheck 團隊。 + This program is licensed under the terms of the GNU General Public License version 3 該程式是根據 GNU 通用公眾授權條款第 3 版 @@ -32,11 +37,13 @@ of the GNU General Public License version 3 + Visit Cppcheck homepage at %1 訪問 Cppcheck 主頁: %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> @@ -46,11 +53,13 @@ of the GNU General Public License version 3 ApplicationDialog + Add an application 新增應用程式 + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -66,21 +75,25 @@ Parameters: -l(line) (file) + &Name: 名稱(&N): + &Executable: 執行檔(&E): + &Parameters: 參數(&P): + Browse 瀏覽 @@ -140,16 +153,19 @@ Parameters: -l(line) (file) HelpDialog + Cppcheck GUI help Cppcheck GUI 幫助 + Contents 內容 + Index 索引 @@ -167,16 +183,19 @@ Parameters: -l(line) (file) LibraryAddFunctionDialog + Add function 新增函式 + Function name(s) 函式名稱 + Number of arguments 引數數量 @@ -185,86 +204,103 @@ Parameters: -l(line) (file) LibraryDialog + Library Editor 程式庫編輯器 + Open 開啟 + Save 儲存 + Save as 另存為 + Functions 函式 + Sort 排序 + Add 新增 + Filter: + Comments 註釋 + noreturn + False + True + Unknown 未知 + return value must be used + ignore function in leaks checking + Arguments 引數 + Edit 編輯 @@ -308,11 +344,13 @@ Parameters: -l(line) (file) LibraryEditArgDialog + Edit argument 編輯引數 + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -323,11 +361,13 @@ Parameters: -l(line) (file) + Not bool + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -338,78 +378,99 @@ Parameters: -l(line) (file) + Not null + Not uninit + String 字串 + Format string + Min size of buffer + + Type 型別 + + None + + argvalue + + mul + + strlen + + Arg + + Arg2 + and + Valid values 有效值 @@ -422,532 +483,644 @@ Parameters: -l(line) (file) + Checking for updates 檢查更新 + Hide 隱藏 + &File 檔案(&F) + &View 檢視(&V) + &Toolbars 工具條(&T) + + Report + &Help 幫助(&H) + A&nalyze 分析(&N) + C++ standard C++ 標準 + &C standard C 標準(&C) + &Edit 編輯(&E) + Standard 標準 + Categories 分類 + Filter 篩選 + &License... 授權(&L)... + A&uthors... 作者(&U)... + &About... 關於(&A)... + &Files... 檔案(&F)... + + Analyze files 分析檔案 + Ctrl+F Ctrl+F + &Directory... 目錄(&D)... + + Analyze directory 分析目錄 + Ctrl+D Ctrl+D + &Reanalyze modified files 重新分析已修改的檔案(&R) + Ctrl+R Ctrl+R + Reanal&yze all files 重新分析所有檔案(&Y) + &Stop 停止(&S) + + Stop analysis 停止分析 + Esc Esc + &Save results to file... 儲存結果為檔案(&S)... + Ctrl+S Ctrl+S + &Quit 退出(&Q) + Ctrl+Q Ctrl+Q + &Clear results 清除結果(&C) + &Preferences 偏好設定(&P) + Style war&nings 樣式警告(&N) + + Show style warnings 顯示樣式警告 + E&rrors 錯誤(&R) - + + + Show errors 顯示錯誤 + &Check all 全部檢查(&C) + &Uncheck all + Collapse &all 全部摺疊(&A) + &Expand all 全部展開(&E) + &Standard 標準(&S) + Standard items 標準項目 + &Contents 內容(&C) + Open the help contents 開啟幫助內容 + F1 F1 + Toolbar 工具條 + &Categories 分類(&C) + Error categories 錯誤分類 + &Open XML... 開啟 XML(&O)... + Open P&roject File... 開啟專案檔(&R)... + Ctrl+Shift+O Ctrl+Shift+O + Sh&ow Scratchpad... + &New Project File... 新增專案檔(&N)... + Ctrl+Shift+N Ctrl+Shift+N + &Log View 日誌檢視(&L) + Log View 日誌檢視 + C&lose Project File 關閉專案檔(&L) + &Edit Project File... 編輯專案檔(&E)... + &Statistics 統計資料(&S) + &Warnings 警告(&W) - + + + Show warnings 顯示警告 + Per&formance warnings 效能警告(&F) + + Show performance warnings 顯示下效能警告 + Show &hidden 顯示隱藏項目(&H) + &Information 資訊(&I) + Show information messages 顯示資訊訊息 + &Portability 可移植性(&P) + Show portability warnings 顯示可移植性警告 + Show Cppcheck results 顯示 Cppcheck 結果 + Clang Clang + Show Clang results 顯示 Clang 結果 + &Filter 篩選(&F) + Filter results 篩選結果 + Windows 32-bit ANSI Windows 32 位元 ANSI + Windows 32-bit Unicode Windows 32 位元 Unicode + Unix 32-bit Unix 32 位元 + Unix 64-bit Unix 64 位元 + Windows 64-bit Windows 64 位元 + P&latforms 平臺(&L) + C++&11 C++&11 + C&99 C&99 + &Posix + C&11 C&11 + &C89 &C89 + &C++03 &C++03 + &Print... 列印(&P)... + Print the Current Report 列印當前報告 + Print Pre&view... 列印預覽(&V)... + Open a Print Preview Dialog for the Current Results 開啟當前結果的列印預覽視窗 + &Library Editor... 程式庫編輯器(&L)... + Open library editor 開啟程式庫編輯器 + &Auto-detect language 自動偵測語言(&A) + &Enforce C++ + E&nforce C + C++14 C++14 + Reanalyze and check library 重新分析並檢查程式庫 + Check configuration (defines, includes) 檢查組態 (定義、包含) + C++17 C++17 + C++20 C++20 + Compliance report... + Normal @@ -961,21 +1134,25 @@ Parameters: -l(line) (file) + Autosar + EULA... + Thread Details + Show thread details @@ -1003,43 +1180,48 @@ Options: Cppcheck GUI - 命令行參數 - - + + Quick Filter: 快速篩選: - - - - + + + + Project: 專案: - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. - + + None of the selected files is part of the project, nothing to analyze. + + + + No suitable files found to analyze! 找不到適合的檔案來分析! - + You must close the project file before selecting new files or directories! 您必須在選取新檔案或目錄之前關閉該專案檔! - + C/C++ Source C/C++ 來源檔 - + Compile database 編譯資料庫 @@ -1052,145 +1234,145 @@ This is probably because the settings were changed between the Cppcheck versions Borland C++ Builder 6 - + Select files to analyze 選取要分析的檔案 - + Select directory to analyze 選取要分析的目錄 - + Select configuration 選取組態 - + Select the configuration that will be analyzed 選取要分析的組態 - + Found project file: %1 Do you want to load this project file instead? - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - - + + Information 資訊 - + The library '%1' contains unknown elements: %2 - + File not found 找不到檔案 - + Bad XML - + Missing attribute - + Bad attribute value - + Unsupported format 未支援的格式 - + Duplicate platform type 重複的平臺型別 - + Platform type redefined 平臺型別重定義 - + Duplicate define - + Unknown element 未知的元素 - + Failed to load the selected library '%1'. %2 無法載入選取的程式庫 '%1'。 %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - - - - + + + + Error 錯誤 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1198,18 +1380,18 @@ Do you want to proceed? - - + + XML files (*.xml) XML 檔案 (*.xml) - + Open the report file 開啟報告檔 - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1218,77 +1400,77 @@ Do you want to stop the analysis and exit Cppcheck? 您想停止分析並離開 Cppcheck 嗎? - + About 關於 - + License 授權 - + Authors 作者 - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML 檔案 (*.xml);;文字檔 (*.txt);;CSV 檔案 (*.csv) - + Save the report file 儲存報告檔 - + Text files (*.txt) 文字檔 (*.txt) - + CSV files (*.csv) CSV 檔案 (*.csv) - + Project files (*.cppcheck);;All files(*.*) 專案檔 (*.cppcheck);;所有檔案 (*.*) - + Select Project File 選取專案檔 - + Build dir '%1' does not exist, create it? 建置目錄 '%1' 不存在,是否建立它? - + To check the project using addons, you need a build directory. - + Failed to open file 無法開啟檔案 - + Unknown project file format 未知的專案檔格式 - + Failed to import project file 無法匯入專案檔 - + Failed to import '%1': %2 Analysis is stopped. @@ -1297,62 +1479,62 @@ Analysis is stopped. 停止分析。 - + Failed to import '%1' (%2), analysis is stopped - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1361,22 +1543,22 @@ Analysis is stopped. 無法匯入 '%1',停止分析 - + Project files (*.cppcheck) 專案檔 (*.cppcheck) - + Select Project Filename 選取專案檔案名稱 - + No project file loaded - + The project file %1 @@ -1393,12 +1575,12 @@ Do you want to remove the file from the recently used projects -list? 您要從最近使用的專案列表中移除該檔案嗎? - + Install 安章 - + New version available: %1. %2 可用的新版本: %1. %2 @@ -1407,26 +1589,31 @@ Do you want to remove the file from the recently used projects -list? NewSuppressionDialog + New suppression 新建抑制 + Error ID 錯誤 ID + File name 檔案名稱 + Line number 行號 + Symbol name 符號名稱 @@ -1468,48 +1655,59 @@ Do you want to remove the file from the recently used projects -list? ProjectFile + Project File 專案檔 + Paths and Defines 路徑與定義 + Import Project (Visual studio / compile database/ Borland C++ Builder 6) 匯入專案 (Visual Studio / 編譯資料庫 / Borland C++ Builder 6) + + Browse... 瀏覽... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> + Analyze all Visual Studio configurations 分析所有 Visual Studio 組態 + Selected VS Configurations 選取 VS 組態 + Paths: 路徑: + + Add... 新增... @@ -1517,6 +1715,9 @@ Do you want to remove the file from the recently used projects -list? + + + Edit 編輯 @@ -1525,274 +1726,334 @@ Do you want to remove the file from the recently used projects -list? + + + + Remove 移除 + Defines: 定義: + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int + Undefines: 未定義: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 + Include Paths: 包含路徑: + Up + Down + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Types and Functions 型別與函式 + Platform 平臺 + Libraries 程式庫 + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. + + Analysis 分析 + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) + This is a workfolder that Cppcheck will use for various purposes. + Parser 剖析器 + Cppcheck (built in) Cppcheck (內建) + Clang (experimental) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check that each class has a safe public interface + Limit analysis + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) + Max CTU depth + Max recursion in template instantiation + Warning options 警告選項 + Root path: 根路徑: + Filepaths in warnings will be relative to this path + Warning tags (separated by semicolon) 警告標記 (由分號分隔) + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files 排除來源檔 + Exclude folder... 排除資料夾... + Exclude file... 排除檔案... + Suppressions 抑制 + Add 新增 + Enable inline suppressions + + Addons + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 Y2038 + Thread safety 執行緒安全 + Coding standards + Misra C + 2012 + + 2023 + 2025 + Misra C++ + 2008 @@ -1802,16 +2063,19 @@ Do you want to remove the file from the recently used projects -list? + MISRA rule texts + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + ... ... @@ -1821,41 +2085,49 @@ Do you want to remove the file from the recently used projects -list? + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Cert C++ + Autosar + Safety profiles (defined in C++ core guidelines) + Bug hunting (Premium) + Bug hunting + External tools 外部工具 @@ -2382,21 +2654,25 @@ Please check the application path and parameters are correct. ResultsView + Results 結果 + Critical errors + Analysis Log 分析日誌 + Warning Details 警告詳細資訊 @@ -2502,26 +2778,31 @@ To toggle what kind of errors are shown, open view menu. ScratchPad + Scratchpad + Copy or write some C/C++ code here: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": + filename 檔案名稱 + Check @@ -2530,122 +2811,147 @@ To toggle what kind of errors are shown, open view menu. Settings + Preferences 偏好設定 + General 一般 + Number of threads: 執行緒數量: + Max count: + Force checking all #ifdef configurations + Show full path of files 顯示檔案的完整路徑 + Show "No errors found" message when no errors found + Display error Id in column "Id" + Enable inline suppressions + Check for inconclusive errors also + Show statistics on check completion + Check for updates 檢查更新 + Show internal warnings in log 顯示日誌中的內部警告 + Applications 應用程式 + Add... 新增... + + Edit... 編輯... + Remove 移除 + Set as default 設定為預設值 + Reports 報告 + Save all errors when creating report + Save full path to files in reports 在報告中儲存檔案的完整路徑 + Language 語言 + Addons + Python binary (leave this empty to use python in the PATH) @@ -2653,71 +2959,87 @@ To toggle what kind of errors are shown, open view menu. + + + ... ... + MISRA addon + MISRA rule texts file MISRA 規則文字檔 + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Clang Clang + Clang path (leave empty to use system PATH) + Visual Studio headers Visual Studio 標頭檔 + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> + Code Editor 程式碼編輯器 + Code Editor Style 程式碼編輯器樣式 + System Style 系統樣式 + Default Light Style + Default Dark Style + Custom 自訂 @@ -2770,6 +3092,8 @@ To toggle what kind of errors are shown, open view menu. + + Statistics @@ -2777,113 +3101,135 @@ To toggle what kind of errors are shown, open view menu. + Project 專案 + Project: 專案: + Paths: 路徑: + Include paths: 包含路徑: + Defines: 定義: + Undefines: 未定義: + Previous Scan 上一次掃描 + Path Selected: 選取的路徑: + Number of Files Scanned: 已掃描的檔案數量: + Scan Duration: 掃描時間: + Errors: 錯誤: + Warnings: 警告: + Stylistic warnings: + Portability warnings: 可移植性警告: + Performance issues: 效能議題: + Information messages: 資訊訊息: + Active checkers: + Checkers + History 歷史紀錄 + File: 檔案: + Copy to Clipboard 複製到剪貼簿 + Pdf Export Pdf 匯出 @@ -3033,6 +3379,7 @@ To toggle what kind of errors are shown, open view menu. ThreadDetails + Thread Details diff --git a/gui/manualtest/docs/handbook.html b/gui/manualtest/docs/handbook.html new file mode 100644 index 00000000000..1da9f571224 --- /dev/null +++ b/gui/manualtest/docs/handbook.html @@ -0,0 +1,453 @@ + + + + + +gui-test Handbook + + + +
+ +
+
gui-test
+

gui-test Handbook

+

The manual tests for cppcheck-gui are written in Gherkin, the plain-language Given/When/Then format. gui-test turns them into automated tests: Claude explores the GUI once and writes a script, and from then on the script is replayed without any AI.

+

Updated 2026-10-24

+ +

Overview

+

Working with gui-test has three steps:

+
    +
  1. Write the test in plain words: what the starting point is, what you do and what you expect to see.
  2. +
  3. Generate the script, once. Claude does the test in the application and writes down what it did as a script.
  4. +
  5. Run the tests as often as you like. The scripts are replayed without AI, and you get a report with the results and screenshots.
  6. +
+

All of this is done in the web interface. The application runs on its own virtual screen, so your desktop is not touched while tests run.

+ +
+ + + Claude writes the script once, every run replays it without AI + + + + + + + + + + A test in words + Gherkin scenarios + + gen.py + Claude does it once + + Replay passes? + + Script saved + in FILE.scripts.json + + run.py + replays it, no AI + + report.html + and results.json + yes + no: Claude gets the reason, up to 3 tries + every run + +
From a test in words to a report: gen.py once, run.py every run.
+
+ +

The tests are kept in tests/, and every run puts its report, logs and screenshots in a new directory under results/.

+ +

Getting started

+

Start web.py with the cppcheck-gui binaries you want to test, then open http://127.0.0.1:8080/ in a browser.

+
./web.py --opensource ~/cppcheck/build/bin/cppcheck-gui \
+         --premium ~/premium/build/bin/cppcheck-gui --src ~/cppcheck
+
    +
  • --opensource and --premium each take the binary of that edition. Give one, both or none; without a binary you can edit tests but not generate or run them.
  • +
  • --src is the git checkout the binaries are built from. It is only used for the git SHA, branch and commit in the report; the default is the directory of the binary.
  • +
  • --dir (default tests), --out (default results) and --port (default 8080) change where test files and results live and which port is used. The server only listens on 127.0.0.1.
  • +
+

Some packages must be installed first. On Ubuntu (checked on 26.04):

+
sudo apt install xvfb xdotool dbus at-spi2-core python3-gi gir1.2-atspi-2.0 python3-pil tesseract-ocr tesseract-ocr-eng
+

The tesseract packages are only needed for ocr checks. To generate scripts the claude command line tool must be installed too.

+ +

The web interface

+
    +
  • Header: Save, Run all (every test in every file), the Edition picker, a status message and a link to this handbook. The Edition picker only shows the editions that web.py got a binary for, and "both" when it got two. Without a binary there is no picker, and tests can be edited but not generated or run.
  • +
  • Left column: three boxes. +
      +
    • Test files, with New file. A file is flagged invalid when a test in it has errors, and regenerate N when N tests have an outdated script.
    • +
    • Test projects, with New test project.
    • +
    • Results: Reports lists the earlier runs with their date, edition, version, test files and result. Click a date to open the report.
    • +
  • +
  • Main area: the open test file with its tests, the open test, or the open test project. Each has an ✕ in the top right corner to close it.
  • +
  • Job box: while a script is generated or tests run, it shows the progress, the results as they come in and a link to the report. Stop ends the job. Its ✕ hides the box until the next job.
  • +
+ +

Gherkin

+

The manual tests are written in Gherkin, the language that Cucumber, behave and other behaviour-driven development tools use. Gherkin describes behaviour in plain words with a small set of keywords, so a test reads the same for a developer, a tester and Claude. Each test file in tests/ is a .feature file with one feature, and every scenario in it is one test.

+
Feature: Preferences
+
+  Background:
+    Given the application is started with no project loaded
+
+  @id:t28ce8afe @project:embedded @edition:opensource
+  Scenario Outline: Misra rule text file
+    Given Edit > Preferences is open on the Addons tab
+    When I select the rule text file {project:embedded}/<rulefile>
+    And I close the dialog with OK
+    And I open the project file {project:embedded}/embedded.cppcheck
+    And I wait until the analysis is done
+    Then the Misra error for the unused parameter has the rule text from the file
+    And there are no internalError results
+
+    Examples:
+      | rulefile              |
+      | rules.txt             |
+      | rules with spaces.txt |
+ +

Keywords

+
+ + + + + + + + + + + + + + + + +
KeywordMeaning here
Feature:The first line of the file. Its text is the title of the test file, shown in the editor and the report. Lines below it, before the first scenario, are a free description
Background:Steps that come before every scenario of the file, typically Given the application is started with no project loaded. At most one, before the scenarios
Scenario:One test. The text after the colon is the name of the test, unique within the file. Example: means the same
Scenario Outline:A test that is run once for every row of its Examples table. Scenario Template: means the same
Examples:The table of a scenario outline. The first row is the header with the column names; <column> in a step is replaced by the value of the row. See Examples (test matrix)
GivenThe starting point: the state that the application is in before the test does anything
WhenAn action of the user: a click, a menu entry, typing, opening a file
ThenThe expected result: something that can be seen in the GUI or in a file. Every scenario needs at least one Then
And, But, *Continue the step above with the same meaning, e.g. a second Then. A scenario can not start with And or But
"""A doc string: lines of text that belong to the step above, e.g. code to type into the scratch pad. It ends with another """
| a | b |A data table that belongs to the step above
@tagTags on the line above a scenario, see below
# textA comment. Comments are lost when the web interface saves the file
TODO:Not standard Gherkin: a description line under the scenario name that says why the test can't be automated yet
+

A scenario can switch between When and Then more than once, when a result has to be checked in the middle of the test:

+
  Scenario: Filter the results
+    Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu
+    And the analysis is done
+    When I type "arrayIndex" in the Filter field
+    Then only the arrayIndexOutOfBounds error in b.c is shown
+    When I clear the Filter field
+    Then all errors are shown again
+ +

Tags

+

Everything about a test that is not a step is a tag on the line above the scenario. Tags can't contain spaces.

+
+ + + + + + + +
TagMeaning
@id:t1a2b3c4dIdentifies the test, also when it is renamed. The script is stored by this id. Added automatically when it is missing; don't change it
@ticket:14893The ticket of the test, shown as #14893
@project:NAMEA test project that the test uses, one tag per project
@edition:opensourceAn edition that the test is for, one tag per edition. Without the tag the test is for all editions
@disabledThe test is not run
+

Other tags are kept but have no meaning for gui-test.

+ +

Writing good steps

+

Claude reads the steps as they are when it makes the script, and the Then steps become the checks. A good scenario is one that a new tester could follow without asking:

+
    +
  • Use the words of the GUI: the menu entries, button texts and dialog titles as they are shown, e.g. When I open File > Edit Project File.
  • +
  • Write Given steps as a state (Given the analysis is done), When steps as an action (When I click Recheck) and Then steps as something that can be seen (Then the nullPointer error in a.c is gone).
  • +
  • One thing per Then step. Then there are no results for a.c and And there are no results for b.c become two checks, and a failure points at the right one.
  • +
  • Be concrete about results: name the file, the error id and the line instead of "the results are correct".
  • +
  • Say how to wait: And I wait until the analysis is done.
  • +
  • Refer to files with {project:NAME}/path, and to the scratch directory with {work}.
  • +
  • Keep the steps that all tests of a file share in the Background.
  • +
+

Changing the steps, the Background or the Examples makes the script of the test outdated, because the script was made for the old words.

+ +

Differences from Cucumber

+
    +
  • There are no step definitions. In Cucumber every step is matched by a pattern to code that someone writes. Here Claude reads the scenario once and writes a script for it, and the script is replayed. Steps can therefore be free text; they don't have to repeat fixed phrases.
  • +
  • The script of a scenario is stored next to the feature file in FILE.scripts.json, by test id.
  • +
  • Rule:, tags on Examples, and more than one Feature per file are not supported.
  • +
  • Placeholders in braces are gui-test variables, not Gherkin: {project:NAME}, {work} and {edition}.
  • +
  • TODO: description lines are a gui-test convention.
  • +
+ +

Writing tests

+

A test is a Gherkin scenario, written as if for a person: Given steps say where the test starts, When steps what is done and Then steps the result to expect. Claude reads exactly these words when it makes the script, so be concrete.

+
Feature: Results list
+
+  Background:
+    Given the application is started with no project loaded
+
+  @id:t389a5f3a @project:basic-project
+  Scenario: Clear results
+    Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu
+    And the analysis is done
+    When I click Clear results
+    Then the results are cleared: the result tree is empty
+

The files can be edited in the web interface or in a text editor. The Gherkin chapter describes the format; the web interface shows the tags of a scenario (ticket, editions, test projects, enabled) as separate fields.

+

Tests live in test files (tests/*.feature), one file per area of the GUI. Click a file in the left column to open it, or New file to create one. An open file shows:

+
    +
  • Title: the Feature: line, shown in the report.
  • +
  • Background: the steps that are done before every test of the file, e.g. Given the application is started with no project loaded.
  • +
  • Tests: the list of tests. Click one to edit it, + New test to add one. A test is flagged invalid when it has errors and regenerate when its script is outdated.
  • +
  • Run tests: runs all tests in the file.
  • +
+

Nothing is written to disk until you press Save; a dot after the file name means there are unsaved changes. Errors, such as a test without a Then step, are shown under the field and must be fixed before you can save.

+

The test editor has these fields. The ↑ and ↓ buttons move the test in the list, and Delete removes it.

+
+ + + + + + + + + + + +
FieldWhat to write
NameUnique within the file. Shown in reports and the history, so a rename starts a new history line
TicketOptional, e.g. a Trac ticket number
enabledUntick to leave the test out of every run without deleting it
EditionsTick the editions the test runs in; by default all. The script is the same for all editions, {edition} is replaced by the edition's name
Scenario stepsOne Gherkin step per line, e.g. "When I open File > New Project File". Every Then step becomes at least one check in the script. Use <column> for the values of the Examples
TODOWhy a test can't be automated yet, e.g. "cannot be automated". Leave empty otherwise. In the file it is a line TODO: ... below the scenario name
Test projectsTick the projects whose files the test uses, see below
ScriptThe script of the test, with the buttons Generate script, Run test and, when it is outdated, Approve the script. See Scripts
ExamplesA Gherkin table; every row is a separate run and the test becomes a Scenario Outline
+ +

Examples (test matrix)

+

A Scenario Outline is run once for every row of its Examples table:

+
    When I select the platform <platform>
+    ...
+    Examples:
+      | platform | lang |
+      | native   | C    |
+      | unix32   | C++  |
+

That is 2 runs. A step like "When I select the platform <platform>" gets the value of each run, in the script it is {platform}. The runs are named after the test plus the values, e.g. Relative paths [platform=unix32, lang=C++], and each one gets its own line in the report. The editor shows how many runs the Examples give.

+ +

Test projects

+

A test project is a directory of files that tests use: source files, a .cppcheck project file, a .cfg file. They live in tests/projects/NAME and are edited under Test projects in the left column. Before every run the project is copied to a new empty directory, so a test always starts with the same files, even if an earlier test changed them. In a script the copy is {project:NAME}, or {project} when the test has only one project.

+

Changing a file in a project makes the scripts of the tests that use it outdated, because the script was made for the old files.

+ +

Scripts

+

A test runs only when it has an up-to-date script. Generate it with Claude once, check it, and from then on it is replayed without AI.

+ +

Generating a script

+

Open the test and press Generate script. gen.py starts the application with the test projects in place, and Claude does the test by hand: it looks at the accessibility tree, clicks and types, and checks the expected result (the Then steps). It then answers with a script. The script is replayed from scratch and saved in FILE.scripts.json only if that replay passes. When the replay fails, Claude is told why and tries again, 3 attempts in all. While a script is generated the editor is locked.

+
    +
  • A Scenario Outline is explored with the first row of its Examples. The script uses {column} where the values belong.
  • +
  • When the application does not do what the expected result says, Claude still writes the script that checks it and marks that one check "observed_fail": true. The script is saved, and the test fails until the bug is fixed. That is a finding, not a broken script.
  • +
  • When the test can't be done through the GUI, Claude answers CANNOT: <reason> and no script is saved.
  • +
+

Read the generated script before you trust it, especially its expect steps: they decide what the test proves.

+ +

The script format

+

A script is a JSON list of steps. Each step has do (an action) or expect (a check), and a label in the words of the test that is shown when it fails. Elements are found by name (part of the accessible name, case-insensitive) and role, and if needed path, nth and exact.

+
[
+  {"do": "click", "name": "Help", "role": "menu item", "label": "Open the Help menu"},
+  {"do": "click", "name": "Contents", "role": "menu item", "label": "Choose Help > Contents"},
+  {"expect": "visible", "name": "Cppcheck GUI help", "role": "dialog", "label": "A help window opens"}
+]
+
+ + + + + + + + + + + + + + + +
StepWhat it does
do: click, rightclick, doubleclick, focus, hoverAct on an element; "mouse": true clicks with the mouse
do: settextReplace the text of an edit field with value
do: type, keyKeyboard input to the focused element; keys uses xdotool names like ctrl+o, Return
do: waitWait for an element to appear, or with "gone": true to disappear
do: restartQuit and start the application again; settings are kept
do: sleep, write, copyPause, write a file in {work}, or copy a file in a test project
expect: visible, goneAn element is shown, or is not
expect: stateAn element is or is not checked, enabled, focused, selected, expanded...
expect: valueThe value or text of a field equals something
expect: text, ocrText is (not) on the screen; ocr reads pixels with tesseract, for context menus AT-SPI can't see
expect: fileA file contains, does not contain or matches a regex
expect: alive, exitedThe application is still running, or has quit by itself with status 0
expect: captureSearch regex in an element and save group 1 as a name; {name} in the later steps is replaced by it, for text that changes such as the version
+

Checks and actions wait for their element up to timeout seconds, 5 by default. The placeholders {work}, {home}, {project:NAME}, {column} (of the Examples) and {edition} are replaced before the run, captured values when the capture step has passed. The full description is under How to write a script below the script in the editor.

+ +

Outdated scripts

+

A script is made for the test's steps, the Background of the file, TODO, Examples and the files of its test projects. When any of those change, the script is OUTDATED: it is kept but skipped by every run, and the editor says so in red. You then have three choices:

+
    +
  1. Generate script again.
  2. +
  3. Approve the script when the change does not affect it, e.g. a typo fix in a step.
  4. +
  5. Edit the script by hand in the editor; it has to be valid JSON before you can save.
  6. +
+ +

Running tests

+

Every test starts a fresh application with an empty HOME and fresh copies of its test projects, so tests never depend on each other.

+ +

From the web interface

+

Pick the edition in the header first: opensource, premium or both. Then:

+
    +
  • Run test in an open test runs that test, all the rows of its Examples.
  • +
  • Run tests in an open test file runs every test in that file.
  • +
  • Run all runs every test in every file.
  • +
+

With "both", the run is done for one edition and then the other, and each edition gets its own report. The job box shows the test and step that is running and the results as they come. Stop ends the run at once: the test that was running is SKIP "aborted by user", and the report is written with the tests that are done. Only one job runs at a time.

+ +

From the command line

+
./run.py ~/cppcheck/build/bin/cppcheck-gui tests/application.feature tests/projects.feature --edition opensource
+
+ + + + + + + + + +
OptionMeaning
APPThe binary to test
FILE ...One or more test files
--edition opensource|premiumAPP is this edition; only the tests for it run. Without it all tests run and there is no history per edition
--test TEXTOnly tests whose name contains TEXT (case-insensitive)
--id IDOnly the test with this id, all the rows of its Examples
--src DIRGit checkout for the SHA in the report; default the directory of APP
--out DIRWhere the run directories go; default results
+

run.py prints one line per test and the path of the report, and exits with 1 when a test failed, so it can be used in a script or CI job. Scripts are generated the same way with ./gen.py APP FILE.feature; it takes --edition, --test, --id, --force (also tests that have a script), --model and --attempts.

+ +

What happens in a run

+
    +
  1. The tests to run are selected: enabled, for this edition, not filtered out. Tests without a script, or with an outdated one, are SKIP.
  2. +
  3. For each test, the test projects are copied and the application is started on a new virtual screen with an empty HOME.
  4. +
  5. The script is replayed step by step. After every step that acts on the GUI (click, type, key, settext, restart...) a screenshot is saved.
  6. +
  7. At the end, or at the first failing step, the step log, a final screenshot and the application log are saved, and the log is searched for a crash.
  8. +
  9. After the last test, results.json and report.html are written in the run directory.
  10. +
+ +

Reading the report

+

Each run writes one self-contained report.html; read it top-down: the verdict first, then what changed, then the details of each failure.

+
+ The top of a report: verdict, run details, number boxes, results per test file, the last runs and the status history +
The top of a report from three runs of two test files.
+
+
+ + + + + + + + + + +
PartWhat it tells you
HeaderFAILED or PASSED with the count, and the run details: date, edition, duration, git SHA ("+ uncommitted changes" when the checkout was dirty), branch, commit, application, host, test files
Number boxesPassed, failed (how many crashed the app), skipped, duration, and with history the change against the previous run
Results per test fileA bar per file, green/red/amber. Shows whether failures are in one part of the GUI. Only when the run has more than one file
The last runsPass, fail and skip counts for up to 15 runs of the same edition; the number on a column is its failures
Changed since the previous runNEW failures, tests that are fixed, and tests that are STILL FAILING
Status historyA row per test that did not pass in every run: "new failure", "failing since 10/22 12:00 (b8b27a)", "fixed since", "flaky: 4 changes", "never ran"
Failed and skipped testsA card per test: the reason, the step strip, the screenshots after the last 3 steps and the final screen with a red frame
All testsEvery test grouped by file, with its time, links to its files and its step screenshots
+ +

The step strip

+

Every test has a strip with a cell per script step: green passed, red failed, grey not run. A failure at step 2 of 14 usually means the test or the application broke early. A failure at the last step usually means one check is wrong, or the bug the check describes. Under the strip it says e.g. "failed at step 9 of 14", "not run" or "did not start".

+ +

Files in a run directory

+

A run directory is results/<date>-<time>-<edition>-<sha>/, e.g. 20261022-120317-opensource-b8b27a95/. The files of a test are named after the test (NAME below), with spaces and other special characters replaced by _. They are also linked from the report.

+
+ + + + + + + + +
FileContent
report.htmlThe report
results.jsonThe run details and every result. The history is read from these files
NAME.txtThe step log: each step, ok or FAIL, its time and its screenshot
NAME.pngThe screen at the end of the test, or when it failed
NAME.stepNN.pngThe screen after step NN, for steps that act on the GUI
NAME.app.logWhat the application printed
+

The history compares runs of the same edition in the same results directory. Tests are matched by name.

+ +

Troubleshooting

+

Start with the reason in the report and the final screenshot: together they usually say whether the application, the script or the test is wrong.

+
+ + + + + + + + + + + + +
What you seeWhat it means and what to do
SKIP "no script"The test has no script yet. Generate one, or write it by hand
SKIP "OUTDATED SCRIPT"The test or one of its test projects changed after the script was made. Generate again, or approve the script if the change doesn't matter to it
FAIL "timeout waiting for element to appear"An element with that name and role wasn't found within the timeout. The reason lists the most similar visible elements and the open windows: a renamed button shows up there. Fix the name in the script, or regenerate
FAIL with observed_fail=True in the reasonClaude saw the application not do what the expected result says when it made the script. It is a known bug, and the test fails until the bug is fixed
FAIL with CRASHThe application was not running at the end of the test, or its log has a fatal message (SIGSEGV, SIGABRT, an assertion, AddressSanitizer, QFATAL...). A crash fails the test even if every step passed. Read NAME.app.log. A test that quits the application with status 0 is not a crash
FAIL "could not start"The session or the application did not start. Check that the packages under Getting started are installed, and that the binary runs
"flaky" in the status historyThe test changes between PASS and FAIL. Usually timing: give the slow step a longer timeout, or add a wait step before it
A context menu can't be foundSome menus are not in the accessibility tree. Check them with an ocr step and choose with key Down and Return
"path ... is outside the test directories"write, copy and file steps may only use {work}, {home} and the test project copies
Generate script or Run test is greyed outweb.py has no binary for the edition picked in the header, or the test is not for that edition. Run test also needs an up-to-date script
+ +

Reference

+

The commands, with all their options. web.py, run.py, gen.py and guitest.py also print their help with --help.

+
web.py [--opensource APP] [--premium APP] [--src DIR] [--dir tests] [--out results] [--port 8080]
+run.py APP FILE.feature... [--edition opensource|premium] [--test TEXT] [--id ID] [--src DIR] [--out results]
+gen.py APP FILE.feature [--edition opensource|premium] [--test TEXT] [--id ID] [--force] [--model M] [--attempts 3]
+testfile.py convert IN.md|IN.json OUT.feature
+ +

guitest.py

+

guitest.py is what Claude uses to drive the GUI, and you can use it by hand to look at the GUI the way a script sees it. The session lives in $GUITEST_STATE (default /tmp/guitest-<uid>/state.json).

+
guitest.py start ~/cppcheck/build/bin/cppcheck-gui
+guitest.py tree --showing --depth 3
+guitest.py click --name Help --role "menu item"
+guitest.py screenshot /tmp/screen.png
+guitest.py stop
+
+ + + + + + + + + + + + +
CommandWhat it does
start APP [ARGS]Start Xvfb, D-Bus, AT-SPI and the application. --home DIR (default an empty directory), --size 1280x900
stop, restartStop everything; quit and start the application again with its settings kept
alive, logExit 0 if the application runs; print what it wrote to stdout and stderr
windows, textsThe top level windows and dialogs; every visible text
treeThe accessibility tree. --showing only visible elements, --depth N, --path P one subtree
click, rightclick, doubleclick, focus, hoverAct on an element found with --name, --role, --path, --nth, --exact. --mouse for a real mouse click
settext VALUE, type VALUE, key KEYSSet a field's text; type into the focused element; press keys (xdotool names)
waitWait for an element, --timeout 10, --gone to wait until it disappears
info, suggestRole, name, text, value and states of one element; the visible elements most like --name/--role
ocr, screenshot FILEText on the screen read by tesseract; a PNG of the screen
+
+
+ + diff --git a/gui/manualtest/docs/report.png b/gui/manualtest/docs/report.png new file mode 100644 index 0000000000000000000000000000000000000000..2a24756da06c1b9514640eb22bb401d5a3737a33 GIT binary patch literal 149022 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 RD13Pgs_+6*CigPnKLE7l_v`=w literal 0 HcmV?d00001 diff --git a/gui/manualtest/gen.py b/gui/manualtest/gen.py new file mode 100755 index 00000000000..0a3360065dd --- /dev/null +++ b/gui/manualtest/gen.py @@ -0,0 +1,234 @@ +#!/usr/bin/env python3 +"""Let Claude write the scripts of the tests. The scripts are replayed by run.py without AI. + + gen.py APP FILE.feature [--edition opensource|premium] [--test SUBSTRING] [--force] [--model M] + +For every test without a script (or every test with --force) Claude gets the scenario, drives the +GUI once with the guitest.py commands and answers with a script, see testfile.SCRIPT_DOC. +The script is run again from scratch and is saved in FILE.scripts.json only if that replay passes. +A Scenario Outline is explored with the first row of its Examples, the script uses {column} where +the values of the row belong. With --edition APP is that edition, tests that are not for it are +left out; the script is used for all the editions of the test. +""" + +import argparse +import json +import os +import re +import signal +import subprocess +import sys +import tempfile + +import runner +import testfile + +HERE = os.path.dirname(os.path.abspath(__file__)) +GUITEST = os.path.join(HERE, 'guitest.py') + +PROMPT = """You are writing an automated GUI test script for a Qt application that has been started for you. +First do the test by hand, driving the application only with this command line tool (each call is separate, +the session is already running): + + python3 {guitest} + +{help} + +Tips: +- Start with `tree --showing --depth 3`, `windows` and `texts` to see what is on screen. +- Use `info --name X` to see the roles and states of an element, e.g. the [checked] state. +- Menu items: click the menu (e.g. --name File --role "menu item"), then click the entry. +- Keyboard input goes to the focused element: `focus` first, then `type` / `key`. +- The files of the test are in the test projects, they are already in place, use them as they are:{projects} + Do not make copies of them. In the script write {{project:NAME}} instead of the directory, it is another + directory every run. Anything else that you need can be created in {work} (use Write), do not touch other places. +- A menu that is on screen but not in `tree`/`texts` (e.g. a context menu) can be read with `ocr`; check it in the + script with {{"expect": "ocr", "contains": "..."}} and use the keyboard (`key Down`, `key Return`) to choose in it. +- Never read or modify the application source code. + +Test name: {name} + +The test is written in Gherkin: the Background and the Given steps are the starting point, the When steps are +what you do and the Then steps are the EXPECTED result. + +{body} + +When you have done the test and checked the EXPECTED result (the Then steps), answer with a script that does the +same without you. The script is replayed by a program, so: +- use the exact roles and names that you saw. Give a name and a role. Use "path" only when nothing else tells + the element apart, paths change when the dialogs change (a file dialog's name field is found by its label) +- a name matches any element that contains it, so always give the role too: a toolbar button + "Preferences" and the dialog "Preferences" have the same name, the dialog is role "dialog" +- give every step a "label" that says what it is for, in the words of the test +- end with "expect" steps that check the EXPECTED result, at least one for each Then step +- the files of the test are the test projects, refer to them with {{project:NAME}} paths; files that + you made yourself are created by "write" steps (in {{work}}), not by you +- the application is started fresh before the script, with an empty HOME +- {matrixnote} +- {editionnote} + +{scriptdoc} + +{previous}Check the EXPECTED result honestly. If the application does not do what EXPECTED says that is a finding, not +a mistake in the script: still write the script that checks EXPECTED (it will fail, that is the point) and put +the line `OBSERVED: FAIL - ` before the JSON block and add "observed_fail": true to +the one check that fails. Otherwise put `OBSERVED: PASS`. + +Finish with the script as one JSON list in a ```json code block and nothing after it. +If the test cannot be done through the GUI answer with the single line CANNOT: . +""" + + +PREVIOUS = """An earlier attempt gave this script: +{script} + +When it was replayed from scratch by the program it failed: +{error} + +Find out what is wrong (look at the GUI again if needed) and answer with a corrected script. + +""" + + +def start_session(app, root, projects): + work = tempfile.mkdtemp(prefix='guitest-work-') + state = os.path.join(work, 'state.json') + env = dict(os.environ, GUITEST_STATE=state) + sub = lambda *a, **kw: subprocess.run([sys.executable, GUITEST, *a], env=env, text=True, **kw) + variables = testfile.materialize(root, projects, work) + r = sub('start', app, capture_output=True) + if r.returncode: + sys.exit('error: could not start: ' + (r.stdout + r.stderr).strip()) + with open(state) as f: + home = json.load(f)['env']['HOME'] + return work, home, env, sub, variables + + +def explore(app, root, test, combo, edition, model, background, previous=''): + """Claude does the test by hand and returns (script, error); with a script the error is (OBSERVED, reason).""" + work, home, env, sub, variables = start_session(app, root, test.get('projects', [])) + try: + note = ('this is a Scenario Outline, you explore it with the Examples row %s. Write {%s} in the script wherever ' + 'that value is used, the script is run once for every row of the Examples' % ( + ', '.join('%s=%s' % kv for kv in combo.items()), '}, {'.join(combo)) + ) if combo else 'there are no Examples, write the values in the script as they are' + others = [e for e in testfile.editions(test) if e != edition] + if not edition: + editionnote = 'there is one edition of the application' + elif others: + editionnote = ('the application is the %s edition. The same script is also run with the %s edition, ' + 'write {edition} where the name of the edition is shown' % (edition, ' and '.join(others))) + else: + editionnote = 'the script is only run with the %s edition' % edition + projects = ''.join('\n {project:%s} = %s, files: %s' % (n, variables['project:' + n], + ', '.join(sorted(testfile.project_files(root, n)))) + for n in test.get('projects', [])) or ' none' + prompt = PROMPT.format(guitest=GUITEST, help=sub('--help', capture_output=True).stdout, work=work, + name=test['name'], body=testfile.body(test, combo, edition, background), matrixnote=note, + editionnote=editionnote, + scriptdoc=testfile.SCRIPT_DOC, previous=previous, projects=projects) + cmd = ['claude', '-p', '--allowedTools', 'Bash(python3 %s:*)' % GUITEST, 'Read', 'Write', '--add-dir', work] + if model: + cmd += ['--model', model] + p = subprocess.run(cmd, input=prompt, env=env, text=True, capture_output=True, cwd=work) + finally: + sub('stop', capture_output=True) + m = re.findall(r'^CANNOT:\s*(.*)$', p.stdout, re.M) + if m: + return None, 'Claude: cannot be tested through the GUI: ' + m[-1] + m = re.findall(r'```json\s*(.*?)```', p.stdout, re.S) + if not m: + return None, 'no script in the answer of Claude: ' + (p.stdout.strip() or p.stderr.strip())[:300] + try: + script = json.loads(m[-1]) + except ValueError as e: + return None, 'the script is not valid JSON: %s' % e + errors = testfile.validate_script(script) + observed = re.findall(r'^OBSERVED:\s*(PASS|FAIL)\s*-?\s*(.*)$', p.stdout, re.M) + return (None, '; '.join(errors)) if errors else (script, observed[-1] if observed else ('PASS', '')) + + +def replay(app, root, test, script): + work, home, env, sub, variables = start_session(app, root, test.get('projects', [])) + try: + ok, msg, log = runner.run_script(sub, script, work, home, variables) + finally: + sub('stop', capture_output=True) + return ok, msg + + +def store(path, test_id, script, made_for): + """Put the script in the file as it is now, the file may have been saved by the web interface meanwhile.""" + doc = testfile.ensure_ids(testfile.load(path)) + for t in doc['tests']: + if t['id'] == test_id: + t['script'], t['script_for'] = script, made_for + testfile.save(path, doc) + + +def main(): + ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + ap.add_argument('app') + ap.add_argument('file') + ap.add_argument('--edition', choices=testfile.EDITIONS, help='the edition that APP is, only the tests for it') + ap.add_argument('--test', help='only tests whose name contains this') + ap.add_argument('--id', help='only the test with this id') + ap.add_argument('--force', action='store_true', help='also tests that have a script') + ap.add_argument('--model') + ap.add_argument('--attempts', type=int, default=3, help='tries per test, a failed replay is told to Claude') + args = ap.parse_args() + signal.signal(signal.SIGINT, signal.default_int_handler) # also when started in the background + if not args.file.endswith(testfile.EXT): + sys.exit('error: FILE must be a %s test file, convert markdown or JSON with testfile.py convert' % testfile.EXT) + app = os.path.abspath(args.app) + doc = testfile.ensure_ids(testfile.load(args.file)) + root = os.path.dirname(os.path.abspath(args.file)) + errors = testfile.validate(doc, root) + if errors: + sys.exit('error: ' + '; '.join(errors)) + + failed = 0 + for t in doc['tests']: + if args.test and args.test.lower() not in t['name'].lower() or args.id and t['id'] != args.id: + continue + if (t.get('script') and not args.force) or not t.get('enabled', True): + continue + if args.edition and args.edition not in testfile.editions(t): + print('%s: not a test for the %s edition' % (t['name'], args.edition), flush=True) + continue + combo = testfile.combinations(t)[0] + values = dict(combo, edition=args.edition) if args.edition else combo + made_for = testfile.definition_hash(t, root, doc.get('background')) # the test may be edited while Claude works + print('%s: exploring...' % t['name'], flush=True) + previous, saved = '', False + for attempt in range(1, args.attempts + 1): + script, err = explore(app, root, t, combo, args.edition, args.model, doc.get('background'), previous) + if script is not None: + # the replay uses the first combination, as the exploration did + observed, why = err + ok, err = replay(app, root, t, testfile.subst_deep(script, values)) + # a test that fails on the check that Claude saw fail by hand is a finding: the script is right + m = re.match(r'step (\d+)/', err) + finding = (not ok and observed == 'FAIL' and m and script[int(m.group(1)) - 1].get('observed_fail')) + if ok or finding: + store(args.file, t['id'], script, made_for) + print('%s: saved a script with %d steps (attempt %d)%s' % ( + t['name'], len(script), attempt, + '. It FAILS on a check, as Claude saw: ' + why if finding else ''), flush=True) + saved = True + break + err = 'the replay of the script failed:\n' + err + previous = PREVIOUS.format(script=json.dumps(script, indent=1), error=err) + print('%s: attempt %d failed. %s' % (t['name'], attempt, err), flush=True) + if re.search(r'usage limit|rate limit|limit reached|out of credits', str(err), re.I): + sys.exit('error: Claude refuses to answer (limit), stopping. Run gen.py again later.') + if err.startswith('Claude: cannot'): + break + if not saved: + failed += 1 + print('%s: no script saved' % t['name'], flush=True) + sys.exit(1 if failed else 0) + + +if __name__ == '__main__': + main() diff --git a/gui/manualtest/guitest.py b/gui/manualtest/guitest.py new file mode 100755 index 00000000000..0b28cd7031d --- /dev/null +++ b/gui/manualtest/guitest.py @@ -0,0 +1,715 @@ +#!/usr/bin/env python3 +"""GUI test helper for Qt applications, driven through AT-SPI. + +The application runs in its own Xvfb display with its own D-Bus and +accessibility bus, so the real desktop is never touched. Each subcommand is a +separate process; the session state (environment, pids) lives in a JSON file. + + guitest.py start APP [ARGS...] start the session and the application + guitest.py tree show the accessibility tree + guitest.py click --name Recheck click an element + guitest.py stop kill everything + +State file: $GUITEST_STATE, default /tmp/guitest-/state.json +""" + +import argparse +import contextlib +import io +import glob +import json +import os +import re +import shutil +import signal +import subprocess +import struct +import sys +import tempfile +import threading +import time +import warnings + +warnings.filterwarnings("ignore") + +STATE = os.environ.get('GUITEST_STATE', '/tmp/guitest-%d/state.json' % os.getuid()) + + +# ---------------------------------------------------------------- session + +def load_state(): + try: + with open(STATE) as f: + return json.load(f) + except FileNotFoundError: + sys.exit('error: no session, run "guitest.py start APP" first') + + +# the shell tells how the application ended in app.log: 139 is SIGSEGV, 134 SIGABRT, 143 killed by us +WRAPPER = '"$@" & echo $! > "$0"; wait $!; echo "application exited with status $?" >&2' + + +def launch(cmd, env, tmp, log): + """Start the application. Returns the shell that waits for it and the pid of the application.""" + pidfile = os.path.join(tmp, 'app.pid') + if os.path.exists(pidfile): + os.remove(pidfile) + p = subprocess.Popen(['sh', '-c', WRAPPER, pidfile] + cmd, env=env, start_new_session=True, + stdin=subprocess.DEVNULL, stdout=log, stderr=subprocess.STDOUT) + for _ in range(100): + try: + with open(pidfile) as f: + return p, int(f.read()) + except (OSError, ValueError): + time.sleep(0.05) + sys.exit('error: the application did not start') + + +def exit_info(state): + """' (exited with status 139, SIGSEGV)' when the log says how the application ended, else ''.""" + try: + with open(os.path.join(state['tmp'], 'app.log'), errors='replace') as f: + m = re.findall(r'application exited with status (\d+)', f.read()) + except OSError: + return '' + if not m: + return '' + code = int(m[-1]) + sig = ', ' + signal.Signals(code - 128).name if 128 < code < 160 else '' + return ' (exited with status %d%s)' % (code, sig) + + +def start(args): + if os.path.exists(STATE): + sys.exit('error: session already running (%s), run stop first' % STATE) + app = os.path.abspath(args.app) + if not os.access(app, os.X_OK): + sys.exit('error: not executable: ' + app) + for tool in ('Xvfb', 'xdotool', 'dbus-daemon', '/usr/libexec/at-spi-bus-launcher'): + if not shutil.which(tool) and not os.path.exists(tool): + sys.exit('error: missing ' + tool) + + tmp = tempfile.mkdtemp(prefix='guitest-') + runtime = os.path.join(tmp, 'run') + home = args.home or os.path.join(tmp, 'home') + os.makedirs(runtime, mode=0o700) + os.makedirs(home, exist_ok=True) + # Cppcheck Premium needs its license file in HOME + lic = os.path.join('.cppcheckpremium', 'cppcheck-premium.lic') + src_lic = os.path.join(os.path.expanduser('~'), lic) + dst_lic = os.path.join(home, lic) + if os.path.isfile(src_lic) and os.path.realpath(src_lic) != os.path.realpath(dst_lic): + os.makedirs(os.path.dirname(dst_lic), exist_ok=True) + shutil.copy2(src_lic, dst_lic) + pids = [] + + def spawn(cmd, env, **kw): + kw.setdefault('stdout', subprocess.DEVNULL) + kw.setdefault('stderr', subprocess.DEVNULL) + p = subprocess.Popen(cmd, env=env, start_new_session=True, stdin=subprocess.DEVNULL, **kw) + pids.append(p.pid) + return p + + env = dict(os.environ) + env.update(XDG_RUNTIME_DIR=runtime, HOME=home) + for k in ('XDG_CONFIG_HOME', 'XDG_DATA_HOME', 'XDG_CACHE_HOME', 'XDG_CONFIG_DIRS'): + env.pop(k, None) # QSettings must not find the real preferences + env.pop('WAYLAND_DISPLAY', None) + env.pop('DBUS_SESSION_BUS_ADDRESS', None) + + # session bus + out = subprocess.run(['dbus-daemon', '--session', '--fork', '--print-address', '--print-pid'], + env=env, capture_output=True, text=True, check=True).stdout.split() + env['DBUS_SESSION_BUS_ADDRESS'] = out[0] + pids.append(int(out[1])) + + # X server + r, w = os.pipe() + spawn(['Xvfb', '-displayfd', str(w), '-screen', '0', args.size + 'x24', '-fbdir', tmp], + env, pass_fds=(w,)) + os.close(w) + env['DISPLAY'] = ':' + os.read(r, 16).decode().strip() + os.close(r) + + # accessibility bus + spawn(['/usr/libexec/at-spi-bus-launcher', '--launch-immediately'], env) + for _ in range(100): + if glob.glob(os.path.join(runtime, 'at-spi', 'bus_*')): + break + time.sleep(0.1) + else: + kill(pids, tmp) + sys.exit('error: accessibility bus did not start') + + env.update(QT_QPA_PLATFORM='xcb', QT_ACCESSIBILITY='1', + QT_LINUX_ACCESSIBILITY_ALWAYS_ON='1', QT_NO_XDG_DESKTOP_PORTAL='1', + QT_QPA_PLATFORMTHEME='generic', # not the KDE file dialog, its KIO jobs crash in this session + LANG='C', LC_ALL='C') + log = open(os.path.join(tmp, 'app.log'), 'w') + appproc, app_pid = launch([app] + args.args, env, tmp, log) + pids.append(appproc.pid) + + state = dict(env={k: env[k] for k in ('XDG_RUNTIME_DIR', 'HOME', 'DBUS_SESSION_BUS_ADDRESS', 'DISPLAY', + 'QT_QPA_PLATFORM', 'QT_ACCESSIBILITY', + 'QT_LINUX_ACCESSIBILITY_ALWAYS_ON', 'QT_NO_XDG_DESKTOP_PORTAL', 'QT_QPA_PLATFORMTHEME', + 'LANG', 'LC_ALL')}, + pids=pids, app_pid=app_pid, app_pgid=appproc.pid, app_cmd=[app] + args.args, tmp=tmp) + os.makedirs(os.path.dirname(STATE), exist_ok=True) + with open(STATE, 'w') as f: + json.dump(state, f) + + # wait for the application to show up on the accessibility bus + os.environ.update(state['env']) + for _ in range(100): + if appproc.poll() is not None: + print(open(os.path.join(tmp, 'app.log')).read()) + kill(pids, tmp) + os.remove(STATE) + sys.exit('error: application exited with code %s' % appproc.returncode) + if find_app(state) is not None: + print('started, display %s, app log %s/app.log' % (env['DISPLAY'], tmp)) + return + time.sleep(0.2) + sys.exit('error: application did not appear on the accessibility bus (see %s/app.log)' % tmp) + + +def restart(args): + """Quit the application and start it again, same HOME so settings are kept.""" + state = load_state() + try: + os.killpg(state['app_pgid'], signal.SIGTERM) + except ProcessLookupError: + pass + time.sleep(1) + env = dict(os.environ) + env.update(state['env']) + log = open(os.path.join(state['tmp'], 'app.log'), 'a') + p, state['app_pid'] = launch(state['app_cmd'], env, state['tmp'], log) + state['app_pgid'] = p.pid + state['pids'].append(p.pid) + with open(STATE, 'w') as f: + json.dump(state, f) + for _ in range(100): + if find_app(state) is not None: + print('restarted') + return + time.sleep(0.2) + sys.exit('error: application did not come back') + + +def kill(pids, tmp): + for pid in reversed(pids): + try: + os.killpg(pid, signal.SIGTERM) + except (ProcessLookupError, PermissionError): + try: + os.kill(pid, signal.SIGTERM) + except (ProcessLookupError, PermissionError): + pass + time.sleep(0.3) + shutil.rmtree(tmp, ignore_errors=True) + + +def stop(args): + try: + state = load_state() + except SystemExit: + return + kill(state['pids'], state['tmp']) + os.remove(STATE) + print('stopped') + + +# ---------------------------------------------------------------- AT-SPI + +_atspi = None + + +def atspi(): + global _atspi + if _atspi is None: + os.environ.update(load_state()['env']) + import gi + gi.require_version('Atspi', '2.0') + from gi.repository import Atspi + _atspi = Atspi + return _atspi + + +def find_app(state): + A = atspi() + desktop = A.get_desktop(0) + for i in range(desktop.get_child_count()): + try: + app = desktop.get_child_at_index(i) + if app is not None and app.get_process_id() == state['app_pid']: + return app + except Exception: + pass + return None + + +def app_running(state): + """The process is there (a zombie is a crashed application nobody has collected).""" + try: + with open('/proc/%d/stat' % state['app_pid']) as f: + return f.read().rsplit(')', 1)[1].split()[0] != 'Z' + except OSError: + return False + + +def get_app(): + state = load_state() + for _ in range(25): # the application does not answer on the accessibility bus while a modal dialog opens + app = find_app(state) + if app is not None: + return app + if not app_running(state): + break + time.sleep(0.2) + if app_running(state): + sys.exit('error: the application is running but does not answer on the accessibility bus (busy or hung?)') + sys.exit('error: the application is not running%s. log: %s/app.log' % (exit_info(state) or ' (crashed?)', state['tmp'])) + + +def children(node): + try: + for i in range(node.get_child_count()): + c = node.get_child_at_index(i) + if c is not None: + yield i, c + except Exception: + return + + +def states(node): + A = atspi() + st = node.get_state_set() + names = [] + for label, s in (('showing', A.StateType.SHOWING), ('enabled', A.StateType.ENABLED), + ('focused', A.StateType.FOCUSED), ('checked', A.StateType.CHECKED), + ('selected', A.StateType.SELECTED), ('expanded', A.StateType.EXPANDED), + ('editable', A.StateType.EDITABLE), ('modal', A.StateType.MODAL)): + if st.contains(s): + names.append(label) + return names + + +def walk(node, path=(), depth=0): + yield path, node, depth + for i, c in children(node): + yield from walk(c, path + (i,), depth + 1) + + +def node_text(node): + # the interface functions take the accessible as first argument, node.get_text_iface() does not work here + A = atspi() + try: + if 'Text' in A.Accessible.get_interfaces(node): + return A.Text.get_text(node, 0, min(A.Text.get_character_count(node), 2000)) + except Exception: + pass + return None + + +def node_value(node): + A = atspi() + try: + if 'Value' in A.Accessible.get_interfaces(node): + return A.Value.get_current_value(node) + except Exception: + pass + return None + + +def extents(node): + A = atspi() + try: + e = node.get_component_iface().get_extents(A.CoordType.SCREEN) + return e.x, e.y, e.width, e.height + except Exception: + return None + + +def describe(path, node, with_geom=True): + name = node.get_name() or '' + s = '%s %s %r' % ('.'.join(map(str, path)) or '-', node.get_role_name(), name) + text = node_text(node) + if text and text != name: + s += ' text=%r' % (text if len(text) < 200 else text[:200] + '...') + val = node_value(node) + if val is not None: + s += ' value=%s' % val + st = states(node) + if st: + s += ' [%s]' % ','.join(st) + g = extents(node) + if with_geom and g and g[2] > 0: + s += ' @%d,%d %dx%d' % g + return s + + +def cmd_tree(args): + app = get_app() + root, rootpath = app, () + if args.path: + rootpath = tuple(int(x) for x in args.path.split('.')) + for i in rootpath: + root = root.get_child_at_index(i) + for path, node, depth in walk(root, rootpath): + d = len(path) - len(rootpath) + if d > args.depth: + continue + if args.showing and 'showing' not in states(node) and d > 0: + continue + print(' ' * d + describe(path, node)) + + +def cmd_windows(args): + app = get_app() + for i, c in children(app): + print(describe((i,), c)) + + +def cmd_texts(args): + """All visible text on screen, one line per element, for checking EXPECTED.""" + app = get_app() + for path, node, depth in walk(app): + if 'showing' not in states(node): + continue + role = node.get_role_name() + name = node.get_name() or '' + text = node_text(node) + if role in ('label', 'push button', 'check box', 'radio button', 'menu item', 'text', 'entry', + 'page tab', 'combo box', 'table cell', 'tree item', 'list item', 'status bar', + 'title bar', 'spin button', 'frame', 'dialog', 'alert') or text: + line = '%s %s %r' % ('.'.join(map(str, path)), role, name) + if text and text != name: + line += ' text=%r' % text + if 'checked' in states(node): + line += ' [checked]' + print(line) + + +# ---------------------------------------------------------------- finding + +def select(args, need_showing=True): + app = get_app() + if args.path: + node = app + for i in (int(x) for x in args.path.split('.')): + node = node.get_child_at_index(i) + if node is None: + sys.exit('error: no such path') + return node + matches = [] + for path, node, depth in walk(app): + role = node.get_role_name() + if args.role and args.role.lower() != role.lower(): + continue + name = node.get_name() or '' + text = '' # found by name only: the text of a panel would match the message of an error + if args.name is not None: + want = args.name.lower() + if args.exact: + if name.lower() != want and text.lower() != want: + continue + elif want not in name.lower() and want not in text.lower(): + continue + elif not args.role: + sys.exit('error: give --name, --role or --path') + if need_showing and 'showing' not in states(node): + continue + matches.append((path, node)) + if not matches: + sys.exit('error: no matching visible element (name=%r role=%r); try "tree --showing"' % (args.name, args.role)) + if args.nth is None and len(matches) > 1: + lines = '\n'.join(' ' + describe(p, n) for p, n in matches[:15]) + sys.exit('error: %d matches, narrow with --role/--exact or pick with --nth N (0-based):\n%s' % (len(matches), lines)) + nth = args.nth or 0 + if nth >= len(matches): + sys.exit('error: no matching visible element: only %d match(es) for name=%r role=%r, nth=%d is too high' + % (len(matches), args.name, args.role, nth)) + return matches[nth][1] + + +def xdo(*a): + env = dict(os.environ) + env.update(load_state()['env']) + subprocess.run(['xdotool'] + [str(x) for x in a], env=env, check=True) + + +def center(node): + g = extents(node) + if not g or g[2] <= 0: + sys.exit('error: element has no geometry') + return g[0] + g[2] // 2, g[1] + g[3] // 2 + + +def mouse(node, button=1, count=1): + x, y = center(node) + xdo('mousemove', x, y) + time.sleep(0.05) + xdo('click', '--repeat', count, '--delay', 80, button) + + +def do_action(node): + A = atspi() + try: + act = node.get_action_iface() + if act is None: + return False + for i in range(act.get_n_actions()): + if act.get_action_name(i).lower() in ('click', 'press', 'toggle', 'activate', 'check', 'uncheck'): + return act.do_action(i) + except Exception: + pass + return False + + +def cmd_click(args): + node = select(args) + desc = describe((), node, False) + if args.mouse: + mouse(node) + else: + # the action of a button that opens a modal dialog does not return until the dialog is closed + done = [] + t = threading.Thread(target=lambda: done.append(do_action(node)), daemon=True) + t.start() + t.join(args.settle + 1) + if done == [False]: + mouse(node) + elif not done: + time.sleep(args.settle) + print('clicked ' + desc, flush=True) + os._exit(0) + time.sleep(args.settle) + print('clicked ' + desc) + + +def cmd_rightclick(args): + node = select(args) + mouse(node, 3) + time.sleep(args.settle) + print('right-clicked ' + describe((), node, False)) + + +def cmd_doubleclick(args): + node = select(args) + mouse(node, 1, 2) + time.sleep(args.settle) + print('double-clicked ' + describe((), node, False)) + + +def cmd_focus(args): + node = select(args) + ok = node.get_component_iface().grab_focus() + if not ok: + mouse(node) + print('focused ' + describe((), node, False)) + + +def cmd_settext(args): + node = select(args) + et = node.get_editable_text_iface() + if et is None: + sys.exit('error: element is not editable text') + et.set_text_contents(args.value) + time.sleep(args.settle) + print('set text of ' + describe((), node, False)) + + +def cmd_type(args): + xdo('type', '--delay', 20, '--', args.value) + time.sleep(args.settle) + + +def cmd_key(args): + xdo('key', *args.keys) + time.sleep(args.settle) + + +def cmd_hover(args): + x, y = center(select(args)) + xdo('mousemove', x, y) + + +def cmd_wait(args): + deadline = time.time() + args.timeout + while True: + try: + node = select(args) + found = describe((), node, False) + except SystemExit as e: + if 'matches' in str(e): # ambiguous means it exists + found = str(e).split('\n')[0] + else: + found = None + if args.gone != (found is not None): + print('gone' if args.gone else 'found ' + found) + return + if time.time() > deadline: + sys.exit('error: timeout waiting for element %s' % ('to disappear' if args.gone else 'to appear')) + time.sleep(0.3) + + +def cmd_info(args): + """One line about the element: role, name, text, value and [states].""" + print(describe((), select(args), False)) + + +def cmd_suggest(args): + """Visible named elements, the ones most like --name first (for error messages).""" + import difflib + want = (args.name or '').lower() + items = [] + for path, node, depth in walk(get_app()): + name = (node.get_name() or '').strip() + if name and 'showing' in states(node): + items.append((node.get_role_name(), name)) + items.sort(key=lambda it: ((it[0].lower() != (args.role or '').lower()) if args.role else 0, + -difflib.SequenceMatcher(None, want, it[1].lower()).ratio())) + seen = [] + for it in items: + if it not in seen: + seen.append(it) + print('%s %r' % it) + if len(seen) >= args.limit: + break + + +def cmd_screenshot(args): + from PIL import Image + state = load_state() + src = os.path.join(state['tmp'], 'Xvfb_screen0') + data = open(src, 'rb').read() + (hdr, _ver, _fmt, _depth, w, h, _xoff, _bo, _bu, _bbo, _bp, bpp, bpl, _vc, + rm, gm, bm, _bpr, _ncm, ncolors) = struct.unpack('>20I', data[:80]) + off = hdr + ncolors * 12 + img = Image.frombuffer('RGB', (w, h), data[off:off + bpl * h], 'raw', 'BGRX', bpl, 1) + img.save(args.file) + print('saved %s (%dx%d)' % (args.file, w, h)) + + +def cmd_ocr(args): + """Text on the screen read by tesseract, also what AT-SPI does not show (some context menus).""" + import tempfile + png = os.path.join(tempfile.mkdtemp(prefix='guitest-ocr-'), 'screen.png') + args.file = png + with contextlib.redirect_stdout(io.StringIO()): + cmd_screenshot(args) + from PIL import Image + img = Image.open(png) + img = img.resize((img.width * 2, img.height * 2), Image.LANCZOS) + img.save(png) + p = subprocess.run(['tesseract', png, '-', '--psm', '11'], capture_output=True, text=True) + if p.returncode: + sys.exit('error: tesseract failed: ' + p.stderr.strip()) + shutil.rmtree(os.path.dirname(png), ignore_errors=True) + print(p.stdout) + + +def cmd_log(args): + print(open(os.path.join(load_state()['tmp'], 'app.log')).read()) + + +def cmd_alive(args): + sys.exit(0 if app_running(load_state()) else 'application is not running') + + +# ---------------------------------------------------------------- cli + +def selector(p): + p.add_argument('--name', help='substring of accessible name or text (case-insensitive)') + p.add_argument('--role', help='role, e.g. "push button", "menu item", "tree item", "check box"') + p.add_argument('--path', help='path from "tree", e.g. 0.1.2') + p.add_argument('--nth', type=int, help='pick the Nth match (0-based)') + p.add_argument('--exact', action='store_true', help='--name must match exactly') + + +def main(): + ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + sub = ap.add_subparsers(dest='cmd', required=True) + + p = sub.add_parser('start', help='start session and application') + p.add_argument('app') + p.add_argument('args', nargs='*') + p.add_argument('--home', help='HOME for the application (default: empty temporary dir)') + p.add_argument('--size', default='1280x900') + p.set_defaults(f=start) + + sub.add_parser('stop', help='stop session').set_defaults(f=stop) + sub.add_parser('restart', help='quit and start the application again (settings are kept)').set_defaults(f=restart) + sub.add_parser('alive', help='exit 0 if the application is running').set_defaults(f=cmd_alive) + sub.add_parser('log', help='application stdout/stderr').set_defaults(f=cmd_log) + sub.add_parser('windows', help='top level windows and dialogs').set_defaults(f=cmd_windows) + sub.add_parser('texts', help='all visible texts').set_defaults(f=cmd_texts) + + p = sub.add_parser('tree', help='accessibility tree') + p.add_argument('--depth', type=int, default=99) + p.add_argument('--path', help='only this subtree') + p.add_argument('--showing', action='store_true', help='only visible elements') + p.set_defaults(f=cmd_tree) + + for name, f, h in (('click', cmd_click, 'click (uses the accessibility action when there is one)'), + ('rightclick', cmd_rightclick, 'right click (opens context menu)'), + ('doubleclick', cmd_doubleclick, 'double click'), + ('focus', cmd_focus, 'give keyboard focus'), + ('hover', cmd_hover, 'move the mouse over the element')): + p = sub.add_parser(name, help=h) + selector(p) + p.add_argument('--settle', type=float, default=0.5, help='seconds to wait afterwards') + if name == 'click': + p.add_argument('--mouse', action='store_true', help='use a real mouse click') + p.set_defaults(f=f) + + p = sub.add_parser('settext', help='replace the text of an edit field') + selector(p) + p.add_argument('value') + p.add_argument('--settle', type=float, default=0.3) + p.set_defaults(f=cmd_settext) + + p = sub.add_parser('type', help='type text with the keyboard into the focused element') + p.add_argument('value') + p.add_argument('--settle', type=float, default=0.3) + p.set_defaults(f=cmd_type) + + p = sub.add_parser('key', help='press keys, xdotool syntax, e.g. Return ctrl+o Escape') + p.add_argument('keys', nargs='+') + p.add_argument('--settle', type=float, default=0.3) + p.set_defaults(f=cmd_key) + + p = sub.add_parser('wait', help='wait until a (visible) element exists') + selector(p) + p.add_argument('--timeout', type=float, default=10) + p.add_argument('--gone', action='store_true', help='wait until it disappears') + p.set_defaults(f=cmd_wait) + + p = sub.add_parser('info', help='role, name, text, value and states of one element') + selector(p) + p.set_defaults(f=cmd_info) + + p = sub.add_parser('suggest', help='visible elements most similar to --name/--role') + p.add_argument('--name') + p.add_argument('--role') + p.add_argument('--limit', type=int, default=8) + p.set_defaults(f=cmd_suggest) + + p = sub.add_parser('ocr', help='print the text on the screen as read by tesseract (for what "texts" does not show)') + p.set_defaults(f=cmd_ocr) + p = sub.add_parser('screenshot', help='save a PNG of the screen') + p.add_argument('file') + p.set_defaults(f=cmd_screenshot) + + args = ap.parse_args() + try: # command history next to the state file, so a watcher can see what a test is doing + with open(os.path.join(os.path.dirname(STATE), 'commands.log'), 'a') as f: + f.write(time.strftime('%H:%M:%S ') + ' '.join(sys.argv[1:]) + '\n') + except OSError: + pass + args.f(args) + + +if __name__ == '__main__': + main() diff --git a/gui/manualtest/mainwindow.md b/gui/manualtest/mainwindow.md deleted file mode 100644 index 563a538530f..00000000000 --- a/gui/manualtest/mainwindow.md +++ /dev/null @@ -1,21 +0,0 @@ - -# Main window - -Some manual testing in the main window interface - - -## Test: Recheck file - -1. Load a project with results. -1. Restart the GUI. -1. Right click on a file and click on "Recheck". - -EXPECTED: Results for that file should be refreshed. - - -## Test: Switch project - -1. Open project #1 -1. Open project #2 that has different results - -EXPECTED: Results for project #1 should go away, results for project #2 should be shown diff --git a/gui/manualtest/projectfiledialog.md b/gui/manualtest/projectfiledialog.md deleted file mode 100644 index ce7d39b1df0..00000000000 --- a/gui/manualtest/projectfiledialog.md +++ /dev/null @@ -1,52 +0,0 @@ - -# Project file dialog - -Some manual testing in the project file dialog interface - - -## Test: Relative paths - -Ticket: #14983 - -1. Configure files/paths in project folder: - * import a projectfile - * add include paths in project folder - * exclude file/folder - -2. Save project - -EXPECTED: Relative paths should be used in the XML - - -## Test: Platform file pic8.xml - -Ticket: #14489 - -EXPECTED: In the project file dialog it should be possible to select xml files i.e. pic8.xml - -TODO: can this test be automated - - -## Test: Custom cfg file - -Ticket: #14672 - -1. Copy addons/avr.cfg to a file "aa.cfg" in same folder as a cppcheck GUI project file - -EXPECTED: It should not be possible to activate "aa.cfg" in the project file dialog, it should appear in alphabetical order. - - -## Test: Misra C checkbox - -Ticket: #14488 - -Matrix: Use both open source and premium - -1. Load project file in trac ticket 14488 -1. Goto "Edit project" -1. Goto "Addons" tab - -EXPECTED: The misra c checkbox should be checked - -TODO: can this test be automated - diff --git a/gui/manualtest/report.py b/gui/manualtest/report.py new file mode 100644 index 00000000000..e84df758eb9 --- /dev/null +++ b/gui/manualtest/report.py @@ -0,0 +1,408 @@ +"""The HTML report of a run.py run: summary, results per test file, history over the earlier runs, +the failed tests with their screenshots and all tests. One file, no external resources. + +write(path, run, history) where run is what run.py saves as results.json and history is the +results.json of earlier runs of the same edition, oldest first. +""" + +import html +import os + +STATUSES = ('PASS', 'FAIL', 'SKIP') +ICON = {'PASS': '✓', 'FAIL': '✗', 'SKIP': '–', None: ''} +COLOR = {'PASS': 'var(--pass)', 'FAIL': 'var(--fail)', 'SKIP': 'var(--skip)'} +HISTORY_RUNS = 15 # columns in the history, including this run + +CSS = """ +:root { + --ink: #1b2330; --ink-2: #4a5568; --muted: #6b7686; --line: #e2e6ec; --line-2: #cfd6df; --paper: #fff; --band: #f7f8fa; + --accent: #2456c8; --accent-soft: #e8eefb; + --pass: #0ca30c; --pass-bg: #e4f5e4; --pass-ink: #0b5a0b; + --fail: #d03b3b; --fail-bg: #fbe6e6; --fail-ink: #9a1d1d; + --skip: #fab219; --skip-bg: #fdf2d6; --skip-ink: #6e4b00; + --none: #dfe3e9; + --sans: system-ui, -apple-system, "Segoe UI", Ubuntu, Cantarell, Roboto, sans-serif; + --mono: ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace; + color-scheme: light; +} +* { box-sizing: border-box; } +body { margin: 0; background: var(--paper); color: var(--ink); font: 14px/1.5 var(--sans); } +main { max-width: 72rem; margin: 0 auto; padding: 1.6rem max(16px, 2.2rem) 3rem; } +h1, h2, h3 { margin: 0; text-wrap: balance; } +a { color: var(--accent); } +section { margin-top: 2rem; } +h2 { font-size: 1.02rem; font-weight: 650; margin-bottom: .2rem; } +.sub { color: var(--muted); font-size: .85rem; margin: 0 0 .8rem; } +.rhead { display: flex; gap: 1rem 2rem; align-items: flex-start; justify-content: space-between; flex-wrap: wrap; } +.rhead h1 { font-size: 1.35rem; font-weight: 650; } +.eyebrow { text-transform: uppercase; letter-spacing: .08em; font-size: .72rem; color: var(--muted); font-weight: 600; } +.verdict { border-radius: 8px; padding: .45rem .85rem; font-weight: 650; } +.verdict.FAIL { background: var(--fail-bg); color: var(--fail-ink); } +.verdict.PASS { background: var(--pass-bg); color: var(--pass-ink); } +.meta { display: grid; grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); gap: .55rem 1.5rem; margin: 1.1rem 0 0; + padding-top: 1rem; border-top: 1px solid var(--line); } +.meta div { min-width: 0; } +.meta dt { font-size: .75rem; color: var(--muted); } +.meta dd { margin: 0; overflow-wrap: anywhere; } +.meta dd.mono { font-family: var(--mono); font-size: .85rem; } +.dirty, .aborted { color: var(--fail-ink); } +.dirty { font-size: .75rem; margin-left: .3rem; } +.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: .8rem; margin-top: 1.4rem; } +.tile { border: 1px solid var(--line); border-radius: 8px; padding: .75rem .9rem; } +.tile .lbl { font-size: .8rem; color: var(--muted); display: flex; align-items: center; gap: .4rem; } +.tile .val { font-size: 1.7rem; font-weight: 650; line-height: 1.2; font-variant-numeric: tabular-nums; } +.tile .note { font-size: .78rem; color: var(--muted); } +.dot { width: .6rem; height: .6rem; border-radius: 50%; display: inline-block; flex: none; } +.d-PASS { background: var(--pass); } .d-FAIL { background: var(--fail); } .d-SKIP { background: var(--skip); } +.chip { display: inline-block; border-radius: 5px; padding: 0 .45rem; font-size: .75rem; font-weight: 650; line-height: 1.6; white-space: nowrap; } +.c-PASS { background: var(--pass-bg); color: var(--pass-ink); } +.c-FAIL { background: var(--fail-bg); color: var(--fail-ink); } +.c-SKIP { background: var(--skip-bg); color: var(--skip-ink); } +.c-CRASH { background: var(--fail-ink); color: #fff; } +.c-NEW { background: var(--accent-soft); color: var(--accent); } +.legend { display: flex; gap: 1rem; flex-wrap: wrap; font-size: .8rem; color: var(--ink-2); margin: .2rem 0 .5rem; } +.legend span { display: inline-flex; align-items: center; gap: .35rem; } +.chart { overflow-x: auto; } +.chart svg { display: block; width: 100%; height: auto; min-width: 34rem; } +.chart text { font-family: var(--sans); fill: var(--ink-2); font-size: 12px; } +.chart text.m { fill: var(--muted); font-size: 11px; } +.chart text.b { fill: var(--ink); font-weight: 600; } +.chart text.sha { font-family: var(--mono); font-size: 9.5px; fill: var(--muted); } +.chart .grid { stroke: var(--line); stroke-width: 1; } +.cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); gap: 1.5rem 2.5rem; } +.cols > * { min-width: 0; } +.changes { display: grid; gap: .45rem; } +.changes div { display: flex; gap: .5rem; align-items: baseline; flex-wrap: wrap; } +.file { color: var(--muted); font-size: .8rem; } +.tbl { overflow-x: auto; } +table.tests { border-collapse: collapse; width: 100%; min-width: 40rem; } +.tests th { text-align: left; font-size: .75rem; color: var(--muted); font-weight: 600; padding: .35rem .6rem; border-bottom: 1px solid var(--line-2); } +.tests td { padding: .45rem .6rem; border-bottom: 1px solid var(--line); vertical-align: top; } +.tests tr.grp td { background: var(--band); font-weight: 600; font-size: .82rem; color: var(--ink-2); padding-top: .55rem; } +.tests tr.grp span { font-weight: 400; color: var(--muted); } +.tests td.t { white-space: nowrap; text-align: right; font-variant-numeric: tabular-nums; color: var(--ink-2); } +.tests td.links { white-space: nowrap; font-size: .82rem; } +.tests details { margin-top: .3rem; font-size: .82rem; } +.tests summary { color: var(--muted); cursor: pointer; } +.reason { font-family: var(--mono); font-size: .8rem; color: var(--ink-2); white-space: pre-wrap; overflow-wrap: anywhere; } +.strip { display: flex; gap: 2px; width: 11rem; margin-top: .35rem; } +.strip i { flex: 1; height: .5rem; background: var(--pass); } +.strip i:first-child { border-radius: 3px 0 0 3px; } .strip i:last-child { border-radius: 0 3px 3px 0; } +.strip i.f { background: var(--fail); } .strip i.n { background: var(--none); } +.stripnote { font-size: .75rem; color: var(--muted); } +.card { border: 1px solid var(--line); border-left: 4px solid var(--fail); border-radius: 8px; padding: .9rem 1rem; display: grid; gap: .5rem; } +.card + .card { margin-top: .8rem; } +.card.SKIP { border-left-color: var(--skip); } +.card-head { display: flex; gap: .5rem; align-items: baseline; flex-wrap: wrap; } +.card-head h3 { font-size: .98rem; } +.card-head .links { margin-left: auto; font-size: .82rem; } +.film { display: flex; gap: .6rem; overflow-x: auto; padding-bottom: .3rem; } +.shot { flex: none; width: 10.5rem; font-size: .75rem; color: var(--ink-2); text-decoration: none; } +.shot:hover b { text-decoration: underline; } +.shot img { display: block; width: 100%; aspect-ratio: 4/3; object-fit: cover; object-position: left top; + border: 1px solid var(--line-2); border-radius: 5px; background: var(--band); } +.shot.bad img { outline: 3px solid var(--fail); outline-offset: -1px; } +.shot b { color: var(--ink); } +.film.small .shot { width: 7.5rem; } +table.hgrid { border-collapse: separate; border-spacing: 3px; } +.hgrid th.name { text-align: right; padding-right: .6rem; font-size: .82rem; font-weight: 500; white-space: nowrap; } +.hgrid th.run { font-size: .68rem; color: var(--muted); font-weight: 500; text-align: center; } +.hgrid th.run.cur { color: var(--ink); font-weight: 700; } +.hgrid td.cell { width: 1.6rem; height: 1.35rem; border-radius: 3px; text-align: center; font-size: .72rem; font-weight: 700; color: #fff; background: var(--band); } +.hgrid td.PASS { background: var(--pass); } .hgrid td.FAIL { background: var(--fail); } +.hgrid td.SKIP { background: var(--skip); color: var(--skip-ink); } +.hgrid td.cur { box-shadow: 0 0 0 2px var(--paper), 0 0 0 3.5px var(--ink); } +.hgrid td.note { font-size: .78rem; color: var(--muted); padding-left: .7rem; white-space: nowrap; } +@media (max-width: 520px) { .card-head .links { margin-left: 0; width: 100%; } } +""" + +e = html.escape + + +def dur(s): + s = int(round(s)) + return '%d min %d s' % (s // 60, s % 60) if s >= 60 else '%d s' % s + + +def chip(status): + return '%s %s' % (status, ICON[status], status) + + +def crash_chip(r): + return ' CRASH' if r['crash'] else '' + + +def count(results, status): + return sum(1 for r in results if r['status'] == status) + + +def short_date(started): + return '%d/%d' % (int(started[5:7]), int(started[8:10])) + + +def links(r, outdir): + """Links to the files of a test that exist (a skipped test has none).""" + out = [(r['slug'] + ext, text) for ext, text in (('.txt', 'steps'), ('.app.log', 'app log'), ('.png', 'screenshot')) + if os.path.exists(os.path.join(outdir, r['slug'] + ext))] + return ' · '.join('%s' % (e(f), t) for f, t in out) + + +def strip(r): + """One cell per step: green passed, red failed, grey not run.""" + n, at = r.get('steps', 0), r.get('failed_step', 0) + if not n: + return '' + if r['status'] == 'SKIP': + cells, note = ['n'] * n, 'not run' + elif r['status'] == 'FAIL' and not at and not r['crash']: + cells, note = ['n'] * n, 'did not start' + else: + cells = ['' if not at or k < at else 'f' if k == at else 'n' for k in range(1, n + 1)] + note = 'failed at step %d of %d' % (at, n) if at else '%d of %d steps' % (n, n) + return '
%s
%s
' % ( + note, ''.join('' % c for c in cells), note) + + +def hbar(x, y, w, h, r, fill, tip): + """A horizontal bar, rounded at the data end only.""" + r = min(r, w / 2, h / 2) + return ('%s' + % (x, y, w - r, r, r, r, r, h - 2 * r, r, r, r, r, w - r, fill, e(tip))) + + +def vbar(x, base, w, h, r, fill, tip, top): + """A column segment; the top segment is rounded at the data end.""" + if not top: + return '%s' % (x, base - h, w, h, fill, e(tip)) + r = min(r, w / 2, h) + return ('%s' + % (x, base, h - r, r, r, r, r, w - 2 * r, r, r, r, r, h - r, fill, e(tip))) + + +def legend(): + return '
%s
' % ''.join('%s' % (k, k) for k in STATUSES) + + +def per_file_chart(run): + rows = [] + for f in run['files']: + rs = [r for r in run['results'] if r['file'] == f['file']] + if rs: + rows.append(dict({k: count(rs, k) for k in STATUSES}, title=f['title'] or f['file'], n=len(rs))) + big = max(r['n'] for r in rows) + step = 1 if big <= 10 else 5 if big <= 50 else 20 + top = -(-big // step) * step + left, width, rh, h = 210, 900, 30, 18 + bw = width - left - 70 + sx = lambda v: v / top * bw + s = [] + for v in range(0, top + 1, step): + s.append('%d' + % (left + sx(v), left + sx(v), len(rows) * rh + 4, left + sx(v), len(rows) * rh + 20, v)) + for i, r in enumerate(rows): + y = 8 + i * rh + title = r['title'] if len(r['title']) <= 30 else r['title'][:29] + '…' + s.append('%s%s' % (left - 10, y + h / 2 + 4, e(title), e(r['title']))) + x = left + segs = [k for k in STATUSES if r[k]] + for j, k in enumerate(segs): + last = j == len(segs) - 1 + w = sx(r[k]) - (0 if last else 2) # a 2px gap between the segments + tip = '%s\n%d %s of %d tests' % (r['title'], r[k], k, r['n']) + s.append(hbar(x, y, w, h, 4, COLOR[k], tip) if last else + '%s' % (x, y, w, h, COLOR[k], e(tip))) + x += sx(r[k]) + s.append('%d/%d' % (x + 8, y + h / 2 + 4, r['PASS'], r['n'])) + return ('
%s
' + % (width, len(rows) * rh + 28, ''.join(s))) + + +def trend_chart(runs): + width, left, base, top = 900, 34, 190, 14 + n = len(runs) + bw = min(30, (width - left - 30) / n * 0.6) + gap = min((width - left - 20 - n * bw) / max(n - 1, 1), 30) + big = max(len(r['results']) for r in runs) or 1 + step = 5 if big <= 25 else 10 if big <= 60 else 50 + ymax = -(-big // step) * step + sy = lambda v: v / ymax * (base - top) + s = [] + for v in range(0, ymax + 1, step): + s.append('%d' + % (left, width - 10, base - sy(v), base - sy(v), left - 6, base - sy(v) + 4, v)) + for i, run in enumerate(runs): + x, cur = left + 6 + i * (bw + gap), i == n - 1 + c = {k: count(run['results'], k) for k in STATUSES} + tip = 'Run %s · %s%s\n%d pass · %d fail · %d skip' % (run['started'][:16].replace('T', ' '), run['sha'][:8], + ' (aborted)' if run.get('aborted') else '', c['PASS'], c['FAIL'], c['SKIP']) + y0 = base + segs = [k for k in STATUSES if c[k]] + for j, k in enumerate(segs): + last = j == len(segs) - 1 + s.append(vbar(x, y0, bw, sy(c[k]) - (0 if last else 2), 4, COLOR[k], tip, last)) + y0 -= sy(c[k]) + if c['FAIL']: + s.append('%d' % (x + bw / 2, y0 - 6, c['FAIL'])) + s.append('%s' % ('b' if cur else 'm', x + bw / 2, base + 16, short_date(run['started']))) + s.append('%s' % (x + bw / 2, base + 30, e(run['sha'][:6]))) + if cur: + s.append('this run' % (x + bw / 2, base + 46)) + return ('
%s
' + % (width, base + 52, ''.join(s))) + + +def describe_history(h, runs): + """What a row of the status history says: flaky, failing since, fixed since...""" + seen = [x for x in h if x] + last = h[-1] + changes = sum(1 for a, b in zip(seen, seen[1:]) if a != b) + since = len(h) - 1 + while since > 0 and h[since - 1] == last: + since -= 1 + when = '%s %s (%s)' % (short_date(runs[since]['started']), runs[since]['started'][11:16], runs[since]['sha'][:6]) + if all(x == 'SKIP' for x in seen): + return 'never ran' + if changes >= 4: + return 'flaky: %d changes' % changes + if last == 'FAIL': + return 'new failure' if since == len(h) - 1 else 'failing since ' + when + if last == 'SKIP': + return 'skipped since ' + short_date(runs[since]['started']) + return 'fixed since ' + when if last == 'PASS' else '' + + +def history_sections(run, history): + runs = history[-(HISTORY_RUNS - 1):] + [run] + status = [{r['name']: r['status'] for r in x['results']} for x in runs] + prev = status[-2] + cur = run['results'] + new = [r for r in cur if r['status'] == 'FAIL' and prev.get(r['name']) != 'FAIL'] + fixed = [r for r in cur if r['status'] == 'PASS' and prev.get(r['name']) == 'FAIL'] + still = [r for r in cur if r['status'] == 'FAIL' and prev.get(r['name']) == 'FAIL'] + line = lambda r, tag: '
%s%s%s
' % (tag, e(r['name']), e(r['file'])) + changes = ''.join([line(r, 'NEW ' + chip('FAIL')) for r in new] + + [line(r, chip('PASS')) for r in fixed] + + [line(r, '✗ STILL FAILING') for r in still]) or \ + '

No test changed between PASS and FAIL.

' + p = runs[-2] + out = ['

The last %d runs

%s. The number on a column is the failed tests.

%s%s
' + % (len(runs), e(run['edition'] or 'All editions'), legend(), trend_chart(runs)), + '

Changed since the previous run

Run %s · %s

%s
' + % (e(p['started'][:16].replace('T', ' ')), e(p['sha'][:10]), changes)] + rows = [r for r in cur if any(s.get(r['name'], 'PASS') != 'PASS' for s in status)] + if rows: + head = '%s' % ''.join( + '%s' % (' cur' if i == len(runs) - 1 else '', short_date(x['started'])) for i, x in enumerate(runs)) + body = [] + for r in rows: + h = [s.get(r['name']) for s in status] + cells = ''.join('%s' % ( + x or '', ' cur' if i == len(runs) - 1 else '', + e('%s · %s %s: %s' % (r['name'], short_date(runs[i]['started']), runs[i]['sha'][:8], x or 'not in this run')), ICON[x]) + for i, x in enumerate(h)) + body.append('%s%s%s' % (e(r['name']), cells, describe_history(h, runs))) + out.append('

Status history

The tests that did not pass in every run. ' + 'The framed column is this run.

%s%s
' + % (head, ''.join(body))) + return out, len(new) - len(fixed), len(new), len(fixed) + + +def film(r, outdir): + """The screenshots after the last steps before the failure, and the final screenshot.""" + shots = [(s['file'], 'Step %d' % s['step'], s['label'], False) for s in r.get('shots', [])][-3:] + if os.path.exists(os.path.join(outdir, r['slug'] + '.png')): + at = r.get('failed_step', 0) + shots.append((r['slug'] + '.png', 'Step %d · failed here' % at if at else 'At the end', '', True)) + return '
%s
' % ''.join( + '%s%s
%s
' % ( + ' bad' if bad else '', e(f), e(f), e(title), e(title), e(label)) for f, title, label, bad in shots) if shots else '' + + +def problem_cards(run, outdir): + rs = [r for r in run['results'] if r['status'] != 'PASS'] + rs.sort(key=lambda r: r['status'] != 'FAIL') + return ''.join('
%s%s

%s

%s%s
' + '%s
%s
%s
' % ( + r['status'], chip(r['status']), crash_chip(r), e(r['name']), e(r['file']), links(r, outdir), + strip(r) if r['status'] == 'FAIL' else '', e(r['reason']), film(r, outdir) if r['status'] == 'FAIL' else '') + for r in rs) + + +def all_tests(run, outdir): + rows = [] + for f in run['files']: + rs = [r for r in run['results'] if r['file'] == f['file']] + if not rs: + continue + rows.append('%s · %s · %d of %d passed' % ( + e(f['title'] or f['file']), e(f['file']), count(rs, 'PASS'), len(rs))) + for r in rs: + shots = r.get('shots', []) + more = ('
screenshots after the steps (%d)
%s
' % ( + len(shots), ''.join('Step %d
%s
' % ( + e(s['file']), e(s['file']), s['step'], e(s['label'])) for s in shots))) if shots else '' + rows.append('%s%s
%s
%s%s%s%s' % ( + chip(r['status']), crash_chip(r), e(r['name']), strip(r), more, + dur(r['seconds']) if r['status'] != 'SKIP' else '–', links(r, outdir))) + return ('
' + '%s
ResultTestTimeFiles
' % ''.join(rows)) + + +def write(path, run, history): + outdir = os.path.dirname(path) + rs = run['results'] + c = {k: count(rs, k) for k in STATUSES} + ran = c['PASS'] + c['FAIL'] + total = sum(r['seconds'] for r in rs) + crashes = sum(1 for r in rs if r['crash']) + verdict = 'FAIL' if c['FAIL'] else 'PASS' + sha = run['sha'][:8] + text = ('✗ FAILED · %d of %d tests failed' % (c['FAIL'], len(rs)) if c['FAIL'] else + '✓ PASSED · all %d tests passed' % ran if not c['SKIP'] else '✓ PASSED · %d passed, %d skipped' % (ran, c['SKIP'])) + meta = [('Date', e(run['started'][:19].replace('T', ' ')), ''), + ('Edition', e(run['edition'] or 'not given, all tests'), ''), + ('Duration', dur(total), ''), + ('Git SHA', e(run['sha']) + ('+ uncommitted changes' if run['dirty'] else ''), 'mono'), + ('Branch', e(run['branch']), ''), + ('Commit', e(run['subject']), ''), + ('Application', e(run['app']), 'mono'), + ('Host', e(run['host']), ''), + ('Test files', e(', '.join(f['file'] for f in run['files'])), '')] + if run.get('aborted'): + meta.append(('Aborted', 'the run was stopped before all tests were done', '')) + hist, delta, new, fixed = history_sections(run, history) if history else ([], 0, 0, 0) + + def tile(label, value, note, status=''): + return '
%s%s
%s
%s
' % ( + '' % status if status else '', label, value, note) + tiles = [tile('Passed', c['PASS'], '%d %% of the tests' % round(100 * c['PASS'] / len(rs)) if rs else '', 'PASS'), + tile('Failed', c['FAIL'], '%d of them crashed the app' % crashes if crashes else 'no crashes', 'FAIL'), + tile('Skipped', c['SKIP'], 'no script or outdated script' if c['SKIP'] else ' ', 'SKIP'), + tile('Duration', dur(total), 'average %d s per test' % round(total / ran) if ran else ' ')] + if history: + tiles.append(tile('Compared to the previous run', '%+d' % delta if delta else '±0', + '%d new failure%s, %d fixed' % (new, '' if new == 1 else 's', fixed))) + + out = ['', '', + '', + 'GUI test report %s %s' % (e(run['edition'] or ''), e(sha)), '
', + '
GUI test report

%s %s · %s

%s
' % ( + e(os.path.basename(run['app'])), e(run['edition'] or ''), e(sha), verdict, text), + '
%s
' % ''.join('
%s
%s
' % (k, cls, v) for k, v, cls in meta), + '
%s
' % ''.join(tiles)] + if len([f for f in run['files'] if any(r['file'] == f['file'] for r in rs)]) > 1: + out.append('

Results per test file

Which part of the GUI has problems.

%s%s
' + % (legend(), per_file_chart(run))) + out += hist + if c['FAIL'] or c['SKIP']: + out.append('

Failed and skipped tests

The reason, how far the test got, and the screenshots ' + 'after the last steps. The red frame is the screen when the test failed.

%s
' % problem_cards(run, outdir)) + if rs: + out.append('

All tests

Grouped by test file. The strip shows the steps: green passed, ' + 'red failed, grey not run.

%s
' % all_tests(run, outdir)) + if not history: + out.append('

No earlier runs of this edition with results.json were found in %s, ' + 'the history is shown from the next run.

' % e(os.path.dirname(outdir))) + out.append('
') + with open(path, 'w', encoding='utf-8') as f: + f.write('\n'.join(out) + '\n') diff --git a/gui/manualtest/run.py b/gui/manualtest/run.py new file mode 100755 index 00000000000..1d7668cda27 --- /dev/null +++ b/gui/manualtest/run.py @@ -0,0 +1,230 @@ +#!/usr/bin/env python3 +"""Run the manual tests in a test file by letting Claude drive the GUI. + + run.py APP FILE.feature... [--edition opensource|premium] [--test SUBSTRING] [--id ID] [--src DIR] [--out DIR] + +FILE.feature is a Gherkin test file, edited with web.py or by hand, see testfile.py. The scripts +are in FILE.scripts.json. For each scenario (and each row of its Examples) the application is started +fresh (empty HOME) and the script of the test is run with guitest.py commands, see runner.py. +No AI is involved. With --edition APP is that edition and only the tests for it are run. +Tests without a script are SKIP. A step that fails gives PASS -> FAIL with the +step, the reason and the elements that are on the screen. +""" + +import argparse +import os +import re +import datetime +import json +import platform +import signal +import subprocess +import sys +import tempfile +import time + +import report +import runner +import testfile + +HERE = os.path.dirname(os.path.abspath(__file__)) +GUITEST = os.path.join(HERE, 'guitest.py') + +def parse(path, edition=None): + return [dict(t, file=os.path.basename(path)) for t in testfile.expand(path, edition)] + + +CRASH_RE = re.compile(r'exited with status (?!0\b|143\b)\d+|Segmentation fault|SIGSEGV|SIGABRT|Aborted|core dumped|terminate called|' + r'QFATAL|Fatal error|AddressSanitizer|runtime error:|Assertion .* failed', re.I) + + +def screenshot(sub, path): + """Save a screenshot without the empty (black) part of the screen right of and below the windows. + The top left corner stays, so positions in the image are screen positions.""" + if sub('screenshot', path, capture_output=True).returncode: + return False + try: + from PIL import Image + img = Image.open(path) + box = img.convert('RGB').getbbox() + if box and (box[2] < img.width or box[3] < img.height): + img.crop((0, 0, box[2], box[3])).save(path) + except (ImportError, OSError): + pass + return True + + +def detect_crash(sub, outdir, slug): + """Return a description when the application died or logged a fatal error, else ''.""" + log = sub('log', capture_output=True).stdout + with open(os.path.join(outdir, slug + '.app.log'), 'w') as f: + f.write(log) + hits = [l.strip() for l in log.splitlines() if CRASH_RE.search(l)] + dead = sub('alive', capture_output=True).returncode != 0 + if dead and re.search(r'application exited with status 0\b', log): + dead = False # the test closed the application (Quit) + if not dead and not hits: + return '' + why = 'application is not running at the end of the test' if dead else 'fatal message in application log' + return why + (': ' + hits[0] if hits else '') + + +def emit(kind, **data): + """One line of progress for the web interface, with --events.""" + if EVENTS: + print('@' + json.dumps(dict(data, kind=kind)), flush=True) + + +EVENTS = False + + +def run_test(app, test, outdir, on_step=None): + """Returns {status, reason, crash, steps, failed_step, shots}. failed_step is 0 when no step failed, + shots are the screenshots after the steps: [{step, label, file}].""" + slug = re.sub(r'\W+', '_', test['name']) + shots, reached = [], [0] + result = lambda status, reason, crash='', failed=0: {'status': status, 'reason': reason, 'crash': crash, + 'steps': len(test['script']), 'failed_step': failed, 'shots': shots} + if test.get('stale'): + return result('SKIP', 'OUTDATED SCRIPT: the test was changed after the script was made. ' + 'Generate the script again (gen.py or the web interface) or approve it there.') + if not test['script']: + return result('SKIP', 'no script, make one with gen.py or in the web interface') + work = tempfile.mkdtemp(prefix='guitest-work-') + state = os.path.join(work, 'state.json') + env = dict(os.environ, GUITEST_STATE=state) + sub = lambda *a, **kw: subprocess.run([sys.executable, GUITEST, *a], env=env, text=True, **kw) + try: + variables = testfile.materialize(test['root'], test['projects'], work) # same files every run + except FileNotFoundError as e: + return result('FAIL', str(e)) + r = sub('start', app, capture_output=True) + if r.returncode: + return result('FAIL', 'could not start: ' + (r.stdout + r.stderr).strip()) + try: + with open(state) as f: + home = json.load(f)['env']['HOME'] + def shot(i, label): + name = '%s.step%02d.png' % (slug, i) + if not screenshot(sub, os.path.join(outdir, name)): + return None + shots.append({'step': i, 'label': label, 'file': name}) + return name + def step(i, n, label): + reached[0] = i + if on_step: + on_step(i, n, label) + ok, reason, log = runner.run_script(sub, test['script'], work, home, variables, step, shot) + with open(os.path.join(outdir, slug + '.txt'), 'w') as f: + f.write(log) + screenshot(sub, os.path.join(outdir, slug + '.png')) + crash = detect_crash(sub, outdir, slug) + status = 'PASS' if ok else 'FAIL' + if crash: + # a crash is a failure even if all the steps passed + status, reason = 'FAIL', 'APPLICATION CRASHED: %s\n%s' % (crash, reason) + return result(status, reason, crash, 0 if ok else reached[0]) + finally: + sub('stop', capture_output=True) + + +def git(directory, *a): + r = subprocess.run(['git', '-C', directory, *a], text=True, capture_output=True) + return r.stdout.strip() if r.returncode == 0 else '' + + +def app_info(app, src): + """git info for the tested application, taken from SRC (default: the directory of the binary).""" + d = os.path.abspath(src) if src else os.path.dirname(app) + sha = git(d, 'rev-parse', 'HEAD') + return { + 'path': app, + 'sha': sha or 'unknown', + 'branch': git(d, 'rev-parse', '--abbrev-ref', 'HEAD') or 'unknown', + 'subject': git(d, 'log', '-1', '--format=%s') if sha else '', + 'dirty': bool(git(d, 'status', '--porcelain', '--untracked-files=no')) if sha else False, + } + + +def load_history(out, edition, current): + """results.json of the earlier runs of EDITION in OUT, oldest first.""" + runs = [] + for d in sorted(os.listdir(out)): + path = os.path.join(out, d, 'results.json') + if d == current or not os.path.isfile(path): + continue + try: + with open(path, encoding='utf-8') as f: + run = json.load(f) + except (OSError, ValueError): + continue + if run.get('edition') == edition: + runs.append(run) + return runs[-(report.HISTORY_RUNS - 1):] + + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument('app') + ap.add_argument('file', nargs='+', help='one or more .feature test files') + ap.add_argument('--edition', choices=testfile.EDITIONS, help='the edition that APP is, only the tests for it') + ap.add_argument('--test', help='only tests whose name contains this') + ap.add_argument('--id', help='only the test with this id (all the rows of its Examples)') + ap.add_argument('--src', help='git checkout of the application (default: the directory of APP)') + ap.add_argument('--out', default=os.path.join(HERE, 'results')) + ap.add_argument('--events', action='store_true', help='progress lines for the web interface') + args = ap.parse_args() + global EVENTS + EVENTS = args.events + signal.signal(signal.SIGINT, signal.default_int_handler) # also when started in the background + + started = datetime.datetime.now() + info = app_info(os.path.abspath(args.app), args.src) + # each run gets its own directory: results/[-]-/ + parent = args.out + args.out = os.path.join(args.out, '%s%s-%s' % (started.strftime('%Y%m%d-%H%M%S'), + '-' + args.edition if args.edition else '', info['sha'][:8])) + os.makedirs(args.out, exist_ok=True) + failed = 0 + results = [] + aborted = False + try: + selected = [t for f in args.file for t in parse(f, args.edition) + if not (args.test and args.test.lower() not in t['name'].lower() or args.id and t['id'] != args.id)] + emit('start', total=len(selected), out=args.out, edition=args.edition) + for index, test in enumerate(selected, 1): + name = test['name'] + emit('test', index=index, name=name, file=test['file'], steps=len(test['script'])) + t0 = time.time() + try: + res = run_test(os.path.abspath(args.app), test, args.out, + lambda k, n, label: emit('step', step=k, steps=n, label=label)) + except KeyboardInterrupt: + results.append({'name': name, 'file': test['file'], 'status': 'SKIP', 'reason': 'aborted by user', 'crash': '', + 'seconds': time.time() - t0, 'slug': re.sub(r'\W+', '_', name), 'steps': 0, 'failed_step': 0, 'shots': []}) + emit('result', **results[-1]) + raise + results.append(dict(res, name=name, file=test['file'], seconds=time.time() - t0, slug=re.sub(r'\W+', '_', name))) + emit('result', **results[-1]) + print('%-4s %s: %s' % (res['status'], name, res['reason']), flush=True) + failed += res['status'] == 'FAIL' + except KeyboardInterrupt: + # the report is written with what is done, tests not started are left out + aborted = True + print('aborted') + run = {'started': started.isoformat(timespec='seconds'), 'edition': args.edition, 'app': info['path'], + 'sha': info['sha'], 'dirty': info['dirty'], 'branch': info['branch'], 'subject': info['subject'], + 'host': '%s, %s' % (platform.node(), platform.platform()), 'aborted': aborted, + 'files': [{'file': os.path.basename(f), 'title': testfile.load(f).get('title', '')} for f in args.file], + 'results': results} + with open(os.path.join(args.out, 'results.json'), 'w', encoding='utf-8') as f: + json.dump(run, f, indent=1) + path = os.path.join(args.out, 'report.html') + report.write(path, run, load_history(parent, args.edition, os.path.basename(args.out))) + print('report: ' + path) + emit('done', report=path) + sys.exit(1 if failed else 0) + + +if __name__ == '__main__': + main() diff --git a/gui/manualtest/runner.py b/gui/manualtest/runner.py new file mode 100644 index 00000000000..11634cdb1e4 --- /dev/null +++ b/gui/manualtest/runner.py @@ -0,0 +1,232 @@ +"""Executes a test script (see testfile.SCRIPT_DOC) with guitest.py commands, no AI involved. + +run_script() gets `sub`, a function that runs one guitest.py command in the session of the test: +sub(cmd, *args, capture_output=True) -> CompletedProcess with returncode, stdout, stderr. +""" + +import os +import re +import shutil +import time + +import testfile + +# actions that change the GUI, a screenshot is taken after each of them +GUI_ACTIONS = ('click', 'rightclick', 'doubleclick', 'focus', 'hover', 'settext', 'type', 'key', 'restart') +NO_ELEMENT = ('no matching visible element', 'does not answer on the accessibility bus') +DEFAULT_TIMEOUT = 5 + + +def selector_args(step): + a = [] + for k in ('name', 'role', 'path'): + if k in step: + a += ['--' + k, str(step[k])] + if 'nth' in step: + a += ['--nth', str(step['nth'])] + if step.get('exact'): + a.append('--exact') + return a + + +def describe(step): + return ' '.join('%s=%r' % (k, v) for k, v in step.items() if k != 'label') + + +def message(p): + text = (p.stderr.strip() or p.stdout.strip() or 'exit code %d' % p.returncode).removeprefix('error: ') + return text.replace('; try "tree --showing"', '') + + +class StepFailed(Exception): + pass + + +def check_path(path, allowed): + path = os.path.realpath(path) + if not any(path == d or path.startswith(d + os.sep) for d in (os.path.realpath(x) for x in allowed)): + raise StepFailed('path %s is outside the test directories' % path) + return path + + +def gui(sub, cmd, step, extra=()): + """Run a command that needs an element. The element may not have appeared yet, so retry.""" + deadline = time.time() + step.get('timeout', DEFAULT_TIMEOUT) + while True: + p = sub(cmd, *selector_args(step), *extra, capture_output=True) + if p.returncode == 0: + return p + if not any(m in message(p) for m in NO_ELEMENT) or time.time() > deadline: + raise StepFailed(message(p)) + time.sleep(0.4) + + +def run_step(sub, step, dirs, captured): + action = step.get('do') or step['expect'] + if 'do' in step: + if action in ('click', 'rightclick', 'doubleclick', 'focus', 'hover'): + gui(sub, action, step, ['--mouse'] if step.get('mouse') else []) + elif action == 'settext': + gui(sub, 'settext', step, [step['value']]) + elif action == 'type': + ok(sub('type', step['value'], capture_output=True)) + elif action == 'key': + keys = step['keys'].split() if isinstance(step['keys'], str) else step['keys'] + ok(sub('key', *keys, capture_output=True)) + elif action == 'wait': + ok(sub('wait', *selector_args(step), '--timeout', str(step.get('timeout', 10)), + *(['--gone'] if step.get('gone') else []), capture_output=True)) + elif action == 'restart': + ok(sub('restart', capture_output=True)) + elif action == 'sleep': + time.sleep(float(step['seconds'])) + elif action == 'copy': + src, dst = check_path(step['from'], dirs), check_path(step['to'], dirs) + if not os.path.isfile(src): + raise StepFailed('file %s does not exist' % src) + os.makedirs(os.path.dirname(dst), exist_ok=True) + shutil.copyfile(src, dst) + elif action == 'write': + path = check_path(step['path'], dirs) + os.makedirs(os.path.dirname(path), exist_ok=True) + with open(path, 'w', encoding='utf-8') as f: + f.write(step['content']) + return + if action == 'visible': + ok(sub('wait', *selector_args(step), '--timeout', str(step.get('timeout', DEFAULT_TIMEOUT)), + capture_output=True)) + elif action == 'gone': + ok(sub('wait', *selector_args(step), '--gone', '--timeout', str(step.get('timeout', DEFAULT_TIMEOUT)), + capture_output=True)) + elif action == 'state': + info = gui(sub, 'info', step).stdout + have = set((re.search(r'\[([\w,]*)\]\s*$', info.strip()) or [None, ''])[1].split(',')) + if 'state' in step and step['state'] not in have: + raise StepFailed('element is not %s, its states are [%s]: %s' % (step['state'], ','.join(sorted(have)), info.strip())) + if 'not_state' in step and step['not_state'] in have: + raise StepFailed('element is %s but should not be: %s' % (step['not_state'], info.strip())) + elif action == 'value': + info = gui(sub, 'info', step).stdout.strip() + found = re.findall(r" value=(\S+)", info) + re.findall(r" text='(.*?)'(?= value=| \[|$)", info) + if not any(same(v, step['equals']) for v in found): + raise StepFailed('the value is %s, not %r: %s' % (found or 'missing', step['equals'], info)) + elif action == 'exited': + deadline = time.time() + step.get('timeout', DEFAULT_TIMEOUT) + while sub('alive', capture_output=True).returncode == 0: + if time.time() > deadline: + raise StepFailed('the application is still running') + time.sleep(0.3) + status = re.findall(r'application exited with status (\d+)', sub('log', capture_output=True).stdout) + if status and status[-1] != '0': + raise StepFailed('the application ended with status %s, not 0' % status[-1]) + elif action == 'text': + deadline = time.time() + step.get('timeout', DEFAULT_TIMEOUT) # the screen may take a moment to change + while True: + texts = sub('texts', capture_output=True).stdout + problem = None + if 'contains' in step and step['contains'] not in texts: + problem = 'the text %r is not on the screen' % step['contains'] + elif 'not_contains' in step and step['not_contains'] in texts: + problem = 'the text %r is on the screen but should not be' % step['not_contains'] + if not problem: + break + if time.time() > deadline: + raise StepFailed(problem) + time.sleep(0.4) + elif action == 'ocr': + deadline = time.time() + step.get('timeout', DEFAULT_TIMEOUT) + norm = lambda x: re.sub(r'\s+', ' ', x).lower() + while True: + p = sub('ocr', capture_output=True) + if p.returncode: + raise StepFailed(message(p)) + seen = norm(p.stdout) + problem = None + if 'contains' in step and norm(step['contains']) not in seen: + problem = 'the text %r is not on the screen (OCR)' % step['contains'] + elif 'not_contains' in step and norm(step['not_contains']) in seen: + problem = 'the text %r is on the screen (OCR) but should not be' % step['not_contains'] + if not problem: + break + if time.time() > deadline: + raise StepFailed(problem + '. OCR read: ' + seen[:300]) + time.sleep(0.4) + elif action == 'file': + path = check_path(step['path'], dirs) + try: + with open(path, encoding='utf-8', errors='replace') as f: + text = f.read() + except FileNotFoundError: + raise StepFailed('file %s does not exist' % path) + if 'contains' in step and step['contains'] not in text: + raise StepFailed('%s does not contain %r' % (path, step['contains'])) + if 'not_contains' in step and step['not_contains'] in text: + raise StepFailed('%s contains %r but should not' % (path, step['not_contains'])) + if 'regex' in step and not re.search(step['regex'], text, re.M): + raise StepFailed('%s does not match /%s/' % (path, step['regex'])) + elif action == 'alive': + ok(sub('alive', capture_output=True)) + elif action == 'capture': + info = gui(sub, 'info', step).stdout.strip() + m = re.search(step['regex'], info) + if not m: + raise StepFailed('/%s/ does not match: %s' % (step['regex'], info)) + captured[step['as']] = m.group(1) if m.groups() else m.group(0) + + +def same(a, b): + try: + return float(a) == float(b) # a spin box says 1.0 + except ValueError: + return a == b + + +def ok(p): + if p.returncode: + raise StepFailed(message(p)) + + +def context(sub, step): + """What the screen looks like when a step failed, to make a renamed button easy to find.""" + out = [] + if {'name', 'role', 'path'} & set(step): + cmd = ['suggest'] + ['--%s=%s' % (k, step[k]) for k in ('name', 'role') if k in step] + s = sub(*cmd, capture_output=True).stdout.strip() + if s: + out.append('most similar visible elements:\n' + '\n'.join(' ' + l for l in s.splitlines())) + w = sub('windows', capture_output=True).stdout.strip() + if w: + out.append('windows:\n' + '\n'.join(' ' + l.split(' @')[0] for l in w.splitlines()[:6])) + return '\n '.join(out) + + + +def run_script(sub, script, work, home, variables=None, progress=None, shot=None): + """Returns (ok, message, log). On failure the message names the step and what was on screen. + shot(i, label) is called after each step i that is one of GUI_ACTIONS and returns the name of the + screenshot it saved, or None.""" + dirs = [work, home] + variables = dict(variables or {}, work=work, home=home) + captured = {} # {name} values of the capture steps so far + log = [] + for i, step in enumerate(script, 1): + step = testfile.subst_deep(step, dict(variables, **captured)) + t0 = time.time() + label = step.get('label') + if progress: + progress(i, len(script), label or describe(step)) + head = 'step %d/%d%s: %s' % (i, len(script), ' "%s"' % label if label else '', describe(step)) + try: + run_step(sub, step, dirs, captured) + except StepFailed as e: + log.append('FAIL %s (%.1f s)' % (head, time.time() - t0)) + msg = '%s\n %s' % (head, e) + ctx = context(sub, step) + return False, msg + ('\n ' + ctx if ctx else ''), '\n'.join(log) + '\n' + msg + '\n' + log.append('ok %s (%.1f s)' % (head, time.time() - t0)) + if shot and step.get('do') in GUI_ACTIONS: + time.sleep(0.2) # let the application paint + name = shot(i, label or describe(step)) + if name: + log[-1] += ' screenshot ' + name + return True, 'all %d steps passed' % len(script), '\n'.join(log) + '\n' diff --git a/gui/manualtest/testfile.py b/gui/manualtest/testfile.py new file mode 100644 index 00000000000..a915e7960fa --- /dev/null +++ b/gui/manualtest/testfile.py @@ -0,0 +1,743 @@ +#!/usr/bin/env python3 +"""Test files for run.py, written in Gherkin (FILE.feature), with the scripts in FILE.scripts.json. + + Feature: Project file dialog + + Background: + Given the application is started with no project loaded + + @id:t1a2b3c4d @ticket:14983 @project:relative-paths + Scenario: Relative paths + TODO: cannot be automated optional, a description line that starts with TODO: + When I open the project dialog + And I select the platform + Then relative paths are used in the XML + + Examples: + | platform | lang | + | native | C | + | unix32 | C++ | + +Feature: is the title of the file. Background: steps are done before every scenario of the file. +A scenario has steps that start with Given, When, Then, And, But or *, at least one Then (the +expected result). A step can be followed by a doc string (lines between \"\"\") or a table (| a | b |). +Lines that start with # are comments, they are not kept when the file is saved by web.py. + +Tags of a scenario (all optional): + @id:ID identifies a test when it is renamed, added when it is missing + @ticket:NUMBER the ticket of the test (#NUMBER) + @project:NAME a test project, see below; one tag per project + @edition:NAME an edition that the test is for, one of EDITIONS; one tag per edition, none: all + @disabled the test is not run +Other tags are kept but not used. + +A run is for one edition (run.py --edition, with the binary of that edition), the tests that are +not for it are left out. The script is the same for all editions, {edition} in the steps and the +script is the name of the edition of the run. + +Examples (Scenario Outline) are the test matrix: the test is run once for every row of the table. + in the steps and {column} in the script are replaced by the value of the row. + +"script" is what run.py executes, see SCRIPT_DOC below. It is written by gen.py (an AI explores +the GUI once) or by hand, and is then replayed without any AI. The scripts are kept in +FILE.scripts.json, {"ID": {"script": [...], "script_for": "..."}}, next to the feature file. + +@project:NAME are test projects, directories with files and code in DIR/projects/NAME, +shared by all tests next to them. Before every run they are copied to an empty temporary directory, +so a test always starts with the same files: {project:NAME} in steps and scripts is the copy of NAME, +and {project} when the test has exactly one project. + +A script is made for the steps (with the Background), todo, examples and test projects (the files in +them) of a test. "script_for" is a hash of those at the time, when they are changed afterwards the +script is OUTDATED: it is kept but not run until it is generated again, edited or approved. + +In Python a test file is a dict {"title", "background": [lines], "tests": [test]}, a test is +{"id", "name", "steps": [lines], "todo", "ticket", "enabled", "projects", "editions", "examples": +[{column: value}], "script", "script_for"}. The lines of the steps are Gherkin without indentation. + + testfile.py convert IN.md|IN.json OUT.feature import a markdown or an older JSON test file +""" + +import hashlib +import itertools +import json +import os +import re +import shutil +import sys + +AXIS_RE = re.compile(r'^\w+$') +PROJECT_RE = re.compile(r'^[\w-]+$') +PROJECTS = 'projects' # test projects: one directory per project, next to the test files +EDITIONS = ('opensource', 'premium') +EXT = '.feature' +SCRIPTS_EXT = '.scripts.json' + +SCRIPT_DOC = """A script is a list of steps. Every step is an object with "do" (an action) or "expect" (a check), +and an optional "label" that says what the step is for (shown when it fails). Elements are found +with name (substring of the accessible name/text, case-insensitive), role, path, nth, exact, like +the guitest.py commands. {work} is a temporary directory for files, {home} the HOME of the +application, {project:NAME} the copy of the test project NAME ({project} when the test has just one), +use those for the files of a test instead of write steps. {column} values of the Examples row and {edition} +(opensource or premium, the same script is used for both) are replaced before the run. + +actions + {"do": "click|rightclick|doubleclick|focus|hover", "name": "...", "role": "...", "mouse": true} + {"do": "settext", "name": "...", "value": "..."} set the text of an edit field + {"do": "type", "value": "..."} keyboard input to the focused element + {"do": "key", "keys": ["ctrl+o", "Return"]} xdotool key names + {"do": "wait", "name": "...", "gone": true, "timeout": 10} + {"do": "restart"} quit and start the application again + {"do": "sleep", "seconds": 1} + {"do": "write", "path": "{work}/a.c", "content": "..."} + {"do": "copy", "from": "{project:p}/a_v2.c", "to": "{project:p}/a.c"} change a file of the project +checks, the test fails when one is wrong + {"expect": "visible", "name": "...", "role": "...", "timeout": 5} + {"expect": "gone", "name": "..."} + {"expect": "state", "name": "...", "state": "checked"} or "not_state": "checked"; also + showing enabled focused selected expanded + {"expect": "value", "name": "...", "equals": "1"} value or text of a field, a spin box... + {"expect": "exited"} the application has ended by itself, status 0 (Quit) + {"expect": "text", "contains": "..."} or "not_contains": anywhere on screen + {"expect": "ocr", "contains": "Recheck"} text on the screen read by OCR (tesseract), or "not_contains"; + only for what "text" cannot see, e.g. a context menu that + is not in the accessibility tree. Case is ignored. + {"expect": "file", "path": "{home}/x.xml", "contains": "...", "not_contains": "...", "regex": "..."} + {"expect": "alive"} + {"expect": "capture", "name": "...", "role": "frame", "regex": "'Cppcheck (\\d[^']*)'", "as": "version"} + the regex is searched in the element's info line + (role 'name' text='...' value=...), group 1 (or the + whole match) is stored and {version} in the later + steps is replaced by it; use it instead of hard coding + text that changes, e.g. the version +A check can have "observed_fail": true when the application was seen not to do what the check says +(a known failure, only for the check that failed). Text checks wait up to "timeout" seconds (default 5). +Actions that need an element wait up to "timeout" seconds (default 5) for it to appear.""" + +SELECTOR = {'name', 'role', 'path', 'nth', 'exact'} +# step name -> (required keys, allowed optional keys) +STEPS = { + 'do': { + 'click': ((), SELECTOR | {'mouse'}), 'rightclick': ((), SELECTOR), 'doubleclick': ((), SELECTOR), + 'focus': ((), SELECTOR), 'hover': ((), SELECTOR), + 'settext': (('value',), SELECTOR), 'type': (('value',), set()), 'key': (('keys',), set()), + 'wait': ((), SELECTOR | {'gone'}), 'restart': ((), set()), + 'sleep': (('seconds',), set()), 'write': (('path', 'content'), set()), 'copy': (('from', 'to'), set()), + }, + 'expect': { + 'visible': ((), SELECTOR), 'gone': ((), SELECTOR), 'value': (('equals',), SELECTOR), 'exited': ((), set()), + 'state': ((), SELECTOR | {'state', 'not_state'}), + 'text': ((), {'contains', 'not_contains'}), 'file': (('path',), {'contains', 'not_contains', 'regex'}), + 'alive': ((), set()), 'ocr': ((), {'contains', 'not_contains'}), + 'capture': (('regex', 'as'), SELECTOR), + }, +} +NEEDS_SELECTOR = {'click', 'rightclick', 'doubleclick', 'focus', 'hover', 'settext', 'wait', 'visible', 'gone', 'state', 'value', + 'capture'} +STATES = {'showing', 'enabled', 'focused', 'selected', 'expanded', 'checked', 'editable', 'modal'} + + +def validate_script(script, where='script'): + if not isinstance(script, list): + return [where + ': must be a list of steps'] + errors = [] + for i, step in enumerate(script, 1): + w = '%s step %d' % (where, i) + if not isinstance(step, dict): + errors.append(w + ': not an object') + continue + kinds = [k for k in ('do', 'expect') if k in step] + if len(kinds) != 1: + errors.append(w + ': needs exactly one of "do" or "expect"') + continue + kind, action = kinds[0], step[kinds[0]] + if action not in STEPS[kind]: + errors.append('%s: unknown %s "%s", use one of %s' % (w, kind, action, ', '.join(STEPS[kind]))) + continue + required, optional = STEPS[kind][action] + allowed = set(required) | optional | {kind, 'label', 'timeout'} | ({'observed_fail'} if kind == 'expect' else set()) + for k in step: + if k not in allowed: + errors.append('%s: "%s" is not used by %s %s' % (w, k, kind, action)) + for k in required: + if k not in step: + errors.append('%s: %s %s needs "%s"' % (w, kind, action, k)) + if action in NEEDS_SELECTOR and not (SELECTOR - {'nth', 'exact'}) & set(step): + errors.append('%s: %s %s needs name, role or path' % (w, kind, action)) + if action in ('text', 'ocr') and not {'contains', 'not_contains'} & set(step): + errors.append(w + ': expect %s needs contains or not_contains' % action) + if action == 'state' and not {'state', 'not_state'} & set(step): + errors.append(w + ': expect state needs state or not_state') + for k in ('state', 'not_state'): + if k in step and step[k] not in STATES: + errors.append('%s: unknown state "%s", use one of %s' % (w, step[k], ', '.join(sorted(STATES)))) + if action == 'capture': + try: + re.compile(step['regex']) + except (re.error, TypeError) as e: + errors.append('%s: bad regex: %s' % (w, e)) + if not re.fullmatch(r'[\w-]+', str(step['as'])): + errors.append(w + ': "as" must be a name of letters, digits, _ and -') + if script and not any('expect' in s for s in script if isinstance(s, dict)): + errors.append(where + ': needs at least one "expect" step, otherwise nothing is tested') + return errors + + +STEP_RE = re.compile(r'^(Given|When|Then|And|But|\*)\s+\S') +SCENARIO_RE = re.compile(r'^(Scenario Outline|Scenario Template|Scenario|Example):\s*(.*)$') +TAG_RE = re.compile(r'^@[^\s@]+$') +DOCSTRING = ('"""', '```') + + +class ParseError(ValueError): + pass + + +def validate_steps(lines, where, need_then=True): + """Errors in the Gherkin lines of a scenario or background.""" + errors, fence, keyword = [], None, None + for n, line in enumerate(lines, 1): + s = line.strip() + if fence: + if s == fence: + fence = None + continue + if s.startswith(DOCSTRING) or s.startswith('|'): + if keyword is None: + errors.append('%s line %d: a doc string or table must come after a step' % (where, n)) + if s.startswith(DOCSTRING): + fence = s[:3] + continue + m = STEP_RE.match(s) + if not m: + errors.append('%s line %d: a step must start with Given, When, Then, And, But or *: %s' % (where, n, s)) + continue + if keyword is None and m.group(1) in ('And', 'But'): + errors.append('%s line %d: the first step can not start with %s' % (where, n, m.group(1))) + keyword = keyword if m.group(1) in ('And', 'But', '*') else m.group(1) + if fence: + errors.append(where + ': a doc string is not closed with ' + fence) + if need_then and not any(re.match(r'^Then\s', line.strip()) for line in lines): + errors.append(where + ': needs a Then step, the expected result') + return errors + + +def parse(text): + """A .feature file as a test file dict. Raises ParseError.""" + doc = {'title': '', 'tests': []} + tags, section, fence, indent, table = [], None, None, 0, None + lines = text.splitlines() + + def fail(n, msg): + raise ParseError('line %d: %s' % (n, msg)) + + for n, raw in enumerate(lines, 1): + s = raw.strip() + if fence: # inside a doc string, kept as it is + section['steps'].append(raw[indent:] if raw[:indent].strip() == '' else s) + if s == fence: + section['steps'][-1] = s + fence = None + continue + if not s or s.startswith('#'): + continue + if s.startswith('@'): + for tag in s.split('#')[0].split(): + if not TAG_RE.match(tag): + fail(n, 'bad tag ' + tag) + tags.append(tag[1:]) + continue + table = table if s.startswith('|') else None + if s.startswith('Feature:'): + if 'feature' in doc: + fail(n, 'only one Feature per file') + doc['feature'] = True + doc['title'] = s[len('Feature:'):].strip() + if tags: + doc['tags'], tags = tags, [] + section = doc + continue + if 'feature' not in doc: + fail(n, 'the file must start with Feature:') + if s.startswith('Background:'): + if doc['tests'] or 'background' in doc: + fail(n, 'the Background must come before the scenarios, once') + doc['background'] = [] + section = {'steps': doc['background']} + continue + m = SCENARIO_RE.match(s) + if m: + section = scenario(m.group(2).strip(), tags) + doc['tests'].append(section) + tags = [] + continue + if s.startswith(('Rule:', 'Scenarios:')) or (s.startswith('Examples:') and section is doc): + fail(n, s.split(':')[0] + ' is not supported here') + if s.startswith('Examples:'): + if 'name' not in section: + fail(n, 'Examples only belong to a scenario') + section['examples'] = section.get('examples', []) + table = [] + continue + if table is not None: # a row of Examples + cells = [c.strip() for c in s.strip('|').split('|')] + if not s.endswith('|') or len(s) < 2: + fail(n, 'a table row must start and end with |') + if not table: + table.append(cells) + section['_columns'] = cells + elif len(cells) != len(table[0]): + fail(n, 'the row has %d cells, the header has %d' % (len(cells), len(table[0]))) + else: + section['examples'].append(dict(zip(table[0], cells))) + continue + if section is doc: + doc.setdefault('description', []).append(s) + continue + if 'examples' in section: + fail(n, 'steps must come before the Examples') + if not section['steps'] and not STEP_RE.match(s) and 'name' in section: + if s.startswith('TODO:'): # description lines of a scenario + section['todo'] = (section.get('todo', '') + '\n' + s[5:].strip()).strip() + else: + section.setdefault('description', []).append(s) + continue + section['steps'].append(s) + if s.startswith(DOCSTRING): + fence, indent = s[:3], len(raw) - len(raw.lstrip()) + if fence: + fail(len(lines), 'the doc string is not closed') + if 'feature' not in doc: + fail(1, 'no Feature: in the file') + del doc['feature'] + for t in doc['tests']: + if 'examples' in t and not t['examples']: + raise ParseError('%s: Examples without rows' % t['name']) + t.pop('_columns', None) + return doc + + +def scenario(name, tags): + t = {'name': name, 'steps': []} + other = [] + for tag in tags: + key, _, value = tag.partition(':') + if key == 'id' and value: + t['id'] = value + elif key == 'ticket' and value: + t['ticket'] = '#' + value if value.isdigit() else value + elif key == 'project' and value: + t.setdefault('projects', []).append(value) + elif key == 'edition' and value: + t.setdefault('editions', []).append(value) + elif tag == 'disabled': + t['enabled'] = False + else: + other.append(tag) + if other: + t['tags'] = other + return t + + +def write_steps(out, lines, indent): + """Doc strings and tables are indented below their step.""" + fence = None + for line in lines: + s = line.strip() + inner = fence or s.startswith(DOCSTRING) or s.startswith('|') + out.append((indent + ' ' * bool(inner) + line) if line else '') + if fence and s == fence: + fence = None + elif not fence and s.startswith(DOCSTRING): + fence = s[:3] + + +def table(rows): + cols = list(rows[0]) + width = {c: max(len(c), *(len(r.get(c, '')) for r in rows)) for c in cols} + fmt = lambda cells: '| ' + ' | '.join(v.ljust(width[c]) for c, v in zip(cols, cells)) + ' |' + return [fmt(cols)] + [fmt([r.get(c, '') for c in cols]) for r in rows] + + +def to_gherkin(doc): + out = [] + if doc.get('tags'): + out.append(' '.join('@' + t for t in doc['tags'])) + out.append('Feature: ' + doc.get('title', '')) + for line in doc.get('description', []): + out.append(' ' + line) + if doc.get('background'): + out += ['', ' Background:'] + write_steps(out, doc['background'], ' ') + for t in doc['tests']: + tags = ['id:' + t['id']] if t.get('id') else [] + if t.get('ticket'): + tags.append('ticket:' + t['ticket'].lstrip('#')) + tags += ['project:' + p for p in t.get('projects', [])] + if t.get('editions') and len(t['editions']) < len(EDITIONS): + tags += ['edition:' + e for e in t['editions']] + if t.get('enabled') is False: + tags.append('disabled') + tags += t.get('tags', []) + out.append('') + if tags: + out.append(' ' + ' '.join('@' + x for x in tags)) + out.append(' %s: %s' % ('Scenario Outline' if t.get('examples') else 'Scenario', t['name'])) + for line in t.get('description', []): + out.append(' ' + line) + for line in (t.get('todo') or '').splitlines(): + out.append(' TODO: ' + line.strip()) + write_steps(out, t.get('steps', []), ' ') + if t.get('examples'): + out += ['', ' Examples:'] + out += [' ' + row for row in table(t['examples'])] + return '\n'.join(out) + '\n' + + +def legacy_steps(steps, expected): + """Steps and expected result in plain words (markdown and older JSON files) as Gherkin lines.""" + lines = [] + for s in steps: + if s.startswith(('* ', '- ')) and lines: + lines[-1] += ' ' + s[2:] + else: + lines.append(('Given ' if not lines else 'When ' if len(lines) == 1 else 'And ') + s) + if expected: + lines.append('Then ' + ' '.join(expected.split())) + return lines + + +def from_legacy_json(old): + """An older JSON test file: steps, expected and a matrix of axes.""" + doc = {'title': old.get('title', ''), 'tests': []} + for o in old.get('tests', []): + t = {k: o[k] for k in ('id', 'name', 'ticket', 'enabled', 'todo', 'projects', 'editions', 'script', 'script_for') + if k in o} + matrix = o.get('matrix') or {} + steps = legacy_steps(o.get('steps', []), o.get('expected', '')) + t['steps'] = [re.sub(r'\{(%s)\}' % '|'.join(map(re.escape, matrix)), r'<\1>', s) if matrix else s for s in steps] + if matrix: + t['examples'] = [dict(zip(matrix, v)) for v in itertools.product(*matrix.values())] + doc['tests'].append(t) + return doc + + +def from_markdown(text): + m = re.search(r'^#\s+(.+)$', text, re.M) + doc = {'title': m.group(1).strip() if m else '', 'tests': []} + for m in re.finditer(r'^## Test:\s*(.+?)\s*\n(.*?)(?=^## |\Z)', text, re.S | re.M): + test = {'name': m.group(1), 'steps': [], 'expected': '', 'todo': ''} + field = None + for line in m.group(2).splitlines(): + s = line.strip() + if s.startswith('Ticket:'): + test['ticket'] = s[len('Ticket:'):].strip() + field = None + elif s.startswith('EXPECTED:'): + test['expected'] = s[len('EXPECTED:'):].strip() + field = 'expected' + elif s.startswith('TODO:'): + test['todo'] = s[len('TODO:'):].strip() + field = 'todo' + elif not s: + field = None + elif field: + test[field] += '\n' + s + else: + test['steps'].append(re.sub(r'^\d+\.\s+', '', s)) + test['steps'] = legacy_steps(test['steps'], test.pop('expected')) + if not test['todo']: + del test['todo'] + doc['tests'].append(test) + return doc + + +def validate(doc, root=None): + """Return a list of error strings, empty when the document is fine. With ROOT (the directory of + the test file) the test projects must exist.""" + errors = [] + if not isinstance(doc, dict) or not isinstance(doc.get('tests'), list): + return ['the document needs a "tests" list'] + if not isinstance(doc.get('title', ''), str) or '\n' in doc.get('title', ''): + errors.append('the title must be one line') + background = doc.get('background', []) + if not isinstance(background, list) or not all(isinstance(s, str) for s in background): + errors.append('the background must be a list of lines') + else: + errors += validate_steps(background, 'Background', need_then=False) + names = set() + for i, t in enumerate(doc['tests'], 1): + where = 'test %d' % i + if not isinstance(t, dict): + errors.append(where + ': not an object') + continue + name = t.get('name') + if not isinstance(name, str) or not name.strip(): + errors.append(where + ': name is missing') + elif '\n' in name: + errors.append(where + ': the name must be one line') + elif name in names: + errors.append('%s: duplicate name "%s"' % (where, name)) + else: + names.add(name) + steps = t.get('steps', []) + if not isinstance(steps, list) or not all(isinstance(s, str) and '\n' not in s for s in steps): + errors.append(where + ': steps must be a list of lines') + else: + errors += validate_steps(steps, where) + for k in ('todo', 'ticket', 'id'): + if not isinstance(t.get(k, ''), str): + errors.append('%s: %s must be a string' % (where, k)) + if re.search(r'\s', t.get('ticket', '') or '') or re.search(r'\W', t.get('id', '') or ''): + errors.append(where + ': the ticket and the id can not have spaces, they are tags') + projects = t.get('projects', []) + if not isinstance(projects, list) or not all(isinstance(p, str) and PROJECT_RE.match(p) for p in projects): + errors.append(where + ': projects must be a list of project names (letters, digits, _ and -)') + elif root: + errors += ['%s: the test project "%s" does not exist' % (where, p) for p in projects + if not os.path.isdir(os.path.join(root, PROJECTS, p))] + editions = t.get('editions', list(EDITIONS)) + if (not isinstance(editions, list) or not editions or len(set(editions)) != len(editions) + or not all(e in EDITIONS for e in editions)): + errors.append('%s: editions must be a list of one or more of %s' % (where, ', '.join(EDITIONS))) + errors += validate_script(t.get('script', []), where + ' script') + examples = t.get('examples', []) + if not isinstance(examples, list) or not all(isinstance(r, dict) for r in examples): + errors.append(where + ': examples must be a list of rows') + continue + if examples: + cols = list(examples[0]) + for c in cols: + if not AXIS_RE.match(c): + errors.append('%s: Examples column "%s" must be letters, digits and _' % (where, c)) + if any(list(r) != cols for r in examples): + errors.append(where + ': every row of the Examples must have the same columns') + if not all(isinstance(v, str) and v and '|' not in v for r in examples for v in r.values()): + errors.append(where + ': every cell of the Examples needs a value without |') + if len({json.dumps(r, sort_keys=True) for r in examples}) != len(examples): + errors.append(where + ': a row of the Examples is there twice') + return errors + + +def scripts_path(path): + return path[:-len(EXT)] + SCRIPTS_EXT if path.endswith(EXT) else path + SCRIPTS_EXT + + +def load(path): + with open(path, encoding='utf-8') as f: + text = f.read() + if path.endswith('.md'): + return from_markdown(text) + if path.endswith('.json'): + return from_legacy_json(json.loads(text)) + doc = parse(text) + try: + with open(scripts_path(path), encoding='utf-8') as f: + scripts = json.load(f) + except FileNotFoundError: + scripts = {} + for t in doc['tests']: + s = scripts.get(t.get('id')) if t.get('id') else None + if isinstance(s, dict) and s.get('script'): + t['script'] = s['script'] + if s.get('script_for'): + t['script_for'] = s['script_for'] + return doc + + +def combinations(test): + """The rows of the Examples of a test as a list of {column: value}; [{}] when there are none.""" + return [dict(r) for r in test.get('examples') or []] or [{}] + + +def editions(test): + """The editions that a test is for, all of them when it does not say.""" + return test.get('editions') or list(EDITIONS) + + +def substitute(text, combo): + return re.sub(r'\{([\w:-]+)\}', lambda m: combo.get(m.group(1), m.group(0)), text) + + +def substitute_step(text, combo): + """ of the Examples and {edition} in a line of the steps.""" + text = re.sub(r'<(\w+)>', lambda m: combo.get(m.group(1), m.group(0)), text) + return substitute(text, {k: v for k, v in combo.items() if k == 'edition'}) + + +def body(test, combo, edition=None, background=()): + """The test as it is shown to Claude: the scenario in Gherkin, with the values of the run.""" + parts = [] + if test.get('ticket'): + parts.append('Ticket: ' + test['ticket']) + if edition: + parts.append('Edition of the application: ' + edition) + if combo: + parts.append('Examples row for this run: ' + ', '.join('%s=%s' % kv for kv in combo.items())) + combo = dict(combo, edition=edition) if edition else combo + lines = [] + if background: + lines += ['Background:'] + [' ' + substitute_step(s, combo) for s in background] + [''] + lines += ['Scenario: ' + test['name']] + [' ' + substitute_step(s, combo) for s in test.get('steps', [])] + parts.append('\n'.join(lines)) + if test.get('todo'): + parts.append('TODO: ' + substitute_step(test['todo'], combo)) + return '\n\n'.join(parts) + + +def project_files(root, name): + """{relative path: bytes} of a test project.""" + base = os.path.join(root, PROJECTS, name) + out = {} + for dirpath, _, files in os.walk(base): + for f in files: + p = os.path.join(dirpath, f) + with open(p, 'rb') as fh: + out[os.path.relpath(p, base)] = fh.read() + return out + + +def project_hash(root, name): + h = hashlib.sha1() + for path, data in sorted(project_files(root, name).items()): + h.update(path.encode() + b'\0' + data + b'\0') + return h.hexdigest()[:12] + + +def materialize(root, names, work): + """Copy the test projects to WORK/projects/NAME. Returns the variables for the script.""" + variables = {} + for name in names: + src = os.path.join(root, PROJECTS, name) + if not os.path.isdir(src): + raise FileNotFoundError('the test project "%s" does not exist' % name) + dst = os.path.join(work, PROJECTS, name) + shutil.copytree(src, dst) + variables['project:' + name] = dst + if len(names) == 1: + variables['project'] = variables['project:' + names[0]] + return variables + + +def definition_hash(test, root=None, background=()): + """What a script depends on: changing any of these, the Background of the file or a file of a + test project makes the script outdated.""" + d = {'steps': list(background or []) + list(test.get('steps') or []), 'todo': test.get('todo') or '', + 'examples': test.get('examples') or []} + if test.get('projects'): + d['projects'] = {p: project_hash(root, p) if root and os.path.isdir(os.path.join(root, PROJECTS, p)) else 'missing' + for p in test['projects']} + return hashlib.sha1(json.dumps(d, sort_keys=True, ensure_ascii=False).encode()).hexdigest()[:12] + + +def ensure_ids(doc): + for t in doc.get('tests', []): + if not t.get('id'): + t['id'] = 't' + hashlib.sha1(str(t.get('name', '')).encode()).hexdigest()[:8] + return doc + + +def is_stale(test, root=None, background=()): + """A script that was made for another version of the test. No script_for: old file, trusted.""" + return bool(test.get('script') and test.get('script_for') + and test['script_for'] != definition_hash(test, root, background)) + + +def stamp_scripts(doc, old, root=None): + """Before saving. A new, edited or approved ("_approve") script is current for the test as it is + now. An untouched script keeps what it was made for, so editing the test makes it outdated.""" + ensure_ids(doc) + old = ensure_ids(old or {}) + prev = {t['id']: t for t in old.get('tests', [])} + for t in doc['tests']: + t.pop('_stale', None) + approve = t.pop('_approve', False) + if not t.get('script'): + t.pop('script_for', None) + continue + p = prev.get(t['id']) + if approve or p is None or p.get('script') != t['script']: + t['script_for'] = definition_hash(t, root, doc.get('background')) + else: + t['script_for'] = p.get('script_for') or definition_hash(p, root, old.get('background')) + return doc + + +def subst_deep(obj, combo): + if isinstance(obj, str): + return substitute(obj, combo) + if isinstance(obj, list): + return [subst_deep(x, combo) for x in obj] + if isinstance(obj, dict): + return {k: subst_deep(v, combo) for k, v in obj.items()} + return obj + + +def expand(path, edition=None): + """One dict {name, id, body, script, stale, combo} per Examples row of every enabled test. + With EDITION only the tests for that edition, and {edition} is replaced.""" + doc = ensure_ids(load(path)) + root = os.path.dirname(os.path.abspath(path)) + errors = validate(doc, root) + if errors: + sys.exit('error: %s: %s' % (path, '; '.join(errors))) + background = doc.get('background', []) + out = [] + for t in doc['tests']: + if not t.get('enabled', True) or edition and edition not in editions(t): + continue + for combo in combinations(t): + name = t['name'] + (' [%s]' % ', '.join('%s=%s' % kv for kv in combo.items()) if combo else '') + values = dict(combo, edition=edition) if edition else combo + out.append({'name': name, 'id': t['id'], 'body': body(t, combo, edition, background), 'combo': combo, + 'root': root, 'projects': t.get('projects', []), 'stale': is_stale(t, root, background), + 'script': subst_deep(t.get('script', []), values)}) + return out + + +def write_atomic(path, text): + tmp = path + '.tmp' + with open(tmp, 'w', encoding='utf-8') as f: + f.write(text) + os.replace(tmp, path) + + +def save(path, doc): + """Write FILE.feature and the scripts in FILE.scripts.json.""" + if not path.endswith(EXT): + raise ValueError('a test file is saved as ' + EXT) + ensure_ids(doc) + scripts = {t['id']: {k: t[k] for k in ('script', 'script_for') if t.get(k)} for t in doc['tests'] if t.get('script')} + write_atomic(path, to_gherkin(doc)) + if scripts: + write_atomic(scripts_path(path), json.dumps(scripts, indent=2, ensure_ascii=False) + '\n') + elif os.path.exists(scripts_path(path)): + os.remove(scripts_path(path)) + + +def convert(src, dst): + """Import a markdown or an older JSON test file. Scripts that were up to date stay up to date.""" + root = os.path.dirname(os.path.abspath(src)) + current = set() + if src.endswith('.json'): + with open(src, encoding='utf-8') as f: + old = json.load(f) + for o in old.get('tests', []): + d = {k: o.get(k) or ([] if k == 'steps' else {} if k == 'matrix' else '') for k in ('steps', 'expected', 'todo', 'matrix')} + if o.get('projects'): + d['projects'] = {p: project_hash(root, p) if os.path.isdir(os.path.join(root, PROJECTS, p)) else 'missing' + for p in o['projects']} + h = hashlib.sha1(json.dumps(d, sort_keys=True, ensure_ascii=False).encode()).hexdigest()[:12] + if o.get('script') and o.get('script_for') in (None, h): + current.add(o.get('id')) + doc = ensure_ids(load(src)) + for t in doc['tests']: + if t['id'] in current: + t['script_for'] = definition_hash(t, os.path.dirname(os.path.abspath(dst)), doc.get('background')) + save(dst, doc) + + +if __name__ == '__main__': + if len(sys.argv) != 4 or sys.argv[1] != 'convert' or not sys.argv[3].endswith(EXT): + sys.exit(__doc__) + convert(sys.argv[2], sys.argv[3]) diff --git a/gui/manualtest/tests/analysis.feature b/gui/manualtest/tests/analysis.feature new file mode 100644 index 00000000000..fc43506dd98 --- /dev/null +++ b/gui/manualtest/tests/analysis.feature @@ -0,0 +1,55 @@ +Feature: Analysis and recheck + + Background: + Given the application is started with no project loaded + + @id:te65b1fa8 @project:basic-project + Scenario: Reanalyze all files + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I change {project:basic-project}/src/a.c and {project:basic-project}/src/b.c so that they only contain ";" + And I click Reanalyze all files + And I wait until the analysis is done + Then there are no results for a.c + And there are no results for b.c + + @id:tc707b85b @ticket:14893 @project:recheck + Scenario: Recheck a changed file + Given the project file {project:recheck}/p.cppcheck is opened + And the analysis is done + And the results show a nullPointer error in a.c and an arrayIndexOutOfBounds error in b.c + When I copy {project:recheck}/a_v2.c over {project:recheck}/a.c (a_v2.c has an uninitvar error instead) + And I right click on the file a.c in the results and click Recheck + Then the results for a.c are refreshed + And the nullPointer error in a.c is gone + And the uninitvar error from the changed a.c is shown + And the arrayIndexOutOfBounds error in b.c is still shown, unchanged + + @id:tc550387d @project:basic-project + Scenario: Recheck a header file + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I right click on the file util.h in the results + Then the context menu of util.h has a Recheck entry + When I click Recheck + And I wait until the analysis is done + Then the analysis is run again for the files that include util.h + And the nullPointer error in util.h is shown again + + @id:ta6f3b40b @project:syntax-error + Scenario Outline: Analyze a broken source file + Given the project file {project:syntax-error}/.cppcheck checks .c, a broken or unusual source file, and ok.c, which has a nullPointer error + When I open the project file {project:syntax-error}/.cppcheck + And I wait until the analysis is done + Then the analysis finishes + And the application does not crash + And the nullPointer error in ok.c is shown + + Examples: + | case | + | braces | + | empty | + | binary | + | latin1 | + | long_line | + | unclosed_nesting | diff --git a/gui/manualtest/tests/analysis.scripts.json b/gui/manualtest/tests/analysis.scripts.json new file mode 100644 index 00000000000..54d89a4c39d --- /dev/null +++ b/gui/manualtest/tests/analysis.scripts.json @@ -0,0 +1,399 @@ +{ + "te65b1fa8": { + "script": [ + { + "label": "Open the File menu", + "do": "click", + "name": "File", + "role": "menu item" + }, + { + "label": "Choose Open Project File", + "do": "click", + "name": "Open Project File", + "role": "menu item" + }, + { + "label": "Enter the project file path", + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck" + }, + { + "label": "Confirm the file dialog", + "do": "key", + "keys": [ + "Return" + ] + }, + { + "label": "Wait until the first analysis shows results for a.c", + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "timeout": 30 + }, + { + "label": "Results for b.c are shown too", + "expect": "visible", + "name": "src/b.c", + "role": "table cell" + }, + { + "label": "Edit a.c so it only contains ;", + "do": "write", + "path": "{project:basic-project}/src/a.c", + "content": ";" + }, + { + "label": "Edit b.c so it only contains ;", + "do": "write", + "path": "{project:basic-project}/src/b.c", + "content": ";" + }, + { + "label": "Click Reanalyze all files", + "do": "click", + "name": "Reanalyze all files", + "role": "button" + }, + { + "label": "Wait until the analysis is done (No errors found dialog)", + "expect": "visible", + "name": "No errors found", + "role": "label", + "timeout": 30 + }, + { + "label": "Close the dialog", + "do": "click", + "name": "OK", + "role": "button" + }, + { + "label": "No results for a.c", + "expect": "gone", + "name": "src/a.c", + "role": "table cell" + }, + { + "label": "No results for b.c", + "expect": "gone", + "name": "src/b.c", + "role": "table cell" + } + ], + "script_for": "c692e526a6cd" + }, + "tc707b85b": { + "script": [ + { + "do": "wait", + "name": "Cppcheck", + "role": "frame", + "timeout": 20, + "label": "Application started with no project" + }, + { + "do": "click", + "name": "Open Project File", + "role": "button", + "label": "Open the project file dialog" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:recheck}/p.cppcheck", + "label": "Enter the path of p.cppcheck" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Open the project" + }, + { + "expect": "visible", + "name": "b.c", + "role": "table cell", + "timeout": 30, + "label": "Analysis done, b.c in the results" + }, + { + "expect": "visible", + "name": "a.c", + "role": "table cell", + "timeout": 30, + "label": "a.c in the results" + }, + { + "do": "sleep", + "seconds": 3, + "label": "Let the analysis finish" + }, + { + "do": "copy", + "from": "{project:recheck}/a_v2.c", + "to": "{project:recheck}/a.c", + "label": "Change a.c by copying a_v2.c over it" + }, + { + "do": "rightclick", + "name": "a.c", + "role": "table cell", + "nth": 0, + "label": "Right click on a.c in the results" + }, + { + "expect": "ocr", + "contains": "Recheck", + "label": "Context menu shows Recheck" + }, + { + "do": "key", + "keys": [ + "Down", + "Return" + ], + "label": "Click Recheck" + }, + { + "do": "sleep", + "seconds": 4, + "label": "Wait for the recheck" + }, + { + "do": "click", + "name": "b.c", + "role": "table cell", + "nth": 0, + "label": "Select the b.c row" + }, + { + "do": "key", + "keys": [ + "Right", + "Down", + "Down", + "Down", + "Right" + ], + "label": "Expand b.c and a.c to show their results" + }, + { + "expect": "text", + "contains": "uninitvar", + "label": "The uninitvar error of the changed a.c is shown" + }, + { + "expect": "text", + "not_contains": "nullPointer", + "label": "The nullPointer error is gone" + }, + { + "expect": "text", + "contains": "arrayIndexOutOfBounds", + "label": "The arrayIndexOutOfBounds error in b.c is still shown" + } + ], + "script_for": "0c160519508a" + }, + "tc550387d": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the project file path" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the file dialog" + }, + { + "expect": "visible", + "name": "include/util.h", + "role": "table cell", + "timeout": 30, + "label": "Analysis is done and util.h is in the results" + }, + { + "expect": "visible", + "name": "src/b.c", + "role": "table cell", + "timeout": 30, + "label": "Analysis finished for all files" + }, + { + "do": "rightclick", + "name": "include/util.h", + "role": "table cell", + "label": "Right click on util.h in the results" + }, + { + "do": "sleep", + "seconds": 1, + "label": "Wait for the context menu" + }, + { + "do": "key", + "keys": [ + "Down", + "Return" + ], + "label": "Click the Recheck entry of the context menu" + }, + { + "expect": "text", + "contains": "Checking /tmp", + "timeout": 30, + "label": "The analysis was run again" + }, + { + "expect": "text", + "contains": "src/a.c ...", + "timeout": 30, + "label": "The file that includes util.h is checked again" + }, + { + "do": "sleep", + "seconds": 3, + "label": "Wait until the analysis is done" + }, + { + "do": "click", + "name": "include/util.h", + "role": "table cell", + "mouse": true, + "label": "Select util.h with the mouse so it has focus" + }, + { + "do": "key", + "keys": [ + "Right" + ], + "label": "Expand util.h" + }, + { + "expect": "visible", + "name": "nullPointer", + "role": "table cell", + "timeout": 10, + "label": "The nullPointer error in util.h is shown again" + }, + { + "expect": "visible", + "name": "Null pointer dereference", + "role": "table cell", + "timeout": 5, + "label": "The nullPointer message is shown" + } + ], + "script_for": "dc8fcd30e236" + }, + "ta6f3b40b": { + "script": [ + { + "label": "Start the application with no project loaded", + "expect": "visible", + "name": "Cppcheck", + "role": "frame" + }, + { + "label": "Open the project file", + "do": "click", + "name": "Open Project File", + "role": "button" + }, + { + "label": "Wait for the Select Project File dialog", + "do": "wait", + "name": "Select Project File", + "timeout": 10 + }, + { + "label": "Enter the project file {case}.cppcheck", + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:syntax-error}/{case}.cppcheck" + }, + { + "label": "Confirm the file dialog", + "do": "key", + "keys": [ + "Return" + ] + }, + { + "label": "The project is loaded", + "expect": "visible", + "name": "Project: {case}.cppcheck", + "role": "frame", + "timeout": 15 + }, + { + "label": "Wait until the analysis is done (ok.c is checked)", + "expect": "text", + "contains": "Checking ok.c", + "timeout": 60 + }, + { + "label": "Give the analysis time to finish", + "do": "sleep", + "seconds": 3 + }, + { + "label": "The analysis finishes: Stop analysis is disabled again", + "expect": "state", + "name": "Stop analysis", + "role": "button", + "not_state": "enabled", + "timeout": 60 + }, + { + "label": "The analysis finishes: Reanalyze all files is enabled again", + "expect": "state", + "name": "Reanalyze all files", + "role": "button", + "state": "enabled", + "timeout": 30 + }, + { + "label": "The broken source file {case}.c was analyzed", + "expect": "text", + "contains": "Checking {case}.c" + }, + { + "label": "The nullPointer error in ok.c is shown (ok.c has a result row)", + "expect": "visible", + "name": "ok.c", + "role": "table cell" + }, + { + "label": "The application does not crash", + "expect": "alive" + } + ], + "script_for": "3090dfe1cf47" + } +} diff --git a/gui/manualtest/tests/application.feature b/gui/manualtest/tests/application.feature new file mode 100644 index 00000000000..378e1a636cc --- /dev/null +++ b/gui/manualtest/tests/application.feature @@ -0,0 +1,59 @@ +Feature: Application, menus and help + + Background: + Given the application is started with no project loaded + + @id:t41f9102b + Scenario: All menus open + When I open each of the menus File, Edit, View, Analyze and Help in turn + And I look at its entries and close it with Escape + Then each of the menus File, Edit, View, Analyze and Help opens + And each menu shows at least one entry + + @id:t1cc2be0f + Scenario: Show and hide toolbars + Given all entries of View > Toolbar are checked + When I uncheck the entries of View > Toolbar one at a time + Then a toolbar that is unchecked is no longer shown in the main window + And the toolbars that are still checked are shown + + @id:t5fdeee58 @edition:opensource + Scenario: Same version in the title and in About + Given the title of the main window is "Cppcheck " + When I note the version in the title + And I open Help > About + Then the About dialog shows the same version as the title of the main window + + @id:t90321d9c + Scenario: Help contents + When I open Help > Contents + Then a help window opens + And the help window has contents, it is not empty + + @id:tc059b730 + Scenario: Other Help menu entries + When I open each of the other entries of the Help menu in turn (About and the rest) + And I close each window with Escape or its Close button + Then every entry opens a dialog or window with text in it + And none of them is empty + + @id:t5bf8f6ae @ticket:13982 + Scenario: Scratch pad + When I open View > Scratch Pad + And I enter this code, one line each: + """ + int main(void) + { + int *p = 0; + return *p; + } + """ + And I click Check + Then the code is analysed + And a nullPointer error is shown + And the application does not crash + + @id:t1a2285d8 + Scenario: Quit from the File menu + When I open File > Quit + Then the application closes diff --git a/gui/manualtest/tests/application.scripts.json b/gui/manualtest/tests/application.scripts.json new file mode 100644 index 00000000000..98f5b20a42d --- /dev/null +++ b/gui/manualtest/tests/application.scripts.json @@ -0,0 +1,548 @@ +{ + "t41f9102b": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "expect": "visible", + "name": "Open XML...", + "role": "menu item", + "label": "File menu shows entries" + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Close the File menu" + }, + { + "do": "click", + "name": "Edit", + "role": "menu item", + "label": "Open the Edit menu" + }, + { + "expect": "visible", + "name": "Clear results", + "role": "menu item", + "label": "Edit menu shows entries" + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Close the Edit menu" + }, + { + "do": "click", + "name": "View", + "role": "menu item", + "label": "Open the View menu" + }, + { + "expect": "visible", + "name": "Toolbars", + "role": "menu item", + "label": "View menu shows entries" + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Close the View menu" + }, + { + "do": "click", + "name": "Analyze", + "role": "menu item", + "label": "Open the Analyze menu" + }, + { + "expect": "visible", + "name": "Files...", + "role": "menu item", + "label": "Analyze menu shows entries" + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Close the Analyze menu" + }, + { + "do": "click", + "name": "Help", + "role": "menu item", + "label": "Open the Help menu" + }, + { + "expect": "visible", + "name": "Contents", + "role": "menu item", + "label": "Help menu shows entries" + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Close the Help menu" + } + ], + "script_for": "06424398d415" + }, + "t1cc2be0f": { + "script": [ + { + "do": "click", + "name": "View", + "role": "menu item", + "label": "Open View menu" + }, + { + "do": "click", + "name": "Toolbars", + "role": "menu item", + "label": "Open Toolbars submenu" + }, + { + "expect": "state", + "name": "Standard", + "role": "menu item", + "state": "checked", + "label": "Standard toolbar entry is checked" + }, + { + "expect": "state", + "name": "Categories", + "role": "menu item", + "state": "checked", + "label": "Categories toolbar entry is checked" + }, + { + "expect": "state", + "name": "Filter", + "role": "menu item", + "state": "checked", + "label": "Filter toolbar entry is checked" + }, + { + "do": "click", + "name": "Standard", + "role": "menu item", + "label": "Uncheck Standard toolbar" + }, + { + "expect": "gone", + "name": "Standard", + "role": "tool bar", + "label": "Standard toolbar is no longer shown" + }, + { + "expect": "visible", + "name": "Categories", + "role": "tool bar", + "label": "Categories toolbar still shown" + }, + { + "expect": "visible", + "name": "Filter", + "role": "tool bar", + "label": "Filter toolbar still shown" + }, + { + "do": "click", + "name": "Categories", + "role": "menu item", + "label": "Uncheck Categories toolbar" + }, + { + "expect": "gone", + "name": "Categories", + "role": "tool bar", + "label": "Categories toolbar is no longer shown" + }, + { + "expect": "visible", + "name": "Filter", + "role": "tool bar", + "label": "Filter toolbar still shown" + }, + { + "do": "click", + "name": "Filter", + "role": "menu item", + "label": "Uncheck Filter toolbar" + }, + { + "expect": "gone", + "name": "Filter", + "role": "tool bar", + "label": "Filter toolbar is no longer shown" + } + ], + "script_for": "6a99d7841493" + }, + "t5fdeee58": { + "script": [ + { + "expect": "capture", + "name": "Cppcheck", + "role": "frame", + "regex": "'Cppcheck (?:Premium )?(\\d[^']*)'", + "as": "version", + "label": "Note the version in the title of the main window" + }, + { + "do": "click", + "name": "Help", + "role": "menu item", + "label": "Open the Help menu" + }, + { + "do": "click", + "name": "About...", + "role": "menu item", + "label": "Open Help > About" + }, + { + "expect": "visible", + "name": "About Cppcheck", + "role": "dialog", + "label": "About dialog is shown" + }, + { + "expect": "visible", + "name": "Version {version}", + "role": "label", + "label": "About dialog shows the same version as the main window title ({version})" + } + ], + "script_for": "5dadee22b5ec" + }, + "t90321d9c": { + "script": [ + { + "do": "click", + "name": "Help", + "role": "menu item", + "label": "Open the Help menu" + }, + { + "do": "click", + "name": "Contents", + "role": "menu item", + "label": "Choose Help > Contents" + }, + { + "expect": "visible", + "name": "Cppcheck GUI help", + "role": "dialog", + "label": "A help window opens", + "observed_fail": true + }, + { + "expect": "text", + "contains": "Contents", + "label": "The help window has contents (it is not empty)" + }, + { + "expect": "text", + "not_contains": "was not found", + "label": "No error that the help file was not found" + } + ], + "script_for": "7c97b218aa0f" + }, + "tc059b730": { + "script": [ + { + "do": "click", + "name": "Help", + "role": "menu item", + "label": "Open the Help menu" + }, + { + "do": "click", + "name": "License...", + "role": "menu item", + "label": "Open License" + }, + { + "expect": "visible", + "name": "License", + "role": "dialog", + "label": "License dialog opens" + }, + { + "expect": "text", + "contains": "GNU GENERAL PUBLIC LICENSE", + "label": "License dialog has text" + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Close License with Escape" + }, + { + "expect": "gone", + "name": "License", + "label": "License dialog is closed" + }, + { + "do": "click", + "name": "Help", + "role": "menu item", + "label": "Open the Help menu" + }, + { + "do": "click", + "name": "Authors...", + "role": "menu item", + "label": "Open Authors" + }, + { + "expect": "visible", + "name": "Authors", + "role": "dialog", + "label": "Authors dialog opens" + }, + { + "expect": "text", + "contains": "The cppcheck team", + "label": "Authors dialog has text" + }, + { + "do": "click", + "name": "Close", + "role": "button", + "label": "Close Authors with its Close button" + }, + { + "expect": "gone", + "name": "Authors", + "role": "dialog", + "label": "Authors dialog is closed" + }, + { + "do": "click", + "name": "Help", + "role": "menu item", + "label": "Open the Help menu" + }, + { + "do": "click", + "name": "About...", + "role": "menu item", + "label": "Open About" + }, + { + "expect": "visible", + "name": "About Cppcheck", + "role": "dialog", + "label": "About dialog opens" + }, + { + "expect": "text", + "contains": "Cppcheck - A tool for static C/C++ code analysis.", + "label": "About dialog has text" + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Close About with Escape" + }, + { + "expect": "gone", + "name": "About Cppcheck", + "role": "dialog", + "label": "About dialog is closed" + }, + { + "do": "click", + "name": "Help", + "role": "menu item", + "label": "Open the Help menu" + }, + { + "do": "click", + "name": "Contents", + "role": "menu item", + "label": "Open Contents" + }, + { + "expect": "visible", + "name": "Cppcheck", + "role": "alert", + "label": "Contents shows a message" + }, + { + "expect": "text", + "contains": "Helpfile", + "label": "Message has text" + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Close the message with Escape" + }, + { + "expect": "visible", + "name": "Cppcheck GUI help", + "role": "dialog", + "label": "Help window opens" + }, + { + "expect": "text", + "contains": "Introduction", + "observed_fail": true, + "label": "Help window has text in it, not empty" + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Close the help window with Escape" + } + ], + "script_for": "97511d2313db" + }, + "t5bf8f6ae": { + "script": [ + { + "do": "click", + "name": "View", + "role": "menu item", + "label": "Open the View menu" + }, + { + "do": "click", + "name": "Show Scratchpad", + "role": "menu item", + "label": "Open View > Scratch Pad" + }, + { + "expect": "visible", + "name": "Scratchpad", + "role": "dialog", + "label": "Scratchpad dialog is shown" + }, + { + "do": "focus", + "path": "1.1", + "label": "Focus the code editor of the scratchpad" + }, + { + "do": "type", + "value": "int main(void)", + "label": "Type line 1" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "New line" + }, + { + "do": "type", + "value": "{", + "label": "Type line 2" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "New line" + }, + { + "do": "type", + "value": " int *p = 0;", + "label": "Type line 3" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "New line" + }, + { + "do": "type", + "value": " return *p;", + "label": "Type line 4" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "New line" + }, + { + "do": "type", + "value": "}", + "label": "Type line 5" + }, + { + "do": "click", + "name": "Check", + "role": "button", + "label": "Click Check" + }, + { + "expect": "text", + "contains": "nullPointer", + "timeout": 15, + "label": "A nullPointer error is shown" + }, + { + "expect": "text", + "contains": "Null pointer dereference: p", + "label": "The null pointer message is shown" + }, + { + "expect": "alive", + "label": "The application did not crash" + } + ], + "script_for": "30d9d26803fd" + }, + "t1a2285d8": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Quit", + "role": "menu item", + "label": "Choose File > Quit" + }, + { + "expect": "exited", + "label": "The application closes" + } + ], + "script_for": "bc31dd4069bf" + } +} diff --git a/gui/manualtest/tests/preferences.feature b/gui/manualtest/tests/preferences.feature new file mode 100644 index 00000000000..70d0a82fa47 --- /dev/null +++ b/gui/manualtest/tests/preferences.feature @@ -0,0 +1,42 @@ +Feature: Preferences + + Background: + Given the application is started with no project loaded + + @id:t232a9783 + Scenario: Default number of threads + When I open Edit > Preferences + And I look at the General tab + Then the number of threads is 1 + + @id:tf5b5a7e1 + Scenario: Number of threads cannot be 0 + Given Edit > Preferences is open on the General tab + When I type 0 in the number of threads field + And I close the dialog with OK + And I open Edit > Preferences again + Then the field has not accepted 0 + And the number of threads is at least 1, it is never 0 + + @id:t841cca6c @project:basic-project + Scenario: Analysis with 100 threads + Given the number of threads is set to 100 in Edit > Preferences and the dialog is closed with OK + When I open the project file {project:basic-project}/basic.cppcheck from the File menu + And I wait until the analysis is done + Then the application does not crash + And the analysis is done and the results are shown + + @id:t28ce8afe @project:embedded @edition:opensource @disabled + Scenario Outline: Misra rule text file + Given Edit > Preferences is open on the Addons tab + When I select the rule text file {project:embedded}/ + And I close the dialog with OK + And I open the project file {project:embedded}/embedded.cppcheck + And I wait until the analysis is done + Then the Misra error for the unused parameter has the rule text from the file (TEST RULE TEXT: unused parameters are not allowed) + And there are no internalError results + + Examples: + | rulefile | + | rules.txt | + | rules with spaces.txt | diff --git a/gui/manualtest/tests/preferences.scripts.json b/gui/manualtest/tests/preferences.scripts.json new file mode 100644 index 00000000000..2da801e7e71 --- /dev/null +++ b/gui/manualtest/tests/preferences.scripts.json @@ -0,0 +1,306 @@ +{ + "t232a9783": { + "script": [ + { + "do": "click", + "name": "Edit", + "role": "menu item", + "label": "Open the Edit menu" + }, + { + "do": "click", + "name": "Preferences", + "role": "menu item", + "label": "Open Edit > Preferences" + }, + { + "expect": "visible", + "name": "Preferences", + "role": "dialog", + "label": "Preferences dialog is shown" + }, + { + "expect": "state", + "name": "General", + "role": "page tab", + "state": "selected", + "label": "General tab is shown" + }, + { + "expect": "value", + "name": "Number of threads", + "role": "text", + "equals": "1", + "label": "The number of threads is 1" + } + ], + "script_for": "3c6d225d76b6" + }, + "tf5b5a7e1": { + "script": [ + { + "do": "click", + "name": "Edit", + "role": "menu item", + "label": "Open the Edit menu" + }, + { + "do": "click", + "name": "Preferences", + "role": "menu item", + "label": "Open Edit > Preferences" + }, + { + "expect": "visible", + "name": "Preferences", + "role": "dialog", + "label": "Preferences dialog is shown" + }, + { + "do": "click", + "name": "General", + "role": "page tab", + "label": "Go to the General tab" + }, + { + "do": "settext", + "name": "Number of threads", + "role": "text", + "value": "0", + "label": "Type 0 in the number of threads field" + }, + { + "do": "click", + "name": "OK", + "role": "button", + "label": "Close the dialog with OK" + }, + { + "do": "click", + "name": "Edit", + "role": "menu item", + "label": "Open the Edit menu again" + }, + { + "do": "click", + "name": "Preferences", + "role": "menu item", + "label": "Open Edit > Preferences again" + }, + { + "expect": "visible", + "name": "Preferences", + "role": "dialog", + "label": "Preferences dialog is shown again" + }, + { + "do": "click", + "name": "General", + "role": "page tab", + "label": "Go to the General tab again" + }, + { + "expect": "value", + "name": "Number of threads", + "role": "text", + "equals": "1", + "label": "The number of threads is at least 1, never 0" + } + ], + "script_for": "6a7660844e11" + }, + "t841cca6c": { + "script": [ + { + "do": "click", + "name": "Edit", + "role": "menu item", + "label": "Open the Edit menu" + }, + { + "do": "click", + "name": "Preferences", + "role": "menu item", + "label": "Open Preferences from the Edit menu" + }, + { + "expect": "visible", + "name": "Preferences", + "role": "dialog", + "label": "Preferences dialog is shown" + }, + { + "do": "settext", + "name": "Number of threads", + "role": "text", + "value": "100", + "label": "Set the number of threads to 100" + }, + { + "expect": "value", + "name": "Number of threads", + "role": "text", + "equals": "100", + "label": "Thread count field holds 100" + }, + { + "do": "click", + "name": "OK", + "role": "button", + "label": "Close the Preferences dialog with OK" + }, + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "expect": "visible", + "name": "Select Project File", + "role": "dialog", + "label": "File dialog is shown" + }, + { + "do": "settext", + "name": "File name", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the path of basic.cppcheck" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Open the project file" + }, + { + "expect": "visible", + "name": "src/b.c", + "role": "table cell", + "timeout": 60, + "label": "Analysis is done and results for src/b.c are shown" + }, + { + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "label": "Results for src/a.c are shown" + }, + { + "expect": "text", + "contains": "Project: basic.cppcheck", + "label": "The project is loaded" + }, + { + "expect": "alive", + "label": "The application did not crash" + } + ], + "script_for": "3f99ba3a159c" + }, + "t28ce8afe": { + "script": [ + { + "do": "click", + "name": "Preferences", + "role": "button", + "label": "Open Preferences" + }, + { + "do": "click", + "name": "Addons", + "role": "page tab", + "label": "Go to the Addons tab" + }, + { + "do": "settext", + "name": "MISRA addon", + "role": "text", + "value": "{project:embedded}/{rulefile}", + "label": "Select the rule text file" + }, + { + "do": "click", + "name": "OK", + "role": "button", + "label": "Close the dialog with OK" + }, + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "settext", + "name": "File name", + "role": "text", + "value": "{project:embedded}/embedded.cppcheck", + "label": "Enter the project file name" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Open the project file" + }, + { + "do": "sleep", + "seconds": 8, + "label": "Wait until the analysis is done" + }, + { + "expect": "visible", + "name": "gpio.c", + "role": "table cell", + "timeout": 20, + "label": "Results for gpio.c are shown" + }, + { + "do": "doubleclick", + "name": "gpio.c", + "role": "table cell", + "label": "Select the gpio.c result row" + }, + { + "do": "key", + "keys": [ + "Right" + ], + "label": "Expand the result row" + }, + { + "expect": "text", + "contains": "TEST RULE TEXT: unused parameters are not allowed", + "timeout": 10, + "label": "Misra error has the rule text from the file" + }, + { + "expect": "text", + "contains": "misra-c2012-2.7", + "label": "The unused parameter Misra rule id is shown" + }, + { + "expect": "text", + "not_contains": "internalError", + "label": "There are no internalError results" + } + ], + "script_for": "755194f793e0" + } +} diff --git a/gui/manualtest/tests/project_dialog.feature b/gui/manualtest/tests/project_dialog.feature new file mode 100644 index 00000000000..2d28b7dbc0e --- /dev/null +++ b/gui/manualtest/tests/project_dialog.feature @@ -0,0 +1,40 @@ +Feature: Project file dialog + + Background: + Given the application is started with no project loaded + + @id:tcf7ddb76 @ticket:14983 @project:relative-paths + Scenario: Relative paths in the saved project + Given a new project file is created and the project file dialog is open + When I import the project {project:relative-paths}/compile_commands.json (Paths and defines, Import project) + And I add the include directory {project:relative-paths}/inc + And I exclude the file {project:relative-paths}/skip/b.c + And I save the project file as {project:relative-paths}/rel.cppcheck + Then in the saved rel.cppcheck the import project is written relative to the project file: compile_commands.json + And the include directory is written relative to the project file: inc + And the excluded file is written relative to the project file: skip/b.c + And the XML contains no absolute path to the project folder + + @id:t5afff002 @ticket:14489 + Scenario: Select the platform pic8.xml + Given a new project file is created and the project file dialog is open + When I open the Platform drop-down list + And I select pic8.xml in the list + Then pic8.xml is in the Platform list + And pic8.xml is the platform that the dialog shows + + @id:t91490557 @ticket:14672 @project:custom-cfg + Scenario: Custom cfg file in the library list + Given the folder of {project:custom-cfg}/p.cppcheck also holds aa.cfg, a copy of cfg/avr.cfg + When I open the project file {project:custom-cfg}/p.cppcheck + And I open the project file dialog (edit the project file) + And I look at the library list (Libraries) + Then aa is in the library list + And aa comes before avr, the list is in alphabetical order + + @id:t0ec0680b @ticket:14488 @project:embedded @edition:opensource + Scenario: Misra checkbox of a loaded project + When I open the project file {project:embedded}/embedded.cppcheck + And I open the project file dialog (edit the project file) + And I go to the Addons tab + Then the Misra C 2012 checkbox is checked diff --git a/gui/manualtest/tests/project_dialog.scripts.json b/gui/manualtest/tests/project_dialog.scripts.json new file mode 100644 index 00000000000..08dfc5965ce --- /dev/null +++ b/gui/manualtest/tests/project_dialog.scripts.json @@ -0,0 +1,371 @@ +{ + "tcf7ddb76": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "New Project File", + "role": "menu item", + "label": "Create a new project file" + }, + { + "do": "settext", + "name": "File name", + "role": "text", + "value": "{project:relative-paths}/rel.cppcheck", + "label": "Enter the project file name" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the project file name" + }, + { + "expect": "visible", + "name": "Project file: rel.cppcheck", + "role": "dialog", + "label": "Project file dialog is open" + }, + { + "do": "click", + "name": "Add...", + "role": "button", + "nth": 1, + "label": "Add an include directory" + }, + { + "do": "settext", + "name": "Directory:", + "role": "text", + "value": "{project:relative-paths}/inc", + "label": "Enter the include directory {project:relative-paths}/inc" + }, + { + "do": "click", + "name": "Choose", + "role": "button", + "label": "Choose the include directory" + }, + { + "do": "click", + "name": "Warning options", + "role": "page tab", + "label": "Open the tab with the excluded files" + }, + { + "do": "click", + "name": "Exclude file", + "role": "button", + "label": "Exclude a file" + }, + { + "do": "settext", + "name": "File name", + "role": "text", + "value": "{project:relative-paths}/skip/b.c", + "label": "Enter the excluded file {project:relative-paths}/skip/b.c" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the excluded file" + }, + { + "expect": "visible", + "name": "skip/b.c", + "role": "list item", + "label": "skip/b.c is in the exclude list" + }, + { + "do": "click", + "name": "Paths and Defines", + "role": "page tab", + "label": "Back to Paths and Defines" + }, + { + "do": "click", + "name": "Browse...", + "role": "button", + "nth": 0, + "label": "Browse for the import project" + }, + { + "do": "settext", + "name": "File name", + "role": "text", + "value": "{project:relative-paths}/compile_commands.json", + "label": "Enter the import project {project:relative-paths}/compile_commands.json" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the import project" + }, + { + "do": "click", + "name": "OK", + "role": "button", + "label": "Save the project file as rel.cppcheck" + }, + { + "do": "sleep", + "seconds": 1 + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Dismiss the build dir question" + }, + { + "expect": "file", + "path": "{project:relative-paths}/rel.cppcheck", + "contains": "compile_commands.json", + "label": "Import project is relative" + }, + { + "expect": "file", + "path": "{project:relative-paths}/rel.cppcheck", + "contains": "", + "label": "Excluded file is relative (skip/b.c)" + }, + { + "expect": "file", + "path": "{project:relative-paths}/rel.cppcheck", + "not_contains": "{project:relative-paths}", + "label": "No absolute path to the project folder in the XML" + } + ], + "script_for": "edfc96b05beb" + }, + "t5afff002": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "New Project File", + "role": "menu item", + "label": "Create a new project file" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{work}/t.cppcheck", + "label": "Enter the project file name" + }, + { + "do": "click", + "name": "Save", + "role": "button", + "exact": true, + "label": "Save the new project file; the project file dialog opens" + }, + { + "expect": "visible", + "name": "Project file", + "role": "dialog", + "label": "Project file dialog is open" + }, + { + "do": "click", + "name": "Types and Functions", + "role": "page tab", + "label": "Go to the tab with the Platform setting" + }, + { + "do": "click", + "name": "Platform", + "role": "combo box", + "label": "Open the Platform drop-down list" + }, + { + "expect": "visible", + "name": "pic8.xml", + "role": "list item", + "label": "pic8.xml is in the Platform list" + }, + { + "do": "click", + "name": "pic8.xml", + "role": "list item", + "exact": true, + "mouse": true, + "label": "Select pic8.xml in the list" + }, + { + "expect": "visible", + "name": "pic8.xml", + "role": "combo box", + "label": "The dialog shows pic8.xml as the platform" + } + ], + "script_for": "619f376b22e1" + }, + "t91490557": { + "script": [ + { + "do": "click", + "name": "Open Project File", + "role": "button", + "label": "Open the project file dialog from the toolbar" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:custom-cfg}/p.cppcheck", + "label": "Enter the path of p.cppcheck" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Open the project file" + }, + { + "expect": "visible", + "name": "Cppcheck", + "role": "alert", + "label": "Analysis finishes and an alert appears" + }, + { + "do": "click", + "name": "OK", + "role": "button", + "label": "Dismiss the alert" + }, + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Edit Project File", + "role": "menu item", + "label": "Open the project file dialog (edit the project file)" + }, + { + "expect": "visible", + "name": "Project file: p.cppcheck", + "role": "dialog", + "label": "The project file dialog is open" + }, + { + "expect": "visible", + "name": "aa", + "role": "list item", + "exact": true, + "label": "aa is in the Libraries list" + }, + { + "expect": "visible", + "name": "avr", + "role": "list item", + "exact": true, + "label": "avr is in the Libraries list" + } + ], + "script_for": "b0bf245f7042" + }, + "t0ec0680b": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "wait", + "name": "Select Project File", + "role": "dialog", + "label": "File dialog is shown" + }, + { + "do": "settext", + "name": "File name", + "role": "text", + "value": "{project:embedded}/embedded.cppcheck", + "label": "Enter the project file path" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Open the project file" + }, + { + "do": "wait", + "name": "Project: embedded.cppcheck", + "role": "frame", + "label": "Project is loaded" + }, + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu again" + }, + { + "do": "click", + "name": "Edit Project File...", + "role": "menu item", + "label": "Open the project file dialog" + }, + { + "do": "wait", + "name": "Project file: embedded.cppcheck", + "role": "dialog", + "label": "Project file dialog is shown" + }, + { + "do": "click", + "name": "Addons", + "role": "page tab", + "label": "Go to the Addons tab" + }, + { + "expect": "state", + "name": "Misra C 2012", + "role": "check box", + "state": "checked", + "label": "The Misra C 2012 checkbox is checked" + } + ], + "script_for": "187bd0d82a72" + } +} diff --git a/gui/manualtest/tests/projects.feature b/gui/manualtest/tests/projects.feature new file mode 100644 index 00000000000..a4c2324551e --- /dev/null +++ b/gui/manualtest/tests/projects.feature @@ -0,0 +1,72 @@ +Feature: Open and create projects + + Background: + Given the application is started with no project loaded + + @id:tf9fc8bf6 @project:basic-project + Scenario: Open a project file + When I open the project file {project:basic-project}/basic.cppcheck with the open project file entry in the File menu + Then the project opens + And the title of the main window names basic.cppcheck + And the analysis results are shown: nullPointer errors in a.c and util.h, arrayIndexOutOfBounds in b.c + + @id:t6bb11424 @project:switch-project + Scenario: Open a second project + TODO: with and without build dir + Given the project file {project:switch-project}/one/p1.cppcheck is opened + And the analysis is done + And the results show a nullPointer error in a.c + When I open the project file {project:switch-project}/two/p2.cppcheck + And I wait until the analysis is done + Then the results of the first project (nullPointer in a.c) are gone + And the results of the second project (arrayIndexOutOfBounds in b.c) are shown + + @id:t176fd17f @project:switch-project + Scenario: Open a recent project + Given the project file {project:switch-project}/one/p1.cppcheck is opened and analysed + And the project file {project:switch-project}/two/p2.cppcheck is opened and analysed + When I open the File menu + And I click p1.cppcheck in the list of recent projects + Then the project p1.cppcheck is opened + And the title of the main window names p1.cppcheck, not p2.cppcheck or another file + + @id:t1e899c1c @project:basic-project + Scenario: New project file + When I open File > New Project File + And I enter the file name {project:basic-project}/OSgui.cppcheck + And I add the folder {project:basic-project}/src as a path to check in the project file dialog + And I save the project file without selecting an addon + And I wait until the analysis is done + Then the project file OSgui.cppcheck is saved without any addon in it + And the analysis is run + And the results are shown: nullPointer errors in a.c, arrayIndexOutOfBounds in b.c + And util.h is not checked, the new project has no include path to it + + @id:t202b9515 @project:basic-project + Scenario Outline: New project file with an addon + When I open File > New Project File + And I enter the file name {project:basic-project}/OSgui.cppcheck + And I add the folder {project:basic-project}/src as a path to check in the project file dialog + And I tick the checkbox of the addon whose name contains "" on the Addons tab (Misra C, Y2038 or Thread safety) + And I save the project file + And I wait until the analysis is done + Then the project file OSgui.cppcheck is saved with an addon entry that contains "" (misra, y2038 or threadsafety) + And the analysis is run and results are shown + And none of the results is an internalError about the addon + + Examples: + | addon | + | misra | + | y2038 | + | thread | + + @id:tf6da2cfd @project:basic-project @edition:opensource + Scenario: Add the Misra addon to a project + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I open File > Edit Project File + And I select MISRA C 2012 on the Addons tab + And I save the project file + And I wait until the analysis is done + Then basic.cppcheck has the addon misra in it + And the analysis is run again diff --git a/gui/manualtest/tests/projects.scripts.json b/gui/manualtest/tests/projects.scripts.json new file mode 100644 index 00000000000..a78d2f6b793 --- /dev/null +++ b/gui/manualtest/tests/projects.scripts.json @@ -0,0 +1,771 @@ +{ + "tf9fc8bf6": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File in the File menu" + }, + { + "expect": "visible", + "name": "Select Project File", + "role": "dialog", + "label": "The project file dialog is shown" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the path of basic.cppcheck" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the dialog to open the project" + }, + { + "expect": "visible", + "name": "Project: basic.cppcheck", + "role": "frame", + "timeout": 15, + "label": "The title of the main window names basic.cppcheck" + }, + { + "do": "wait", + "name": "Select Project File", + "gone": true, + "label": "The dialog is closed" + }, + { + "do": "sleep", + "seconds": 4, + "label": "Wait for the analysis to finish" + }, + { + "do": "focus", + "role": "tree", + "label": "Focus the results tree" + }, + { + "do": "key", + "keys": [ + "Home", + "Down", + "Down", + "Right", + "Up", + "Right", + "Up", + "Right", + "Home" + ], + "label": "Expand the results of all three files and go to the top" + }, + { + "expect": "visible", + "name": "nullPointer", + "role": "table cell", + "timeout": 10, + "label": "nullPointer errors are shown for util.h and a.c" + }, + { + "expect": "text", + "contains": "src/a.c", + "label": "Results for a.c are shown" + }, + { + "expect": "text", + "contains": "include/util.h", + "label": "Results for util.h are shown" + }, + { + "do": "key", + "keys": [ + "End" + ], + "label": "Scroll to the results of b.c" + }, + { + "expect": "visible", + "name": "arrayIndexOutOfBounds", + "role": "table cell", + "timeout": 10, + "label": "arrayIndexOutOfBounds error is shown for b.c" + } + ], + "script_for": "7128457516b3" + }, + "t6bb11424": { + "script": [ + { + "do": "click", + "name": "Open Project File", + "role": "button", + "label": "Open the first project" + }, + { + "do": "type", + "value": "{project:switch-project}/one/p1.cppcheck", + "label": "Enter path of p1.cppcheck" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the file dialog" + }, + { + "expect": "visible", + "name": "Project: p1.cppcheck", + "role": "frame", + "timeout": 10, + "label": "First project is loaded" + }, + { + "expect": "visible", + "name": "a.c", + "role": "table cell", + "timeout": 20, + "label": "Results of the first project show a.c" + }, + { + "do": "click", + "name": "Open Project File", + "role": "button", + "label": "Open the second project" + }, + { + "do": "type", + "value": "{project:switch-project}/two/p2.cppcheck", + "label": "Enter path of p2.cppcheck" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the file dialog" + }, + { + "expect": "visible", + "name": "Project: p2.cppcheck", + "role": "frame", + "timeout": 10, + "label": "Second project is loaded" + }, + { + "expect": "visible", + "name": "b.c", + "role": "table cell", + "timeout": 20, + "label": "Results of the second project show b.c" + }, + { + "expect": "gone", + "name": "a.c", + "role": "table cell", + "label": "Results of the first project are gone" + } + ], + "script_for": "70097c80a6ed" + }, + "t176fd17f": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:switch-project}/one/p1.cppcheck", + "label": "Enter the path of p1.cppcheck" + }, + { + "do": "click", + "name": "Open", + "role": "button", + "exact": true, + "label": "Open p1.cppcheck" + }, + { + "expect": "text", + "contains": "Project: p1.cppcheck", + "timeout": 10, + "label": "Project p1 is open" + }, + { + "expect": "visible", + "name": "Checking a.c", + "timeout": 15, + "label": "Analysis of p1 is done" + }, + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:switch-project}/two/p2.cppcheck", + "label": "Enter the path of p2.cppcheck" + }, + { + "do": "click", + "name": "Open", + "role": "button", + "exact": true, + "label": "Open p2.cppcheck" + }, + { + "expect": "text", + "contains": "Project: p2.cppcheck", + "timeout": 10, + "label": "Project p2 is open" + }, + { + "do": "sleep", + "seconds": 3, + "label": "Wait until the analysis of p2 is done" + }, + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "p1.cppcheck", + "role": "menu item", + "label": "Click p1.cppcheck in the recent projects list" + }, + { + "expect": "text", + "contains": "Project: p1.cppcheck", + "timeout": 10, + "label": "Main window title names p1.cppcheck" + }, + { + "expect": "text", + "not_contains": "Project: p2.cppcheck", + "label": "Title does not name p2.cppcheck" + } + ], + "script_for": "2ea42621479d" + }, + "t1e899c1c": { + "script": [ + { + "label": "Open File menu", + "do": "click", + "name": "File", + "role": "menu item" + }, + { + "label": "Open File > New Project File", + "do": "click", + "name": "New Project File", + "role": "menu item" + }, + { + "label": "Wait for the file name dialog", + "do": "wait", + "name": "Select Project Filename", + "role": "dialog" + }, + { + "label": "Enter the file name OSgui.cppcheck", + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/OSgui.cppcheck" + }, + { + "label": "Confirm the file name", + "do": "key", + "keys": [ + "Return" + ] + }, + { + "label": "Project file dialog is shown", + "expect": "visible", + "name": "Project file: OSgui.cppcheck", + "role": "dialog" + }, + { + "label": "Add a path to check", + "do": "click", + "name": "Add...", + "role": "button", + "nth": 0 + }, + { + "label": "Wait for the directory dialog", + "do": "wait", + "name": "Select a directory to check", + "role": "dialog" + }, + { + "label": "Enter the src folder", + "do": "settext", + "name": "Directory:", + "role": "text", + "value": "{project:basic-project}/src" + }, + { + "label": "Choose the src folder", + "do": "click", + "name": "Choose", + "role": "button" + }, + { + "label": "src is in the paths list", + "expect": "visible", + "name": "src", + "role": "list item" + }, + { + "label": "Save the project file without selecting an addon", + "do": "click", + "name": "OK", + "role": "button" + }, + { + "label": "Create the build dir when asked", + "do": "click", + "name": "Yes", + "role": "button" + }, + { + "label": "Wait until the analysis has checked b.c", + "expect": "text", + "contains": "Checking src/b.c", + "timeout": 30 + }, + { + "label": "Wait for the results of a.c", + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "timeout": 30 + }, + { + "label": "Select a.c results", + "do": "click", + "name": "src/a.c", + "role": "table cell", + "nth": 0, + "mouse": true + }, + { + "label": "Collapse a.c results to get a known state", + "do": "key", + "keys": [ + "Left" + ] + }, + { + "label": "Expand a.c results", + "do": "key", + "keys": [ + "Right" + ] + }, + { + "label": "nullPointer is reported in a.c", + "expect": "visible", + "name": "nullPointer", + "role": "table cell", + "timeout": 10 + }, + { + "label": "Select b.c results", + "do": "click", + "name": "src/b.c", + "role": "table cell", + "nth": 0, + "mouse": true + }, + { + "label": "Collapse b.c results to get a known state", + "do": "key", + "keys": [ + "Left" + ] + }, + { + "label": "Expand b.c results", + "do": "key", + "keys": [ + "Right" + ] + }, + { + "label": "arrayIndexOutOfBounds is reported in b.c", + "expect": "visible", + "name": "arrayIndexOutOfBounds", + "role": "table cell", + "timeout": 10 + }, + { + "label": "util.h is not checked", + "expect": "text", + "not_contains": "Checking include/util.h" + }, + { + "label": "Project file contains the src path", + "expect": "file", + "path": "{project:basic-project}/OSgui.cppcheck", + "contains": "" + }, + { + "label": "Project file has no addon", + "expect": "file", + "path": "{project:basic-project}/OSgui.cppcheck", + "not_contains": "addon" + }, + { + "label": "Project file has no include path", + "expect": "file", + "path": "{project:basic-project}/OSgui.cppcheck", + "not_contains": "include" + } + ], + "script_for": "b3616d866fea" + }, + "t202b9515": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "New Project File...", + "role": "menu item", + "label": "Open File > New Project File" + }, + { + "do": "wait", + "name": "Select Project Filename", + "role": "dialog", + "label": "Wait for the file name dialog" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/OSgui.cppcheck", + "label": "Enter the file name OSgui.cppcheck" + }, + { + "do": "focus", + "name": "File name:", + "role": "text", + "label": "Focus the file name field" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the file name" + }, + { + "do": "wait", + "name": "Project file: OSgui.cppcheck", + "role": "dialog", + "timeout": 10, + "label": "Wait for the project file dialog" + }, + { + "do": "click", + "name": "Paths and Defines", + "role": "page tab", + "label": "Go to the Paths and Defines tab" + }, + { + "do": "click", + "name": "Add...", + "role": "button", + "nth": 0, + "label": "Add a path to check" + }, + { + "do": "wait", + "name": "Select a directory to check", + "role": "dialog", + "label": "Wait for the directory dialog" + }, + { + "do": "settext", + "name": "Directory:", + "role": "text", + "value": "{project:basic-project}/src", + "label": "Enter the folder src" + }, + { + "do": "click", + "name": "Choose", + "role": "button", + "label": "Choose the folder src" + }, + { + "do": "wait", + "name": "Select a directory to check", + "role": "dialog", + "gone": true, + "label": "Directory dialog closes" + }, + { + "expect": "visible", + "name": "src", + "role": "list item", + "exact": true, + "label": "src is in the paths to check" + }, + { + "do": "click", + "name": "Addons", + "role": "page tab", + "label": "Go to the Addons tab" + }, + { + "do": "click", + "name": "{addon}", + "role": "check box", + "nth": 0, + "label": "Tick the addon checkbox" + }, + { + "expect": "state", + "name": "{addon}", + "role": "check box", + "nth": 0, + "state": "checked", + "label": "The addon checkbox is ticked" + }, + { + "do": "click", + "name": "OK", + "role": "button", + "label": "Save the project file" + }, + { + "do": "wait", + "name": "Yes", + "role": "button", + "timeout": 10, + "label": "Question to create the build dir" + }, + { + "do": "click", + "name": "Yes", + "role": "button", + "label": "Create the build dir" + }, + { + "do": "wait", + "name": "src/b.c", + "role": "table cell", + "timeout": 120, + "label": "Wait for the analysis results" + }, + { + "do": "sleep", + "seconds": 3 + }, + { + "expect": "state", + "name": "Stop analysis", + "role": "button", + "not_state": "enabled", + "timeout": 120, + "label": "The analysis is done" + }, + { + "do": "focus", + "name": "src/a.c", + "role": "table cell", + "label": "Select the results of a.c" + }, + { + "do": "key", + "keys": [ + "asterisk", + "End", + "asterisk" + ], + "label": "Expand the results of all files" + }, + { + "do": "sleep", + "seconds": 1 + }, + { + "expect": "file", + "path": "{project:basic-project}/OSgui.cppcheck", + "contains": "{addon}", + "label": "Project file has the addon entry" + }, + { + "expect": "file", + "path": "{project:basic-project}/OSgui.cppcheck", + "contains": "", + "label": "Project file has the path src" + }, + { + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "label": "Analysis results are shown" + }, + { + "expect": "text", + "not_contains": "internalError", + "label": "No internalError about the addon in the results" + } + ], + "script_for": "60cd34c48191" + }, + "tf6da2cfd": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the project file path" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the file dialog" + }, + { + "do": "wait", + "name": "Checking src/b.c", + "timeout": 20, + "label": "Wait for the first analysis to run" + }, + { + "do": "sleep", + "seconds": 3, + "label": "Let the first analysis finish" + }, + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Edit Project File", + "role": "menu item", + "label": "Choose Edit Project File" + }, + { + "expect": "visible", + "name": "Project file: basic.cppcheck", + "role": "dialog", + "label": "Project file dialog is open" + }, + { + "do": "click", + "name": "Addons", + "role": "page tab", + "label": "Go to the Addons tab" + }, + { + "do": "click", + "name": "Misra C 2012", + "role": "check box", + "label": "Select MISRA C 2012" + }, + { + "expect": "state", + "name": "Misra C 2012", + "state": "checked", + "label": "MISRA C 2012 is checked" + }, + { + "do": "click", + "name": "OK", + "role": "button", + "label": "Save the project file" + }, + { + "expect": "gone", + "name": "Project file: basic.cppcheck", + "label": "Project file dialog is closed" + }, + { + "do": "sleep", + "seconds": 4, + "label": "Wait for the second analysis to finish" + }, + { + "expect": "file", + "path": "{project:basic-project}/basic.cppcheck", + "contains": "misra", + "label": "Project file has the misra addon" + }, + { + "expect": "visible", + "name": "Checking src/b.c", + "role": "list item", + "nth": 1, + "label": "The analysis was run again" + } + ], + "script_for": "452f351f0fb2" + } +} diff --git a/gui/manualtest/tests/projects/basic-project/basic.cppcheck b/gui/manualtest/tests/projects/basic-project/basic.cppcheck new file mode 100644 index 00000000000..c8805a32587 --- /dev/null +++ b/gui/manualtest/tests/projects/basic-project/basic.cppcheck @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/gui/manualtest/tests/projects/basic-project/include/util.h b/gui/manualtest/tests/projects/basic-project/include/util.h new file mode 100644 index 00000000000..48ae2d54a95 --- /dev/null +++ b/gui/manualtest/tests/projects/basic-project/include/util.h @@ -0,0 +1,5 @@ +static inline int helper(void) +{ + int *r = 0; + return *r; +} diff --git a/gui/manualtest/tests/projects/basic-project/src/a.c b/gui/manualtest/tests/projects/basic-project/src/a.c new file mode 100644 index 00000000000..3a84d86a5ff --- /dev/null +++ b/gui/manualtest/tests/projects/basic-project/src/a.c @@ -0,0 +1,18 @@ +#include "util.h" + +int first(void) +{ + int *p = 0; + return *p; +} + +int second(void) +{ + int *q = 0; + return *q; +} + +int main(void) +{ + return first() + second() + helper(); +} diff --git a/gui/manualtest/tests/projects/basic-project/src/b.c b/gui/manualtest/tests/projects/basic-project/src/b.c new file mode 100644 index 00000000000..20be2edc145 --- /dev/null +++ b/gui/manualtest/tests/projects/basic-project/src/b.c @@ -0,0 +1,5 @@ +void f(void) +{ + char a[4]; + a[10] = 0; +} diff --git a/gui/manualtest/tests/projects/custom-cfg/a.c b/gui/manualtest/tests/projects/custom-cfg/a.c new file mode 100644 index 00000000000..58fe69254d0 --- /dev/null +++ b/gui/manualtest/tests/projects/custom-cfg/a.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff --git a/gui/manualtest/tests/projects/custom-cfg/aa.cfg b/gui/manualtest/tests/projects/custom-cfg/aa.cfg new file mode 100644 index 00000000000..bb21afac352 --- /dev/null +++ b/gui/manualtest/tests/projects/custom-cfg/aa.cfg @@ -0,0 +1,402 @@ + + + + + + + + + + + + + + + + + + + + + + + false + + + 0:255 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + 0: + + + + false + + + + + + + + + + + + + + false + + + + + + + + + + + + + + false + + + + + + + + false + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + false + + + + false + + + + + + + false + + + + + + + false + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + + + + + + + + diff --git a/gui/manualtest/tests/projects/custom-cfg/p.cppcheck b/gui/manualtest/tests/projects/custom-cfg/p.cppcheck new file mode 100644 index 00000000000..e8db10582ad --- /dev/null +++ b/gui/manualtest/tests/projects/custom-cfg/p.cppcheck @@ -0,0 +1,6 @@ + + + + + + diff --git a/gui/manualtest/tests/projects/embedded/board.h b/gui/manualtest/tests/projects/embedded/board.h new file mode 100644 index 00000000000..8a5bddc04a0 --- /dev/null +++ b/gui/manualtest/tests/projects/embedded/board.h @@ -0,0 +1,10 @@ +#ifndef BOARD_H +#define BOARD_H + +#define GPIOA_ODR (*(volatile unsigned int *)0x40020014U) +#define UART_DR (*(volatile unsigned int *)0x40011004U) + +void gpio_set(unsigned int pin, unsigned int mask); +void uart_putc(char c); + +#endif diff --git a/gui/manualtest/tests/projects/embedded/embedded.cppcheck b/gui/manualtest/tests/projects/embedded/embedded.cppcheck new file mode 100644 index 00000000000..679b87f6d90 --- /dev/null +++ b/gui/manualtest/tests/projects/embedded/embedded.cppcheck @@ -0,0 +1,9 @@ + + + + + + + misra + + diff --git a/gui/manualtest/tests/projects/embedded/gpio.c b/gui/manualtest/tests/projects/embedded/gpio.c new file mode 100644 index 00000000000..73968d86135 --- /dev/null +++ b/gui/manualtest/tests/projects/embedded/gpio.c @@ -0,0 +1,6 @@ +#include "board.h" + +void gpio_set(unsigned int pin, unsigned int mask) +{ + GPIOA_ODR |= mask; +} diff --git a/gui/manualtest/tests/projects/embedded/main.c b/gui/manualtest/tests/projects/embedded/main.c new file mode 100644 index 00000000000..6daafe949b4 --- /dev/null +++ b/gui/manualtest/tests/projects/embedded/main.c @@ -0,0 +1,10 @@ +#include "board.h" + +int main(void) +{ + gpio_set(5U, 0x20U); + uart_putc('A'); + for (;;) + { + } +} diff --git a/gui/manualtest/tests/projects/embedded/rules with spaces.txt b/gui/manualtest/tests/projects/embedded/rules with spaces.txt new file mode 100644 index 00000000000..a707cb8673d --- /dev/null +++ b/gui/manualtest/tests/projects/embedded/rules with spaces.txt @@ -0,0 +1,7 @@ +Appendix A Summary of guidelines + +Rule 2.7 +TEST RULE TEXT: unused parameters are not allowed +Category Advisory +Analysis Decidable, Single Translation Unit +Applies to C90, C99 diff --git a/gui/manualtest/tests/projects/embedded/rules.txt b/gui/manualtest/tests/projects/embedded/rules.txt new file mode 100644 index 00000000000..a707cb8673d --- /dev/null +++ b/gui/manualtest/tests/projects/embedded/rules.txt @@ -0,0 +1,7 @@ +Appendix A Summary of guidelines + +Rule 2.7 +TEST RULE TEXT: unused parameters are not allowed +Category Advisory +Analysis Decidable, Single Translation Unit +Applies to C90, C99 diff --git a/gui/manualtest/tests/projects/embedded/uart.c b/gui/manualtest/tests/projects/embedded/uart.c new file mode 100644 index 00000000000..3720b2fde22 --- /dev/null +++ b/gui/manualtest/tests/projects/embedded/uart.c @@ -0,0 +1,6 @@ +#include "board.h" + +void uart_putc(char c) +{ + UART_DR = (unsigned int)c; +} diff --git a/gui/manualtest/tests/projects/recheck/a.c b/gui/manualtest/tests/projects/recheck/a.c new file mode 100644 index 00000000000..a4f00f729cb --- /dev/null +++ b/gui/manualtest/tests/projects/recheck/a.c @@ -0,0 +1,5 @@ +int main(void) +{ + int *p = 0; + return *p; +} diff --git a/gui/manualtest/tests/projects/recheck/a_v2.c b/gui/manualtest/tests/projects/recheck/a_v2.c new file mode 100644 index 00000000000..229abfebb92 --- /dev/null +++ b/gui/manualtest/tests/projects/recheck/a_v2.c @@ -0,0 +1,5 @@ +int main(void) +{ + int x; + return x; +} diff --git a/gui/manualtest/tests/projects/recheck/b.c b/gui/manualtest/tests/projects/recheck/b.c new file mode 100644 index 00000000000..20be2edc145 --- /dev/null +++ b/gui/manualtest/tests/projects/recheck/b.c @@ -0,0 +1,5 @@ +void f(void) +{ + char a[4]; + a[10] = 0; +} diff --git a/gui/manualtest/tests/projects/recheck/p.cppcheck b/gui/manualtest/tests/projects/recheck/p.cppcheck new file mode 100644 index 00000000000..760eb8837f8 --- /dev/null +++ b/gui/manualtest/tests/projects/recheck/p.cppcheck @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gui/manualtest/tests/projects/relative-paths/compile_commands.json b/gui/manualtest/tests/projects/relative-paths/compile_commands.json new file mode 100644 index 00000000000..130de6bca98 --- /dev/null +++ b/gui/manualtest/tests/projects/relative-paths/compile_commands.json @@ -0,0 +1,4 @@ +[ + {"directory": ".", "command": "gcc -c src/a.c", "file": "src/a.c"}, + {"directory": ".", "command": "gcc -c skip/b.c", "file": "skip/b.c"} +] diff --git a/gui/manualtest/tests/projects/relative-paths/inc/util.h b/gui/manualtest/tests/projects/relative-paths/inc/util.h new file mode 100644 index 00000000000..874a45c458c --- /dev/null +++ b/gui/manualtest/tests/projects/relative-paths/inc/util.h @@ -0,0 +1 @@ +int helper(int x); diff --git a/gui/manualtest/tests/projects/relative-paths/skip/b.c b/gui/manualtest/tests/projects/relative-paths/skip/b.c new file mode 100644 index 00000000000..5bb061143c0 --- /dev/null +++ b/gui/manualtest/tests/projects/relative-paths/skip/b.c @@ -0,0 +1,4 @@ +int unused(void) +{ + return 0; +} diff --git a/gui/manualtest/tests/projects/relative-paths/src/a.c b/gui/manualtest/tests/projects/relative-paths/src/a.c new file mode 100644 index 00000000000..db8654dea9f --- /dev/null +++ b/gui/manualtest/tests/projects/relative-paths/src/a.c @@ -0,0 +1,6 @@ +#include "util.h" + +int main(void) +{ + return helper(1); +} diff --git a/gui/manualtest/tests/projects/switch-project/one/a.c b/gui/manualtest/tests/projects/switch-project/one/a.c new file mode 100644 index 00000000000..a4f00f729cb --- /dev/null +++ b/gui/manualtest/tests/projects/switch-project/one/a.c @@ -0,0 +1,5 @@ +int main(void) +{ + int *p = 0; + return *p; +} diff --git a/gui/manualtest/tests/projects/switch-project/one/p1.cppcheck b/gui/manualtest/tests/projects/switch-project/one/p1.cppcheck new file mode 100644 index 00000000000..5eb66587401 --- /dev/null +++ b/gui/manualtest/tests/projects/switch-project/one/p1.cppcheck @@ -0,0 +1,6 @@ + + + + + + diff --git a/gui/manualtest/tests/projects/switch-project/two/b.c b/gui/manualtest/tests/projects/switch-project/two/b.c new file mode 100644 index 00000000000..20be2edc145 --- /dev/null +++ b/gui/manualtest/tests/projects/switch-project/two/b.c @@ -0,0 +1,5 @@ +void f(void) +{ + char a[4]; + a[10] = 0; +} diff --git a/gui/manualtest/tests/projects/switch-project/two/p2.cppcheck b/gui/manualtest/tests/projects/switch-project/two/p2.cppcheck new file mode 100644 index 00000000000..a79d287d385 --- /dev/null +++ b/gui/manualtest/tests/projects/switch-project/two/p2.cppcheck @@ -0,0 +1,6 @@ + + + + + + diff --git a/gui/manualtest/tests/projects/syntax-error/binary.c b/gui/manualtest/tests/projects/syntax-error/binary.c new file mode 100644 index 0000000000000000000000000000000000000000..c91312c3af04c4ea13103c233b48b7de9d4ac210 GIT binary patch literal 4096 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 literal 0 HcmV?d00001 diff --git a/gui/manualtest/tests/projects/syntax-error/binary.cppcheck b/gui/manualtest/tests/projects/syntax-error/binary.cppcheck new file mode 100644 index 00000000000..7804897af2d --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/binary.cppcheck @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gui/manualtest/tests/projects/syntax-error/braces.c b/gui/manualtest/tests/projects/syntax-error/braces.c new file mode 100644 index 00000000000..66d81f572c3 --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/braces.c @@ -0,0 +1,3 @@ +int main( { + return 0 +} diff --git a/gui/manualtest/tests/projects/syntax-error/braces.cppcheck b/gui/manualtest/tests/projects/syntax-error/braces.cppcheck new file mode 100644 index 00000000000..94d206fd67c --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/braces.cppcheck @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gui/manualtest/tests/projects/syntax-error/empty.c b/gui/manualtest/tests/projects/syntax-error/empty.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/gui/manualtest/tests/projects/syntax-error/empty.cppcheck b/gui/manualtest/tests/projects/syntax-error/empty.cppcheck new file mode 100644 index 00000000000..eb36efbe086 --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/empty.cppcheck @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gui/manualtest/tests/projects/syntax-error/latin1.c b/gui/manualtest/tests/projects/syntax-error/latin1.c new file mode 100644 index 00000000000..7e730fd3a83 --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/latin1.c @@ -0,0 +1,6 @@ +/* färg och smör */ +int färg(void) +{ + const char *s = "grön"; + return s[0]; +} diff --git a/gui/manualtest/tests/projects/syntax-error/latin1.cppcheck b/gui/manualtest/tests/projects/syntax-error/latin1.cppcheck new file mode 100644 index 00000000000..06ccf58dfd5 --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/latin1.cppcheck @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gui/manualtest/tests/projects/syntax-error/long_line.c b/gui/manualtest/tests/projects/syntax-error/long_line.c new file mode 100644 index 00000000000..14807c9e52b --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/long_line.c @@ -0,0 +1 @@ +int x = a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + diff --git a/gui/manualtest/tests/projects/syntax-error/long_line.cppcheck b/gui/manualtest/tests/projects/syntax-error/long_line.cppcheck new file mode 100644 index 00000000000..f13ad9aa112 --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/long_line.cppcheck @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gui/manualtest/tests/projects/syntax-error/ok.c b/gui/manualtest/tests/projects/syntax-error/ok.c new file mode 100644 index 00000000000..8e1e58ce827 --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/ok.c @@ -0,0 +1,5 @@ +int ok(void) +{ + int *p = 0; + return *p; +} diff --git a/gui/manualtest/tests/projects/syntax-error/unclosed_nesting.c b/gui/manualtest/tests/projects/syntax-error/unclosed_nesting.c new file mode 100644 index 00000000000..7d6ac74625a --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/unclosed_nesting.c @@ -0,0 +1,4 @@ +int f(int a) +{ + return ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((a; +} diff --git a/gui/manualtest/tests/projects/syntax-error/unclosed_nesting.cppcheck b/gui/manualtest/tests/projects/syntax-error/unclosed_nesting.cppcheck new file mode 100644 index 00000000000..baeddf3ef2f --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/unclosed_nesting.cppcheck @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gui/manualtest/tests/projects/xml-results/a.c b/gui/manualtest/tests/projects/xml-results/a.c new file mode 100644 index 00000000000..38775adee5f --- /dev/null +++ b/gui/manualtest/tests/projects/xml-results/a.c @@ -0,0 +1,5 @@ +int first(void) +{ + int *p = 0; + return *p; +} diff --git a/gui/manualtest/tests/projects/xml-results/results.xml b/gui/manualtest/tests/projects/xml-results/results.xml new file mode 100644 index 00000000000..c6f4b14c0c1 --- /dev/null +++ b/gui/manualtest/tests/projects/xml-results/results.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/gui/manualtest/tests/result_list.feature b/gui/manualtest/tests/result_list.feature new file mode 100644 index 00000000000..f370d296fb0 --- /dev/null +++ b/gui/manualtest/tests/result_list.feature @@ -0,0 +1,91 @@ +Feature: Results list + + Background: + Given the application is started with no project loaded + + @id:t852206f1 + Scenario: Severity buttons toggle + When I click each of the toolbar buttons Error, Warning, Style, Portability, Performance, Information, Cppcheck and Clang once + Then every button can be clicked and changes between checked and unchecked + When I click each of them once more + Then all buttons are in the state they had at the start + + @id:td7decf1a @project:basic-project + Scenario: Filter the results + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I type "arrayIndex" in the Filter field + Then only the arrayIndexOutOfBounds error in b.c is shown + When I clear the Filter field + Then all errors are shown again + + @id:t2af9d498 @project:basic-project + Scenario: Expand all + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I open View > Collapse All + And I open View > Expand All + Then all files are expanded and show their errors + And the errors in a.c, util.h and b.c are visible + + @id:tec898362 @project:basic-project + Scenario: Collapse all + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I open View > Expand All + And I open View > Collapse All + Then all files are collapsed + And the file entries are shown and their errors are not + + @id:t4c027507 @project:basic-project + Scenario: Context menu of a file entry + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I right click on the file a.c in the results (not on one of its errors) + Then the context menu of the file entry has the entries Recheck and Open containing folder + But it has none of the entries Hide, Hide all with ID or Suppress selected id, they only apply to a single error + + @id:taacc3841 @project:basic-project + Scenario: Hide one error + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I expand a.c in the results + And I right click on the first nullPointer error (line 6) and click Hide + Then that error is gone + And the other errors are still shown, including the second nullPointer error in a.c (line 12) + + @id:t2937b690 @project:basic-project + Scenario: Hide all errors with the same ID + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I expand a.c in the results + And I right click on a nullPointer error and click Hide all with ID + Then all nullPointer errors are gone, in a.c and in util.h + And the arrayIndexOutOfBounds error in b.c is still shown + + @id:t313463d3 @project:basic-project + Scenario: Show hidden errors again + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I expand a.c in the results + And I right click on the first nullPointer error and click Hide all with id + Then the a.c results are hidden + When I open View > Show Hidden + Then the error that was hidden is shown again + + @id:t90bf32e9 @project:basic-project + Scenario: Suppress selected ID + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I expand a.c in the results + And I right click on a nullPointer error and click Suppress selected id + And I open File > Edit Project File and go to Warning options + Then no nullPointer error is shown in the results + And the id nullPointer is listed under Suppressions in the project file dialog + + @id:t389a5f3a @project:basic-project + Scenario: Clear results + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I click Clear results + Then the results are cleared: the result tree is empty diff --git a/gui/manualtest/tests/result_list.scripts.json b/gui/manualtest/tests/result_list.scripts.json new file mode 100644 index 00000000000..739dd0bd32e --- /dev/null +++ b/gui/manualtest/tests/result_list.scripts.json @@ -0,0 +1,1127 @@ +{ + "t852206f1": { + "script": [ + { + "do": "click", + "name": "Show errors", + "role": "check box", + "label": "Click Error once" + }, + { + "do": "click", + "name": "Show warnings", + "role": "check box", + "label": "Click Warning once" + }, + { + "do": "click", + "name": "Show style warnings", + "role": "check box", + "label": "Click Style once" + }, + { + "do": "click", + "name": "Show portability", + "role": "check box", + "label": "Click Portability once" + }, + { + "do": "click", + "name": "Show performance warnings", + "role": "check box", + "label": "Click Performance once" + }, + { + "do": "click", + "name": "Show information", + "role": "check box", + "label": "Click Information once" + }, + { + "do": "click", + "name": "Cppcheck", + "role": "check box", + "label": "Click Cppcheck once" + }, + { + "do": "click", + "name": "Clang", + "role": "check box", + "label": "Click Clang once" + }, + { + "expect": "state", + "name": "Show errors", + "role": "check box", + "not_state": "checked", + "label": "Error changed to unchecked after first click" + }, + { + "expect": "state", + "name": "Show warnings", + "role": "check box", + "not_state": "checked", + "label": "Warning changed to unchecked after first click" + }, + { + "expect": "state", + "name": "Show style warnings", + "role": "check box", + "not_state": "checked", + "label": "Style changed to unchecked after first click" + }, + { + "expect": "state", + "name": "Show portability", + "role": "check box", + "not_state": "checked", + "label": "Portability changed to unchecked after first click" + }, + { + "expect": "state", + "name": "Show performance warnings", + "role": "check box", + "not_state": "checked", + "label": "Performance changed to unchecked after first click" + }, + { + "expect": "state", + "name": "Show information", + "role": "check box", + "not_state": "checked", + "label": "Information changed to unchecked after first click" + }, + { + "expect": "state", + "name": "Cppcheck", + "role": "check box", + "not_state": "checked", + "label": "Cppcheck changed to unchecked after first click" + }, + { + "expect": "state", + "name": "Clang", + "role": "check box", + "not_state": "checked", + "label": "Clang changed to unchecked after first click" + }, + { + "do": "click", + "name": "Show errors", + "role": "check box", + "label": "Click Error a second time" + }, + { + "do": "click", + "name": "Show warnings", + "role": "check box", + "label": "Click Warning a second time" + }, + { + "do": "click", + "name": "Show style warnings", + "role": "check box", + "label": "Click Style a second time" + }, + { + "do": "click", + "name": "Show portability", + "role": "check box", + "label": "Click Portability a second time" + }, + { + "do": "click", + "name": "Show performance warnings", + "role": "check box", + "label": "Click Performance a second time" + }, + { + "do": "click", + "name": "Show information", + "role": "check box", + "label": "Click Information a second time" + }, + { + "do": "click", + "name": "Cppcheck", + "role": "check box", + "label": "Click Cppcheck a second time" + }, + { + "do": "click", + "name": "Clang", + "role": "check box", + "label": "Click Clang a second time" + }, + { + "expect": "state", + "name": "Show errors", + "role": "check box", + "state": "checked", + "label": "Error is back to its start state (checked)" + }, + { + "expect": "state", + "name": "Show warnings", + "role": "check box", + "state": "checked", + "label": "Warning is back to its start state (checked)" + }, + { + "expect": "state", + "name": "Show style warnings", + "role": "check box", + "state": "checked", + "label": "Style is back to its start state (checked)" + }, + { + "expect": "state", + "name": "Show portability", + "role": "check box", + "state": "checked", + "label": "Portability is back to its start state (checked)" + }, + { + "expect": "state", + "name": "Show performance warnings", + "role": "check box", + "state": "checked", + "label": "Performance is back to its start state (checked)" + }, + { + "expect": "state", + "name": "Show information", + "role": "check box", + "state": "checked", + "label": "Information is back to its start state (checked)" + }, + { + "expect": "state", + "name": "Cppcheck", + "role": "check box", + "state": "checked", + "label": "Cppcheck is back to its start state (checked)" + }, + { + "expect": "state", + "name": "Clang", + "role": "check box", + "state": "checked", + "label": "Clang is back to its start state (checked)" + } + ], + "script_for": "e5baac140df9" + }, + "td7decf1a": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the project file path" + }, + { + "do": "click", + "name": "Open", + "role": "button", + "exact": true, + "label": "Confirm the file dialog" + }, + { + "expect": "visible", + "name": "src/b.c", + "role": "table cell", + "timeout": 30, + "label": "Analysis is done and results are shown" + }, + { + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "label": "All files are listed before filtering" + }, + { + "expect": "visible", + "name": "include/util.h", + "role": "table cell", + "label": "util.h is listed before filtering" + }, + { + "do": "focus", + "path": "0.4.1", + "role": "text", + "label": "Focus the Filter field" + }, + { + "do": "type", + "value": "arrayIndex", + "label": "Type arrayIndex in the Filter field" + }, + { + "expect": "visible", + "name": "src/b.c", + "role": "table cell", + "label": "Only the b.c error remains shown" + }, + { + "expect": "gone", + "name": "src/a.c", + "role": "table cell", + "label": "a.c error is filtered out" + }, + { + "expect": "gone", + "name": "include/util.h", + "role": "table cell", + "label": "util.h error is filtered out" + }, + { + "do": "settext", + "path": "0.4.1", + "role": "text", + "value": "", + "label": "Clear the Filter field" + }, + { + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "label": "a.c error is shown again" + }, + { + "expect": "visible", + "name": "src/b.c", + "role": "table cell", + "label": "b.c error is shown again" + }, + { + "expect": "visible", + "name": "include/util.h", + "role": "table cell", + "label": "util.h error is shown again" + } + ], + "script_for": "f86b9b8205a7" + }, + "t2af9d498": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the project file path" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the file dialog" + }, + { + "do": "wait", + "name": "Checking src/b.c", + "role": "list item", + "timeout": 30, + "label": "Wait until the analysis has run" + }, + { + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "timeout": 30, + "label": "Results are shown" + }, + { + "do": "click", + "name": "View", + "role": "menu item", + "label": "Open the View menu" + }, + { + "do": "click", + "name": "Collapse all", + "role": "menu item", + "label": "View > Collapse All" + }, + { + "do": "click", + "name": "Expand all", + "role": "menu item", + "label": "View > Expand All (menu is still open)" + }, + { + "expect": "visible", + "name": "Null pointer dereference: r", + "role": "table cell", + "label": "The error in util.h is visible" + }, + { + "expect": "visible", + "name": "Null pointer dereference: p", + "role": "table cell", + "label": "The error in a.c is visible" + }, + { + "expect": "state", + "name": "include/util.h", + "role": "table cell", + "state": "expanded", + "nth": 0, + "label": "util.h is expanded" + }, + { + "expect": "state", + "name": "src/a.c", + "role": "table cell", + "state": "expanded", + "nth": 0, + "label": "a.c is expanded" + } + ], + "script_for": "3d1da0542440" + }, + "tec898362": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "wait", + "name": "Select Project File", + "role": "dialog", + "label": "File dialog appears" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the project file path" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the file dialog" + }, + { + "expect": "visible", + "name": "src/b.c", + "role": "table cell", + "timeout": 60, + "label": "Analysis is done and the file entries are shown" + }, + { + "do": "click", + "name": "View", + "role": "menu item", + "label": "Open the View menu" + }, + { + "do": "click", + "name": "Expand all", + "role": "menu item", + "label": "View > Expand All" + }, + { + "expect": "visible", + "name": "nullPointer", + "role": "table cell", + "label": "Errors are visible after expanding" + }, + { + "do": "hover", + "name": "View", + "role": "menu item", + "label": "Open the View menu again" + }, + { + "do": "click", + "name": "Collapse all", + "role": "menu item", + "label": "View > Collapse All" + }, + { + "expect": "visible", + "name": "include/util.h", + "role": "table cell", + "label": "File entry util.h is shown" + }, + { + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "label": "File entry a.c is shown" + }, + { + "expect": "visible", + "name": "src/b.c", + "role": "table cell", + "label": "File entry b.c is shown" + }, + { + "expect": "gone", + "name": "nullPointer", + "label": "Errors are not shown" + }, + { + "expect": "gone", + "name": "constVariablePointer", + "label": "Style errors are not shown" + } + ], + "script_for": "405a34af72d2" + }, + "t4c027507": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File from the File menu" + }, + { + "do": "wait", + "name": "Select Project File", + "role": "dialog", + "label": "Wait for the file dialog" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the path of basic.cppcheck" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the file dialog" + }, + { + "do": "wait", + "name": "src/b.c", + "role": "table cell", + "timeout": 60, + "label": "Wait until the analysis is done and results are shown" + }, + { + "do": "wait", + "name": "Select Project File", + "gone": true, + "label": "File dialog is closed" + }, + { + "do": "rightclick", + "name": "src/a.c", + "role": "table cell", + "label": "Right click on the file a.c in the results" + }, + { + "expect": "ocr", + "contains": "Recheck", + "label": "Context menu has Recheck" + }, + { + "expect": "ocr", + "contains": "Open containing folder", + "label": "Context menu has Open containing folder" + }, + { + "expect": "ocr", + "not_contains": "Hide", + "label": "Context menu has no Hide entries" + }, + { + "expect": "ocr", + "not_contains": "Suppress selected id", + "label": "Context menu has no Suppress selected id" + } + ], + "script_for": "237d77caee36" + }, + "taacc3841": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the project file path" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Open the project file" + }, + { + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "timeout": 30, + "label": "Analysis is done and results show a.c" + }, + { + "do": "focus", + "name": "src/a.c", + "role": "table cell", + "label": "Focus the a.c row" + }, + { + "do": "key", + "keys": [ + "Right" + ], + "label": "Expand a.c in the results" + }, + { + "expect": "visible", + "name": "Null pointer dereference: p", + "role": "table cell", + "label": "First nullPointer error (line 6) is shown" + }, + { + "do": "rightclick", + "name": "Null pointer dereference: p", + "role": "table cell", + "label": "Right click on the first nullPointer error" + }, + { + "do": "key", + "keys": [ + "Down", + "Down", + "Down", + "Return" + ], + "label": "Click Hide (Hide 1 result(s)) in the context menu" + }, + { + "expect": "gone", + "name": "Null pointer dereference: p", + "label": "The hidden error is gone" + }, + { + "expect": "visible", + "name": "Null pointer dereference: q", + "role": "table cell", + "label": "Second nullPointer error (line 12) is still shown" + }, + { + "expect": "visible", + "name": "Variable 'p' can be declared as pointer to const", + "role": "table cell", + "label": "Other errors are still shown (line 5)" + }, + { + "expect": "visible", + "name": "Variable 'q' can be declared as pointer to const", + "role": "table cell", + "label": "Other errors are still shown (line 11)" + } + ], + "script_for": "13f9f46bd6a3" + }, + "t2937b690": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the project file path" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Open the project file" + }, + { + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "timeout": 30, + "label": "Wait until the analysis is done and results are shown" + }, + { + "do": "doubleclick", + "name": "src/a.c", + "role": "table cell", + "label": "Select a.c in the results" + }, + { + "do": "key", + "keys": [ + "Right" + ], + "label": "Expand a.c in the results" + }, + { + "expect": "visible", + "name": "nullPointer", + "role": "table cell", + "label": "nullPointer errors are listed before hiding" + }, + { + "do": "rightclick", + "name": "nullPointer", + "role": "table cell", + "nth": 0, + "label": "Right click on a nullPointer error" + }, + { + "do": "key", + "keys": [ + "Down", + "Down", + "Down", + "Down" + ], + "label": "Move to Hide all with id in the context menu" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Click Hide all with ID" + }, + { + "expect": "gone", + "name": "nullPointer", + "role": "table cell", + "label": "All nullPointer errors are gone from a.c and util.h" + }, + { + "expect": "visible", + "name": "constVariablePointer", + "role": "table cell", + "label": "Other errors in a.c are still shown" + }, + { + "do": "key", + "keys": [ + "End", + "Right" + ], + "label": "Expand b.c in the results" + }, + { + "expect": "visible", + "name": "arrayIndexOutOfBounds", + "role": "table cell", + "label": "The arrayIndexOutOfBounds error in b.c is still shown" + } + ], + "script_for": "0c3a81139be4" + }, + "t313463d3": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Given the project file is opened from the File menu: open File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Given the project file is opened from the File menu: Open Project File" + }, + { + "do": "wait", + "name": "Select Project File", + "role": "dialog", + "label": "Project file dialog is shown" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the project file basic.cppcheck" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Open the project file" + }, + { + "expect": "visible", + "name": "Project: basic.cppcheck", + "role": "frame", + "timeout": 10, + "label": "The project is loaded" + }, + { + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "timeout": 30, + "label": "And the analysis is done: a.c is in the results" + }, + { + "expect": "state", + "name": "Stop analysis", + "role": "button", + "not_state": "enabled", + "timeout": 30, + "label": "And the analysis is done" + }, + { + "do": "focus", + "name": "src/a.c", + "role": "table cell", + "label": "When I expand a.c in the results: select a.c" + }, + { + "do": "key", + "keys": [ + "Right" + ], + "label": "When I expand a.c in the results" + }, + { + "expect": "visible", + "name": "Null pointer dereference: p", + "role": "table cell", + "label": "The first nullPointer error of a.c is shown" + }, + { + "expect": "visible", + "name": "Null pointer dereference: q", + "role": "table cell", + "label": "The second nullPointer error of a.c is shown" + }, + { + "do": "rightclick", + "name": "Null pointer dereference: p", + "role": "table cell", + "label": "And I right click on the first nullPointer error" + }, + { + "expect": "ocr", + "contains": "Hide all with id", + "label": "The context menu has Hide all with id" + }, + { + "do": "key", + "keys": [ + "Up", + "Up", + "Up" + ], + "label": "Move to Hide all with id in the context menu" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "And click Hide all with id" + }, + { + "expect": "gone", + "name": "Null pointer dereference: p", + "label": "Then the a.c results are hidden: first nullPointer error" + }, + { + "expect": "gone", + "name": "Null pointer dereference: q", + "label": "Then the a.c results are hidden: second nullPointer error" + }, + { + "expect": "visible", + "name": "Variable 'p' can be declared as pointer to const", + "role": "table cell", + "label": "Other a.c results are still shown" + }, + { + "do": "click", + "name": "View", + "role": "menu item", + "label": "When I open View menu" + }, + { + "do": "click", + "name": "Show hidden", + "role": "menu item", + "label": "When I open View > Show Hidden" + }, + { + "expect": "visible", + "name": "Null pointer dereference: p", + "role": "table cell", + "label": "Then the error that was hidden is shown again" + }, + { + "expect": "visible", + "name": "Null pointer dereference: q", + "role": "table cell", + "label": "Then the other hidden nullPointer error is shown again" + } + ], + "script_for": "0b1c29212e8d" + }, + "t90bf32e9": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open File menu" + }, + { + "do": "click", + "name": "Open Project File", + "role": "menu item", + "label": "Click Open Project File" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter project file path" + }, + { + "do": "click", + "name": "Open", + "role": "button", + "exact": true, + "label": "Confirm the file dialog" + }, + { + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "timeout": 60, + "label": "Wait until the analysis is done" + }, + { + "do": "sleep", + "seconds": 3, + "label": "Let the analysis finish" + }, + { + "do": "focus", + "name": "src/a.c", + "role": "table cell", + "label": "Select a.c in the results" + }, + { + "do": "key", + "keys": [ + "Right" + ], + "label": "Expand a.c in the results" + }, + { + "expect": "visible", + "name": "nullPointer", + "role": "table cell", + "label": "nullPointer error is shown under a.c" + }, + { + "do": "rightclick", + "name": "nullPointer", + "role": "table cell", + "nth": 0, + "label": "Right click on a nullPointer error" + }, + { + "do": "key", + "keys": [ + "Down", + "Down", + "Down", + "Down", + "Down", + "Return" + ], + "label": "Click Suppress selected id" + }, + { + "expect": "gone", + "name": "nullPointer", + "role": "table cell", + "label": "No nullPointer error is shown in the results" + }, + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open File menu" + }, + { + "do": "click", + "name": "Edit Project File", + "role": "menu item", + "label": "Click Edit Project File" + }, + { + "do": "click", + "name": "Warning options", + "role": "page tab", + "label": "Go to Warning options" + }, + { + "expect": "visible", + "name": "nullPointer", + "role": "list item", + "label": "The id nullPointer is listed under Suppressions" + } + ], + "script_for": "fb50a62ef505" + }, + "t389a5f3a": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "settext", + "name": "File name", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the project file path" + }, + { + "do": "click", + "name": "Open", + "role": "button", + "exact": true, + "label": "Confirm the file dialog" + }, + { + "expect": "visible", + "name": "src/b.c", + "role": "table cell", + "timeout": 30, + "label": "Analysis results are shown" + }, + { + "do": "sleep", + "seconds": 3, + "label": "Wait until the analysis is done" + }, + { + "expect": "state", + "name": "Clear results", + "role": "button", + "state": "enabled", + "label": "Analysis finished, Clear results is available" + }, + { + "do": "click", + "name": "Clear results", + "role": "button", + "label": "Click Clear results" + }, + { + "expect": "gone", + "name": "src/a.c", + "role": "table cell", + "label": "Result tree has no src/a.c entry" + }, + { + "expect": "gone", + "name": "src/b.c", + "role": "table cell", + "label": "Result tree has no src/b.c entry" + }, + { + "expect": "gone", + "name": "include/util.h", + "role": "table cell", + "label": "Result tree has no include/util.h entry" + } + ], + "script_for": "96a64734a43b" + } +} diff --git a/gui/manualtest/tests/xml_results.feature b/gui/manualtest/tests/xml_results.feature new file mode 100644 index 00000000000..2a7b48c5285 --- /dev/null +++ b/gui/manualtest/tests/xml_results.feature @@ -0,0 +1,45 @@ +Feature: XML results + + Background: + Given the application is started with no project loaded + + @id:tc1fc409e @project:basic-project + Scenario Outline: Save results to a file + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I open File > Save results to file + And I choose the file type for files + And I save the results as results. in the work directory {work} + Then the file results. is saved in the format + And it has the nullPointer error in a.c ("Null pointer dereference") + And it has the arrayIndexOutOfBounds error in b.c ("out of bounds") + + Examples: + | format | + | xml | + | txt | + | csv | + + @id:tcdb051d4 @project:xml-results + Scenario: Open XML results + When I open File > Open XML + And I select {project:xml-results}/results.xml + Then the XML results are opened + And the nullPointer error in a.c is shown + + @id:t8d9a2076 @ticket:13984 @project:xml-results + Scenario: No Recheck in XML results + Given the XML results {project:xml-results}/results.xml are opened with File > Open XML + When I right click on the file a.c in the results + Then the context menu of the file has no Recheck entry and no Open containing folder entry, XML results can not be analysed again + And the application does not crash + + @id:t053b7c9c @project:xml-results @project:basic-project + Scenario: Reanalyze enabled after XML results + Given the XML results {project:xml-results}/results.xml are opened with File > Open XML + Then the button Reanalyze all files is disabled + And if I rightclick on a.c in the results I get a popup + And there is a option "Recheck 1 file(s)" in the popup that is disabled + When I open the project file {project:basic-project}/basic.cppcheck + And I wait until the analysis is done + Then the button Reanalyze all files is enabled and can be clicked diff --git a/gui/manualtest/tests/xml_results.scripts.json b/gui/manualtest/tests/xml_results.scripts.json new file mode 100644 index 00000000000..95fa6cebb97 --- /dev/null +++ b/gui/manualtest/tests/xml_results.scripts.json @@ -0,0 +1,466 @@ +{ + "tc1fc409e": { + "script": [ + { + "label": "Start the application with no project loaded", + "expect": "visible", + "name": "Cppcheck", + "role": "frame" + }, + { + "label": "Open the File menu", + "do": "click", + "name": "File", + "role": "menu item" + }, + { + "label": "Choose File > Open Project File", + "do": "click", + "name": "Open Project File...", + "role": "menu item" + }, + { + "label": "Wait for the project file dialog", + "do": "wait", + "name": "Select Project File", + "role": "dialog" + }, + { + "label": "Enter the project file basic.cppcheck", + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck" + }, + { + "label": "Open the project file", + "do": "key", + "keys": [ + "Return" + ] + }, + { + "label": "The project is loaded", + "expect": "visible", + "name": "Project: basic.cppcheck", + "role": "frame", + "timeout": 10 + }, + { + "label": "Analysis has produced results for b.c", + "expect": "visible", + "name": "src/b.c", + "role": "table cell", + "timeout": 30 + }, + { + "label": "Wait until the analysis is done", + "expect": "state", + "name": "Stop analysis", + "role": "button", + "not_state": "enabled", + "timeout": 30 + }, + { + "label": "Open the File menu", + "do": "click", + "name": "File", + "role": "menu item" + }, + { + "label": "Open File > Save results to file", + "do": "click", + "name": "Save results to file...", + "role": "menu item" + }, + { + "label": "Wait for the save dialog", + "do": "wait", + "name": "Save the report file", + "role": "dialog" + }, + { + "label": "Open the Files of type list", + "do": "click", + "name": "XML files", + "role": "combo box", + "mouse": true + }, + { + "label": "Choose the file type for {format} files", + "do": "click", + "name": "(*.{format})", + "role": "list item", + "mouse": true + }, + { + "label": "Enter results.{format} in the work directory as file name", + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{work}/results.{format}" + }, + { + "label": "Save the results", + "do": "click", + "name": "Save", + "role": "button", + "exact": true + }, + { + "label": "The save dialog is closed", + "expect": "gone", + "name": "Save the report file", + "role": "dialog" + }, + { + "label": "results.{format} is saved and names a.c", + "expect": "file", + "path": "{work}/results.{format}", + "contains": "src/a.c" + }, + { + "label": "results.{format} has the nullPointer error in a.c (Null pointer dereference)", + "expect": "file", + "path": "{work}/results.{format}", + "contains": "Null pointer dereference" + }, + { + "label": "results.{format} has the arrayIndexOutOfBounds error in b.c (out of bounds)", + "expect": "file", + "path": "{work}/results.{format}", + "regex": "src/b.c[\\s\\S]*out of bounds|out of bounds[\\s\\S]*src/b.c" + } + ], + "script_for": "dad1485bb95a" + }, + "tcdb051d4": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open XML", + "role": "menu item", + "label": "Choose File > Open XML" + }, + { + "expect": "visible", + "name": "Open the report file", + "role": "dialog", + "label": "The file dialog is shown" + }, + { + "do": "settext", + "name": "File name", + "role": "text", + "value": "{project:xml-results}/results.xml", + "label": "Select results.xml of the xml-results project" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the file dialog" + }, + { + "do": "wait", + "name": "Open the report file", + "gone": true, + "label": "The file dialog closes" + }, + { + "expect": "visible", + "name": "a.c", + "role": "table cell", + "label": "The file a.c is listed in the results" + }, + { + "do": "focus", + "name": "a.c", + "role": "table cell", + "label": "Give keyboard focus to the a.c entry" + }, + { + "do": "key", + "keys": [ + "Right" + ], + "label": "Expand the a.c entry to see its error" + }, + { + "expect": "visible", + "name": "nullPointer", + "role": "table cell", + "label": "The nullPointer error is shown" + }, + { + "expect": "visible", + "name": "Null pointer dereference: p", + "role": "table cell", + "label": "The nullPointer summary is shown" + }, + { + "expect": "visible", + "name": "error", + "role": "table cell", + "label": "The severity of the error is shown" + } + ], + "script_for": "35589d1420ec" + }, + "t8d9a2076": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open XML", + "role": "menu item", + "label": "Choose File > Open XML" + }, + { + "do": "wait", + "name": "Open the report file", + "timeout": 10, + "label": "Wait for the open dialog" + }, + { + "do": "settext", + "name": "File name", + "role": "text", + "value": "{project:xml-results}/results.xml", + "label": "Enter the path of results.xml" + }, + { + "do": "click", + "name": "Open", + "role": "button", + "nth": 1, + "label": "Confirm the file dialog" + }, + { + "expect": "visible", + "name": "a.c", + "role": "table cell", + "timeout": 10, + "label": "The results show the file a.c" + }, + { + "do": "rightclick", + "name": "a.c", + "role": "table cell", + "label": "Right click on the file a.c in the results" + }, + { + "do": "key", + "keys": [ + "Menu" + ], + "label": "Make sure the context menu is open" + }, + { + "expect": "gone", + "name": "Recheck", + "label": "The context menu has no Recheck entry" + }, + { + "expect": "gone", + "name": "Open containing folder", + "label": "The context menu has no Open containing folder entry" + }, + { + "expect": "alive", + "label": "The application does not crash" + } + ], + "script_for": "a23ab5dd15e4" + }, + "t053b7c9c": { + "script": [ + { + "expect": "visible", + "name": "Cppcheck", + "role": "frame", + "label": "Given the application is started with no project loaded" + }, + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Given the XML results are opened with File > Open XML: open the File menu" + }, + { + "do": "click", + "name": "Open XML...", + "role": "menu item", + "label": "Given the XML results are opened with File > Open XML: choose Open XML" + }, + { + "expect": "visible", + "name": "Open the report file", + "role": "dialog", + "label": "The Open XML file dialog is shown" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:xml-results}/results.xml", + "label": "Enter the XML results file name" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Open the XML results" + }, + { + "do": "wait", + "name": "Open the report file", + "gone": true, + "timeout": 10, + "label": "Wait until the file dialog is closed" + }, + { + "expect": "visible", + "name": "results.xml", + "role": "frame", + "timeout": 10, + "label": "The XML results are loaded" + }, + { + "expect": "visible", + "name": "a.c", + "role": "table cell", + "timeout": 10, + "label": "a.c is shown in the results" + }, + { + "expect": "state", + "name": "Reanalyze all files", + "role": "button", + "not_state": "enabled", + "label": "Then the button Reanalyze all files is disabled" + }, + { + "do": "rightclick", + "name": "a.c", + "role": "table cell", + "label": "And if I rightclick on a.c in the results" + }, + { + "do": "sleep", + "seconds": 1 + }, + { + "expect": "ocr", + "contains": "Copy", + "label": "I get a popup" + }, + { + "expect": "ocr", + "not_contains": "Recheck", + "label": "There is an option Recheck 1 file(s) in the popup that is disabled (greyed out, not read by OCR)" + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Close the popup" + }, + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "When I open the project file: open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "When I open the project file: choose Open Project File" + }, + { + "expect": "visible", + "name": "Select Project File", + "role": "dialog", + "label": "The project file dialog is shown" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the project file name" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Open the project file" + }, + { + "do": "wait", + "name": "Select Project File", + "gone": true, + "timeout": 10, + "label": "Wait until the file dialog is closed" + }, + { + "expect": "visible", + "name": "Project: basic.cppcheck", + "role": "frame", + "timeout": 10, + "label": "The project is loaded" + }, + { + "expect": "state", + "name": "Stop analysis", + "role": "button", + "not_state": "enabled", + "timeout": 30, + "label": "And I wait until the analysis is done" + }, + { + "expect": "state", + "name": "Reanalyze all files", + "role": "button", + "state": "enabled", + "timeout": 30, + "label": "Then the button Reanalyze all files is enabled" + }, + { + "do": "click", + "name": "Reanalyze all files", + "role": "button", + "label": "And can be clicked" + }, + { + "expect": "alive", + "label": "The application still runs after clicking Reanalyze all files" + }, + { + "expect": "state", + "name": "Reanalyze all files", + "role": "button", + "state": "enabled", + "timeout": 30, + "label": "Reanalyze all files is enabled again after the reanalysis" + } + ], + "script_for": "299ae476b3db" + } +} diff --git a/gui/manualtest/web.py b/gui/manualtest/web.py new file mode 100644 index 00000000000..e538b00bdb8 --- /dev/null +++ b/gui/manualtest/web.py @@ -0,0 +1,464 @@ +#!/usr/bin/env python3 +"""Web interface for editing, generating and running the Gherkin tests. + + web.py [--opensource APP] [--premium APP] [--src DIR] [--dir tests] [--out results] [--port 8080] + +Serves on 127.0.0.1 only. Reads and writes DIR/*.feature, with the scripts in DIR/*.scripts.json, +and starts gen.py and run.py with the application that is tested, one binary per edition. SRC is the git checkout that both are built +from, for the git sha in the reports. --app is the same as --opensource. Without any APP the +tests can be edited but not generated or run. +""" + +import argparse +import json +import mimetypes +import os +import re +import signal +import subprocess +import sys +import shutil +import threading +import time +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer +from urllib.parse import parse_qs, quote, unquote, urlparse + +import testfile + +HERE = os.path.dirname(os.path.abspath(__file__)) +NAME_RE = re.compile(r'^[\w.-]+\.feature$') +ID_RE = re.compile(r'^\w+$') + + +class Job: + """gen.py or run.py in the background, one at a time. The output is shown in the web page. + A run of several editions is one run.py after the other, each with its own report.""" + + def __init__(self, kind, file, test_id, cmds, out_dir): + self.kind, self.file, self.test_id, self.out_dir = kind, file, test_id, out_dir + self.editions = [e for e, _ in cmds] + self.lines, self.reports, self.rc = [], [], None + self.started = time.time() + self.progress = {'total': 0, 'index': 0, 'test': '', 'testfile': '', 'step': 0, 'steps': 0, 'label': '', 'base': None, + 'edition': None, 'results': []} + self.proc, self.stopped, self.lock = None, False, threading.Lock() + threading.Thread(target=self.work, args=(cmds,), daemon=True).start() + + def work(self, cmds): + rc = 0 + for edition, cmd in cmds: + with self.lock: + if self.stopped: + break + self.edition = edition + self.proc = subprocess.Popen(cmd, cwd=HERE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, + env=dict(os.environ, PYTHONUNBUFFERED='1'), start_new_session=True) + if len(cmds) > 1: + self.lines.append('=== %s ===' % edition) + self.read() + rc = max(rc, self.proc.wait()) + self.rc = rc + + def stop(self): + with self.lock: + self.stopped = True + if self.proc and self.proc.poll() is None: + self.proc.send_signal(signal.SIGINT) # run.py writes its report, gen.py cleans up + + def read(self): + for line in self.proc.stdout: + line = line.rstrip('\n') + if line.startswith('@{') and self.event(line[1:]): + continue + self.lines.append(line) + m = re.match(r'report: (.+)$', line) + if m: + self.reports.append({'edition': self.edition, + 'url': '/results/' + os.path.relpath(m.group(1), self.out_dir)}) + + def event(self, text): + """A progress line from run.py --events. False when it is not one.""" + try: + e = json.loads(text) + kind, p = e['kind'], self.progress + except (ValueError, KeyError, TypeError): + return False + if kind == 'start': + p.update(total=e['total'], index=0, test='', testfile='', step=0, steps=0, label='', edition=e.get('edition'), + base='/results/' + os.path.relpath(e['out'], self.out_dir)) + elif kind == 'test': + p.update(index=e['index'], test=e['name'], testfile=e.get('file', ''), step=0, steps=e['steps'], label='') + elif kind == 'step': + p.update(step=e['step'], steps=e['steps'], label=e['label']) + elif kind == 'result': + p['results'].append(dict({k: e[k] for k in ('name', 'status', 'reason', 'seconds', 'crash', 'slug')}, + file=e.get('file', ''), + shots=e.get('shots', []), edition=p['edition'], base=p['base'])) + return True + + def info(self): + return {'kind': self.kind, 'file': self.file, 'id': self.test_id, 'running': self.rc is None, + 'rc': self.rc, 'output': '\n'.join(self.lines), 'reports': self.reports, 'editions': self.editions, + 'progress': self.progress, 'started': self.started, 'now': time.time()} + + +class Handler(BaseHTTPRequestHandler): + directory = None + out_dir = None + apps = {} # edition -> path of the binary + src = None + job = None + lock = threading.Lock() + + def log_message(self, fmt, *args): + pass + + def reply(self, code, data, ctype='application/json'): + if ctype == 'application/json': + data = json.dumps(data, ensure_ascii=False) + if isinstance(data, str): + data = data.encode() + self.send_response(code) + self.send_header('Content-Type', ctype + ('; charset=utf-8' if ctype.startswith(('text/', 'application/json')) else '')) + self.send_header('Content-Length', str(len(data))) + self.send_header('Cache-Control', 'no-store') + self.end_headers() + self.wfile.write(data) + + def allowed(self): + # only localhost names as Host (DNS rebinding) and JSON for writes (cross-site forms) + host = self.headers.get('Host', '').rsplit(':', 1)[0] + if host not in ('127.0.0.1', 'localhost'): + self.reply(403, {'error': 'bad host'}) + return False + if self.command in ('PUT', 'POST') and self.headers.get('Content-Type', '').split(';')[0] != 'application/json': + self.reply(415, {'error': 'application/json required'}) + return False + return True + + def path_of(self, query): + name = parse_qs(query).get('name', [''])[0] + if not NAME_RE.match(name): + self.reply(400, {'error': 'bad file name (letters, digits, _ - . and .feature)'}) + return None + return os.path.join(self.directory, name) + + def project_path(self, query): + name = parse_qs(query).get('name', [''])[0] + if not testfile.PROJECT_RE.match(name): + self.reply(400, {'error': 'bad project name (letters, digits, _ and -)'}) + return None + return os.path.join(self.directory, testfile.PROJECTS, name) + + def used_by(self, project): + used = [] + for f in sorted(os.listdir(self.directory)): + if NAME_RE.match(f): + try: + tests = testfile.load(os.path.join(self.directory, f)).get('tests', []) + except (ValueError, OSError): + continue + used += ['%s: %s' % (f, t.get('name')) for t in tests if project in t.get('projects', [])] + return used + + def reports(self): + """The earlier runs in the out directory, newest first.""" + found = [] + for d in os.listdir(self.out_dir) if os.path.isdir(self.out_dir) else []: + if not os.path.isfile(os.path.join(self.out_dir, d, 'report.html')): + continue + try: + with open(os.path.join(self.out_dir, d, 'results.json'), encoding='utf-8') as f: + run = json.load(f) + counts = {} + for r in run.get('results', []): + counts[r['status']] = counts.get(r['status'], 0) + 1 + except (ValueError, OSError, KeyError, TypeError): + run, counts = {}, {} + found.append({'id': d, 'url': '/results/%s/report.html' % quote(d), 'started': run.get('started', ''), + 'edition': run.get('edition'), 'branch': run.get('branch'), 'sha': (run.get('sha') or '')[:8], + 'dirty': run.get('dirty'), 'aborted': run.get('aborted'), 'counts': counts, + 'files': [f.get('title') or f.get('file') for f in run.get('files', [])]}) + return sorted(found, key=lambda r: r['id'], reverse=True) + + def annotate(self, doc): + """Add _stale (the script is outdated) and _errors (what is wrong with the test or its script) + to every test, for the web page. Not saved, see stamp_scripts.""" + tests = doc.get('tests') if isinstance(doc, dict) else None + background = doc.get('background') if isinstance(doc, dict) and isinstance(doc.get('background'), list) else [] + for t in tests if isinstance(tests, list) else []: + if not isinstance(t, dict): + continue + t['_stale'] = testfile.is_stale(t, self.directory, background) + t['_errors'] = testfile.validate({'tests': [t]}, self.directory) + + def file_status(self): + """{file: {invalid: n, stale: n}}: tests with errors and tests whose script must be generated again. + invalid is 1 for a file that is not valid Gherkin.""" + out = {} + for name in os.listdir(self.directory): + if not NAME_RE.match(name): + continue + try: + doc = testfile.ensure_ids(testfile.load(os.path.join(self.directory, name))) + self.annotate(doc) + tests = [t for t in doc['tests'] if isinstance(t, dict)] + bad = sum(1 for t in tests if t['_errors']) + (len(tests) != len(doc['tests'])) + bool( + testfile.validate(dict(doc, tests=[]), self.directory)) + out[name] = {'invalid': bad, 'stale': sum(1 for t in tests if t['_stale'])} + except (ValueError, OSError, KeyError, TypeError, AttributeError): + out[name] = {'invalid': 1, 'stale': 0} + return out + + def body(self): + return json.loads(self.rfile.read(int(self.headers.get('Content-Length', 0))) or b'null') + + def do_GET(self): + if not self.allowed(): + return + u = urlparse(self.path) + if u.path == '/': + with open(os.path.join(HERE, 'web', 'index.html'), 'rb') as f: + self.reply(200, f.read(), 'text/html') + elif u.path == '/api/files': + self.reply(200, sorted(f for f in os.listdir(self.directory) if NAME_RE.match(f))) + elif u.path == '/api/file-status': + self.reply(200, self.file_status()) + elif u.path == '/api/script-doc': + self.reply(200, testfile.SCRIPT_DOC, 'text/plain') + elif u.path == '/api/config': + self.reply(200, {'apps': self.apps, 'editions': list(testfile.EDITIONS), 'can_run': bool(self.apps)}) + elif u.path == '/api/job': + self.reply(200, self.job.info() if self.job else None) + elif u.path == '/api/projects': + base = os.path.join(self.directory, testfile.PROJECTS) + names = sorted(n for n in os.listdir(base) if os.path.isdir(os.path.join(base, n))) if os.path.isdir(base) else [] + self.reply(200, [{'name': n, 'used_by': self.used_by(n)} for n in names]) + elif u.path == '/api/project': + path = self.project_path(u.query) + if path: + if not os.path.isdir(path): + return self.reply(404, {'error': 'no such project'}) + files, binary = {}, [] + for rel, data in sorted(testfile.project_files(self.directory, os.path.basename(path)).items()): + try: + files[rel] = data.decode('utf-8') + except UnicodeDecodeError: + binary.append(rel) + self.reply(200, {'files': files, 'binary': binary, 'used_by': self.used_by(os.path.basename(path))}) + elif u.path == '/api/reports': + self.reply(200, self.reports()) + elif u.path.startswith('/results/'): + self.static_file(self.out_dir, unquote(u.path[len('/results/'):])) + elif u.path.startswith('/docs/'): + self.static_file(os.path.join(HERE, 'docs'), unquote(u.path[len('/docs/'):])) + elif u.path == '/api/file': + path = self.path_of(u.query) + if path: + try: + doc = testfile.ensure_ids(testfile.load(path)) + except FileNotFoundError: + return self.reply(404, {'error': 'no such file'}) + except ValueError as e: + return self.reply(400, {'error': '%s is not valid Gherkin (fix it in a text editor): %s' % ( + os.path.basename(path), e)}) + self.annotate(doc) + self.reply(200, doc) + else: + self.reply(404, {'error': 'not found'}) + + def static_file(self, base, rel): + """A file below BASE: the results of the runs or the handbook.""" + base = os.path.realpath(base) + path = os.path.realpath(os.path.join(base, rel)) + if not path.startswith(base + os.sep) or not os.path.isfile(path): + return self.reply(404, {'error': 'not found'}) + ctype = 'text/plain' if path.endswith('.log') else mimetypes.guess_type(path)[0] or 'text/plain' + with open(path, 'rb') as f: + self.reply(200, f.read(), ctype) + + def do_PUT(self): + if not self.allowed(): + return + u = urlparse(self.path) + if u.path == '/api/project': + return self.put_project(u.query) + path = self.path_of(u.query) if u.path == '/api/file' else None + if not path: + return + try: + doc = self.body() + except ValueError: + return self.reply(400, {'errors': ['not valid JSON']}) + errors = testfile.validate(doc, self.directory) + if errors: + return self.reply(400, {'errors': errors}) + try: + old = testfile.load(path) + except (FileNotFoundError, ValueError): + old = None + testfile.save(path, testfile.stamp_scripts(doc, old, self.directory)) + self.reply(200, {'saved': os.path.basename(path)}) + + def put_project(self, query): + path = self.project_path(query) + if not path: + return + try: + files = self.body()['files'] + assert isinstance(files, dict) and all(isinstance(v, str) for v in files.values()) + except (ValueError, KeyError, TypeError, AssertionError): + return self.reply(400, {'errors': ['expected {"files": {"path": "content"}}']}) + clean = {} + for rel, content in files.items(): + norm = os.path.normpath(rel) + if (not rel or os.path.isabs(norm) or norm.startswith('..') or '\0' in rel or norm == '.' + or norm.split(os.sep)[0] == '..'): + return self.reply(400, {'errors': ['bad file path: %r (relative, inside the project)' % rel]}) + clean[norm] = content + if sum(len(c) for c in clean.values()) > 4_000_000: + return self.reply(400, {'errors': ['the project is too big for this editor']}) + os.makedirs(path, exist_ok=True) + # text files that are not in the request were removed in the editor, binary files stay + for rel, data in testfile.project_files(self.directory, os.path.basename(path)).items(): + if rel not in clean: + try: + data.decode('utf-8') + except UnicodeDecodeError: + continue + os.remove(os.path.join(path, rel)) + for rel, content in clean.items(): + target = os.path.join(path, rel) + os.makedirs(os.path.dirname(target), exist_ok=True) + with open(target + '.tmp', 'w', encoding='utf-8', newline='') as f: + f.write(content) + os.replace(target + '.tmp', target) + for dirpath, dirs, fs in os.walk(path, topdown=False): # directories that became empty + if dirpath != path and not os.listdir(dirpath): + os.rmdir(dirpath) + self.reply(200, {'saved': os.path.basename(path), 'files': len(clean)}) + + def do_POST(self): + if not self.allowed(): + return + route = urlparse(self.path).path + try: + data = self.body() + if route == '/api/job': + self.start_job(data) + elif route == '/api/job/stop': + if self.job and self.job.rc is None: + self.job.stop() + self.reply(200, {'stopping': True}) + else: + self.reply(404, {'error': 'not found'}) + except (ValueError, KeyError, TypeError): + self.reply(400, {'errors': ['bad request']}) + + def start_job(self, data): + action, name, test_id, edition = data['action'], data['file'], data.get('id'), data.get('edition') + if not self.apps: + return self.reply(400, {'errors': ['web.py was started without --opensource or --premium']}) + everything = action == 'run' and name == '*' # every test file in the directory + if action not in ('generate', 'run') or not (everything or NAME_RE.match(name)) or ( + test_id and not ID_RE.match(test_id)): + return self.reply(400, {'errors': ['bad request']}) + if action == 'generate' and not test_id: + return self.reply(400, {'errors': ['generate needs a test id']}) + if everything: + paths = sorted(os.path.join(self.directory, n) for n in os.listdir(self.directory) if NAME_RE.match(n)) + if not paths or test_id: + return self.reply(404, {'errors': ['no test files']}) + else: + paths = [os.path.join(self.directory, name)] + if not os.path.isfile(paths[0]): + return self.reply(404, {'errors': ['no such file']}) + path = paths[0] + # the editions of the job: the chosen ones that web.py has a binary for and, for one test, that it is for + editions = [e for e in testfile.EDITIONS if e in self.apps and edition in (e, 'both')] + if test_id: + test = next((t for t in testfile.ensure_ids(testfile.load(path)).get('tests', []) if t['id'] == test_id), None) + if not test: + return self.reply(404, {'errors': ['no such test']}) + allowed = [e for e in testfile.editions(test) if e in self.apps] + if action == 'generate' and not set(editions) & set(allowed): + editions = allowed # the script is the same for all editions, make it with one that we have + editions = [e for e in editions if e in allowed] + if not editions: + return self.reply(400, {'errors': ['the test is not for the edition %s, or web.py has no application for it' % (edition or '')]}) + if action == 'generate': + editions = editions[:1] + cmds = [] + for e in editions: + app = self.apps[e] + if action == 'generate': + cmd = [sys.executable, 'gen.py', app, path, '--force', '--id', test_id, '--edition', e] + else: + cmd = [sys.executable, 'run.py', app, *paths, '--out', self.out_dir, '--events', '--edition', e] + cmd += ['--src', self.src] if self.src else [] + cmd += ['--id', test_id] if test_id else [] + cmds.append((e, cmd)) + with self.lock: + if self.job and self.job.rc is None: + return self.reply(409, {'errors': ['a job is already running']}) + Handler.job = Job(action, name, test_id, cmds, self.out_dir) + self.reply(200, self.job.info()) + + def do_DELETE(self): + if not self.allowed(): + return + u = urlparse(self.path) + if u.path == '/api/project': + path = self.project_path(u.query) + if path: + used = self.used_by(os.path.basename(path)) + if used: + return self.reply(409, {'errors': ['the project is used by: ' + '; '.join(used)]}) + if not os.path.isdir(path): + return self.reply(404, {'error': 'no such project'}) + shutil.rmtree(path) + self.reply(200, {'deleted': os.path.basename(path)}) + return + path = self.path_of(u.query) if u.path == '/api/file' else None + if path: + try: + os.remove(path) + if os.path.exists(testfile.scripts_path(path)): + os.remove(testfile.scripts_path(path)) + self.reply(200, {'deleted': os.path.basename(path)}) + except FileNotFoundError: + self.reply(404, {'error': 'no such file'}) + + +def main(): + ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + for e in testfile.EDITIONS: + ap.add_argument('--' + e, *(['--app'] if e == 'opensource' else []), metavar='APP', + help='the %s edition of the application to test' % e) + ap.add_argument('--src', help='git checkout of the application, the same for all editions (default: the directory of APP)') + ap.add_argument('--dir', default=os.path.join(HERE, 'tests')) + ap.add_argument('--out', default=os.path.join(HERE, 'results')) + ap.add_argument('--port', type=int, default=8080) + args = ap.parse_args() + for e in testfile.EDITIONS: + app = getattr(args, e) + if app: + if not os.access(app, os.X_OK): + sys.exit('error: not executable: ' + app) + Handler.apps[e] = os.path.abspath(app) + Handler.src = os.path.abspath(args.src) if args.src else None + Handler.directory = os.path.abspath(args.dir) + Handler.out_dir = os.path.realpath(args.out) + os.makedirs(Handler.directory, exist_ok=True) + os.makedirs(Handler.out_dir, exist_ok=True) + Handler.out_dir = os.path.realpath(Handler.out_dir) + server = ThreadingHTTPServer(('127.0.0.1', args.port), Handler) + print('http://127.0.0.1:%d/ (%s)' % (args.port, Handler.directory), flush=True) + try: + server.serve_forever() + except KeyboardInterrupt: + pass + + +if __name__ == '__main__': + main() diff --git a/gui/manualtest/web/index.html b/gui/manualtest/web/index.html new file mode 100644 index 00000000000..7cccc8e9b23 --- /dev/null +++ b/gui/manualtest/web/index.html @@ -0,0 +1,677 @@ + + + + + +GUI tester + + + +
+

GUI tester

+ no file selected + + + + + + Handbook +
+
+ +

Select a file on the left or create a new one.

+
+
+ + + From 1bcfdabe0c4e852afc6cb5029ee2baf407bbd53d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 25 Oct 2026 14:04:28 +0100 Subject: [PATCH 12/32] Fix #15136 (gui: rewrite the online help) (#8959) Extend the GUI help with detailed explanations and new screenshots: - rewrite the existing pages and describe every option in the project file dialog and the preferences - add pages for the main window, suppressions, results files/printing/ statistics, scratchpad/library editor, command line options and troubleshooting - add a shared stylesheet, a contents tree and index keywords - replace the old screenshots with new ones of the current GUI - remove the obsolete manual.html (Cppcheck 1.46) --- gui/help/commandline.html | 63 ++ gui/help/images/add-application.png | Bin 0 -> 15935 bytes gui/help/images/context-menu-tag.png | Bin 0 -> 15822 bytes gui/help/images/context-menu.png | Bin 0 -> 26013 bytes gui/help/images/index-mainwindow.png | Bin 201009 -> 0 bytes gui/help/images/library-editor.png | Bin 0 -> 15713 bytes gui/help/images/main-window.png | Bin 0 -> 52891 bytes gui/help/images/menu-analyze.png | Bin 0 -> 12283 bytes gui/help/images/menu-edit.png | Bin 0 -> 3138 bytes gui/help/images/menu-file.png | Bin 0 -> 7401 bytes gui/help/images/menu-help.png | Bin 0 -> 2954 bytes gui/help/images/menu-view-report.png | Bin 0 -> 13770 bytes gui/help/images/menu-view.png | Bin 0 -> 10444 bytes gui/help/images/new-suppression.png | Bin 0 -> 4680 bytes gui/help/images/preferences-addons.png | Bin 0 -> 7242 bytes gui/help/images/preferences-applications.png | Bin 0 -> 8527 bytes gui/help/images/preferences-clang.png | Bin 0 -> 10267 bytes gui/help/images/preferences-code-editor.png | Bin 0 -> 8791 bytes gui/help/images/preferences-general.png | Bin 0 -> 14745 bytes gui/help/images/preferences-language.png | Bin 0 -> 8229 bytes gui/help/images/preferences-reports.png | Bin 0 -> 5381 bytes gui/help/images/projectfile-addons.png | Bin 0 -> 16410 bytes gui/help/images/projectfile-analysis.png | Bin 0 -> 27453 bytes gui/help/images/projectfile-import.png | Bin 0 -> 16417 bytes .../images/projectfile-paths-and-defines.png | Bin 0 -> 16397 bytes .../projectfile-types-and-functions.png | Bin 0 -> 15054 bytes .../images/projectfile-warning-options.png | Bin 0 -> 13892 bytes gui/help/images/quick-filter.png | Bin 0 -> 21348 bytes gui/help/images/report-misra.png | Bin 0 -> 35181 bytes gui/help/images/scratchpad.png | Bin 0 -> 12611 bytes gui/help/images/statistics-previous-scan.png | Bin 0 -> 8613 bytes gui/help/images/statistics-project.png | Bin 0 -> 7298 bytes gui/help/images/statistics-statistics.png | Bin 0 -> 8669 bytes gui/help/images/toolbar.png | Bin 0 -> 6082 bytes gui/help/images/walkthrough-analysis.png | Bin 142639 -> 0 bytes .../images/walkthrough-import-project.png | Bin 12437 -> 0 bytes gui/help/images/walkthrough-library.png | Bin 4743 -> 0 bytes gui/help/images/walkthrough-new-project.png | Bin 10712 -> 0 bytes .../images/walkthrough-toolbar-severities.png | Bin 6693 -> 0 bytes gui/help/images/walkthrough-warning-menu.png | Bin 9096 -> 0 bytes gui/help/index.html | 92 +- gui/help/investigating-warnings.html | 177 +++- gui/help/mainwindow.html | 293 ++++++ gui/help/manual.html | 947 ------------------ gui/help/online-help.qhp | 130 ++- gui/help/preferences.html | 247 +++-- gui/help/projectfiledialog.html | 505 ++++++++-- gui/help/reports.html | 125 +++ gui/help/severities.html | 191 +++- gui/help/standalone-analysis.html | 122 ++- gui/help/style.css | 68 ++ gui/help/suppressions.html | 158 +++ gui/help/tagging.html | 62 +- gui/help/tools.html | 146 +++ gui/help/troubleshooting.html | 190 ++++ gui/help/walkthrough.html | 159 ++- 56 files changed, 2451 insertions(+), 1224 deletions(-) create mode 100644 gui/help/commandline.html create mode 100644 gui/help/images/add-application.png create mode 100644 gui/help/images/context-menu-tag.png create mode 100644 gui/help/images/context-menu.png delete mode 100644 gui/help/images/index-mainwindow.png create mode 100644 gui/help/images/library-editor.png create mode 100644 gui/help/images/main-window.png create mode 100644 gui/help/images/menu-analyze.png create mode 100644 gui/help/images/menu-edit.png create mode 100644 gui/help/images/menu-file.png create mode 100644 gui/help/images/menu-help.png create mode 100644 gui/help/images/menu-view-report.png create mode 100644 gui/help/images/menu-view.png create mode 100644 gui/help/images/new-suppression.png create mode 100644 gui/help/images/preferences-addons.png create mode 100644 gui/help/images/preferences-applications.png create mode 100644 gui/help/images/preferences-clang.png create mode 100644 gui/help/images/preferences-code-editor.png create mode 100644 gui/help/images/preferences-general.png create mode 100644 gui/help/images/preferences-language.png create mode 100644 gui/help/images/preferences-reports.png create mode 100644 gui/help/images/projectfile-addons.png create mode 100644 gui/help/images/projectfile-analysis.png create mode 100644 gui/help/images/projectfile-import.png create mode 100644 gui/help/images/projectfile-paths-and-defines.png create mode 100644 gui/help/images/projectfile-types-and-functions.png create mode 100644 gui/help/images/projectfile-warning-options.png create mode 100644 gui/help/images/quick-filter.png create mode 100644 gui/help/images/report-misra.png create mode 100644 gui/help/images/scratchpad.png create mode 100644 gui/help/images/statistics-previous-scan.png create mode 100644 gui/help/images/statistics-project.png create mode 100644 gui/help/images/statistics-statistics.png create mode 100644 gui/help/images/toolbar.png delete mode 100644 gui/help/images/walkthrough-analysis.png delete mode 100644 gui/help/images/walkthrough-import-project.png delete mode 100644 gui/help/images/walkthrough-library.png delete mode 100644 gui/help/images/walkthrough-new-project.png delete mode 100644 gui/help/images/walkthrough-toolbar-severities.png delete mode 100644 gui/help/images/walkthrough-warning-menu.png create mode 100644 gui/help/mainwindow.html delete mode 100644 gui/help/manual.html create mode 100644 gui/help/reports.html create mode 100644 gui/help/style.css create mode 100644 gui/help/suppressions.html create mode 100644 gui/help/tools.html create mode 100644 gui/help/troubleshooting.html diff --git a/gui/help/commandline.html b/gui/help/commandline.html new file mode 100644 index 00000000000..d66d7fb598b --- /dev/null +++ b/gui/help/commandline.html @@ -0,0 +1,63 @@ + + +Command line options + + + + +

Command line options

+ +

The GUI can be started from a terminal or a shortcut with options:

+ +
cppcheck-gui [OPTIONS] [files or paths]
+ + + + + + + + + + +
OptionDescription
-p <file>Open the project file and analyze + it. If the project has a build dir with earlier results, these are shown + instead; click Reanalyze all files to analyze again.
-l <file>Open a results file in XML + format.
-d <directory>Used with -l: + the folder that was analyzed to create the results file. Relative paths in + the results file are relative to this folder. It is needed to show the + source code of the warnings.
-h, --helpShow a short description + of the options.
-v, --versionShow the version of + the GUI.
--data-dir=<directory>Meant for + installation scripts. Stores the folder where Cppcheck's data files + (translations, library configurations, platforms, addons) are installed. + The GUI is not started when this option is used.
files or pathsAnalyze these files and folders without + a project. If one of the arguments is a project file + (*.cppcheck), it is opened as with -p. If one of + them is an XML file, it is opened as a results file.
+ +

Examples

+ +

Open a project:

+
cppcheck-gui -p myproject.cppcheck
+

or simply:

+
cppcheck-gui myproject.cppcheck
+ +

Look at the results of a CI job. The job ran Cppcheck in the folder +/home/me/src/myproject and saved the results:

+
cppcheck-gui -l results.xml -d /home/me/src/myproject
+ +

Analyze a folder without a project:

+
cppcheck-gui src/
+ +

Starting without options

+ +

When the GUI is started without options, it opens the project that was open +when it was closed last time, and shows the results of the last analysis if +the project has a build dir.

+ + + + + diff --git a/gui/help/images/add-application.png b/gui/help/images/add-application.png new file mode 100644 index 0000000000000000000000000000000000000000..68e4b422ace0dfac90ab4550aa1266faef4090f9 GIT binary patch literal 15935 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 literal 0 HcmV?d00001 diff --git a/gui/help/images/context-menu-tag.png b/gui/help/images/context-menu-tag.png new file mode 100644 index 0000000000000000000000000000000000000000..69c510f3d489aca2f607d8902ce6d961cd5b873f GIT binary patch literal 15822 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 literal 0 HcmV?d00001 diff --git a/gui/help/images/context-menu.png b/gui/help/images/context-menu.png new file mode 100644 index 0000000000000000000000000000000000000000..6afa8f805423f74a315ada14835d678a047d22b0 GIT binary patch literal 26013 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 XDqKA3TWa8ISI{(6bd>8ApGW>bHn+?` literal 0 HcmV?d00001 diff --git a/gui/help/images/index-mainwindow.png b/gui/help/images/index-mainwindow.png deleted file mode 100644 index aa67a5e836d26ec59ae8079091d4826ffdc9c968..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 201009 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໹@8OTfl4t2Pcavl+;m)e@aC6-!?j{^x; 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 rTUZMRihQ+mAJ|CnhvH#?|aP$4D|vd<~+ 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 diff --git a/gui/help/images/library-editor.png b/gui/help/images/library-editor.png new file mode 100644 index 0000000000000000000000000000000000000000..5bdf7db02bac585a7abcc5e50268a2ba3054f764 GIT binary patch literal 15713 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 literal 0 HcmV?d00001 diff --git a/gui/help/images/main-window.png b/gui/help/images/main-window.png new file mode 100644 index 0000000000000000000000000000000000000000..e678199f2e0a21ff0f2169c50ffd63b541d0eee6 GIT binary patch literal 52891 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 literal 0 HcmV?d00001 diff --git a/gui/help/images/menu-edit.png b/gui/help/images/menu-edit.png new file mode 100644 index 0000000000000000000000000000000000000000..18b587ceb44baeb58b1273d621daa0f9fa298c7e GIT binary patch literal 3138 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 AOaK4? literal 0 HcmV?d00001 diff --git a/gui/help/images/menu-view-report.png b/gui/help/images/menu-view-report.png new file mode 100644 index 0000000000000000000000000000000000000000..65050ce279c3b4837d40bb54f3cea9eb7e3f3044 GIT binary patch literal 13770 zcmYMb1yoe;^FO{pEWI>JxHJL+0#YKbbV&#ZNF&|dv2=HLhk&${bTmIE``o$n%*>s6&1{H*oCFT$OH2R&fFmU-`UL<0Mk9YH5HRx0+r-#X000b7 zkX06Y{*RuXpC6x}AD*A@pPz4^pRfP#`0@Dxd3^tTk34nz{BZsJbb-9?@!{#|{Qmy_ z?(Xj9?*8WP{Py;{5#l^!(!N?CkVEIziI&)4}u8?(-vZY}`NXJl`+h-z{CAFFoInKHqgd+;%_T z)<55rKi*V5UbH`+ms}qX-|p95?`7PqG(W7z->*a*JU*}AKX2V#9G{*aA0Ka@UG1DL z9{op$`$xxzhle`{N88)mYg>mKo9hQ#rR%F}D=RBY%R8&f%S%g3JIiV73+oFDiwg@2 z+YA0%a}hHSPZRe~f9{{BZte!}9y@NIMoz9rHZP{;S7+yD8gK4@UOknc+*E8_X6)T1 zZat=KZN{(M1ux!iOb<`b%ui2GPfky+O^%FDOpcF^&UW`dOb6c$xgU>5?eqq$4@=#3 zSl@M6op)Hzcf2`naawEQ8yNZ9+c((J^|uR2zb8t@PogGI{3mYeTmQzlu6A@(wKO;X z{{6e5p`p9Zt-ijltU0E-W12@wfpK{3A~vt_IYuT9(kS=DVR)E=4sSo~UgC0lr`n6)9Ew9b>X$QQMsA3wks zHEbFe${XIt5#G-c-fJEHeJ0@3Q~>v1Kjh#V@)I6(6lk#G8vQC#p+yxE8szGqW9*l2 z?3|t8_|?kUI7gK!L*`YAI9`Mbx3Q9}sDC$ye?Omd1E)n@JKN+ShLcxlQHR#!rs!6 z(h-xAQ{a&j;*nz!31H)qV4`6oZJ`yC(*yu;21tp1Qg)d?%D~bjoT)oS|0MdCWPb8~ zsq5D5evkk1-)vaa7rtNTU)D4)Z{P}1SH5-3P!tVi?oR>C+8`$2n_~YYpWxhn5#>K6 zTR7(v%M<9qkawU@JlILS_9Q`t9UbFia0mf;`!=4-s^hL->7oUf6qQ|=4{}W|uCq1u7#6w? z*M`Z|$c*tld%11jj+OU=Ldu7mS~_oZWlZIrZ<)WpvXwW!!wl-9&L#T3A!6CrqqX$- zdgy!4k_wv$NL_7yG6f})fBlccuhRO?6uq}l$y9sIZP$A{z~+S0a>B*c4=dXj?-Rw1 z(s5#^q78dq3t3Y2qPq{OQo6ZyyHH!J$OfU4Et+4ez8Ndg2L5ol5yVkiIJ_vpmT0SO10I&)8Tu)0gLO**y;pD>#<;YFUweLlLFBtxF zf2_lqNAM97`}nCSbN90IE`MufNkflfYMllvzYS?9I{`smak}4!Vu>J|1L_;}r(NOL zYK9p);CN818L>O!@Wo<>iWoEi}A-tIK|<>*d0N4jeWV zs^nuu#y(b}84=i8)FndF&;DDjtWtvNKJC8g_x%@qsIGYKNrk>HHcIR^31}Gd7wX;( z8xgwM6uX8R2p7XyUop74`Y6&P4xf(}2{c8*^USK-Ssi!B^)|LvR4T}Ni#0Z;DL$)* z^bWnic|jy8e)>h14G*i3$fI zR3ejWu5SZNR6qKelm?C7;$Qt){B&Gi9>1lx{xo_{+*MY6_YF7ibt$B*`YRW!^7*cT z>*x{v@JQ23;F)X5=`JTc5af$b!yBFCFB#DSS$u_i@6L`+(FIWa5yRxV{et^GT+^< zB>PDBR)k7R1!%B3ez*wiq_p|>V=*^3cTvgjfk$R`c7A?dEfDwRW_{JQ%?q@CMx0&K z)u_7)Oo$E$#lgV^_Rq*mL}XQA#H%o|@RjGkQQ@|ZR9C^%A{uIHJiyx0nqt~q;|Xpw z4cp@oI85#q>4eYM!$5{@>62>2q^gef%;nh$BN6B$6gNS3wG?m;uwTVO-OJq;PMp^p zc$nQRb;lik=#Ev|B0xRfzfx383`cvUgg ze&w-#%V}aDtHMgMAxyWZ55)^{n*!6j+9 zVO4l$H5ENZ#xp{}lpx8quK7c>wQTsq1I0F*T4j4@=YSnGzqwSZs|parp+OJ9Bxrv= zM{yjjY0@NNb^LaFc z{c-&#qaRmin$V_UNS;_fX1@0pLaCk|oN%UXX{4d1fx%#36ciMqRihQ6VQ^*|puVaS z$~S-1{J$s@KHV3%jEzlAO${J6L2bdK`l0pp^gsZE1w?FaQLRU~2F8GauQyi80ve47Ave>dC30xV1-X57Q;SC095vD_p~fqYohsVo0y7VpUp=WUTw(Q=LCL-TFHygp?_`{<>lg zM;nZ|v8=4Fqnmz2kq)sl}()uTJkB?f2+iw=$QnN=E)N=q+@TMi7 zF%ICovYf}s()s>dXlV3^S0Z|bB>(Qg!H)Bv4*7Xa>flp!lBG7x@+dip2H^{~;%uO) zX-J3u@F?Qr>Q#j#350hht9~C34Gqouam3ryY84LqQyc`&!$sJ%?84XIZ-H~!qU7@7 zmOi+eXF^)Vsr~7;NY?>8?GgVVh{R~>K|7|=RuGhbq>NNJ?l^95ON z^N=8<4y;r@(IzP|2!IRH+#JdU;eRDW=-~S1=IC06F@7K-I)|hAciIO>hlj%EA?Qq^ zTnl3z15pgEUwJ`4B(himqD~p*%zQ0Yj-uUrp#5>1K>>S)>!8q$SzE+$&|rxVy!|Ic zwc!HA{M{v0u!+&mGU|j{H;zTOYw+4gbAC!`4ty4GcSsvI%xN0_sTvq{xpd^@RQeS} zyrz`e_?Dc~!&K0N)My;Bxg#MeE{=wHkKz3c(WY|!&IJ6Tq@u29JGXwGk%RD1>ei~) zzhpC@GC=UzwajX=4aKmt1@MXL3$>_o`BXORzZOOKR<@}9oir=HpK>30dH?Px0?{XJ zEi4wi-A<;X!}uCsr^v4mw^4I&{FWHs|FnI{3Cix{;&85dJ}&i{9$>d~LkY+S0Wc^4 zo4Z7YUoet zC7V@rBYuLKbO;Z)tA+h#ctJ|nS*bGY##-bz@X!T+U6Gk&BJCY1B*?w&6bO&Su@Pk2 ze6>-nKJnI%WE1$=hL}2a4lY)f4k3fHe)jwhYRQ+VIcM>uVa7c7LqHH8qWWc4T@?|{ z=51-@F3L1MK7IgvZ5;bq8x=l)q&jIiS-(f{U_)dV7(@Ac3@QQJ@EftG=m||~(7Gfz z_6;o&jCHii+VjmD-rV0J=#x>TAS#Q&aaJcUu}_~oyaK!x6uhWzyq^>!i6mEbaZ7Ao zz{*PX;39IGhBXEff>g#n#hcX>lsb4gwgyMrDCZji!n+@dd%;u`?04~(aPeX#60);) zvX8IOWt3ov6Ek{g4XoAhu*411&bC(_3LPvz zk3zF+HV|KAsi#zp>dlLc^aG{@3_Y76isdEEJv^E>Up*if*hJDe20p84^D90fVXHR? z-A;WoSSFQ!*Q>HW?ARld9*a)tQOvSdt-<};3O9C1!9aq7nWK`^$47HN{#{r##M}Ze zDFRIw5suoQ4J4@vjB1Ond2tUVMeCnMAOpI?t~GGQriBqA9IaosDrgZe2q2UQbiw%*R79e0DbMO^WLYG)As2o z>CE>U?`j)T!eSX?&dMv$p?*J_nprr^m3kxNNS9C)bl5tG3IU??B@X|dZP6xhd>oW~ zP}uJ*(E)bZmRN;p_V=`8vzWBE4)$#O2L?;ij2l`yq&R2TgR%?fJILGzXJtzvOfCK;sxpOGOFN#a(aKaqQN=iR10Vc zpdc*~DAcdPmS-PaRHj=w(Ih(#6@YTNHJ5IK2WHoBEG5Oi-HO$JXb(*9w(K`ng+^l! z^LctCwSXhsI0_vrOS_H;Cj$TYC?J`_f~A-~OSTbN+%vjoGX?QJqZ=lm`Yd+5{3z>I zz#9mK7$r}x75)P17!CkZghQOCTwo5=Mr^5z9ojtQlHLjM-s|xY2EYq+nl?Px$||Q5 ztb{RF2;Qogp=-UySr-%r2_6h7#*403W;AGJH3TTW!@mUP4tl6R2Znt?6ekDY0d9Gx zFj6w5_~FVjqMnFwk=C-esIrfzUnTE(-kVEYsRvg;=^o z2)?Y6(VsM+hw`>E=$bl$o%{%CaPZ&tD(`U3z?&bYFmNC{#j@Ppijj-(mn&Evw{|}_ zUj9xvdBFki1^CDEA-G^RCM_PKfN1fJ(}W}TutTF3!|Z^TE4YywHznyu(gN8mugVdv z0XEG+w#7WK@Bsjy-^at{A5+kCwfELXl|GROM1uxzJ%zU8(bL3rP08~CyEHLp9cktv ztfR>M)(%+Z{yw@U@ct92Ld>-n9=uM2H!JO(xp!QV;bWuvATg(cl?D8(-K%_FIa)h6YrLeuYsFy0q0qjpn2~fOm;CK zf8v*El1qPc;3g0q33!&7X9c_x{W5J8cn$@vFM*UVoG?)#!%2vf_lCQA>&p9T86|L0-_ZJ z?X@i}Ey=Vc2Rf~~G7ISl{S+W8*;X@?chAJU$0=|rERjIEMG?NX+JrwaW`K1e{)FXH39VG^& zLWT=Y-88?>PikBQl=zs4sm!bKTIPYOT&ls%j}NbU64+eC--Q)gX7OaHh)ev5enZqE zsgvUYW3i?7={9;!r6eZC+MJoU00p}~QtHzDvTo+fC4clF#4mN-==*^_&tlm=@SSNc z-PMx@zZK&tIz?vflI(KP>57e31)QQZv9dIiC5u|UyT@bm_QQQ=ZDr}8Yp%R{-c3)P z{44Jt;gMy^8M;ml(eUaT?@RHIcUeq3_*Q>O6P;A}%vTz&8R{A$!bRWTSlEB{igW+> zfn%D3k~Wk?bS;ha(y_le{M2pnnrT4%QfWH3u;TD2&)lL749ES$-A&RZ)T+|5Td(Vx z{Ye_6UnI~G+!suQ6Y{OWCaS)^URea8w%pXVcQ>X~B^K4M_BpIi=Yyc#fu>vum8R{L zqw}@0OfD*;G*^;-a%5C7*B%Zrc)a!NBSUgrri=JWeMZJ))s$>}nb>UfoCW!kb?LQ` z-Au&S)WA~}#=mg^a5)76#hx#TE%4_YMRa(-+Q|CQm{8Ocu(znAs;>wK6dcKI|Jp;R zZ|6r*s82RUU9#S&*u}(XZ>gomue>IK#W&;3Lz`daox}PBmCIGt;k~A)U>}=&@yAb0 zxT5CN)<5<}jI#*g!D^o~4vy+Cuj@nzL6*Tmbp>H45QY&=%=jV0SmIYxBHKi%=kZ+EpcfN-~&KDrx$4+-EmNL9T`%k$@i%QxxmFWBJcL)m&gL^uH? zElmU63e()%Q=xyyt!mT5;ruS#FV#WxUI4>@Hz`Zwo2sg6D)}?c%uo#QoLNBsisPnf zQ!azDf2XgDj#ol&p9rnLbhm$Ij7JL5F3Ur~mNc}M%^ipxZF?da+G;i3GceP)iKmBP zQcTpp$Z|1TA&ZmG0Ol%(lvMTjgbVEZ19N5H4kMFfRrS2cA$G({j%wcwH>?SXIkg(s zJ{V%*ZFJyV==VG>5!a<+`70q`f)8e==pL^J$4YIb2(nFvE~V7|J*RX0%jlI9ipe}S zx(7-56<1Wz2={mV^~*n$iGYdMfB1vhd)y7(WrV7HJ_=pN-rj-#r;qpX8*nd2_^jiv zs;XZFtQgSGkobjb6Y_GV2}J&DCIGnEaYa1OrxNp^`u5>aAP1#C*vAe%(=*3Dugg;S zUrSU?lbd;+nGSo~l>3z%>dgcHZr@|=UU);j9idU|)TC>pWf=Iz*N%28vJ1GmScFQq zw+?r(T1+b$hYS1oawqmoPuo&%;l$UtJQPT2-K%${D~p_r7}5WTt8gx4e*~YoBGFG$ zjnX@;`I&F&pTjijHWzs~9aHiNaB|S-@Zk)alNLC7ThoRouUY2(N`pOo>@K9)Sj||P zA2C8PCT@?f;>oYqHpm_>p#5>W7W#6`%mCcKN8g6lehg9t-HwpL^v&P|K$Ob)a!eRU z@V#AJnx>D~{7gxa)_tbk1nnz&AOVC0KtenhL_-|It{}J58>Kjfo@HsVV5UAhJ8SQb z`B2P*6kGYYek|(nj`*ti@QvzKwX+bF1<&lC z{X75FHlw9l6_EcG#yS&M&d_R`?pJ9L|F@chUXNB1;>&-&et9&>*Ojpz

sbN<}jgc{*;cxd=w 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 literal 0 HcmV?d00001 diff --git a/gui/help/images/menu-view.png b/gui/help/images/menu-view.png new file mode 100644 index 0000000000000000000000000000000000000000..40d66eaf972d98dde85b960069dff07cc90635ea GIT binary patch literal 10444 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 u=N@OAw-n{HmH%6x$*FW><= literal 0 HcmV?d00001 diff --git a/gui/help/images/preferences-addons.png b/gui/help/images/preferences-addons.png new file mode 100644 index 0000000000000000000000000000000000000000..70eb064225634e4036e713c5c8ccf9d04b3a1203 GIT binary patch literal 7242 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 literal 0 HcmV?d00001 diff --git a/gui/help/images/preferences-applications.png b/gui/help/images/preferences-applications.png new file mode 100644 index 0000000000000000000000000000000000000000..41a94dcda3265e99a93b04584227cc7015a5fcb2 GIT binary patch literal 8527 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 literal 0 HcmV?d00001 diff --git a/gui/help/images/preferences-clang.png b/gui/help/images/preferences-clang.png new file mode 100644 index 0000000000000000000000000000000000000000..bb00ea2d31ca63c49b76cba52d892d0e17639231 GIT binary patch literal 10267 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 AhX4Qo literal 0 HcmV?d00001 diff --git a/gui/help/images/preferences-code-editor.png b/gui/help/images/preferences-code-editor.png new file mode 100644 index 0000000000000000000000000000000000000000..5edb3658d6d963bb56a9a307ca865633ce9d7cd6 GIT binary patch literal 8791 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 literal 0 HcmV?d00001 diff --git a/gui/help/images/preferences-general.png b/gui/help/images/preferences-general.png new file mode 100644 index 0000000000000000000000000000000000000000..98f567282018fb227d3daf9d9f2ecdf158e966a2 GIT binary patch literal 14745 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 literal 0 HcmV?d00001 diff --git a/gui/help/images/projectfile-analysis.png b/gui/help/images/projectfile-analysis.png new file mode 100644 index 0000000000000000000000000000000000000000..1d846829455f7ce2dcfa3008939d36970a9ecde5 GIT binary patch literal 27453 zcmZ^~1z1~8w>?aOQoKl!;8LJC1TXHTc(LLXf)yyGxI>{(Ab64BQrz94cqqZ$-Q9zK z;dkx5_x=9!)re7k;~ib|G0eq^ofhJ+nfKq{Pdyo!`s^<_|+c# zYWC*t>gw|H^5Wv^^x^_>LbRjP%d7Kq!~@YzPtGsT&dyFxPft!xkB`rekB^Uz5MSMf zU#-HgR?e?B;g`$s^TqS?Rrm$$`n>D>d=P%pd3#oReNq8GDY!f-ygn-0xrDD=z$Y)S zr%&Pgr>D#32LqQkgXeJAIlTAcy5|)B_iVrA?5g|}et39zaBzHZaIkZDvbT4*x3{;w zf4IB5yS=@=zIV8`y}P-Ic)GcTcx-KLY;LTtuV3xSX5eCR8+M8TXQ8*VK~_o7A80Hop;ceZ_t-#&=)x5!`bC4(&hs6`?G1) za1vS6Xj!(dTez>8d#sUrteLx~p1JKGY@r)dt(3f~7~CusvncX&gx{l$&9$e+_I0r( zM~MM>hVJW3Rf+_8K!OZjoD6>4(-A8{iYiD47$!rZY~iEzULGt)93VjTS?IL{KksYX z7Fw%D8p}o|`z%_k`ZqSwjGyvIjmzI?$Gy_dBT|6i%Er^k1W*aPF!K4+1AXb99^RaM zlB9f&?woXvEHsvH*vx3T-!m%6F%j`HXz)_M(IS%7A&}N4kWwd*(k15CdPy%urp!&o zBabJ^|B{=Y)rFYFnTkb*oL-iOT#jPcuZ~OeBB;(OT{erx|{$XbeC#NB6M*}Hmwg2euD&OO)vxr3Dk&k8*WNec=28IT5#2IXH*=uyx7 zkpOuAeR4xsD;G}aq!I6Bf z6KZnkke9t6J|A=_63`Eu2IW6aJh@TsYYCLA15vCtNB{{rLtGLN%0#WBVM z2XX_%eO0~vRU8I1svqkoR@fE}XtbPC38QApxtqIP*IGrKK#pJRJx^N6jJL=YP7hb@ z$oaRNc$vH^h2%#J58cx}7q%O?D=|brwh0m4Y8Y*$*5mNjNLsXgGV^F>BL8mV)ycV) z5&!V~Z%vgbgjhOAdi(uiEk4tHN_nRJ8y0ABV*~x}=zgB`VV^~lz`on8&n@g&PI$au zCXNk$zd}vdZ!~)dAH_>fvhI%UE1q`)g85FHkY;Nr(er+3*4 zW5jX(ZbQ4tV(5TgH0rRwZddVv&-1Zv()rG%eW8K|?;He^kCj6^U73C7S{7)t&%=(J zy64)Kv!%H!zU>qIr41z@p^h^TI4eP_nf@_5Y!GgBO3!|0ic&-|b+bN{CH#T^{YW^B zW#KPShf|E^49O8v3j#X1G~6@T*%YLI`N?v-`c8J9>2LHPcdaMuZuBtZFaMsVGxkd< zgD)@8p&4m(JVf@Hj0Bf+eI-|v>KQibRgc&U!_%Xj$FKZy_ggwYxr6k)1O&C1 z>SLs_0bBZS2;#Zk=Geb61)W!_e-jN!49!a~!%k{Gx~sV(27`@iVJ#;MOGo`SDt}tA z?-8pz-_^nHI3d1#MICg_Pce-~OevSED%7Q(waNn;Hzk>pTlzdts?|8L5%ee*Z{-%t zR9N{c@F)o93yyImY$EI>ROHVeaPz@i-;&xNv;mtybO5h%0gdw5g_qC6f|>2rq|&%d z>Yk1at;Iwf&0;dj}L6Gh_GD%>?ovMnNqcWJ;G#CP9n~#fJ6y=Rjw; zf?ZlWPQO|*syxKadN3#_WB&;}*F<_g}Ky9cMaKQ4a9 z0u`Lv$nn|LbZ^~`&1ZbXiPpK5M(dS{#?R6`FdsL|tI2F2TOeC)Zpqo0`?wKhw26FR z{#~6@n&+Q2X97j7gWLbgGRpmM$?U7)YQOZ(=r)6Csb^WQb-)KdqNiUT-q&SmG*VOW z*wXOUy{I#-q!7BS+ilrYXTMl_*{VedB##`A|FZD&#aV?FhqMN{(j_Ti`~yX0k{gJk zm3e-1c_7q3Ps2*=SYUGhCWuaI^LpOx{LvaxfDO^%`COLTEExq!S*+fiF>!a*KSg$m z^4TT<1Y^Ca58qj+Y*Xl0Gr7M28fRGdF6B6JbjmA)9k~b}YKSDLho_d|3{1HFMipH? z9t+ZruxZ(^^2XdS2(ox`FPrUA4ifC^^WmHVa;$oH0HFM<1y=&GZZm$TH}Y0hxbkov z(RELVjl6jKQT^Mdu(|@evz^V9h{OJePxU|SD3KsIUoL>WIB&L=5?992qD8M+OwVR& zZMFja0X}Avad!gR*bgOyb}ru1A#N^QN%3hn!MBt;k``vRglSDq&uynubUfL2-uptM zzRiDdHU$QTwQmZbwQLvxMUDo?=~k^3D|5@=u7cLz!FptWOxIrrZbD4i#raE zmbW-VOivY|1X>i}yk(Je!hOcIGylLGZM;0nK{k6x*nu1o!7Xg>V{~m^qqc#lUO>Ih zch<(_|111Q_JH_0sDUq^LsTCh;O9GL1BQIR@TE4#xOKzRk%7_@n@9Ro=?@Pd9d&Tb z1Ea2Q6N`J=P=EpQjL0$<6F+IHUa*|@sry2${3U3V>Cq(6P?13rH2?ebfAG;iXvq&7 z9Tn;)k&Ofq@R=ELT~e;KH-&XWvhK?)sCn)$1+Pg*;T&@fg@Z2-(tk7C)%5e3Uo5ZE zf9QD=VV+fOvKjEZR2!A(hk+r_c#2f%PYzvY#}~XyBcZTr@6*AwZ$mF+El$6vhC?&% zJA^y{%&}BVz}1gm(Ub3)a72~E?svJ&DUd&pv*S-|?CAq5spn6FfZ* z8HQ2|0SU8b3B+8M?K_U6@%hwTxq+*M^W+CqHk>?kn4Br1AQ0Mng*$b{{*#~u?=lT4 z*X9+J@VjVwGc9LRf`)tX4QEZbDkk%gdNo6aypf7!lkEj3BBD!?vyah-mV#_*k2Y~z zrdLUhi8j_lk1I*4joPSw>M?!E7_vkJe0YBzeJ9 zg#<%GO5IZj{9ilheRNpO5>4=4SQjlR;K|-dbw!vLZ&3(aPTxA7RL{jF?zsqy^MH+= zcnx0a4p_Y0C(w(Lc_ge)UIw6h(AQL1*D}46K*`H^Vs16G(Ep$fuMeac?^l7KmfWe+ zuNhUP@u$}!iCT{(MR|r)1^Awg^|MtwAG>9@s;z1|+nQ?r$kUqOej2fzIOly#!<``; z%_s<|M#bQ1G9y^&ouc1jG{<*X-GIa653;GVhLhNrBrxnU_F9*s3h4yZ1fv>rb*Fs;@4ier3P6$o7xVGqUYN4#gh$Os5z^iP>;N^?7iUgkWrpIMH5SXn>B| z3ME}heC^kE_d2~4V>}4NT4n_?CG%b%cMI&aCM$%Cbr9K)KhLK*+ui9>&|4ve z^aY1m*a$5$LQ@nNuI_Mt{b?(m{hi*tLa0@VXMFg<%oRN~XqNjkov&Q*K&$ZJX)37( zuW&9*4@(}%UAb?U^7Z3d6D@n-SN5~2lU&OWjLQ8=sexoPw?( z;=mE(CVJqpR)M3WbIl_TO=7>|N|;M5RyBy#FxLVnGP*+hHbdSSTr>l(jYXwi$bSLc{_UF$N560)NwH zH(-;Of68nsx!6i>op?5b0bvGdu8o#crC;vul&NcTT)2sn&6_QIjU@K`O#A-rUT2Lz zo-4vW%SHu(U))mIkdtWXXG6$qz2$sbk?8|CJUI3F`&QrCal4C4iv5hrRF{cg>7!6d zA-d!c&MG{K0k*>>1z4f#^`aL?OM<5>ifJ088Jlqu-BGxa5S0tZ)2Ww zbuS>xcJ2$01EQFg*E_{wJqbUf+FM{nOX*FOjJtWe5>x-q8LR#ADOU@NB2(^z9zb_y^2Ep!^>?M)}yt9)omsC*MkBCz+&)mDqk zv$|wGNr8m)$s#o!0AQ@OHnP__-j~OnyuqF|IZiu0#lbEVr; z5KjR6iTUFV#7k|*d{TndcO0q|VI6V%r+p56$UI`X0c?9%x^$;hg~hO`4*>dt8~24q z76T5N8ahur?q2(Fj8zA*8ICi+%>Pb7EUOy8ZE4ktVC>H$Z<=PSAzy03T||IiaIzY} z2fUp6-<2}E8g5X9WFrU7)jFs)b(K*eQ$=e`jT41WQ$}`q2OEc6YN0|x)TiEq&zno~ zx|buq`y?J5SFiw!3eB-7Y#mk!brH79dSwFYV4Zw8$_Iv6GfG>K{WEzT3Ju0Z70KIn z!VWrXP1`j0CapwQKhJsIDlq$Ey7TQ>p0Xit1w~>=KsfXO}^7}Cyq4qntSSZ#FY;`iFAtgXQiP{sLYaYt*4ke0_wjacI1N%nbqlT92!kEzs2Qny>{1R> z0yRuY)*`nF8fRk_inD&TaNA(v83rvSI@gl4`bD-$;C7H#^?nEMx?VyXxtPeaJMou?DK$8CiA;V_!7C)xqef=cXbo86Gv2g%pstM$r&;5IfzzO!pWMn}7 zcn6wcx5-L&Y3WVs9yQAh2lh2zYJh zsg8n2-o_P(kpdSNeGwNR%`MlH*XQVe=R9SiW_X^Vk~zTQkD7mCtz_WG$}!h2-dM;ZRw^Ibu~IaW_-m3rHp9?abmq*!=@wc_3U6AH@Au@G>wdL1apWWLtW0f7 z*#Cglt!G0H?@%CL{)T60t4Gz1rEnYIgha~|&Vl!CI}2h4g(mq9>q*doj0|3n5(L8N zdi8xQKw1h@&4-(TaU=wfV-;c-;w7cMpVr(TW%G%&;hdwzB=Xo0t&5PM{av_+-X=qc ze!vj<#dEBAVN3>&y8H8Cs@wTj^QV27ezn_)HI5S@d8V_-xhs4;K4Hlf=KQm8@9_x| zqq3L*FpDpui(d=Hl34%X#ntm75l2d?IAp1WV|%h=X^Czasd7KJQ8 z_-`#|pU2&Oc2fu;2y;0H@Qw)5ZF5 zIM@QxpT$JsYf50J8ZqiQKcBLnpXc`f)E-4^h;?ADy+q&v>6GGhgulQCJ~oC9d4?Xa zVwBF%9-6~Ay4D^-j?9M@cxA;LCD49jKyrHMXhHGh`bJT-AaJ<4?|0W?5zoWFo}=l7 z0mCN)T9xJLQ-G_Y9Qq&_`31%hDr>9USR9GZ5d%Igk1}sUAIGmmyByYVYI;Wqy|T@` zKC(}n`7>#>0dr!dGrd1Y$zB=f&qoX_^elFH%C=4&AyM(EW4{r(DDVYHB0$QbuhqAg z5Oi$72zMEd38=BQU(sTqtZg&D4u=)6TnEH05==R!sVF?KM!shA6of`4XbTyumj4Mm zE+L@}xN>4p3>2^kadK{bt~x@5;wvDex2SQ#A#H(dn5i;-<;4LR2z+I^EMP%saC(@c zO0bwX@*MexfQ67B_B$S6zl@&bCXh+|qx)NYyUfeUl;g?Da?g|g;==c0UkCTTa9;lL z91&k(Z;iM(i6>EMVQBT)F@v{bL;9^ASkO>C(4nN9)RF)cUG$zjwmY z+Q0@(X9=Q<%VuaEtKP872!ldTd1x;-Dsr9D|IPycd4>2bHxf2eTx3xL5IA#CVok3{ zTE?Oun9nm@|BuV!1f;><->|9L%k$h0{pnaz2%>7=`%Zfd+;Fb?3j8kG$nS zaz6)2_<(5L^7S@7=(lKy0=?)b9+Cpdf6v zyBFVoJR&#^tKsiNkbl3~{~%YSkk~SD@P^R^;sfh=qkprsF1+H zaZ>15!>E_i_kQ@4LRP=SU{EZt%J6ct>?wEG9|RY>_FUdqcD^RQA{!eU!`69B`fa5e zzZ{vEF`Pc~XTKjjc-eFDraORSYfUD3?L1E=?qjDnO1LbDj#wFvhaZsW?%T17KC4p= zkAn1O)*{8yD<1_d#W-s4!b z$ElD~M4%NlW38p^0RY1?YwHt!>nyFz+w3p5`lsQ6I+FI^02$=wa~uB*%LxzeSKDeB zB2k%7Ja^y$Y7EytjCYEcdke&pVStKu?}jn_Q&f~j?tG#pLmJ16wkNUn54ESIW|AWvg!esv+PRSEgf#t+Anji+{~< zKPoM+73Z0%GSuKVRB&+?;|hnDIC`a3&)>xT(fdyPGRD2fe>0m}*iC<|0j4LCfN?u8 z#MU%C=_M>}p*?P{O6mEs_9%fe;sXAhG`0WL`;p7`=a{^TTp{#QgJ4i>tIkG&4;zrWt>TZgo4^GBPgkzAg*U z7a&OM$Npe-3WV~oJ4Uu&0W-Kmm3+nfDbRq70Op{8x9Y-`(`aAFtzdN7x}6A1BpX5$ z!k*Z-ec`fh)j_*(<gFvC!r;7U>cRjO z%xLdHPG)19f0R+f@j>Mm)SP^(7J*<5+}beidohJY@0o@Xs%7{8z~(ZBzHTBO)LxML2x|l`H4!OZ&NN&)y||2>xq!1FN4Y ze9v#J_l2+!KC-r<76@zUVi={Gxy#RWzKiw*W-kX(HbU|fK84VOv<+VdCZm%zL66g5 zP9_#U{EO$Q<yS)9al)*hxkaWea*1{p}p{-F5#Z-bKZJVo$<;wTp7U@j?e z&4Smgg8!s;(ht0iE@k0y!$7aTsy!93%=o~S2s>Jy%e39va1^Gp3_ip#26hUK1mfesjyU8E{gqL{Qq4yOg(T!1EvmD`qOIc~f- z&m`iLcudDkax8|YB`uD{`>W4u`J?$;!o&-GZyyn4&;0Sz8dQX0Ypb}YF1W7pw$351 zAr|wK5&W-({y)L~zfA&JREixD5i^2A!QA5jD}#QwpHN#}G-oujDZN^AE2x{@$1lxJ z+~~XZSMK`_iR_D3ZDp0ZlE5>iCY^FQqTzi{>c3$J7_p+G{oNh~iHbpBkn zob==36xcK(@Y8BEL@vPqk^f~#((-T@vags0-xEAp@hhOV787IirZECkPzYFO*(@Ro zoqA(g8=?sZct8$k$yjvYxx~5_IeW|guRhQ-3kft{s%VEYT~$wTt>4aQ5x-l-dj2=^ ztEJU=H+C@d*Fu#<8Bc)6p8^hv{*z7Ix*((~ST)2C+lqqjss0zL)Q8NTK-T2T-&$02 zGdb8PTXoW!KA1abfx_dl+z%U9h|Y;2b%GmvF;r4ag?Px?@mA$1GN# zuzf5ka9;u*S64;IRP{XZ8DLmY#zO19LV*sXw&Y*SSY?#^y553GI*4jm&-s2EC%rEi zgOw}cS-3oiv6r{kdwJQeD@sx${<+8E$Q+fU23Ew5ww0imlut$0*i2IS+O##wUXz?KA_828;X*A*ol=co^#6se=Y7d3| zSMvWqM8v;&)inyhQ42o4XGZMO>%%%4t6;h#{;9FMaEnQ#DWY^B9oMGq?$0*T3jn9(67T{IT0 zrgjZa0G25-_y@SpNB`8`t-En!{-adTOD_q~P0CMXNb8)2W9Vn-N6ppRJdfH-3t#UV z-WL)*bOH{2>0M0+SLC=TfE0(N*!?T=6)TyEC8nm#1)1;$uo0-ag%SPqbn|EyJfKw& z^b!NmOYXAX_nJMaH=G&taT$evY^&>G_houMKI9n>H4;Q?3Psa3m}HO~4R}?8seW`$s8@qpkNKu_e~|nu6f4&6y{?0;vi{d>zRagNmvu&pLuNsWv=&n~dVz z7h{oPE+_98^A?!7vE7&r2(3j$aXMYV^c@tDM(7&~9G97zt&%j%?L8|3$3nEvd0#-N z)vHN7zh!oh;)1Q*AUKxJqQheH4s~vnEuotZ=9G$<3nj+)^~0W$Df$DROR2H0#+Msb zTyI~*R2@DaN#u^^wH@65nZ-I&c}f}_kY}AC7tXQMx?k3IV-b^e|0^&JWOs8v(j0%0 zzn!p|l*(K)*{`%i4xdAm<0vV5cFFNiKiI^a{qjCNtVQjgcl+{Qv#)tLz2zhX_c!)m z3AM2d{87?(d{o^`Z|`r+ImmuAOcf)Nyg~k_aA^pR;V=#+1D5c4l!R!GI3t*5%9N#% zc$4}YG_ecHjf3*Hb8|*NzwgOpHg49`renrmRp+(7E@X15(7@#o?nBd}W8H06TtOf_ zrAm!HbGa9sgG@ho@TUH9=ylZTUR3QbG8V87eHc*oa@{^KznVQi57{0(tffg>N|bmC zu8?m0JHxRV0|rm_Dm8-nax;wjw3nC~?BO%u)n z@VQ*mn5m&Qw`#@9!XLoSm&)L7nK_$w1{xAUz{1%upRp>}2vTvfvq3Z|ATmR~rotVNklM#!Di08RzEOl*ob#>nhwhQU?ycJy~d?cQC=9ts4073Q9>&RDAX%h}^K|)G13W*c2}& z$s_+yC9vS`0QPE(Cto^}jXSHoSX7g7bVWwD3}i@OBkHdGA#2L%6V8(J*yBtr z_AkW0U~$%k7aXVee*)!(?uPW;*@_s46zAvbOA3&2>IHL3LyKSk&?q2!23UFji&Akx zS5T2pfO2FZQ!6_ZjN50=_7cX%3B@*8N3b^wmG3mQMZC?S8S<#T0~v}*cAa%osa#I= zbpjVk_Bu4lEXypiIQ|>~L1=o{*O*SiK8ay)JbLNb-d*E+_{{U7o}Js%BtqiRA~szr zHs+KEqPm_1fh*1I*@vVxI>qqmo6oP^$#@!j*=)lMsX z0!nWd!!FHN6oDOzCcuaf?D*yw1P%e*4jT8{pJZ12)oMMC0r;AS9; zpSu_@cMa564tvhxpd=To23I{-mF8&c!1Pf)*!_F$zlvliO9nsa=%D4F{{*BI z(}BT*lFtAi(8SGYPyxSi!z6POMsPX9m6OL_K-PAl!!~&_Mw`Sca~m!xw1pNy;BA)- z{$k3Rb%iuZtHZH#jze>q3z@}lIb@lM*Y7onC+M!$l|`y$6H4f}vN{F`Cqn)GU=H{| zHs_UM-NJ@~MM?v{eWNqzFjsGn;%1rlaaZ$W+-WJqHz8Cmt+vsqHhGtD^9AehZ=`Su zp5%RPt$r|t$o%KkO+njq=ZyJIU{irFXn1*Uw(Ir)#w(r2lDW|^e>pa(gTTON(E2I3 zQur=r^-}4P0m+}zQ06PHAv#CEuUAxiiQdNKWt3X_rd>-s#Mml}fjvsOcx?OqX>Tv7 zQu@R1Xd-g_?cJp*{>e-?n2dfiVU+nv*_2Ix)Ve3mpA-1ne{cqCi{=IiCY{+VPBy*> zHR@MMwltQFYX8Txtwev~9{$|Lv>K?bHHGF-x&_@^`5U;=|5(HcgloDSloIgsvgJ)7lZa(m#FR_XMzp)4?l|+P4a20yw)qRr z(Wjxr?0ugfid}?-^52UKr)la<+|Et{*y#0j3zISzDGIc?GM)QO>`{x+efZ$>NyX64 zcI&?MB7FVzw@aZmL&d_1G2FpDTdYKtcwU}rD4l)PjjUWUTYv>2Tbp*;>uQm)kFo_g zvOzqeS@mH{iQFKi$R}otl9cV}i(+lA4xn;Mf{hu-CdWff@q_m;alA9Vj2vEm4G@zAZEBIi|+}R@y$6sjTa+dkOqKxm~j! zuFEIaBa(eN+ea<}MEg7EKUc1S8@d%*qB-KhH2CLXe?fyYWEbP&ek8xtG0;fPVEl&g z1`(63Vu@5VSt(do<_e+ZjI=3yh7A9>v$})@o0PV&X3?~DOLzW>uh=x5CGfv{XWe1q zS2v%#^Y5LdwxmdJseSy~J7`K_~zoXZ5>z)7F*q!*MXOM*dK1`-y~G#Ir{{%Rlipqr9>GLjbv^K_lYZ4Hp`@o9_h z8KStJyG4*sfK)rlJC22OU>_1Rv9O8lB_`xJ)S0u<<1$1VP$ZYV`9cCsn6rqOg!dFt zp~yX}so9dvRnj`xUJ*Ej9xpZ_`bQ}OyzejJpXvNmmv{Zc>@UaqO^x5PsGaO~nz8h~ z^Pj~c8Tb&%x10e~(>F(62Z-_>VDYBxZNUg3eLxy?VF1IiK&N7qF46T&OI~iB4rUOc zB^nTNRXW<9kVr>pY39Q0f=2Ald-TCWST*mmqq^jTd;{=|P}?+VJsbe?XyRy6cV^{Y~D z=@_J-DnF-6?5*4wdI|K?$nj+Vc*l=l9y#@^+tHL5U&7zR>+-W1%yFEzpS zzL{8G*_9!?NJRma)n@o7En$UKNAOS5F4*mR)y?|-YIk%%5zCBJ-JE|{kz39v-N*EX z>q|*FcT7j2Nu3jH3u60q09ztm!mZCAj_!w6(@2ZxI-V+$T<9_R6-cffM>tUW$UKiU z(fHl(ptdf&Sje3zXuIKeaCX%jd|>WO?>yO*!<`TtXptF`#FeeQ2!b@e*yBpK(3YhG z{fg+DcKM7Z6_gqpQL%j3M?7kkcmZ_e@5y=Kj0?@)!g7}V9PQ4`BWxWA^K!wEw*@&k z=uDBk`!0-Wx9~to^HDc|iUa7+QHO#DoOV|i;0bpl3S;|z;zitaeJLv^_@jYhjXPkJ z2hP9%)Nt2Wzj0gnz)=axna`74}MG$)L0qyP_&!6u`YgprV)gTq61J?NnNECo*<$g~5@ z|2)=wQ(MV9NtY-jO8qV48MIs@WQ_(ZLbkIw0pd?JQ})4O{q8!eu>;Mw`Vx{_ebF9P zT)Gt!C26Ur^}^KBIVXUZAbR#zHqn^w!6U;#AQZ^AFL86Hn3V0>})Z2#5fx8hwu z@oc}E2Iv`JwYmPOx3$s;Ljcv)TA}cXY)pdBH7vPbOdltt^eOphMRDK9Cpj@kSL7>A zS2EQ11gBKL!o~-V8zs{5$X5H4rCIgglackPBbI}L@{ft=k;RLn zSbg!++HUAah81`2ioXK4jM1s|m=Hk*4MGc%drQXt@A}*;ep=BXqfxp$iSr}?+IpX8 zNY)33b1!wnOg&Idm<j6)T=Z2piUy?m!fT?MYkYn0+$_ z1uoyn1|e3gM{9oRaX|3o!!CK33RxSsS?w6y6H?`>dhkIqNLM1b;<=Xuy+7>ZF^DR~ zs0>U!axRyk0kk@&Is1Lb<|sD~O-haA$O8@MOKpZkg*6MAydERhQtA6&b(nwM*7E-@ zoZ$nGL1@o_%YE3$qOU<{h#&mJ|3O}l%M}%KIb~{L$XJ4fJ*eAPkUir4!OKE{h3US_ z?XFiiocw&OFtNct>1xr#wFsdoqAjkqebr9BA-OA;*3Y;}m|{}wCTz5X?LYB7fr#B_ zwZ+u%%P*HxQx;jp#F{|B(UP}eA;|zlbp@|ReqL@^t&A?us&pBqRK-M_Os#(YO0No! zoh5SdSlvU)@=asEs57n+X4?%eizZ8h*T&A8#yfu;LCP2;2X|uZ?6}(A#*x!BOySLs z?5BFAP|2-h&J;;aAM0n&kC zJq$)l#%Hx_N_lxUTM(Q)sT#tKIX$x;(2Y7Zdt1BO63}=&xR&2yA5C$uC(J=tOx3d8XQK#S*zX2yIf5u-Y z(weD5xcb{s$hk5x=QK(F2rbU;OyZfO#pT|Nj|q(vo1`reTPCSjM+v<+i|BZ*wW=lW z0g+L$MG_4*_$v%3D~um_x%X~;A*@0jF^0`iSB|aKYR>^x_8bZ+8?tBamYdAHo&=TE z9j+TLD4*OOjB=IIRpY~D=X5WHro}+U#Uc(v8xus zqzxlYA_FE{{t{f8w@%Y1FH3-QWYLyRf~+i=NR6&Az&-u9Caj9DPd(+J!~O8@MF1H> z5Zm=E_jNq%o#B_Guh#Dh+dq~zQVDWIwL3z9Ax8Ur=P7tX&x9AxKS2}CNj!HQu^|kQ z0yOm;g8iNR!-1cvVF;E}H@oS+cGNae5OYjZ7Wxw>Vtf!aO`>Yu9g7@6>;)35a&nG=HS~CYMH*92C`FS{j{0@J)y@>eWXu zc$7=8Tr|z2-ilV4NLV|pIew%ecj@ofcbg;;8ldAKepA1=Q@omKP##y_Xa4do=*N}# zU`(s%WaBq0sAg8SaSC^`-fhC0A7Y~|v?!rj80J0ZuK={K;{I4QTQo}-RLXQ6UE{f| zg2sHE0LI5+Xd{B?tuC;ks6yvrtgi+3cJ0}!Ct0sm@BUzG2^`M4cM5$bfJKeeiD$jJ z1VLdqZKp=Hw*SHU5bg$1?s+D=WIyhIb$;MVIDfrjjtdh?bbXa;;YSDRLK~)N`32a_ zjQ=sTybuNe!hn!#p{9vq9Z9rE>#wnEsSx)vvsaZrrVnl7nwy%cSp8JzsATj0Kw-}I zGCzPc32P2i%;ltj=v#JsPbF}!klkX1Ubl^|0MCSMgw%GA9p;aB%`+oaesM9RLdI8S zdF2hbWFZ6U2j;~!*@q*`5bkr?#qJw5NzG5kM6d9}g3`tDK_B1jB8-V$Mr^uR=6#zb z7`p|`S)U}yn|gR$6A)C1pmL7tokZU8T=T0xDoD$nou?~hRdHmu#!cYxV7N4g_uQ{D z+d*V!sY}bXrbe7hc2^V~`39)~KzofXlSTDh6#|*!ZavBGBsk1+0bO6R8|fB!%_0gH(^MoIcF~@vj8rn2 z{Y&(;naD$9Kf%K_D%~zHFN|)E#Nq^e#``Rzpg02KhJwM!)DF(N-}~lDm8#pSqMBU2 z1vesXr_cFA$@ixzbKl+6ys#_0Ya%0*TNfxbwV&lUUWgdq7`Ae9ODM5 z&2s^7weUf?@65RM-#G z2_`OrGMV)Nb{dVJjNh5I4T21NNDL-ulIYIJjD-akjIo*i4Tk2PSYJ;k6EdyZc zi4%hS`24@09EVmkga9Ev93qV34%hni_9VWK6q54V-L-+q(gT&jkln{D-pRUk83qG~ zIY2i7p;Y7N$E4p&4b8OT{*25}oebNR-esnMYGcE`)N;nXTabf>tEa zYOpnP@3rn{BPs|_cCvJ8mUj#tMo_*8v{VY(iz1_raC2h`&xC~4%plw!zlX_JHZm#% zKCrJ+yFry(Bf2)hLg5)9uev@5wk{W4dDu-IU+&DyyY8uS-Vbdmf0j0XhmWSCiOh)i^IpVnXZVNT)D6Cz z0?x2yFXMAeeBQAe(C*whJ9tc#>)GfbgdaST;yw6OuuGOa6F2Aw9Y7;a+3%9fAJ|D8GecX>`@JTj1GSX#D+bQhbq)LcXcRLd6d7A4$q29Cy3UGm@76Kbl#*e-|YDUj@T3VTclRf-kEiWb`{k4MHOk)R)C#w}}L` zy-Y`q!$1bPiInoSdip*IY2^y6clwrkZIr>+%z4>DUq;uh+_xxw1HpR-lzN2O?_ovquu5^FP_s8d1#&)x2LHuQ!YBbUFg&#*$G&G|iy z&P+K5->d4Iv{D9HB1A`~ppcq1ob(WG2CQm?-14~ec$8%L4_ouy^8_^Nt9VqK@#lsq z0F9NGWk?9QRebznooGo3V!tFNdqU7f?#T7jx;g0+5%yaai}7i@WMVk(u53SNry>#_ zO#s))QYAy7W=B+r?ddos6I4k>+?k&$l}iX-OD&e4!({i}6`4kYF&BMcM_}RH3@Q_+ zpu~d#)H|FS793bK8_nH&ww+OT&}HboRO~OYh6^#6k5%ed5`7o#@V5a`$4aC*yZaGV zRr7sg!LARXGcL%wSE0a$N%$!}R_23)$xxpG1LQ2ejcbwTOCspXkDw>*vzk8wzWX3> z_7I%z_hd|ia>u8h1^V96s$*o zlNIqNZoAq<*5cnO^Zy?WG-CG`S}^#^D7rb51;L{tLH7-5M~(8|BYK1fB$W9eDYv!U z-LMPTp?H&+Jr5N1_WF8K^5C5J*QJdl=%LvKz1wAQPla#&Fqz=*4BKs@SewqBuChkQ zy5Y(2FC@q(+UzFP#Tku5cVkfQ{-vh7)(|W^2kI^NU+9d z#l*0vcCVN>*ce5*OH3;nsVtszVGQTH!=~1~k(QowSd>;`ujOoRQzAA|rL7G7V1JFt+Tn3nBYnjL8zRBs(G54PuOaUz45e$u^km zWS4!?G$a-cIIcayjKVXSG%Skty-ha##BX=jDc)%`Tys;X@?^HC3PO;1y! z>06J~0`)=egq(}Gc06c#3k}sL+owc# zOCQPit+;5y5G9=`8kwx-0Eb*%y3wy;V~(qxO)>;_-8=mw10NE+2`yVAn7`7+QpL9- zP_Foil(POZ3$JDc2B)XHR;uZ3@C08wQ4wbie7K?XK$5Fvg5 zA^IKQ=CAs`K|EHzooUG_mHsP2@DY8}mxYLzM?I7RdnYrOuA*}ocxEMbdc$dI3m{PQ zZ?@Jm*6Wj`2a(7*iN;8r%#EIRC7dNg2U_sBRCUc!MNp04;<4egbD*x!*KD(@8ElO= zqZo~|)n)_&^CT7{HWj*8ZR?e*!as4H$1FD_P48Vs0qKql9L3R~kA!*oBI}rDrSGo0N^lW%@Hj?P&XWAt1q#%PIb@nuVPa?C z;$N!p2KpD$crJ8=&^3V_YR;iqHW|pH$|x1XSZmU`F$9OC9)Deiw~ss3Fg_}7u}_hbMigE(9^sILSu1;i8!W5;aWiWn&&#D)ju zuRD7XTcbte&dVmZ%ndA;pU=)GyAlzh?ilI+xqKzm*m_HkoA*BwoBvQY|AXaHxe5jP z-uR61xCb1uE)6iLFJII~YD@6)sCaD<#W^8z=gGBW>W(ALKmJ6q?{`zPLxDV3LesYu z0`<6K^w_Nkv~!ji(r>%$Gud)7H!;7;(rVxsbx@X-<_U-DN*b_b0FETO_JzqCBRT!= z7)1VZf$>Ct@{tgNn$3L1um-79|EG;S!+*f+j_^AA=5aigCDAjYH3KoB4Yu0qtvrTL9 zZT?GM*gg=$Vji7&oiLIa74Lg7!O}YJWudNsw3b+ZnmlKEd0sWYYUkgm!aT|od%-nW zo~xUi{?Ngb))i38%AsIT44~LS$M)W7+8UbM&EnI8jo68tWnZ-75^CB~&voTq&I@cP zq3mcie0h%m9PMnu<6oLlsttdWg8yU#Y3ZOZxCpNJjxaFH?kxj)AIPVox3-C-%D6wa zKqZQFS`mo%%qWSXd;L9#_aDwBiZVw60FwjPdw^>eUey9_01@XkSq9S@WqIcr{#v1E^`z2V`#{L{FA&OP4B@!@K_w**m z-gZUBM~uuh*~L^nA@(MGq=W^wq#8KYHS*r`TMXv)POcT&mP|Q)d&)iE4Iza-bV*G( zmcyf2<5YGJ&@9S*{JcJ>3T>33v43tdX6LIUZA&`U`EP_BhdzA^!gmi#wz_*8!2uTi zHC*78p`kESY5BLM%Mp#5j2v+SAtxqDcb%tLl;@qBY&H!y5D2y0$l=?*o4MLU|FXQMlu)5-o-+gk6A4^DcTdt?INWSlQhQWcpDC32 z?g)>P5?+Vi?;}`Xu=Ldt79lBEvbZ@@)>K&Ego0(~`TKO?pSY|KG%2rwRMle`Hi4=8 z3=Ty z$odTPJ`U4Jt8Ff`=Ie-;5Qbk{I#;`+BYuQ_{W!T<2;v{&7EJ8oLuVQ6rr^3q14?@C z7FD5tQ-L>c13wok(l3$Xo00z@Q)3#O@pMBG<{&kA-DbEkt`&7dWrw|w^#c$SNS};M zvwj&f4(8y#VR4;Huy4NYIkD#HQZb|G5A;i64|!#|gYL{m?VpMz)%86?xhun;9(*#8 z4U``7!_-&Zvx`xOy}@hPvWQ^(+(!I;*XL-N)tp#LRyXB?O(l+UgH_mxxb4uti+J9$ z^gB&z!3=dFZlN?3lZTJamy#sicnBjva&u7ijkujdwu_B*tr0w^-G;c6fVK26ArEI{ z7%%&?^n$9sw~Ld0f`x3aIPXWmB&Yiup>QRSs*P)T9}k5C(r)#U zvV7K=-HwxD_C$zTU$6vvB?!wK_N(4^xQerXHau4agBE(#+XH%h}5=dtjtdY;=a^T>ek zN1GQjrjfYzUY0Qj85@Bz*-unTcCgq~<7Y@1-*pTk?Dz(RL672MRQ*8kbqh*f1*L`P z(NkC3z(+fHa{V9dNp$52C6%H>@0(`Ci`|9*>d-L=0Bt;~`9bU+`h2&?>;L96Wv`>C z;`xK;o0+84$r;p5c$xDsR02HyA*$^e&o`Cgqo0-6<_Oua@EzmhG?Z?oS+?rC&#{#P z#>>vBj1(7UZt$_EPFj?yhSLKPNMQre;)!OkIXJI~c@gQg0QEMayL@F3$146HU}W@o ztCW=)nj=$($WZ-OHEEv#do_r$-HI5)GF>ydM7h$m5OQrH%gF*|r?vVVCg1Epu%5t1 zt)eo}sqy-xZE#g=wV#H22M`nd7rsgKoZa~(!< zw6j*x74kCcS-d|LbhpR}MwW!vW3&)Mr<|B<948+?d8a{X*dQ8>AaRB8ZXP?(*hns! zP)Fw=uamLldbO%N6+$X-b19q$GDs2J?r?=rr{II&z|KF6h!E0M%y1l}Ob27PSD747 zCBJd~{ApL9=Fh07A$^Lk)%xRG>`l-`pJdR$AWv4K{i^|W8xpLGul=E&kBV4QGpJH? zbouljRvw}`N`vG{?3h;oM)eiM|DAR#2De~;1nHsfu9A21F=ndc!fltKWc#~)&;0)r zydRwyF_!{afs<{ZTf3rt%8T~*eebxm2cb;Yh%5acgNDb_eg5VE(KqBA`-6D-F}>s7 z0?LfPM(wtSqHset$Le>R*EoUD^5zI zx^eV9t-e)`vsA0%D$znh-c>M2WX94SP{k_oi{xu5*liG1gdAYEfscHsSQyhjFKH^K zZHSg^Qn0SnqlNU62aaFlc4hsw(!`QzjG%hWGxmUKpDmh@XvY;hG|@m6D8QqHpofU} zq!0$t)F8p~D$KFnR^*YvIvxphF4Rq>m?+=))aEmgO*otS)7m<0>8I3o0puS9uy@u% zb#J+wwOrt4zw)R%hbRB`H>MG6A$xB5+%e@&&uJu$Xgg@+1{EEvc6f7Xh1pD z*)U~OElD=F1di}*w`S!ibSWQ#H73{Dmncm6d=XKO#J-u6+kXDtp zEi~`wG%WyEXS7S>N$Y)2O$%X~2csgAUwT#o>ekWnlE})o(yu+%tFIOLHSC|<99=wh z;>eYyf!NCjhCoH<51_NZLs9bSOV@b5A3(zuMkA;i*0afi3cFp3nL-_1>I4KcPTKag@-3hdL z7&X>K=zsB$qY4s$SYazx#8}4gAMoj80EP(^s52yor_QESd>xI4+^II&pD@x?h}(%D z<(lP=%YA+4G#6+Zn-6T0JPr^ zWngOAyo@OBR^6>&R(u@%@HG2d7||*n2Q)9*KQWFD3LU;aJ6}J2b9EtCp~fp}v8@NF zzujrCK#BXKT;vD)+S%rwd-!CfMW7x?Z3~ z#S-u7^=#7ccVK=?!Z2-3yW6O`F(ZWv!=EO+f#{g5hxYG(KaJTGObb4e*WG$}>f&YM zt{;#bGPa&bKBy3yLjVI}*rj;&e5-H7+yLfnIRci1h78{yA#fjkzp& z#i=ZTD>a$RaMD|<-$XwQVO|~MJ#jpq=T7(NtA$94-H|vmJrAL|K=?2Tf zAWHp4vU(<>eEWTpL4@Uza1uYDIolHAPasMgd0A7jnZL2s!hUd;qLTSiN+N=;99p1z zZS0xnn)F1f8WNRg^1_oLVgjETD%5vlDte44wwqV^}u{u&Mu-tj+hjQBQPF1T9l9>Pc6-;hZL9uI=Qi>Rc+o5QPc;^R5zV+ zzcT9bEYJ9t;Ab0vvuo`n!L38a&0gWz; z8eS&c|07d%II78lBqUcjGYEY@Mm!{bxqyaR;Vr|)mC!NXYO|*> zoecM_9@FH^)HSm_RZg6cR;@9~!c__B!$@im zeiS?EDp6S)veyikfii-0%iLIG$wk+NC=!3_HY4$_J)20~N|ab`zFpU1<3|cHq5i?@ zkrn8{m;{-vHmTu;c2N2)wYy#xGk+S4NZotjRIEj1Y+Jo-OoK@D#*6PTI7DzmeQ+!M zngq8lmVS!<7x756h@%S7P-8Y;PBxhTCUF<`9>qxy-m{3@Rgfej)h6(a^o!6^u?}yK z@^c{|JD+wrHIaRwDL#p-H_&++wFlh@a)UVfAn?SI7Q=yv>CX>UpfLF!NzQbCLcUly z+WaH(#*WgE<01adKaL*RC()lj>9PwSv@Y4-RpUO{vs!*thR(e9;t2jCTfjeVB)69U!;5y!!!kvue$BTo@`wmCfP8_s{WY08c z9(2gyf~8C~HE$#unx7CSC>~bPNS;7hwS3;R4};f#Kc!tbvuZG$s(J)^*e#^``z1lD1{lX7mW13@(lC1$pT=`5*gjpkZOEm|}pNw}D_yZrNbP`IxA*15rykic8 z>4>hz0-z`#1dmWa)&|%Q)r|KCiVuD%N+B42_c*G)AqpiK36+q#;~^jz-{~CZ3}zMr z9mq$m!yO=Ec%-7CO>6P$q}dPu>9_03`_VE%tie&50WW>&vg>zhjd>r`&aC-eu+zyN zGVe(JyVG|sIBNL*Hy}p)p#aNem@!oXGutWfU7y6#?X|hr{_k8Qx+SLBD>i*rIxY{5 zTTKv(rxOOwcE#@EPG7_mYXw}$Leu9kLLM-)76PKs%XR^bMVMXetWE*m!Q~WJkwwR?cyP2DzW_HsvB4HB&xy^B?dhSlu z-P>PoyZ`MdO4<}A&HZahmpZ{=av~1sOu+=B4~2G(L{>(hhJ3OaibFJN8YLkg#A2tm z_g!kv{hlaY<*X?hx@KLEDP}RfWwR`*IM{tLQZMaB8a?M(F4Eq7_iF<7;^CCz>u%f=TjR1G>FM^@}Ow>Rkb7j>pmTERcA z#T+juA6VT5Mc@C0w9p$P6?u>p@V@*S^)+C~z|?xedG=sNTzVT14kDM{r0Zv_GZw}B z-#9=CPlv=;n&pZO1ITY(LcMCiCU7wlXvAZ&vrjFAmA9^<3B56N5n_r@j|tBS(B7>$ z&^Xap%{q?_UyMVy=z(tE(T+lLDzVp9n1tyyNN^s@Y2`}THgr|2z3Ea>vmamqdCde#}C|h(_Y3@LO0+P#GoAuCjupo65r&dRVM=wZ+gpRmr#8 z`j@>Kq{v%;6@?1_HVe3DXyVTkDY&N53=bLB!pS$pX2B5U2^$&1@Qc>kO*Bf@-okIV za!JOYz$(zq%Hfgjv-d}fDyd<+rv`W@1y&NRdC&K^XU;WzS-uZHo)IBAF1vm4(_anE zlfqpgmhrzGMUAHNf_6Dy<6iO)p&ea$%EH;?eD1y?-z{8d+OQ{ZLcgPN`;T7seIp{2 zS!WChd=s$ry#5Ht<-Lts&t%(kBohN1-Ovh#!JWaul@k5=TTse5I}Uc0r668{)iz6j z`tz0!CLK{%LX9<@l0G<+S~!T-+q!Yez=Mxq*xsjA;@lC_!FXSSBtf{${!>Nx?=kp4 znO*w+aJ;?HhwcqGfVa2^_t_%{oZv}dHXeevcfP8svkPK!81DlU9rQQjd*IJtv42Yw z0A>h0_h2u2?}CsWq)CgGi0F5UBDg!@zrAsO53nZ!a}CRJPL5dN*iOx7s|RUMm@dAQ zxS}5OEv|mdAte#upVvNM;9exJMjz_OsXxgMc&0wl=Z8^$S-wTaq7z#5(}CPZiQ#2t~FWAtXK^E$LYgU{YCL_c(DXDUOCOtZf0$hGI{ z#U<@~z_lmbxM$4>_LO*4Od!ZCO}HRTQ|O&jb(EFUrb> zh5l*0$;{@->0kBNl%EI2yqj#yg{72+pmFn%=^PX0p9&iQ_xs>{=3O)T)bpTXWA?tt z9fvK{_4Dd&r~RK;3#UdN>^Sm7u6BO@!g+A^t$^X12%B~NMG;rgAJbS7MW?UDg0bI} zaEyhKKV5TBhtvF%iuA`|bBmv^tWB+HnYQWvEgws6Fh7deM=!|n75t;#42UQmH(h^D zkpt9_--hygv(ZIY!K15kZRnea>IRh!$BS@`Q(Ofn?QQXONGHs*?NIUB z+|Xs#hWKB7MFr3|-~G_f|1~LEKieGCfpl{2yXT}6RSk3pP5m$`MbNW2TP({IB;~R} zL@KCZ(p-hepp!`3u3Eqw45|4+L$cONG%7 z1Ajtgu8jE{K4o0C+Hvx1kj}eB9Jp<7uhuK_doRy9v~&Cg%rlwwWa4TY-jt=ElJf|` zzs66M;yei$S7%vAZzYhTe7|a5q>LDaR8QKh%s)2?8&WyLHY0f=GDV;fbq^vczV#&k zj8vBM!xVZZIBDeaS?+v!FjkZCqjb-5K@Fzk(|<6}cb~l(iIQ0~jzW(7(qR9De!$sA zF?~lA^X$H*!2<;Row}LZ}sjGuURUwF9yT8Ufm!Rut7L`W^G?3o;GNi7& zE6Ot>@Vf&lpMRvy>tG-i=mx=^=aRB#hFcYP3}>56rM+a)GY zdIe}%KOOKaIx7S9($VHIJzSJzVCm^q%lW@%6k8W)hWyWbHJMh=ntBJrOHXC)=P8*a zvC{i;>SWjpj>fGH-I7~?0{0kK%7(=T1vi!w_X3Bvr~kgm@S%S_D2RUWfIDpHi_5z& z%y%MMUngNzUfR2@pZ`f(0I%Bh5Bv{tc>aWroGy)8E!xirQnt0-8cf~=6MAKnzQPV}^ovn*w zKVO0ZcLDOc%dktR)W4g}rs6^)}wO4cwTe>9_IhW zW6^&6{|sV|dw!#KNz!}2C4!PzmeG?zg#s1Uc3lr5*>2F|*iUf?;HBI4JQ%mG43VjxY@`t*XUv;>A}e`W{mWc-G7FZN}z%i2~H0;WyByYWFry zcP8hWrt1DYroIeK>Gca~lxH*r@~wabrX#N>=PZfcQ#c^R5Q6%9t;o?y*J7AJpqb*K?3La*k(h$Ty;yu9(#EbgcFV$KsYwmg%*#t zOE6_f*qqh>noN~?i38Ic=N&Q3a^X^-o@|^JY1D1F-Yq^Fu z!<;U~#tg9LcxrkaDrIzSrb0k$M#ic8Xy;tRUW|jsmC;p==tICasGD_Mv$crv#smjz zIEpbbF=bZ|#lHrAZl@}zg$`lBq@a22SI6!sGLgD5O{y`-pZt7d8RQqp;NVpaxK!WsqjLj??VXL*LJ<#>jo;l-5Foof0W|>&4`T<$*HS0cwnx)a@t%8RhPJiX7>fla zHk6U!oO7v{Z%1I%H6zL5Se?&dH90{dS$0fxi>Gp!Za) zi?C+f-D^L$(eAg@r>pwh%(PP5NNtI+izeb|we5`CH#hLm&stc1zRs|vp3ch$aWq_R zly#H`Vj*_2xkS!F<N5sw6?(r zT^7=db!7hf*!cC{(~jdeQ+`Jh6WOr_#<2g?>q5j2J`yNL{^izmH*(T|p6kykl-2KWh zdLHA~W?m-^2WQ%UpeC;KXLT1F#!`C$lfa{~jvA=T#!)BwE!1lS=O#~zS_?*Mi+fDi uUJUNm2uuU1>i@3_qyLuRH8nh^NJHQ$-+%sv0K69Kl7h@L=`WHmeEtg!2TgMT literal 0 HcmV?d00001 diff --git a/gui/help/images/projectfile-import.png b/gui/help/images/projectfile-import.png new file mode 100644 index 0000000000000000000000000000000000000000..ae487d9bf3cb7596cb36006b53b8adbc8084018d GIT binary patch literal 16417 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 Ttpi^D$5D_~ktvcg`S5=LT+yz5 literal 0 HcmV?d00001 diff --git a/gui/help/images/projectfile-paths-and-defines.png b/gui/help/images/projectfile-paths-and-defines.png new file mode 100644 index 0000000000000000000000000000000000000000..a6ec3a4d2c897586f34ef243be68edd53b750eb5 GIT binary patch literal 16397 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 CR%$^2 literal 0 HcmV?d00001 diff --git a/gui/help/images/projectfile-types-and-functions.png b/gui/help/images/projectfile-types-and-functions.png new file mode 100644 index 0000000000000000000000000000000000000000..4b2fb57f435216b6c446ecfdf147e1a2be3e1c05 GIT binary patch literal 15054 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 literal 0 HcmV?d00001 diff --git a/gui/help/images/quick-filter.png b/gui/help/images/quick-filter.png new file mode 100644 index 0000000000000000000000000000000000000000..cefbe833e427b4a98dd7548f16170c9028a32208 GIT binary patch literal 21348 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 PJrjb}Gtqsn4MhDLk1bci literal 0 HcmV?d00001 diff --git a/gui/help/images/report-misra.png b/gui/help/images/report-misra.png new file mode 100644 index 0000000000000000000000000000000000000000..30071346a4421dfd235d3abb86eecdfeb881a2db GIT binary patch literal 35181 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

GPC`M|G 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 literal 0 HcmV?d00001 diff --git a/gui/help/images/statistics-project.png b/gui/help/images/statistics-project.png new file mode 100644 index 0000000000000000000000000000000000000000..5e909732bf4851276482ff844790830722f7bc89 GIT binary patch literal 7298 zcmZ{J2V7Ix@;|~_Q9+7`6s0dks(^;7fDo$m4oWD}TaXgU3Zl|GC>U5FbO8bBZ58QF zLT{m$8$u{a2qct$*nRu$vPR^ZkbMBcrGvApT^;B2=+LhZ^sHmu}fi+YO zsHo22DOdI-8p?>V6U}QXDjKS%+D2-pXLNjgdU|qla(qTdM`ss>$mBm8GMRjGa!4j0 z9+B}UN6UvNCnWL_iA*A%p6rv!#3SM^nS`PUlg{XnL_VP0BjG5$!^1=JA@1Oe@Z|kn z;vs3D!UqS$Gs5kk(H`O8kU%`xJv_wk9}xEUclY-R1OlGIcnafj1R{a3i#wy8Jpyr$ zfZxUM@8a=0c)}hIw~Zrg=fTE2|qL%gf7)i;JuC>sN{MsgJ6+O3#My+owEG(cSqK zljz;q6<~5@cVcaIdU<1Vd1G{bdvsx}a|8Rw%3A%}cKs5jYkoFo6_>h1%0S_P@q&$^ zGW_V<&4Jg%AJF|)x3!MftAD)uIWqZkXn0_-x390SyR*Bkt!=a|udZ*bxw(0>-gV`R z{c71WR28(N8ZllPTv}TCethTM$X06aM)=RY;BM^Ow)wYJ-EPghUSH-QH9JHTE1u4kAIGcE203 zW`dbtJr&VNpI3?*RS2%V=iediRm$&`E#{EVGdt3Wk#G3u#a>HWvhQ%Lf?c#FD2zbpsjwdm950q6`xbC_KToIxd|7C@XI=wKQ zntJa_9DDsS5Rz=; zu*a?QScGALoFp1-0DQk|Im2NXQ|A7(d!@N|MJ@BS8L#qBBJc5?Z2C`SWphRlS2hs1 zLNYLkpDVr0{oSBuT~?4=yStMW0{qT_t-KWJuN{HsSd?=-8>pc{a&aKJj$tVt!wVOI zk12{y^n=I~MYYD^1?z&vPTwcOL#!Eijj5#Ka+{1dlW))0xw0}w-JhLd>$2oLv3_XJ z+=NcWn`H65LjHJ|_YCz+p$baOJUPi;dM?yw9pHta<20M85LJ>)LNg;Y$gnGPjh9<4 zu%`^X;-2$5*qc32jT|c>tz1swo;zi;wUe*tmewXuV_B^HR7f8ij7|I5kcc`FLj-z% z@i@q`>oa zE4^CM3*y!3V1)RaB4r>hFDC?$YCvAx|5!1Z$A;8tbBU4i6eI=`>@8y-`D92Zd1PAK zVdl}U`YF!^zksGdE?RB&>t2Kc%TSB5St7KI6zb;FbwjSMm)aoW`id4*=^NJG_ba@; zhT6gakwWrzj&~ycU~;xC9NG;w9=fJicQi{v?N8n)B?hz91T_~_G<`SZ-AWS>&k`Mw zz#a9fE%ECa=tXk601ZBo$Ei)MeF%66GRc@AV#a zUPoU2?vh65!Om_-YAww#?=OCZY{h;L!E_az1G#j+XXGNnUqKq>om&I7mOeW1=Hu3P zTp6OEIGDGujFHXdMEyAknC11@&HA}?+k?>-en^hS&2c6@`L4voR#2C)7= z$g>HOd7k8lON!B7Q40~ulg5<3fxS}4 zjg0ht-yBC44k*Y;mJ=YqHzXFIrXhugliF0^$inuqDg~)8u)<{-0GZPx8k7#8w+|m` zjcMjv1RtjFP9n)<=E!UhV?;s>CYPH*!#`ts5sa{HX?Pndcpo_@)F(|KhNgd27=Oj- z5HprBTXMx}%fK^kwm^5qKV_V)2 zOehKa`{CsM-{4`s_qS-B zzCgjni|i*HwfW@XmStC<-zXYd{<0?oaXn~hs4qVG!~LXeoz_bpbrr6NnTBe!jHojDi~= zstR)M{i?I>3!5Q6Fy%?y4aRAhVcqF> zQ2y612k8arJo~-ILa*$O0s z|9z>o$@j>1QFfok>A)YSS+_1q`qZ!b1tbl$AT0DgR?DH7^k|{lZ6?8!z||&KRsE#7 zNOh&l3MEO{bkkr}dLMiMr1Oz~qnH6_=^@kT2bB$d$z`?-dFl5~{7OLfC=_9(#Lb zhC|0`TLHQ++FiV3uXLVAK`Y;cw;^5&1S^5HHomw+t~3X(Pr=op$|ODAs<^OVgi6Us%{soO?u$!)*^~-e@4Bvq;ke+?MjfE4N_b zP(Sy9tXZB=13$b_OmI$v<@Stt>Bu_8y)R3Yj$9*LG%0Ml&z}ow;0@{7&D<FREh@RdK(^T*wG7)5~yy`!DQ}5reI?(CmfZFN4FDteT$j(}TEx$40kU=pTa+Du468@WB5E z5Y7fPx}<%oBciN%SeRmOkA(0CNQ;!iav~>MXhdA8&rrlavm#je;0?0k3sv|}Q<*R9 z_%+sB@mzoPa;_nrYx&zpYJ}91&+GK#_iNZ{@HX4}1Q#`AXD_wND9^?G5jP!L_~7wT zaEA22>~o8;MfY^mA8o$g*(3AXYG7LZ1S|Ft=1A>mHQWU@6A~e^xldMh&G?{Sh1sVT zCU7g**wR$YDSt%bcu$9i;&W$d{koq6gY!R>wrAy4K@ZanqtC(Hk$Sb$w|M*9Da(t) z>pV&q)9974(_SyfUwatc`27M~=KG$Mv{niAVh`dfWPk9{f8wRT-}Kv8&8`w-dspi2 z@n7l#1g^~bUXZ>0AA9kPUu%86XmoXkT1d5oI<&P!{fK6iiTp!yw07}V&w%%9 z%%0UmW#&O@pl~`l7LTW1kqKHO9z6}KRv}3hx-x@tH1;$2k6G@N5eIIf_Oq-zX&$K9 zbVV(M9LLEk2qRC3hfQVW)N}0>$M*N4#=^+BBB%mwKWbO*-x~QAn-=f7^59&R^nhYw z+2x5ANF=REy)x);{P)-UC}$wD=5cIR@_f~tTg-_&YApEzr9qNc+p?g?;+`54V1V?2 z@6CK=zGrtr1QbqLMWV1Vi|6uiAGg#y=*d=${PC!yN@%=hl5q97l1-^cLV>`=)D#8q z8{4dZq|+1{g14vvu$Le{2;x>SpY<5rRb!uwxNXH)>C45%5d!q38T z)V}%s^dlVMe6X-g^b5I8h@o6dpsa4zwDY5vNlC}gk5eCO88wz`ct$U?+S|%{#y@ZJ zkHg0qF9kN^;N$14$K`R3)4)jCwKTiTA3e?A-lPp8UP@|i#j0JnG?%RV#ybK-z3!OB zg*+T%`5KG$0HR0H&_11YetO-Hy-zq zbCRwlnS9C~?K4mL#t|=Xi@=Wp7~@WsulH*JY1zD>Skj8xH zL_Vnkr)KR=sE&(3XwAXHGW=cP<4Yg>j6j`G>%{Eux|7BD$attek}ihhhqP8(KjSmhglgoS&pB>4a)msW$87uwJoI3mV#Y4DUiRZ(^}pcx6bEYtt?5ra}s zKS@PUQUP&+Gkbur$gpk>Fc$~K$XYj5Exyb}8TL5fuBjp~t`d*3b7`}J3HSs5CH=P9 zB$R=jo4)UE@u;q6b$bC_evV6wOgDOWdEy-lum7!0I3kLQ$`m2n0Vt$|gn01jY>E>< zLBT+9<|Lo8qs~wefAuBvI}do_u`{ZmHjuvO7yS9DAA4Ckp_!37M@`;EHiO_C%Rsdm zq*$^!n=`wGk(Pv^D}a3VqqTdG2&Ur3S(3f`d_-(tortqdLH1Q1om~DEyQSZuD8Yt-p4wa0 zAGuYgk;QmVso0~o-4R}w$D;hAno3hHJc3fWb^GI*8I~z3yP2vw-5o!M)3fIajfCXN zYAEJg1RV(a^GSG?a@5zEwS-`7=QO6{f|t5X-k8>i*`YQ%z^@`rU8aY%!c!H1YaBn|@}WKP7;Ii67HC zq1h!og$sd3e1(X%K-u`N5xrLD`^|V&b5Tr8F}o^EC&3 zUvC?i;!o$&P>i_8E?qJ*d5oun9f7)GQp|k!RIhC|LUlq5bX`$zW|pp{Ed`!=Knnmt z_8)hI?)8`MJi2+uLt|pa2`#>MuYrHflqi(eTXhcLdt=ndpU0@AWr2;H9|EY)GSEMFS%t^&m;m(bOkR!=h8gx0{B3|FN)sTPZ}Z1`R895fC^xnavY(m zpseAZ``vrz!BbCSfktu{Yqf}R8#lbCwR^=Wnwt?HEHPxnyJh@Ci5ot!@%8U`Ro?VZ zcK?q$B7oHY;T8Ue2G0`me{nwpQ2!*J@vh|vhGr_$YfjFj{#hg~1v>nXssAo6oIT;+ zKmJ+Ee?bk35&WN%^;coyKgIvHq(9M~I)di9R5-qkiqb;GwJ7N1Z)3%8!)XCqJpq8_ zs~9^wC{U?TWk}cEC?4GAwWvPQcRr4=u<$TN!)wRr$!aDZAC~QboMO2Smnwd(>tIw4 zJ`Gxg;%e50CiL`#z8A;#J_LqNXYhN?CZyD(iFaN>C+%tz`KOrmk-nh|2qoDl`BcU4 zmt(Sdg(xm)DPyEhtiY5c=iIOI0#1*-qj|a-7U~q5Wp2mHRXv_6V{Fa3Wd;7gSG}uM zhF`yVEuy34z1mT*L*!U))b2+wL{WqDO3pFixFN#-#K>T8@0VO3U6QAb!-2I~S&1I! zDf-gKch(B^_1MyBRO?Gm?&IT~vdj=wQYjBkjvGF85NATl?XVD~6g}tk4*VOPhncDm zs@!J6#B7f2UMfw&>jPBN-vla&h%hMLG;SC0``*FdaD43S=6yM2eHEojTB~i-!UlGZPS6Cd4kNY3b*IM({mBD#{?n$`=2DVv8L5@)ttDx#0mbQkb)PY6 zK5UJ^Bol6Aw8}QAETbyMq~ajKR)ph5Xy|PFce_Q1ehp$Q5!nP9<(6>Y=GZDKYpdF*UnM?O(VlsY$je!=)skb|+5E@am<6Df;mn21 z_#oTm#!wv8n*}jIghU@W^qDxa9J@?av7|VR3-d9XBv-hm5h1qbJk^#;j$g z>9ryg)W+;AO$#v`kg7NhTYUaQaLjAt&_h;i(!h0DQ%G`u;S6ttuVN=H(IDX!25-b&1Q$r#%ob$z` z`h<5p<3hnmm3Ti3a$QHcCU#H8)0sHs;VpaOtZ&~ zY6*u-`P_qQdnQmBG@b}+k*u~S z@aS20ngcU}qH!z$jd8QJmn84ozS>Me~BekY(!I|SWu0pNeml8v)iLJqrl$DvR%o{`L1t6r}(JJX_ z?&pTJv;G~u{YYtH5iCD4#L?Ie2kSCPv^!FM&D?ipC|}yjZT08p;ABBV5Jk&(-YpPI z#LCScU0|+01CpVB6$ZujHvZy$4MHJ(y3xOvtWbqCTfBTGFoI<4*&m=0E#v;cGUc9S z`b7&C%VcfwqrdtVfJ*Y2hkMjHYt7e4CD-ENa$v2Y@}21q0~+&S3s78hOyJbr1?5g?-N!3K&AHZCX|+4ahKgQI)=S>G1sE#a;~Dj24+gG;IbJj?ZwPKP zEMThzeKn)t!1#m0WqWPno~PENY5{XBG_)pQ%M}7XmGV33B+XL3pxn2x;nTM|Fr%+Z zJHl!>tZ|w+DQI(JVM*VG3frrnkOt>OY{&MAerinx8nA5v%u8qfY9gCWlfMA*hq$`l z1knn~o_9$VdD41CEDldTEXl^xgr8MQeRAfgLBjh}9A*{24&5WY`&b2&g}1Dyb3Ds# z^i?KV+*1XG+^r^3P-N$49wgYAgDhuluvjT-yq0FJ>$H7ZBbslc!^ytgk;rI(@UeA& z_ZB&E-BBH$D=PnhmzURc7~Y4GfS?{8S32jYh1wi^=26mK0iQy|lJ|ue#uce4#ShYm zc%n^u;L%fP-=-eqQS+(u5eBI#YpxVJegmAB{fwJk6us%}%$0L8g`Fd8V=w72mgk7` zTcw?RQ*T#BNF`vUml8U84c2hO2ZzeSAzPcv>v8?at-S0nCI=k3@jVvhny1TM6w#D0 zy0xO17DY}*?&IZMoO&6az!;FRO%G5+ZT=JuqKNKPjP$*=)ywD9xRZfTP|C4U9M=px zhJ#o97XJ#UL#HGnuu_rZTAoB3wjSp%5GRYeoYPxml@iKzj62QJRh+P);b7mxu1NRz ztArOy3QZuw5++*S>Y9=!S|p#M|e8RmcY2%$*tK|0b2 zNG}4RgkAz63FXCe-aX^|@7#Oe95cJDy~fyUtTos7eRJ+azR*#lp<=;^O@L{EXy(?DX{PjQHn7G9vLG2O^Qwa6%*! zh(yxy=#;okAfA$L@P8bKBNC2?ghL{6o79i+$M6K=34wHZK)S-?iFiEeggZIGpZu|7 z;_*HXPdFy|$qDX{VUPdV!O;nRk3cxWonVhoj*gG_kB^Uzj<83^SSsIy){QVi9;Og1Cp+IKginVCV6~g=50z{vl@f0CRvIKOqj`h=Vxd@2Kq&aZ6Dk$e?1i^j~a ztxT`(OfRpa)^^+1cKcSQ>sIy)*05=4e8%GDr$zkl-@gxj!**tWV8$8`rl5zYgw6h> z{T|53)O6MC)^LAcd(Qy&htEDT=osm8h;%tdIv>{9t~5c=-)#n3ipMIWo0^&`YC0wm z!3YFmw#YGM4jVIl@@Zt}J!&tw@9=H=`uoam`}#x6(v3a1!B(#BOwP-RIOUNri7qHO zGx@E>xAj-a)xANFTHZ)Dx$+`xg~II&zL~InF}Rzq!Jev0m->u4LWfT;Z&T;I-(7Tjct#B3l3f6i>WQ$!f_^mtdEH6bZDPY)W!} z`H*4$Gypyge+0VTyhVkH?hah1t5R{`hb7H0-^so7x|PM~(U5NBNm$Lt;c2{6&^C;G z4oF9%;PL9h+WWVXL)vr3ew+bUHLrrc=^A3cI*BUWms?@$$0d83#~w=URI7LaXlSko zSG6CK#ZtadNe0C&*>shHE4#`2Kw$b)X>%p&bQJ?6gbWNqTJjnDcMYoe%^_=zmWP=X zm;~BC?!D)>$wV)7ConRU5)&_SriFMx&BPuuq^5$=SnXy6a>~`QyjfqKU7-iz0u~!0J*C1H&1< zzKE5le)}&PFUDQqd4vb%ffsLDZ*K;{^AhH&{EaZFwzjRg(EHQLrSpkqXCq4qJ6pzJ zpL}kR5wU<_3JCsum>zd`?XMu)&@u7yrs_q?~_hkF0PM-=FokMpp|OJ4fe<01NguUBzPtxXs&);f>Ps zlj^KZK?{j3RC~r5#+Bg@kuy6vW6d*90%Xn0>nvV96qpe?`8*?;>7(p+b>{MW{}uiZ zQMy{l7t@5Hai-7?i}w-`wNgnMA-B(I282)>qc>Mjd8xM6Q7B!*S~1YLu_X{`S2boZ zf%>}BmF2j3I~y4!vy;RScpdt%N8}JG%-B%P2zmd;Jo_s=^wifh@=Gb;T+*>E=c8O% zRhKMMm7*nM1(t&n9uv9l@YU zd9HfTHi`Z~MHJw5G&}vTAarpn1E zZ8>qA3tH95qoiD8vU$y=weH%Q%7H%t!3)pzFX4}=hopHGW9Q_XnP8d#{(6k^E}5}i znH`M3eg@)(adas&RwI-# zB;Y^=E-K4+#O-w0FxAe zojYsF*G`wMI$InwXwc=8^EOw}=9~PjoA*vEJ-b(VvSK1E!mpRTO-ykTU5gZ(D-nt9 zPmf+_uhFFYcterRS0*9`lk*N0;cqNmfCVH`^cA`1RQ4DeL00LiU`A7;sfIf!H zokHuq*_&5~>Q{w6P}OT!s{6<3-=WBf+gpU|*1xC_iHg~s1r5u4ZE1Y>9;=Fw%k(LA z@UrYFkDTc_7OuFmR$xqM{r0mG2Q4+gM!wFz*&*Sf@WW{uoA5n(;^F0^LxR2rpP#R-^@0R2$m z3w~e}inZo&?hw-!N?Ry!&}%pz#HFpu=&GRriY2!=oK0F!6;-2A)&58h=a54mZUrys z7b(mw=+Mndb^E{O$^VJ`|4vc=!C9AqAACsuPXhb%v{WLoi;_olu;805n}EqVIZQMJ zGe?`B5BLloDWMU|&%a<5G3S8IBu%((7gkKGU^}HXq-S{~?PLNf^m0?tA!Z}~rY%ai zQeD)HoQiaXsIvZIkqutaFFlq@O5Sp%hq2nxfWHTK33X(p#i2Rr#}}5yCmOL7wF2W< zlQyekbC)mt)~Z}7k{(RtGJ(deuSgSm_)2gf4LwnUiF)8%tbReC?vS?m-YyX)f;gay+rcB3ss-P7G_jo zNleLD@(A^!sc9u%h;lOoN?t-2@50oWVU^yFB7`Ta2P0iHcc;{A5>o|G3uW9QXF}6# zoLArMYt}k)H&?Ed=LK(*-rqljbIXnIXL_IKge-9L{W=Hd34FIl$qdUXr0o zpb~f89m0^tvTncK{e26!XuM+lDMY%XL%g=_1}cXKqg(;Chjaf4<9}+Mzw5I9Sj>Me zlFGk?+uu6;o`SmZKMYm&@zxLDe4lN8D0egLNA&Xsu0 zYiWmmHgu)KG_>bu<>QTQ;sw$8i~7%jwIV4%zKe%4baW4Rg%~fFGeP`HNvdpiq5F~L z+>9;%&Wt^0QF(BT(r*x0XI|q~s<1npS*2m;d(ZX_VtY`syUJx5ROA3Nss80YsCz3Vb;unlf2 zD!xr`L|C15vb28AqwsdfzqTnk;AMvSQ)-EL_UpwdZVv?lZ=rnqQW)wvjvP3Po{X_r z_xSEUL^uBanwSl8YKzCol!31JUemxSSa3cPJ^O69@OFWzm75jXAwA!Y8XH{LLos)$ z>hDJt!NGeQ$c=u{fLf^nug>MG4T3}3mfj#kwR|Ux$&%1KeE_kW%&v@0@hg5xg={|P&XbQbJU%F_xVqB z$TfA9^Ba6~;*gih`HO3r*XZk}hA;}poO@PKw@>i8TzEvB(yP-H8q|HZ|4#V-Eq?wHf&UBUwl1ZXYD6>- zS8iGj4XRQ3J*UEs3I#i#ot(Uw8oSBKa{L6;&n&YyrW?l-CMI`xkrtW zOPEi1#W4Jsr@&i(@(^~z;UT*d7rTjdG3%(bz0r(HgAPn0f|;?eSNNt$gEqwiDiHJBIJq&l!a>t=UrBRqDHo&10#~9K5o>0%ZrFh# zx_tx{5J8=S>XDJYXWI1pFZzpqS`(fg!b zLb}>;B_SnS(e`);aEoq0G1@ti-1R0f|9D|ZHW<41cz>7#!DtkR6gvwEoh=AoyH&Wa zvb5N~{X0GW&#?cuAoyE;ILwN%&tQ<`-+`9*Yf3~ct8xZM0AGDA_L>O|{M-<;n#I)r z=%H*c^kJ?TZ1Wl6E%XP%i#ogM#)OaiVgJs8QbQaJ!4*cN*RH89=yj@0rotnC)s`TuU2*>%1>(I;E zu1B-yj$uDOan^IgHi2?Xlx90h-a&tu`r&}ct71|JkY`$pl;XP2W>$9_*vw}LK_#2i zu_9&D>_~dVAfcJVYNeB-R~^82Bq6u`APt zzO6&v{sJR8;SDmvtnLE4b(4a@D=AG59jjy#DYdr^jawuyeOjbjA#Gg7UAwyvPg7F| zcXRGs@Bf?{>rb%aDyZDa^3chD!5=}r;EY>?@!fh2n^@2?;Bdrpr`|QS^5QLk8>c^# z-30r769Yfu4E;VCMt!jYKP2Yluw2*ru8~_lLXtBW>1`M6nshR@>#Dh)dACxJXnWLTC)RG z`&{-rMg}!t*OF{SZ1I8^Az_JRYulRH+|#uA$Hn|JKi^-N*w9uPN_Fmmbg8c(XP<RHR|3!so>J?J%b<-h(`b=;9lxOo&+@K0_Fj{xbjj3wCxUx$>Gnux4CtXA&-nsgU>v`&(6P_^}Mv}dtSsg)Yo-Q1GzQj_+{{&+tTgjNkPJL zWwMH6A21U{id6fJ4-}d*mG_6Aqm#$VB~_(gj^9-9rozf%6jz%V7Q?9df~$swfrR&A z-Uio>}vkib>przK5B}HB0pKOD)0?;<@#E_HrGgg5f|F1>qxlaE4gw z&NhQDrRA%-n+|@jIDL(T?Oo*Z>~+GVue%t{<2s+YEt1p{JW&TGCb?#6c1{kpI1j({ zE2waMo~NK*wJ=3dmR_#V?rO45(PP~X4mVsMivfQG@!mj-eH#ynhRvLZV`o5lt?TIqUs^s9nLqFDeZXD~)BzuN>m>dIV%srukXHtp zAf3WUUu2%40>o0W(&wvthT66093}zAGf%VYRnF&1noh|ijZS9>&9>=ca5!X04}Wq~ zse#>U^!#cF7fx8+pR&?iaASrVGnD8vL0Gis>Ei?v(w1HRak4}k^IWguO4n(lXIsJoT<>6m4x_8whb)N;mOuT@ zFwvdpMoQT~{dfcrmpb#*uMXBc8j*a1_Ay}1hdl%Z%rS56=0eg?HD=v&1E&iTP>!G;t zqA=T%6{vsR=RQ3?&RpSX!ucq9K)r=?!JglUpTy0a<`bWjcD|Y*tt6%bG2^l2hzC4D zZK7+H=-wxf^nt=JpBH=Dtc>_s!5~Qv5U@xBkUlQtIYQk+aXA zqM0NaCWJru%vDt1-^XJ5^jkC~(O{k|%8l5KDlp$^k%=5%)iK53Bj zeop#&QFzEHuMwe2=~c4NM9s?x<2Rj|KD&`!38e-OJ2L65mS0DHaGyPm*5XNTCMK-{ zbMouoS(@}qS;`vrXj*o;+S%_u+wfdW;jkhY?Rk+7& zw+J@Qza%jG`=QO>I}XQHR8k$F!^3>W2&B61g(bDN9Io}2W|c-qQZZ-&7JAYCeid@w zJu&2%+(YU!uO7Oeb0>ufgv#kDd(OqQ%JeYWoS++0^ZoRhNHF|PdV->6SgK?pXcu;I z%0%5a#AHOEDBLoAruhJ-3%uwoW6zWk?{yW$K0a_Z^1VtYBve{u%M_BEh&+HZ2b4(> z;3fF>U$mkMEJED&2r0hgrXXR~q4cJGwWWg`g{LKN_|Cv(-dCgrx(Uk`Iq%69TXZbu z_OwUWUnaXhug~iHwS6khb#^p$AGJOC-m(zZVpFsUslX(lJ(C4kT_)JLv)YXUK}uW9AD}F6fsoHr zECvLFt+%IhTAm1z(lmOZd??*m5mz;juy0Th=O^<(p1?=vCsPR8rGp8JY*vHdWaLQP zL5N$ueDDS5pMpn~{1}wmV0JPIglyk=VH!S{DWK7*MBWnb@vS5Q*_^Id&V8D#8(@$0 z;&<&P`ho_yK}f%FEqFN6wy$S8GhOCDjed4Rt-(vs|9eiA9?#jzFTs!4UmtclTy&r` zM!p>nNCavHF05xL01%_7n&JyY z)MXKosQsDN*(hhzMbV!#2emtw(3WsYgZxKPtUGq$QHI z7NEKV`Bu_DQ&O^5G3yQqC>uK7=2*Q`h#S$@2bi2>Y3UFgav@`LX}C>7(A7Z3ojl_G z@U0AmU9|wnIFqbxqN1`#vsJvQ=?d*JywWx=Z6dse0dr)2D}lt7*}_yRIR z>_OFSob0u^xS0fDT(#ro4bKXbaC z7j@uCQp)BdL|-1Cp`Q(HZ1Uvrg7x#_Of_+5-1lU8Tj*B-KS2y);@cPNH>n=x&sVyn zKJ0ch2^Iytbur_6ePQ`UYAqu(+QKqb&$>3k=UUZAUzN68c}nN;o0tuj@#46kFGh?U zwfqbs(9F7I&4Xa9tNHVKkoh8@j8y8S_orNVsRACiHEa^w9{xoT3~r?FED;GqZl})r z_}?C5Z1C-PEF0+*A1yd%VvRYTy?vxups@iOqme6U89U5(r)3T!QamZ1o2d>+wiI85D?;ZFHivIE^bFsKI$}c9fSOEWQ1QisgoZqB(#=rmv23F6A-{kZT1%}T$_;~8c5l5&E=D79R=jes$bXon-o0ihOiOnI+v+=T84U9q{;?>!W;$L8lPH_~sUhmTH z(OZf(v&WqDjxxq@|5v8DM83d^+Z!7Wew}M-_+Xn~+?9ZNp~r3Vl}iBuW$q^q`<~+Y z)c^SUAsFXv-2iqggeWZ!EI_%?te$WCZwgMi|GHH$1uMI#uyo*I$#`&NnZKBwj+pN5emOZ?2jLD5~WQJ0gPgQL?G>Utg3xsd7cAV|!P_@lU2+pGi zM-|2(3izeOWE%V6Y-WsFoLA7Oq@thY`hKhnOlapDt2_j!_(n32KVpt`vKWZQ=_#s1 zW8*=@Jyc`Qmcm&bCm^|hLM5)E5|{ARQijfOW%fit;Axy&UL|gMD_3m{B~!?W!eoM? zy!ME^g2D2}GfLgq@++Q4*)(}NIWa|q*YzHw5&T|MZQ9S|1QLWd0q`QLr-b~UTkgyb zk=JRcsr#5;pk0;}-(};oW1_ZgBA?j0aMJOf?O((f$6&i%Ga}|S{4cg|B#5O4Uu1n7 zC)Ro^H(mIh*CAkKq0Z+`+7A?}eh_-nor2}XrG!uD204&Ni|60RdTQCzk4O-{zH9#% z(0<`E3w0=fPp=u-k^@i!p=6pBLg#;e^LXPBrVWkP+x+Z;0%I=DF*j~v&_}vcQQ|qe zYwv&;KIf;68U)jLj}(rZ7&?(XBeeCH9G^P|fn7NBe2t&O>FU$LhBOHUIU>S2MX;8$ zusebB2kPTR?x;}!@$1CXgYF^2P;OkSJcm=Pzv9P$#OjSq>!m9lZ*68|1zne?{}GIdp*XQfYH Gh5sK}9;o<)N{^p6jIzIVE{v%9smwXw0ezP`S?xwW>o23uQ(tsJbbu5Q5oS%Gb=tgI|AKW2Gu z{b+J!e{ykqXaPPvvpq1r-ZHUMKfG1lzrM9G3tReU@iC7U{#jg@onKg(pPQeZot>GP znVO!No|>9`1cgpaOpJ|sin2CxxKl$xe3wOenU441ze8Aq3eft(29TX7}5s*9Nnmyr>-s_yw zZ4uvL`K`+*rOqj#(fV71XI!agvW{DDm1S_5Nm!#%P_;o|jiz5!aA-tuaEM<}tVd9? zy?;tzV351N?YfiIijG#6ovfRCh`Afs%Gu7y#6<&8qT*JpW*__hgNd%LuEu*A8Q0%Z z4uz7o1!A_pL~IJgtP4b}3q`C8#4R(0jZ%5_{FhWzmPJIm-^jHJ@Evk+z?qpBm`O(1 z+1F`lSIEh0$)2^~U~8!8ynds=tQO7q_G=sigP533A}%hUup~1(e|UA;F->=gJxz`|^8kvYD@&`iT2O19k>F&L*{i9&_s z@bcOc%oK5Anvt>Ph2jjnnfg!AF1@s{npGl10JCJ+i1cS84cFBly>@Z*RnvxT}QX6kn``p_Qx4F zScT{BQ7J`LqzvYdQbAgOPR6mZ<%yC#`+T>V{*VEmy-eu8bt_`XBtv&5Tp1yor%%>O z-bP3Agj)yb+#=7e( zS?ul7B9eg58tyQkKMwXZR{1Z2VFt(U<{we>!RAG&WT5pG_ieq|x8T{fRg^O`@<)UR)I^DhuTIB&E=$3Ai=RLjVR(xNu$pluGQAZ!^m*Qw6q`} zIk}G9bzF9FYg!^{YLFB_`Ls1Ditj^*&)5qy3UhJO*LqY;3>4}aL==*)(qHWF?yk>v zCNC^J9OSW|h6&LvxR^E_hO&HBS~JX_>eShB{hEZ{36|O!`Jj9xsk5{?WdF8G3{73T&GKR-Ha#t?hosS)_@>x{hB30 z`Gm4?IqJ4SY|~^Pq`I%PTdjc+Q#Ibro|e5_g8YO3-@=c;AMDb&@Up-FzXU}pBw00f zO=J3q?pe;{?7$4g;;`rnB%=EOlhMzLHAZYxQc{qocXTusONrsj7X}5UNhe4Z63+?W z;RICF7Y*sM^7OZ;u_r=x?IAsQ+`ZxKq0A#;?O&K=N5p!TM^Il48GuX6>^&Ksa*~-Y zgyHD)u81K$JW3g7u8*HmfutG9dLJl6e?%=dV#OmZWN_p@tLgLhz()@APgtAeFHb|L z*q00GYxI_&&^(8lc%SwTVaajszxvbwXIsnf0^FEdx}cwsG5f-vUE`}dvUw~|+zER> zgO^Dqvj^TVP{x6}X>c30GNkw0$hKF3!PR1XC|7n)P7bCZH0BG#xKTC3?+Vu}N>^AA zj_q-S3B$4{4G#(Um9+770v#X}WAv|&bo}^2Xw_(cdWQ>N@uZ#SSWiz+Gl&6}VTDIa zE3+U1K<$lGDYleoFtHkdTm=m`E|po+fU2A@db|ckQayHSwypDag*ZFkQS+ z`ek2sQin2#bMMm8>*plo^*~wZGL$QW=Q&|h-N#WXM+LzhdzLqs->UJItHkm@emf*T z*VNY3KA&UfAS91mT99RJmeB^A4l6-_>2haOZ05&4V9Y$^eH8w&XtdI2piKZpDqx`% z$nhSizXU`(_ByqGNnemy*5vfNd#z>(bl@1DYG_QVcMZ9g)<9pKZK-&j3!o{V-{kBe zA+8e@cld-b!*R;>Gar1v^pFT{^?v(01fp_d z{8|#=Yl3FywfiTc`qjPw5fk><wX#EF#1~Gyhmi)hmx`RTL!m z=SK=NT#512G9kOF@%N;$a{eT0AeuZd8=9jmiD$AbB`Pu3@Is){8KJScU)sAMSohQ{ zWqji-w(0czt+BD$1W)&G*P)MPX%g}H+OAFYWaL4Nq;Hr>rBOHwcN7JJcqWPBF`cie zSgX|R1fWW_9i1+nUU~1<3SWRsrk|dkasK;liOpEB%Qex?X9NF? z#s3)T;p}Jdsbruk-i{3SY36SlzlNL4r_Is$tqYT$InHx+Y;gpULBqKBhD5Y&6AK|J(Bg>P!qq}fK?mGF1t8RA!7$%_@8bHdJ0h(D4!S{&T-Ce0$dVU=ZT z(Ia#F2cFGmuI(Q3+U1xKH=RkruV*m|mJf#Tp{$nm1dxrDZ^^7FdUn0^dJzFVVTKo6 zUIr1^;EW+)vjujj3ci#$&-@R->`E`aV(t1ZH;}-z)EgC1aTLc3A?OUT`3uVKVghDr0D~+v(~Kot?ex ze6I~DVA~lE{QO^kd-Ao4fW^fok1@x?y|! zcw%H^NLO;WzZv0Un8O~F?SL7N2>}RYJ_|>~ywe)h?j%l6XARic#^L4Y*A{sLMVcT} zU$${1;uaXl-zDz;;#7rTU0KW8#af4U%no&Y7 z6zK?N18CC@N@*nt+YbDpYXLns5wE?1$;L$}+bA`TEV=z#4CJu|Tz_QbO+wm1ZC8Ic zH-~znk?z#DvlI_U=`srZf>E$!W%I$VUQ0rHPz`Wk)2+AR;xNZKl*37VIh0lA7ByEe zV23Imhtmr{A9yX#7srE5fJPGVcrXZ*3Tk0uC)qyT==qHGT(Y87!+oF38P5grm7zw1 zBX!ndl85JO)81*Cl>65-=5aVw=`-MnPSCaEUR=Ico6l1FHN{=}-=tH~JjYD^-%N&W z^Z9#uriPer#6h`%|J@%?2S*o1rg$4{`1{)eG-#j0RN*CUyQs|9A~&MNDC23%BJVg< zA1a-E41fTDI_)4fx208<)yKebWy$}7 zLdHU>i1Z7B1{?cc*_KQ|u3)yoWd3HfQoN0S)$h&+mV&<9=-#ui*!`8mk~_h_+6B1t z$C7^4mV~*2Bz_ul{iKz7F*HaOZ?g=Edudo?+2r_~m1Ony{^SID#KA6wivsy8D$?fgZZq5h1L>YuR8*|U^E=JN_Yg?Fx8<6paJ3jwOx0o+q&Zw* z0ijZW!=R#w#FCm-uof#ZXKBf#!?My@&q99#cD>njMFx`7?Pwn0NV8cX4J3K`G*Ijr z8NHAkq+32?2&*HNQ#*ShxSOmihMW`AFRCqo!MOW{&|*rQ_;2Xy$cD(RT)}CM5D9|2l+M|e_>zIdd*Vc=Mw&lVpVJtXF2{UA#o!%JPO*yd#Sw}Xy$I<>8I~FdNw_I<+FV>XR^z!rqv6KW@Wn8~^CfQ6^rolxnzno`=F)Z(Y{# z@Nn5&ND#Fn@5wVOK`pR!ruS4j`R!R)ID9TQF_c@zR7^I2Te`JULoCXLNc&`OJO|Vi zOziFAjzEtdmGel>Xn!f4+CIU(d^-*&t+%$nKAu9nlci&MxNm#*vUF5W{<@${yKLnPSVDurSOz48Y41Exz^Y498FH5NU zc2@cgpnZ3kg6J{_FT`{^KIjMeT)G%qiA9O)m1qq5~MjU_M9}br=XKZpHCT7JMT{GSIDGA0sUiHv^ z4b|S>-AtoKfsg+*H%l7&_!tKSe9m-<)#}a%+1MUylN>clOGtRG@!kx)tuw>Jd$>X9 z7y!O0sajJcvw&#?#no%9-SCoWCn$r&ga)6VM7>Lv0*s=@|DIfvff)HYQLL12_$7u@ z#Xdoo1>v$asx`gBsbqe}#w3jmmro|!Os2YZ>g*0E4Bi-C6IHydRM^6C#~3}~MS5yN zLzA9`Y0*#dy^jA|v^T}t#l)vf{^`P7o20)h)X7V)z_&0lcs?RIpx}8&gzb}RYNM*5 zv6%8leHuVUD6y#Upp#6H|#7o%iD)GzWn7Dxn&vusS*&9*tXeMWq)n z*k|f4wX`lA$~b~+h;qJDRw~g0!+$rvOp_~W9|Pq{|GQ?l-@$DKNM$sk8pCt&_piKNchg_b;zMQLzwlbVz>d7-$o!tQSod1oRX!NUWo98$ z?@wQ!Zq&AU9yT(0-5g8c^0FQc>oc@*C)wyq@aGG70FNv{l0pZb`eY`~p&qa{RT6)6 zk*IWcg*z2VFPeJYhsSL&hqV*+d7Wc1=6c?}q-9vV#Bo2lpb&z9^cRG(VN8L^9sVba zwYHbX^7pgzOHUh}`8NJLzvtwTVc?=Fpv(U_LA>;o9!a7jBZ;E>}I_(>&o z9yX$j<*6ShAnRFh;0gox zKf1NvF18Y=psg7IAoC zQqaJPX1=ah3fnyGK5!o<#U=DS$1E~$c9X+@iG!Acc8ubF9XdFuxOaY-BXh}c9>VSC zfZ3urCv#qJ;ZTa42B=YEPM@?(T^n4j=n_Zw>=^6lysar#Bz?o5R!XuXMEqoC&*v8g zLp_!cB%PT?yk=@zSa@1kXo^ef33?%u^|wod(eu518qNd82Oxc&bIyK_qSg@CHcw}O z=dXGtwmk~rX|IAweI7n}&6D>CaQD-&z|W`Rws)tuFL4JlXRHV!!NU%Wsba$k8)qBJ zzTrQNMiqV*yBT-z^{IDhK{H>WXJb-g%33Wya`dUDO*yn>t?@)Ld&7@A6fNGaq2H2= zOUQ%{=b}-ZTY)hJN17xBM?nm0fcCJpU=>S{96d&_Dy3~Ep8HmtS zht?t?{Edyd(2E3pz5jB9*NM1wW_5z6DdR^M|jh~#P5%oD{)bgN63=T#t#_arL#XG8=nw$OqH`7~j7NKp4UH6EMT@hF?Ebbht?nTT*@=Cl&9pbaBCA>(6 zl~QT~oA^o}yx|WINSQ!ncX|bUl}_lzVW3Rwb{{X>Vjlbut&)8A|0Z4AQ?ubbO7x{IwehcfYleYo=KY!U+pes-?$HB!;SzmSUxXdD#B| Du*ab^ literal 0 HcmV?d00001 diff --git a/gui/help/images/walkthrough-analysis.png b/gui/help/images/walkthrough-analysis.png deleted file mode 100644 index 94efb2890d80f5d4a1ea5e1c0d127b81b5228b76..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 142639 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⪙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

=5(Nqv$y7dBI~Ow1OxlN=m} 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 diff --git a/gui/help/images/walkthrough-toolbar-severities.png b/gui/help/images/walkthrough-toolbar-severities.png deleted file mode 100644 index f06e3aa41cf97272c39ad85d14a877402bce42b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6693 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

KWg|6F321>6xgS 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 Z7pJMZRCdKEu(bwFNlsn1S_T>NzX0gXG-dz* diff --git a/gui/help/index.html b/gui/help/index.html index 4d2cd43f824..6272ec01151 100644 --- a/gui/help/index.html +++ b/gui/help/index.html @@ -1,21 +1,103 @@ Cppcheck GUI +

Cppcheck GUI

-

With the Cppcheck GUI you can analyze your code.

+

Cppcheck is a static analysis tool for C and C++ code. It looks for bugs +such as undefined behavior, memory leaks, buffer overruns, null pointer +dereferences and uninitialized variables, and it points out code that is +suspicious, slow or hard to maintain. Cppcheck tries hard to avoid false +positives: when it reports something there is usually a reason to look at +it.

+ +

The Cppcheck GUI is a graphical front end for Cppcheck. With the GUI you +can:

+
    +
  • create and edit project files that describe what code to analyze and how + to analyze it,
  • +
  • import Visual Studio solutions and projects, compile databases + (compile_commands.json) and Borland C++ Builder 6 projects,
  • +
  • run the analysis in several threads and watch the results come in,
  • +
  • browse the warnings, read the source code next to them and follow the + path that leads to each bug,
  • +
  • filter, hide, suppress and tag warnings,
  • +
  • open the code in your favorite editor,
  • +
  • save results as XML, text or CSV and print them,
  • +
  • try out small pieces of code in the scratchpad,
  • +
  • write configuration files for your own libraries.
  • +
+ +

Contents

-
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PageWhat you will find there
Getting startedA step by step walk through: create a project, run the analysis and + look at the first results. Start here if you are new to Cppcheck.
The main windowAll menus, toolbars and panels of the main window.
Analyzing without a projectQuick analysis of files and folders, and the settings in the + Analyze menu.
Project filesEvery option in the project file dialog explained in detail.
Investigating warningsHow to read the results list, the warning details and the code + view, and how to decide if a warning is a real bug.
Severities and report typesWhat error, warning, style, performance, portability and information + mean, and how the compliance report types classify warnings.
Hiding and suppressing warningsTemporary hiding, permanent suppressions in the project file, and + inline suppressions in the code.
Tagging warningsCategorize warnings with your own tags.
Results files, printing and statisticsSave and open results, print reports and view statistics.
Scratchpad, library editor and other toolsTools for trying out code and for describing your own libraries.
PreferencesEvery option in the preferences dialog.
Command line optionsHow to start the GUI with a project or a results file.
TroubleshootingAnswers to common questions and problems.
+ +

Projects or quick analysis?

+ +

There are two ways to use the GUI:

+
    +
  • With a project file (recommended). A project file + (*.cppcheck) stores where your code is, the include paths, + the preprocessor defines, the libraries you use, suppressions, tags and + much more. The analysis is more accurate when Cppcheck knows these + things, and you only configure them once. See + Getting started and + Project files.
  • +
  • Without a project file. Use Analyze > Files... or + Analyze > Directory... to analyze some code quickly. See + Analyzing without a project.
  • +
-

Example

+

More information

-
+

The Cppcheck manual describes the analysis itself in more detail, including +the command line tool, the configuration file format and addons. You can find +it at https://cppcheck.sourceforge.io/manual.pdf.

+ +

The Cppcheck home page is +https://cppcheck.sourceforge.io/. +There you can download new versions, read about the checks and report +problems.

+ + - diff --git a/gui/help/investigating-warnings.html b/gui/help/investigating-warnings.html index 5eec66bd054..d1275a8ba01 100644 --- a/gui/help/investigating-warnings.html +++ b/gui/help/investigating-warnings.html @@ -1,22 +1,183 @@ Investigating warnings +

Investigating warnings

-

When you have run the analysis it is time to look at the results.

+

When the analysis is done (or while it is still running) it is time to look +at the results. This page explains how to read a warning, how to decide if it +is a real bug, and what you can do with it.

-

If you click on a warning then the corresponding code will be shown in the -"Warning details" at the bottom.

+

Reading a warning

-

You can right click warnings to get options. The difference of -"hiding" a warning and "suppressing" a warning is that -the suppression is permanent and hiding the warning is only temporary. When -suppressing warning(s), that is saved in the project file. +

+

Click a warning in the results list. The lower part of the window then +shows:

+
    +
  • the id of the warning, for example arrayIndexOutOfBounds. + The id identifies the kind of problem. Search for it in the Cppcheck + documentation or on the internet to learn more about it,
  • +
  • the CWE number, if there is one. CWE (Common Weakness Enumeration) + is a standard list of software weaknesses. Look it up at + cwe.mitre.org for a general + description of the problem,
  • +
  • the full message. It can be longer than the summary in the list,
  • +
  • the source code with the line of the warning highlighted.
  • +
+ +

In the example above Cppcheck says that buf[16] is accessed at +index 16. The array has 16 elements, so the valid indexes are 0 to 15. The loop +condition i <= BUFFER_SIZE should be +i < BUFFER_SIZE.

+ +

Notes: the path to the bug

+ +

Many warnings have notes. Click the arrow in front of the warning to see +them. Notes show the steps that lead to the problem, in order, for +example:

+
Assuming that condition 'i<=16' is not redundant   (line 9)
+Array index out of bounds                         (line 10)
+ +

Click a note to show its line in the code view. For a bug that depends on +values, the notes usually tell you where the value comes from, which +conditions Cppcheck assumes, and where the bad value is used. Follow the notes +to understand the warning.

+ +

A note like Assuming that condition 'x' is not redundant means that +Cppcheck uses the condition in your code as a hint about possible values. For +example, if the code checks if (p == NULL) after it has already +used p, then either the check is not needed or the code can use a +null pointer. Cppcheck warns because one of them must be wrong.

+ +

Is it a real bug?

+ +

Cppcheck tries to avoid false warnings, but no static analysis tool is +perfect. To decide if a warning is right:

+
    +
  1. Read the message and the notes, and look at the code they point to.
  2. +
  3. Think about the values Cppcheck mentions. Can they really happen? Look at + the callers of the function if needed.
  4. +
  5. Check if Cppcheck may be missing information. Warnings in code that uses + macros or types that Cppcheck could not see, because an include path is + missing, can be wrong. Look for missingInclude information + messages and fix the include paths in the project.
  6. +
  7. Check if a library configuration is missing. If your code calls a + function that never returns (like a fatal error handler) and Cppcheck + does not know that, it may warn about code after the call. Select the + library in the project or write a configuration for your own functions. + See Libraries.
  8. +
+ +

Even if a warning is not a bug today, it can point to code that is hard to +understand or easy to break. Many developers prefer to change the code so that +the warning goes away, instead of suppressing it.

+ +

If you are sure Cppcheck is wrong, suppress the warning (see +Hiding and suppressing warnings). It is also +very helpful if you report the false warning, with a small code example, at +https://trac.cppcheck.net/ or in the +Cppcheck forum.

+ +

Inconclusive warnings

+ +

Sometimes Cppcheck finds something suspicious but can not be sure that it +is a bug. These inconclusive warnings are not shown by default. Enable +Check for inconclusive errors also in the +preferences to see them. An extra +Inconclusive column then marks them. Expect more false warnings among +them.

+ +

Where to start

+ +

The first analysis of a large project can give many warnings. Some +tips:

+
    +
  • Start with errors, then warnings. Use the + severity buttons in the toolbar to hide the + other severities.
  • +
  • Look at the information messages early. They are not bugs, but they + tell you about problems in the configuration, such as headers that can + not be found. Fixing them makes the other results better.
  • +
  • Sort by the Id column to handle one kind of warning at a time. If + one kind of warning is wrong everywhere, it may be a configuration + problem.
  • +
  • Use the quick filter to find warnings about a function, a variable or a + file.
  • +
  • With a build dir, sort by Since date to see the newest warnings + first. New warnings are the easiest to fix, because the code is fresh in + your mind.
  • +
  • Use tags to remember what you have looked + at.
  • +
+ +

Opening the code in an editor

+ +

Double-click a warning, or select it and press Enter, to open the file in +your default editor at the line of the warning. You can also right-click a +warning and choose an editor at the top of the context menu.

+ +

Editors are configured in the +preferences on the Applications tab. On some systems the GUI finds +installed editors automatically.

+ +

If the file is not found, for example because the results were loaded from +an XML file created on another computer, the GUI asks you to select the +folder where the file is.

+ + +

The context menu

+ +

Right-click one or more selected warnings to get the context menu. Select +several warnings with Ctrl+click or Shift+click.

+ +

+ + + + + + + + + + + +
CommandDescription
(editors)Open the file of the warning in this editor.
Recheck N file(s)Analyze the selected files again. Select + file items (the top level items in the list) to enable this. Useful after + you have fixed something in a file. Not available while an analysis is + running or for results loaded from an XML file.
CopyCopy the selected warnings, notes or file names to the + clipboard as text, in the format + file:line:column:severity: summary [id], followed by one line + for each note. Paste it in a bug report or a chat.
Hide N result(s)Hide the selected warnings until the next + analysis. See Hiding warnings.
Hide all with idHide all warnings with the same id as the + selected warning, until the next analysis.
Suppress selected id(s)Suppress all warnings with the ids of + the selected warnings, in all files. The suppression is saved in the + project file, so the warnings are not reported again. See + Hiding and suppressing warnings.
Open containing folderOpen the folder of the file in your + file manager.
TagGive the selected warnings a tag. Only shown if the + project has tags. See Tagging warnings.
+ +

Analyzing again

+ +

After you have changed the code:

+
    +
  • Right-click a file in the results list and choose Recheck to + analyze just that file again.
  • +
  • Use Reanalyze all files in the toolbar to analyze everything again. + With a build dir only changed files are analyzed again, so this is + fast.
  • +
  • Use Analyze > Reanalyze modified files (Ctrl+R) to analyze only + the files that changed since the last analysis. See + The main window for when this is + available.
  • +
+ + - diff --git a/gui/help/mainwindow.html b/gui/help/mainwindow.html new file mode 100644 index 00000000000..d12fe51c787 --- /dev/null +++ b/gui/help/mainwindow.html @@ -0,0 +1,293 @@ + + +The main window + + + + +

The main window

+ +

This page describes the parts of the main window and every command in the +menus and toolbars.

+ +

+ +

From top to bottom the main window has:

+
    +
  • the menu bar,
  • +
  • the toolbars: the standard toolbar, the severity toolbar and the + quick filter,
  • +
  • the progress bar, which is shown while an analysis is running,
  • +
  • the results list with all warnings,
  • +
  • the lower panel with two tabs: Warning Details (the message + and the source code of the selected warning) and Analysis Log.
  • +
+ +

The title bar shows the name of the project file that is open. You can drag +the bar between the results list and the lower panel to give more space to +either of them. The GUI remembers the window size, the column widths and the +position of the bar.

+ +

The results list

+ +

The results are grouped by file. Each file is a top level item; click the +arrow to expand it, or use View > Expand all. Each warning in a file +can have child items called notes, which describe the path through the +code that leads to the problem.

+ +

The columns are:

+ + + + + + + + + + + + + +
ColumnMeaning
FileThe file of the warning. By default the path is shown + relative to the project (see Show full path of files in the + preferences and Root path in the + project file).
LineThe line number.
Severityerror, warning, style, performance, portability, + information, or note for the notes. See + Severities. The icon in the File column + shows the severity too.
Classification, Level, Guideline, RuleOnly shown when a + compliance report type (Misra, Cert, Autosar) is selected in + View > Report. See Report + types.
InconclusiveShown when inconclusive warnings are enabled in + the preferences. Marks warnings where Cppcheck is not sure.
SummaryA short description of the problem.
IdThe id of the checker message, for example + nullPointer. You need it for suppressions. The column can be + turned off in the preferences.
Since dateThe date the warning was first seen. Only + available for projects with a build dir; the date is kept from analysis + to analysis as long as the warning is still there. This makes it easy to + see which warnings are new.
TagsYour own tag for the warning. See + Tagging.
CWEThe Common Weakness + Enumeration number of the problem, if there is one.
+ +

Click a column header to sort by that column. Drag the edge of a column +header to change its width.

+ +

Double-click a warning, or select it and press Enter, to open the file in +your default editor at the line of the warning. You must configure the editor +first in the preferences.

+ +

Right-click warnings to get a context menu. See +The context menu.

+ +

Warning Details and the code view

+ +

When you select a warning, the Warning Details tab shows the id, the +CWE number and the full message. Some messages are longer than the summary in +the list and explain the problem in more detail. If the file was included from +another file, it also shows which file included it.

+ +

Below the message, the code view shows the source file with the line of the +warning highlighted. Select a note to see the line of the note. The code view +is read only; use your editor to change the code. The colors of the code view +can be changed in the preferences.

+ +

Analysis Log

+ +

The Analysis Log tab shows which files were analyzed and with which +configuration: the preprocessor defines, undefines, include paths and +platform. Look here if the results are not what you expected, for example to +check that the right include paths are used. Right-click the log to clear it +or copy one or all entries.

+ +

If Show internal warnings in log is enabled in the preferences, +internal debug warnings are shown here too.

+ +

If a critical error happens, for example a syntax error that stops the +analysis of a file, a red message is shown above the results list.

+ +

Toolbars

+ +

+ +

The standard toolbar (left) has, from left to right: Open Project +File, Save results to file, Reanalyze all files, +Stop, Clear results, Preferences and About. These +commands are described with the menus below.

+ +

The severity toolbar (right) has one toggle button for each +severity: error, warning, style, portability, performance and information. +When a button is pressed, warnings with that severity are shown. Release it to +hide them. The last two buttons show or hide results from Cppcheck itself and +results from Clang tools (Clang-Tidy). When you select a compliance report +type, the buttons change to the classifications of that standard, for example +Mandatory, Required and Advisory for Misra.

+ +

The quick filter field shows only warnings that contain the text you +type. The text is searched (ignoring case) in the summary, the message, the id, +the classification and the files and texts of the notes. Click the small cross +in the field to clear the filter.

+ +

+ +

The toolbars can be turned on and off with View > Toolbars.

+ +

The File menu

+ +

+ + + + + + + + + + + + +
CommandDescription
Open XML...Open a results file in XML format that was saved + earlier by the GUI or created with the command line tool + (cppcheck --xml ...). The current results are cleared. See + Opening results.
New Project File...Create a new project file. First you + choose the file name, then the project + file dialog opens. When you click OK the analysis starts.
Open Project File...Open an existing project file + (*.cppcheck). If the project has a build dir with results + from an earlier analysis, those results are shown. Otherwise the analysis + starts.
Edit Project File...Change the settings of the open project. + When you click OK, the project file is saved and the code is analyzed + again.
Close Project FileClose the project and clear the results. + You must close the project before you can analyze files or folders + without a project.
(recent projects)The project files you opened recently. + Click one to open it.
Save results to file...Save the results as XML, text or CSV. + See Saving results.
Print Preview... / Print...Preview or print the results. + See Printing.
QuitClose the GUI. If an analysis is running, you are asked + if you want to stop it.
+ +

The Edit menu

+ +

+ + + + + +
CommandDescription
Clear resultsRemove all results from the list. If the + project has a build dir, the cached analysis results in the build dir are + deleted too, so the next analysis analyzes every file from scratch.
PreferencesOpen the preferences + dialog.
+ +

The View menu

+ +

+ + + + + + + + + + + + + +
CommandDescription
ToolbarsShow or hide the standard toolbar, the severity + toolbar (Categories) and the quick filter.
ReportChoose how warnings are classified: Normal + (Cppcheck severities) or according to a coding standard: Autosar, Cert C, + Cert C++, Misra C, Misra C++ 2008 or Misra C++ 2023. See + Report types.
Show errors ... Show informationThe same as the buttons in + the severity toolbar.
Check all / Uncheck allShow or hide all severities at + once.
Collapse all / Expand allCollapse or expand all files and + warnings in the results list.
Show hiddenShow the warnings again that you have hidden with + the context menu. Only enabled when there are hidden warnings.
Show Scratchpad...Open the + scratchpad, where you can type or paste code and analyze it.
StatisticsShow statistics + about the project and the last analysis.
Library Editor...Open the + library editor to create or change a library configuration (.cfg) + file.
Thread DetailsShow what each analysis thread is doing right + now. See Thread details.
+ +

The Analyze menu

+ +

+ + + + + + + + + + + + + +
CommandDescription
Files...Analyze one or more files without a project. You can + also select a compile database, a Visual Studio solution or project, or a + Borland C++ Builder 6 project here. See + Analyzing without a project.
Directory...Analyze all source files in a folder and its + subfolders, without a project.
Reanalyze modified filesAnalyze again only the files that + changed since the last analysis in this session, including files that + include a changed header. This works for files and folders you selected + with Files... or Directory... and for projects that list + their paths in the project file. For projects that import a compile + database or a Visual Studio project, use Reanalyze all files + instead.
Reanalyze all filesAnalyze all files again. For a project with + a build dir, unchanged files are not analyzed again; their cached results + are used.
Reanalyze and check libraryAnalyze the project again and + report functions and types for which Cppcheck has no configuration. Use it + to find out what is missing in your library configurations. See + Checking the library + configuration.
Check configuration (defines, includes)Analyze the project + again and report problems in the configuration, such as include files + that can not be found. Use it when you set up a new project.
StopStop the running analysis (Esc). Results found so far are + kept.
C standard / C++ standardThe language standard used for + files when the standard is not known in another way (for example from an + imported project).
Auto-detect language / Enforce C++ / Enforce CBy default the + language of each file is chosen from its file extension: .c + files are C and .cpp, .cc, .cxx and + similar are C++. Choose Enforce C++ or Enforce C to analyze + all files as that language, for example if your C++ code is in + .c files.
Native ... Windows 64-bitThe platform to use when the project + does not choose a platform, or when you analyze without a project. + Native is the platform you run Cppcheck on. See + Platform.
+ +

The Help menu

+ +

+ + + + + + + +
CommandDescription
ContentsOpen this help (F1).
License...Show the license of Cppcheck (GNU GPL v3).
Authors...Show the people who have contributed to + Cppcheck.
About...Show the version of Cppcheck.
+ +

Cppcheck Premium also shows EULA... in this menu.

+ +

Keyboard shortcuts

+ + + + + + + + + + + + + + +
ShortcutCommand
Ctrl+Shift+NNew Project File
Ctrl+Shift+OOpen Project File
Ctrl+SSave results to file
Ctrl+PPrint
Ctrl+QQuit
Ctrl+FAnalyze files
Ctrl+DAnalyze directory
Ctrl+RReanalyze modified files
EscStop the analysis
F1Help
EnterOpen the selected warning in the default editor
+ + + + + diff --git a/gui/help/manual.html b/gui/help/manual.html deleted file mode 100644 index a237cb8485b..00000000000 --- a/gui/help/manual.html +++ /dev/null @@ -1,947 +0,0 @@ - -Cppcheck 1.46

Chapter 1. Introduction

Cppcheck is an analysis tool for C/C++ code. Unlike C/C++ compilers - and many other analysis tools, it doesn't detect syntax errors. Cppcheck - only detects the types of bugs that the compilers normally fail to detect. - The goal is no false positives.

Supported code and platforms:

  • You can check non-standard code that includes various compiler - extensions, inline assembly code, etc.

  • Cppcheck should be compilable by any C++ compiler that handles - the latest C++ standard.

  • Cppcheck should work on any platform that has sufficient cpu and - memory.

Accuracy

Please understand that there are limits of Cppcheck. Cppcheck is - rarely wrong about reported errors. But there are many bugs that it - doesn't detect.

You will find more bugs in your software by testing your software - carefully, than by using Cppcheck. You will find more bugs in your - software by instrumenting your software, than by using Cppcheck. But - Cppcheck can still detect some of the bugs that you miss when testing and - instrumenting your software.


Chapter 2. Getting started

2.1. First test

Here is a simple code

int main()
-{
-    char a[10];
-    a[10] = 0;
-    return 0;
-}

If you save that into file1.c and - execute:

cppcheck file1.c

The output from cppcheck will then be:

Checking file1.c...
-[file1.c:4]: (error) Array 'a[10]' index 10 out of bounds

2.2. Checking all files in a folder

Normally a program has many sourcefiles. And you want to check - them all. Cppcheck can check all sourcefiles in a directory:

cppcheck path

If "path" is a folder then cppcheck will check all sourcefiles in - this folder.

Checking path/file1.cpp...
-1/2 files checked 50% done
-Checking path/file2.cpp...
-2/2 files checked 100% done

2.3. Excluding a file or folder from checking

There is no command to exclude a file or folder from checking. But - you can exclude a file or folder by being more careful when including - files and folders in the checking.

Imagine for example that the folder "src" contain the folders "a", - "b" and "c". To exclude "c" this command can be used:

cppcheck src/a src/b

All files under "src/a" and "src/b" are then checked.

The flag --file-list might also be - useful.


2.4. Severities

The possible severities for messages are:

error

used when bugs are found

warning

suggestions about defensive programming to prevent - bugs

style

stylistic issues related to code cleanup (unused functions, - redundant code, constness, and such)

performance

suggestions for making the code faster


2.5. Enable messages

By default only error messages are shown. - Through the --enable command more checks can be - enabled.


2.5.1. Stylistic issues

With --enable=style you enable most - warning, style and - performance messages.

Here is a simple code example:

void f(int x)
-{
-    int i;
-    if (x == 0)
-    {
-        i = 0;
-    }
-}

There are no bugs in that code so Cppcheck won't report anything - by default. To enable the stylistic messages, use the --enable=style - command:

cppcheck --enable=style file3.c

The output from Cppcheck is now:

Checking file3.c...
-[file3.c:3]: (style) Variable 'i' is assigned a value that is never used
-[file3.c:3]: (style) The scope of the variable i can be reduced


2.5.2. Unused functions

This check will try to find unused functions. It is best to use - this when the whole program is checked, so that all usages is seen by - cppcheck.

cppcheck --enable=unusedFunction path

2.5.3. Enable all checks

To enable all checks your can use the - --enable=all flag:

cppcheck --enable=all path

2.6. Saving results in file

Many times you will want to save the results in a file. You can - use the normal shell redirection for piping error output to a - file.

cppcheck file1.c 2> err.txt

2.7. Multithreaded checking

To use 4 threads to check the files in a folder:

cppcheck -j 4 path

Chapter 3. Preprocessor configurations

By default Cppcheck will check all preprocessor configurations - (except those that have #error in them). This is the recommended - behaviour.

But if you want to manually limit the checking you can do so with - -D.

Beware that only the macros, which are given here and the macros - defined in source files and known header files are considered. That - excludes all the macros defined in some system header files, which are by - default not examined by cppcheck.

The usage: if you, for example, want to limit the checking so the - only configuration to check should be "DEBUG=1;__cplusplus" then something - like this can be used:

cppcheck -DDEBUG=1 -D__cplusplus path

Chapter 4. XML output

Cppcheck can generate the output in XML format.

Use the --xml flag when you execute cppcheck:

cppcheck --xml file1.cpp

The xml format is:

<?xml version="1.0"?>
-<results>
-  <error file="file1.cpp" line="123" id="someError"
-               severity="error" msg="some error text"/>
-</results>

Attributes:

file

filename. Both relative and absolute paths are possible

line

a number

id

id of error. These are always valid symbolnames.

severity

either error or style. - warning and performance are - saved as style.

msg

the error message


Chapter 5. Reformatting the output

If you want to reformat the output so it looks different you can use - templates.

To get Visual Studio compatible output you can use "--template - vs":

cppcheck --template vs gui/test.cpp

This output will look like this:

Checking gui/test.cpp...
-gui/test.cpp(31): error: Memory leak: b
-gui/test.cpp(16): error: Mismatching allocation and deallocation: k

To get gcc compatible output you can use "--template gcc":

cppcheck --template gcc gui/test.cpp

The output will look like this:

Checking gui/test.cpp...
-gui/test.cpp:31: error: Memory leak: b
-gui/test.cpp:16: error: Mismatching allocation and deallocation: k

You can write your own pattern (for example a comma-separated - format):

cppcheck --template "{file},{line},{severity},{id},{message}" gui/test.cpp

The output will look like this:

Checking gui/test.cpp...
-gui/test.cpp,31,error,memleak,Memory leak: b
-gui/test.cpp,16,error,mismatchAllocDealloc,Mismatching allocation and deallocation: k


Chapter 6. Suppressions

If you want to filter out certain errors you can suppress these. - First you need to create a suppressions file. The format is:

[error id]:[filename]:[line]
-[error id]:[filename2]
-[error id]

The error id is the id that you want to suppress. - The easiest way to get it is to use the --xml command - line flag. Copy and paste the id string from the xml - output.

Here is an example:

memleak:file1.cpp
-exceptNew:file1.cpp
-uninitvar

You can then use the suppressions file:

cppcheck --suppressions suppressions.txt src/

-

Chapter 7. Exception safety

Cppcheck has a few checks that ensure that you don't break the basic - guarantee of exception safety. It doesn't have any checks for the strong - guarantee yet.

Example:

Fred::Fred() : a(new int[20]), b(new int[20])
-{
-}

By default cppcheck will not detect any problems in that - code.

To enable the exception safety checking you can use - --enable:

cppcheck --enable=exceptNew --enable=exceptRealloc fred.cpp

The output will be:

[fred.cpp:3]: (style) Upon exception there is memory leak: a

If an exception occurs when b is allocated, - a will leak.

Here is another example:

int *p;
-
-int a(int sz)
-{
-    delete [] p;
-    if (sz <= 0)
-        throw std::runtime_error("size <= 0");
-    p = new int[sz];
-}

Check that with Cppcheck:

cppcheck --enable=exceptNew --enable=exceptRealloc except2.cpp

The output from Cppcheck is:

[except2.cpp:7]: (error) Throwing exception in invalid state, p points at deallocated memory

Chapter 8. Html report

You can convert the xml output from cppcheck into a html report. - You'll need python and the pygments module - (http://pygments.org/) for this to work. In the Cppcheck source - tree there is a folder "htmlreport" that contains a script that transforms - a Cppcheck xml file into html output.

This command generates the help screen:

htmlreport/cppcheck-htmlreport -h

The output screen says:

Usage: cppcheck-htmlreport [options]
-
-Options:
-  -h, --help      show this help message and exit
-  --file=FILE     The cppcheck xml output file to read defects from.
-                  Default is reading from stdin.
-  --report-dir=REPORT_DIR
-                  The directory where the html report content is written.
-  --source-dir=SOURCE_DIR
-                  Base directory where source code files can be found.

An example usage:

./cppcheck gui/test.cpp --xml 2> err.xml
-htmlreport/cppcheck-htmlreport --file=err.xml --report-dir=test1 --source-dir=.

Chapter 9. Graphical user interface

9.1. Introduction

A Cppcheck GUI is available.

The main screen is shown immediately when the GUI is - started.


9.2. Check source code

Use the Check menu.


9.3. Inspecting results

The results are shown in a list.

You can show/hide certain types of messages through the - View menu.

Results can be saved to an xml file that can later be opened. See - Save results to file and Open - XML.


9.4. Settings

The language can be changed at any time by using the - Language menu.

More settings are available in - Edit>Preferences.


9.5. Project files

The project files are used to store project specific settings. - These settings are:

  • include folders

  • preprocessor defines

It isn't recommended to provide the paths to the standard C/C++ - headers - Cppcheck has internal knowledge about ANSI C/C++ and it isn't - recommended that this known functionality is redefined. But feel free to - try it.

As you can read in chapter 3 in this manual the default is that - Cppcheck checks all configurations. So only provide preprocessor defines - if you want to limit the checking.

diff --git a/gui/help/online-help.qhp b/gui/help/online-help.qhp index 23411d0f3b4..29f73530ca2 100644 --- a/gui/help/online-help.qhp +++ b/gui/help/online-help.qhp @@ -5,46 +5,136 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + style.css index.html - images/index-mainwindow.png - investigating-warnings.html - preferences.html + walkthrough.html + mainwindow.html + standalone-analysis.html projectfiledialog.html + investigating-warnings.html severities.html + suppressions.html + tagging.html + reports.html + tools.html + preferences.html + commandline.html + troubleshooting.html + images/add-application.png + images/context-menu-tag.png + images/context-menu.png + images/library-editor.png + images/main-window.png + images/menu-analyze.png + images/menu-edit.png + images/menu-file.png + images/menu-help.png + images/menu-view-report.png + images/menu-view.png + images/new-suppression.png + images/preferences-addons.png + images/preferences-applications.png + images/preferences-clang.png + images/preferences-code-editor.png + images/preferences-general.png + images/preferences-language.png + images/preferences-reports.png + images/projectfile-addons.png + images/projectfile-analysis.png + images/projectfile-import.png + images/projectfile-paths-and-defines.png + images/projectfile-types-and-functions.png + images/projectfile-warning-options.png + images/quick-filter.png + images/report-misra.png + images/scratchpad.png images/severities-error.png - images/severities-warning.png - images/severities-style.png + images/severities-information.png images/severities-performance.png images/severities-portability.png - images/severities-information.png - standalone-analysis.html - tagging.html - walkthrough.html - images/walkthrough-analysis.png - images/walkthrough-library.png - images/walkthrough-toolbar-severities.png - images/walkthrough-import-project.png - images/walkthrough-new-project.png - images/walkthrough-warning-menu.png + images/severities-style.png + images/severities-warning.png + images/statistics-previous-scan.png + images/statistics-project.png + images/statistics-statistics.png + images/toolbar.png diff --git a/gui/help/preferences.html b/gui/help/preferences.html index 5a591227b3c..4c298e59e14 100644 --- a/gui/help/preferences.html +++ b/gui/help/preferences.html @@ -1,74 +1,195 @@ Preferences +

Preferences

-

Number of threads
Number of threads to use in analysis. Each -thread checks its own source file.

- -

Force checking of all #ifdef configurations
Cppcheck try to check -all code and will therefore guess different preprocessor configurations. The -maximum number of configurations that is checked is 14 by default.

- -

Show full path of files
Show the full paths in the results.

- -

Show "No errors found" message when no errors found
-If you want to get a message box about this.

- -

Display error id column "Id"
Show error id in results

- -

Enable inline suppressions
You can suppress warnings with comments. -See the Cppcheck manual (https://cppcheck.sourceforge.io/manual.pdf) for more -information about inline suppressions.

- -

Check for inconclusive errors also
When full analysis of the code -can not determine if there should be a warning or not, it is inconclusive. -Normally Cppcheck does not warn then.

- -

Show statistics on check completion
Show statistics in a window -when analysis finish.

- -

Show internal warnings in log
Internal warnings (for debugging) is -shown in the Analysis log.

- -

Applications
Configure external editor to open from context menu -when you right click on a warning.

- -

Save all errors when creating report
If hidden warnings should be -saved or not.

- -

Save full path to files in report
If you use Root path the -warnings on the screen will not have the full path.

- -

Language
Configure language to use for GUI.

- -

Python binary
To be able to execute addons, Cppcheck needs to know -where python is. Unless you configure something, Cppcheck will try to execute -python in your PATH.

- -

MISRA rule texts
Only needed if you want to use the MISRA addon. -Cppcheck is not legally allowed to distribute the MISRA rule texts and these -must be provided by users. The MISRA rule texts are proprietary. An example -rule text file: -

Appendix A Summary of guidelines
-Rule 1.1
-Text of rule 1.1
-Rule 1.2
-Text of rule 1.2
-

- -

Clang path
The path to clang binary. If no path is provided -then system PATH is used.

- -

Visual studio headers
If you want to use the Visual Studio headers -in the analysis you can provide the path(s) here. Hint: Open a visual studio -command prompt and type SET INCLUDE. Then copy/paste the paths.

- -

Code editor style
The visual theme to use for the code editor that -is used when you investigate results.

+

Open the preferences with Edit > Preferences or the preferences +button in the toolbar. The preferences are your personal settings; they are +stored for your user account, not in the project file. Click OK to +apply the changes.

+ +

Some settings exist both here and in the project file, for example +Enable inline suppressions. When a project is open, the project +setting is used.

+ +

General

+ +

+ + + + + + + + + + + + + +
OptionDescription
Number of threadsHow many files are analyzed at the same time. + Each thread analyzes its own file. Max count shows the number of + processor cores of your computer, which is the highest value you can + enter. More threads make the analysis faster, but use more memory. A value + equal to the number of cores is usually a good choice.
Force checking all #ifdef configurationsBy default Cppcheck + analyzes at most 12 preprocessor configurations of each file. With this + option all configurations are analyzed. This finds more bugs in code with + many #ifdefs, but can be very slow. See + Defines.
Show full path of filesShow the full path of files in the + results list, instead of the path relative to the project.
Show "No errors found" message when no errors foundShow a + message box when an analysis finishes without warnings.
Display error Id in column "Id"Show the Id column in + the results list. The id is needed for suppressions.
Enable inline suppressionsAllow comments like + // cppcheck-suppress nullPointer in the code to suppress + warnings. Only used when no project is open; projects have their own + setting. See Inline + suppressions.
Check for inconclusive errors alsoAlso report warnings where + Cppcheck is not sure that there is a problem. These give more findings, but + also more false warnings. An Inconclusive column is added to the + results list.
Show statistics on check completionOpen the + statistics dialog when an analysis + finishes.
Check for updatesWhen the GUI starts, check on the Cppcheck + web site if there is a newer version. If there is, a message is shown at + the top of the main window. This needs an internet connection; nothing + else is sent.
Show internal warnings in logShow debug warnings from the + analysis in the Analysis Log. Only useful if you develop Cppcheck or + investigate a problem with the analysis.
+ + +

Applications

+ +

+ +

The editors (or other programs) that you can open a warning in. They are +shown at the top of the context menu of the results list. The default +application is used when you double-click a warning or press Enter.

+ +

On some systems the GUI finds installed editors automatically and adds them +to the list.

+ +
    +
  • Add...: add an application.
  • +
  • Edit...: change the selected application.
  • +
  • Remove: remove the selected application.
  • +
  • Set as default: make the selected application the default one.
  • +
+ +

+ +

For each application you enter a name for the menu, the executable and the +command line parameters. These texts in the parameters are replaced when the +application is started:

+ + + + + + + +
TextReplaced with
(file)The file name of the warning
(line)The line number
(message)The warning message
(severity)The severity
+ +

Examples for some common editors:

+ + + + + + + + + + + + + + + +
EditorExecutableParameters
Visual Studio Codecode--goto (file):(line)
Katekate-l(line) (file)
Qt Creatorqtcreator-client (file):(line)
Notepad++notepad++.exe-n(line) (file)
Vim (in a terminal)xterm-e vim +(line) (file)
Emacsemacs+(line) (file)
+ +

Reports

+ +

+ + + + + +
OptionDescription
Save all errors when creating reportAlso save hidden warnings + when you save the results to a file. By default only the visible warnings + are saved.
Save full path to files in reportsSave the full path of each + file. By default the path relative to the project (or the root + path) is saved.
+ +

See Results files, printing and statistics.

+ +

Language

+ +

+ +

The language of the user interface. The GUI is translated to several +languages; select one and click OK. This help is only available in +English.

+ + +

Addons

+ +

+ + + + + +
OptionDescription
Python binaryThe Python interpreter used to run addons. Leave + it empty to use the Python found in the PATH. If the file you enter does + not exist, a red warning is shown.
MISRA rule texts fileA text file with the MISRA C rule texts, + used by the Misra addon to show the rule texts in the warnings. Cppcheck is + not allowed to distribute the rule texts, so you must create the file from + your copy of the MISRA C document. See + Addons for the format. This is + the same setting as MISRA rule texts in the project dialog.
+ + +

Clang

+ +

+ + + + + +
OptionDescription
Clang pathThe folder where clang and + clang-tidy are installed. Used by the Clang parser and by + Clang-Tidy (see Analysis and + External tools in the project + dialog). Leave it empty to search the system PATH. On Windows, Clang is + also found in C:\Program Files\LLVM\bin.
Visual Studio headersPaths to the Visual Studio headers, + separated by semicolons. Clang needs them to parse code that uses the + Visual Studio libraries. To get the paths, open a Visual Studio command + prompt, type SET INCLUDE and copy/paste the paths.
+ + +

Code Editor

+ +

+ +

The colors of the code view in the lower part of the main window.

+
    +
  • System Style: use the colors of your desktop theme.
  • +
  • Default Light Style: dark text on a light background.
  • +
  • Default Dark Style: light text on a dark background.
  • +
  • Custom: your own colors. Click Edit... to choose the + foreground and background colors of the editor, the highlighted line and + the line numbers, and the color and font weight of keywords, class names, + strings, comments and symbols. A preview shows the result.
  • +
+ + diff --git a/gui/help/projectfiledialog.html b/gui/help/projectfiledialog.html index 52b4eba444f..e357ebbc91d 100644 --- a/gui/help/projectfiledialog.html +++ b/gui/help/projectfiledialog.html @@ -1,179 +1,474 @@ -Project File Dialog +Project files + -

Project File Dialog

+

Project files

-

The Project file dialog contains 4 tabs:

-
    -
  • Paths and defines; paths to check and basic preprocessor settings. -
  • Types and Functions; configuration of platform and 3rd party libraries -
  • Analysis; analysis options -
  • Warning options; formatting warnings, suppressing warnings, etc -
  • Addons; extra analysis with addons -
+

A project file (*.cppcheck) stores everything Cppcheck needs to +know to analyze your code: which files to analyze, include paths, defines, +libraries, platform, analysis options, suppressions, tags and addons. It is +an XML file, so you can put it in version control and share it with your +team. Paths in the project file are relative to the folder of the project +file.

-

Paths and defines

+

Create a project with File > New Project File... and change it +with File > Edit Project File.... Both open the Project file +dialog described on this page. When you click OK the project file is +saved and the analysis starts. Click Cancel to close the dialog without +saving.

-

It is recommended to import a project file.

+

The dialog has five tabs:

+
    +
  • Paths and Defines: what code to analyze and the + preprocessor settings,
  • +
  • Types and Functions: the platform and the libraries + your code uses,
  • +
  • Analysis: the build dir, the parser and options + that control how deep the analysis is,
  • +
  • Warning options: root path, tags, excluded + files and suppressions,
  • +
  • Addons: addons, coding standards and external + tools.
  • +
-

Import project

+ +

Paths and Defines

+ +

+ +

On this tab you tell Cppcheck what code to analyze. You can either import a +project from your build system, or enter the paths, defines and include paths +yourself. Importing is recommended: you get the exact include paths and +defines that the compiler uses, and you do not have to update the Cppcheck +project when the build changes.

+ + +

Import Project

+ +

Click Browse... to select the project to import. Supported +formats:

+ + + + + + + + + +
FormatNotes
Compile database
compile_commands.json
Contains the exact compiler command line of every source file. CMake + writes it when you configure with + -DCMAKE_EXPORT_COMPILE_COMMANDS=ON. Meson and Ninja write it + too, and for other build systems (for example make) you can create it + with tools such as Bear. When a compile database is imported, each + file is analyzed with just the configuration given on its command line.
Visual Studio
*.sln, *.slnx, + *.vcxproj
Cppcheck reads the source files, include paths and defines of each + configuration (such as Debug|Win32 or + Release|x64).
Borland C++ Builder 6
*.bpr
 
+ +

Click the brush button next to the field to remove the import.

+ +

When a project is imported, the Paths, Include Paths and +Undefines fields are disabled because the information comes from the +imported project. Defines and Include file can still be used; +they are added to what the imported project says.

+ +

Analyze all Visual Studio configurations and Selected VS +Configurations: only enabled when a Visual Studio solution or project is +imported. A Visual Studio project usually has several configurations, and +analyzing all of them takes time. Check Analyze all Visual Studio +configurations to analyze every Debug and Release configuration. +Otherwise check the configurations you want in the list. If you analyze +several configurations of a file, warnings that are the same in all of them +are only reported once.

+ +

Paths

+ +

The folders and files to analyze (only when no project is imported). +Click Add... to add a folder, select a path and click Edit to +change it, or Remove to remove it. All C and C++ source files in the +folders and their subfolders are analyzed (.c, +.cpp, .cxx, .cc, .c++, +.tpp, .txx, .ipp, .ixx). +Headers are analyzed when they are included from a source file.

+ +

To leave out some files or folders, use Exclude source +files on the Warning options tab.

+ + +

Defines

+ +

Preprocessor macros that are defined for the analysis, like the +-D option of a compiler. Separate them with semicolons, and give a +value with =:

+ +
DEBUG;VERSION=5;WORD=int
+ +

To understand when you need defines, you need to know how Cppcheck handles +preprocessor conditions. A compiler only sees one configuration of your code. +Cppcheck instead tries to analyze all configurations. Look at this code:

+ +
#ifdef A
+    code1
+#endif
+#ifdef B
+    code2
+#endif
-Project to import. Cppcheck will get: +

Cppcheck automatically analyzes the code both with and without +A and B defined, so bugs in both code1 +and code2 are found. You normally do not have to set defines. Use +them when:

    -
  • What files to check -
  • Preprocessor defines -
  • Preprocessor include paths -
  • Language standard if set +
  • a macro must always be defined for the code to make sense, for example + a macro that your build system always sets,
  • +
  • a macro has a value that matters, for example + BUFFER_SIZE=1024,
  • +
  • Cppcheck reports a syntax error because a macro it does not know is used + in a way that only works when the macro is defined.
-

Paths (If you do not import project)

+

By default at most 12 configurations are analyzed for each file. If there +are more, an information message tells you. Enable Force checking +all #ifdef configurations in the preferences +to analyze all of them, which can take a long time.

-

What paths to check.

+

Undefines

-

Defines (If you do not import project)

+

Macros that must never be defined, like the -U option of a +compiler. Separate them with semicolons:

-

Cppcheck automatically checks the code with different preprocessor -configurations.

+
A;C
-
#ifdef A
-code1
-#endif
-#ifdef B
-code2
-#endif
+

In the example above, if A is undefined, Cppcheck does not +analyze the configuration where A is defined. Use this for +configurations that are never used, for example code for a platform you do not +support. It makes the analysis faster and avoids warnings for code you do not +care about.

-

Cppcheck will automatically perform analysis both when A is defined and B is -defined. So any bugs in both code1 and code2 will be detected.

+ +

Include Paths

-

If you want to configure that A will always be defined in Cppcheck analysis -you can do that here.

+

The folders where Cppcheck looks for header files that are included with +#include "..." or #include <...>, like the +-I option of a compiler. Folders are searched in the order of the +list; use Up and Down to change the order.

-

Defines are separated by semicolon. So you can for instance write:

+

Add the folders of your own headers and of the headers of 3rd party +libraries that are part of your project. Cppcheck needs them to know your +types, macros, functions and classes. Without them, some bugs can not be found +and you may get false warnings.

-
A;B=3;C
+

Do not add the folders of the standard library and system headers +(for example /usr/include or the Visual Studio include +folders). Cppcheck has built-in knowledge of the standard library and of the +libraries you select on the Types and Functions tab, and analyzing the +system headers makes the analysis slow and can cause wrong results. That is +why the missingIncludeSystem information messages say that Cppcheck does +not need the standard headers.

-

Undefines (If you do not import project)

+

Include file

-

Cppcheck automatically checks the code with different preprocessor -configurations.

+

A header file that is included before every source file, like the +-include option of GCC or /FI of Visual Studio. Use +it if your build forces a header to be included, for example a configuration +header with macros that all files need.

-
#ifdef A
-code1
-#endif
-#ifdef B
-code2
-#endif
+ +

Types and Functions

-

Cppcheck will automatically perform analysis both when A is defined and B is -defined. So any bugs in both code1 and code2 will be detected.

+

-

If you want to configure that A is never defined in Cppcheck analysis you -can do that here.

+ +

Platform

-

Undefines are separated by semicolon. So you can for instance write:

+

The platform decides the sizes of the basic types (short, +int, long, long long, pointers, +size_t, wchar_t) and whether char is +signed. Cppcheck uses this, for example, to find integer overflows, buffer +overruns with sizeof and portability problems.

-
A;C
+

Choose one of the built-in platforms:

+
    +
  • Native: the computer you run Cppcheck on,
  • +
  • Windows 32-bit ANSI, Windows 32-bit Unicode, + Windows 64-bit,
  • +
  • Unix 32-bit, Unix 64-bit.
  • +
-

Include paths (If you do not import project)

+

For embedded targets and other special platforms, choose one of the +platform files (*.xml) in the list, for example +avr8.xml, arm32-wchar_t2.xml or +pic16.xml. You can write your own platform file and put it in the +folder of the project file; it then appears in the list. See the Cppcheck +manual for the format.

-

Specify include paths.

+

If you leave the platform empty, the platform selected in the +Analyze menu of the main window is used.

-

Types and Functions

+ +

Libraries

-

Cppcheck uses the Platform setting to determine size of -short/int/long/pointer/etc.

+

Check the libraries that your code uses. Each library has a configuration +file (.cfg) that describes its functions, types and macros, for +example:

+
    +
  • which functions allocate and free memory or other resources, so that + leaks and double frees can be found,
  • +
  • which arguments must not be null or uninitialized, and which values are + valid,
  • +
  • which functions never return (like exit()),
  • +
  • which return values must be used,
  • +
  • format strings, buffer sizes and so on.
  • +
-

Check the libraries that you use in the Libraries listbox.

+

The standard library (std.cfg) is always used. Some +commonly used libraries are posix (Linux and Unix APIs), +windows (Windows API), gnu, qt, boost, +wxwidgets, gtk, sdl, opengl, openssl, +sqlite3 and googletest.

+

If your code uses a library that is not in the list, or your own library, +you can write a configuration file for it. Put the .cfg file in +the same folder as the project file and it appears in the list. You can create +and edit configuration files with the library +editor. Use Analyze > Reanalyze and check library to find +functions that are not configured.

+ +

Analysis

+

+ +

Cppcheck build dir

-

This is a work-folder that Cppcheck uses. Each Cppcheck project should have -a separate build dir. It is used for:

+

A work folder for Cppcheck. Each project needs its own build dir; do not +share one build dir between projects. A new project automatically gets +<name>-cppcheck-build-dir next to the project file. If the +folder does not exist when the analysis starts, the GUI asks if it should +create it.

+ +

The build dir is optional, but strongly recommended. It is used for:

    -
  • whole program analysis -
  • debug output -
  • faster analysis (if a source file has changed check it, if source file is - not changed then reuse old results) -
  • statistics +
  • Incremental analysis. Cppcheck stores the results of each file. When + you analyze again, files that have not changed (including the headers they + include) are not analyzed again; their stored results are used. This makes + the second analysis of a large project much faster.
  • +
  • Whole program analysis. Some checks need information from all + files, for example finding functions that are never called + (unusedFunction) or bugs where a value is passed from one file to a + function in another file. These checks are only run when there is a build + dir.
  • +
  • Addons. Addons (Misra, Y2038, Thread safety) and Clang-Tidy need a + build dir.
  • +
  • Results history. The results of the last analysis are saved + (lastResults.xml) and shown when you open the project. The + Since date column shows when each warning was first seen.
  • +
  • Statistics of previous analyses.
+

Do not put the build dir in version control. Edit > Clear +results deletes the stored results in the build dir.

+

Parser

-

It is in general recommended to use Cppcheck parser. However you can choose -to use Clang parser; Clang will be executed with a command line flag that tells -it to dump its AST and Cppcheck will read that AST and convert it into a -corresponding Cppcheck AST and use that.

+

Cppcheck (built in) is recommended. Cppcheck has its own parser that +works well even if the code can not be compiled, if headers are missing or if +the code uses compiler extensions.

-

Analysis

+

Clang (experimental) uses Clang to parse the code. Clang is run with +a flag that makes it write its abstract syntax tree (AST); Cppcheck reads this +AST, converts it and runs its checks on it. Clang must be installed (see +Clang path in the preferences), and the +code must be correct enough for Clang to accept it. This is experimental and +not all checks work as well as with the built in parser.

-

Configure what kind of analysis you want.

+

Check level

-

The Normal analysis is recommended for most use cases. Especially if -you use Cppcheck in CI.

+

How much time Cppcheck may spend on the analysis. A higher level finds more +bugs but takes longer.

+
    +
  • Reduced: a limited and fast analysis, for when you want results + right away, for example while you are writing code.
  • +
  • Normal: the default. Meant for normal analysis in CI; it should + finish in reasonable time.
  • +
  • Exhaustive: a deeper analysis of the control flow and of values, + for nightly builds and similar. It can take much longer; up to 10 times + the compilation time is normal.
  • +
-

The Bug hunting can be used if you really want to find a bug in your -code and can invest time looking at bad results and providing extra -configuration.

+

Analysis

-

Limit analysis

+

Check that each class has a safe public interface: normally Cppcheck +only considers the values that are actually passed to a function. With this +option, Cppcheck assumes that the arguments of public member functions can +have any value, and warns if a function does not handle some value +safely, even if no caller passes that value today. Use it if you want your +classes to be robust against all possible use. It gives more warnings, and you +must decide for each of them if it matters.

-

You can turn off checking of headers. That could be interesting if Cppcheck -is very slow. But normally, you should check the code in headers.

+

Limit analysis

-

It is possible to check the code in unused templates. However the Cppcheck -AST will be incomplete/wrong. The recommendation is that you do not check -unused templates to avoid wrong warnings. The templates will be checked -properly when you do use them.

+

Check code in headers: should normally be on. If you turn it off, +Cppcheck does not report warnings in the code of header files and skips some +analysis of it. This can make the analysis much faster for code with large +headers, but you will miss bugs in headers.

-

Max CTU depth: How deep should the whole program analysis be. The risk with -a "too high" value is that Cppcheck will be slow.

+

Check code in unused templates: should normally be on. If it is off, +templates that are never instantiated are not analyzed. Cppcheck can not know +the template arguments in unused templates, so the analysis of them is less +precise. Templates that are used are always analyzed with the actual template +arguments.

-

Max recursion in template instantiation: Max recursion when Cppcheck -instantiates templates. The risk with a "too high" value is that -Cppcheck will be slow and can require much memory.

+

Max CTU depth: how deep the whole program analysis follows function +calls between files (CTU means "cross translation unit"). A higher value finds +bugs where values pass through more function calls, but makes the analysis +slower. The default is 2.

+

Max recursion in template instantiation: how deep recursive templates +are instantiated. Code that uses template metaprogramming can need a higher +value. A high value can make the analysis slow and use a lot of memory. The +default is 100.

+

Warning options

+

+ +

Root path

-

The root path for warnings. Cppcheck will strip away this part of the path -from warnings. For instance if there is a warning in -

../myproject/foo/bar/file.cpp
and the root path is -
../myproject/foo
then the path for the warning will be -
bar/file.cpp
.

+

File paths in warnings are shown relative to this path. If it is empty, the +folder of the project file is used. For example, if a warning is in

+
../myproject/foo/bar/file.cpp
+

and the root path is

+
../myproject/foo
+

then the warning is shown for

+
bar/file.cpp
-

Warning Tags

+

Warning tags

-

Tags allow you to manually categorize warnings.

+

Your own names for categories of warnings, separated by semicolons, for +example todo;false positive;fixed later. When you have entered +tags, you can right-click warnings and give them a tag. See +Tagging warnings. Only letters, digits and spaces +are allowed in tag names.

+

Exclude source files

-

Excluded source files will not be analyzed by Cppcheck.

+

Files and folders that should not be analyzed. Use it for generated code, +3rd party code that you do not maintain, test data and similar. Click +Exclude folder... or Exclude file... to add entries, Edit +to change the selected entry and Remove to remove it.

+

Excluding works for imported projects too. Note that an excluded header is +still read when it is included from a source file that is analyzed, because +Cppcheck needs it to understand that source file.

+ +

Suppressions

-

List of suppressions. These warnings will not be shown.

+

Warnings that should not be reported. Click Add to add a +suppression; double-click a suppression to edit it, and click Remove to +remove it.

-

Addons

+

+ +

A suppression has these fields:

+
    +
  • Error ID (required): the id of the warning, for example + nullPointer. You can select it from the list or type it. Use + * to suppress all warnings (for example for some file).
  • +
  • File name (optional): only suppress the warning in this file. You + can use the wildcards * and ?, for example + src/generated/*.
  • +
  • Line number (optional): only suppress the warning on this line. + This is fragile: when the code changes, the line number changes too. + Inline suppressions are better for single warnings.
  • +
  • Symbol name (optional): only suppress warnings about this + variable, function or other symbol.
  • +
+ +

You can also add suppressions from the results list with the context menu. +See Hiding and suppressing warnings.

-

Y2038
32-bit timers that count number of seconds since 1970 will -overflow in year 2038. Check that the code does not use such timers.

+

Enable inline suppressions

-

Thread safety
Check that the code is thread safe

+

When this is checked, comments in the code like

+
// cppcheck-suppress nullPointer
+

suppress warnings. See Inline +suppressions.

-

MISRA
Ensure that the MISRA coding standard is followed. Please -note you need to have a textfile with the misra rule texts to get proper -warning messages. Cppcheck is not legally allowed to distribute the misra -rule texts.

+ +

Addons

-

Clang-tidy
Run Clang-tidy

+

+ +

Addons are extra checkers, written in Python, that run after the normal +analysis. Addons need Python to be installed (see Python binary in the +preferences) and the project must have a +build dir. If an addon can not be found, it is shown as +(Not found) and can not be selected.

+ +

Addons

+ +

Y2038: on many 32-bit systems time_t is a signed 32-bit +integer that counts seconds since 1970. It overflows on 19 January 2038. This +addon warns about code that uses such 32-bit time values.

+ +

Thread safety: warns about code that is not safe to use from several +threads, for example local static variables and calls to functions that are +not thread safe.

+ +

Coding standards

+ +

Misra C: checks the code against the MISRA C guidelines, a coding +standard for safety critical C code. Open source Cppcheck has a Misra addon +that does not cover all rules.

+ +

The MISRA rule texts are copyrighted and Cppcheck is not allowed to +distribute them. Without them, Misra warnings only show the rule number. To +get the rule texts in the warnings, buy the MISRA C document, copy the text of +Appendix A "Summary of guidelines" to a text file, and select that file in +MISRA rule texts. The file should look like this:

+
Appendix A Summary of guidelines
+Rule 1.1
+Text of rule 1.1
+Rule 1.2
+Text of rule 1.2
+

The rule text file is a user setting; it is not stored in the project +file.

+ +

Misra C++, Cert C, Cert C++, Autosar and +Safety profiles are only available in Cppcheck Premium. Cppcheck +Premium also lets you choose the version of Misra C (2012, 2023 or 2025) and +Misra C++ (2008 or 2023). For Cert C you can give the precision of +int, which is used for rule INT35-C if the precision is not the +same as the size.

+ +

Bug hunting (Premium)

+ +

A very deep analysis that tries to find all bugs of some kinds, at the cost +of more false warnings and a longer analysis. Only available in Cppcheck +Premium.

+ +

External tools

+ +

Clang-Tidy: also run Clang-Tidy on the code and show its warnings +together with the Cppcheck warnings. Clang-Tidy must be installed. It is +searched for in the Clang path from the +preferences, or in the system PATH. If it is not found, the checkbox shows +(not found). Use the Clang button in the severity toolbar to show +or hide the Clang-Tidy results.

+ + - diff --git a/gui/help/reports.html b/gui/help/reports.html new file mode 100644 index 00000000000..7f9b0ab6124 --- /dev/null +++ b/gui/help/reports.html @@ -0,0 +1,125 @@ + + +Results files, printing and statistics + + + + +

Results files, printing and statistics

+ + +

Saving results

+ +

Select File > Save results to file... (Ctrl+S) or click the save +button in the toolbar. Choose a file name and a format:

+ + + + + + +
FormatContents
XML files (*.xml)All information about each warning: file, + line, column, severity, id, CWE, message, notes, tags and more. This is + the same XML format (version 2) as the command line tool writes with + --xml. The GUI can open it again, and many other tools, for + example CI systems and report generators, can read it. Use this format if + you want to keep the results.
Text files (*.txt)One line per warning, in the classic + Cppcheck text format:
+ [src/buffer.c:9] -> [src/buffer.c:10]: (error) Array 'buf[16]' + accessed at index 16, which is out of bounds.
+ The locations of the notes are listed first, connected with + ->.
CSV files (*.csv)One line per warning with the columns file, + line, severity, id and summary. Open it in a spreadsheet to sort, count + and filter warnings.
+ +

Two preferences on the Reports tab affect +what is saved:

+
    +
  • Save all errors when creating report: also save warnings that are + hidden. By default only the warnings you can see are saved, so you can use + the severity buttons, the quick filter and hiding to choose what goes in + the report.
  • +
  • Save full path to files in reports: save the full path of each + file instead of the path relative to the project.
  • +
+ + +

Opening results

+ +

Select File > Open XML... to open a results file in XML format. +The current results are cleared first. The file can come from the GUI or from +the command line tool, for example from a CI job:

+ +
cppcheck --project=compile_commands.json --xml 2> results.xml
+ +

When results are opened from a file, the GUI needs to find the source files +to show the code. If the paths in the file are relative, the GUI asks for the +folder they are relative to when you select a warning. You can also give the +folder on the command line with the -d option; see +Command line options.

+ +

XML files in the old version 1 format can not be opened. Use +--xml with a recent Cppcheck version to create files in the +version 2 format.

+ +

For results opened from a file, the code can not be analyzed again with +Recheck, because the GUI does not know how it was analyzed.

+ + +

Printing

+ +

Select File > Print... (Ctrl+P) to print the results, or File +> Print Preview... to see what will be printed first. The printout has +one line per warning with the file, line, severity and summary. Like saved +reports, only the warnings you can see are printed. You can print to a PDF +file if your system has a PDF printer.

+ + +

Statistics

+ +

Select View > Statistics to see statistics about the project and +the last analysis. Enable Show statistics on check completion in the +preferences to show the statistics +automatically after each analysis.

+ +

The statistics dialog has these tabs:

+ +

Project

+

The root path of the project, the paths that are analyzed, the include +paths, the defines and the undefines.

+

+ +

Previous Scan

+

The path that was analyzed, the number of files and how long the analysis +took.

+

+ +

Statistics

+

The number of warnings of each severity, and the number of active +checkers.

+

+ +

Checkers

+

A report of which checkers were active in the analysis and which were not. +Use it to see what was checked, for example to document the analysis for a +safety certification.

+ +

History

+

A chart of the number of warnings over time, read from the build dir of the +project. Only available if the GUI was built with Qt Charts and the project +has a build dir.

+ +

Click Copy to Clipboard to copy the statistics as text and HTML, for +example to paste them in an e-mail or a document. Click Pdf Export to +save them as a PDF file.

+ +

Note: the statistics count the warnings of the last +analysis in this session. When you open a project with a build dir, the +results of the previous session are shown, but they are not counted until you +analyze again.

+ + + + + diff --git a/gui/help/severities.html b/gui/help/severities.html index 791c78c68e6..7e9f9e66d5d 100644 --- a/gui/help/severities.html +++ b/gui/help/severities.html @@ -1,47 +1,188 @@ -Severities +Severities and report types + -

Severities

+

Severities and report types

-

error

+

Every warning has a severity that tells you what kind of problem it +is and how serious it is. The severity is shown in the Severity column +and as an icon in the results list. Use the buttons in the severity toolbar, +or the View menu, to show or hide each severity.

-
-

when code is executed there is some bad behavior (undefined behavior, leak)

+

error

-

warning

+

The code has a bug that causes bad behavior when it is executed: undefined +behavior, a crash, a memory or resource leak, and similar. Errors should +always be fixed.

-
-

when code is executed there might be undefined behavior

+

Examples: array index out of bounds (arrayIndexOutOfBounds), +null pointer dereference (nullPointer), use of an uninitialized +variable (uninitvar), memory leak (memleak), resource +leak (resourceLeak), use after free +(deallocuse), division by zero (zerodiv), +mismatching allocation and deallocation (mismatchAllocDealloc).

-

style

+
void f()
+{
+    char buf[10];
+    buf[10] = 0;     // error: arrayIndexOutOfBounds
+}
-
-

point out possible mistakes, and suggest more defensive programming. Examples: +

warning

+ +

The code can cause bad behavior in some situations, or there is code that is +almost certainly not doing what the programmer wanted. Warnings should be +looked at carefully; most of them are bugs.

+ +

Examples: a null pointer check after the pointer has already been used +(nullPointerRedundantCheck), not checking the result of +malloc() (nullPointerOutOfMemory), wrong argument type +for a printf format (invalidPrintfArgType_sint), assignment in a +condition where a comparison was meant, a member variable that is not +initialized in a constructor (uninitMemberVar).

+ +
void f(struct S *s)
+{
+    int x = s->x;
+    if (!s)          // warning: nullPointerRedundantCheck
+        return;
+}
+ +

style

+ +

The code is not wrong, but it can be improved: it is confusing, redundant, +or not as safe as it could be. Style warnings often point to real bugs, for +example a condition that is always true can mean that the wrong variable is +used. They also suggest more defensive programming.

+ +

Examples:

+
    +
  • unused variables, functions and code (unusedVariable, + unreadVariable, unusedFunction),
  • +
  • conditions that are always true or false + (knownConditionTrueFalse),
  • +
  • variables, parameters and member functions that can be const + (constVariable, constParameterPointer, + functionConst),
  • +
  • the scope of a variable can be reduced (variableScope),
  • +
  • duplicate code in if/else branches (duplicateBranch),
  • +
  • suspicious operator precedence (clarifyCalculation).
  • +
+ +
int f(int x)
+{
+    if (x > 0 && x > 10)   // style: the first condition is redundant
+        return 1;
+    return 0;
+}
+ +

performance

+ +

Suggestions to make the code faster. They are based on common knowledge +about what is slow. It is not certain that you get a measurable speed +improvement by fixing them; it depends on how often the code runs.

+ +

Examples: passing a large object by value instead of by const reference +(passedByValue), using it++ instead of +++it for iterators (postfixOperator), inefficient use +of STL containers.

+ +
void print(std::vector<std::string> names);   // performance: passedByValue
+ +

portability

+ +

The code may work on your platform but not on others: implementation +defined behavior, 64-bit problems, or undefined behavior that happens to work +"as you want" with your compiler.

+ +

Examples: storing a pointer in an int +(AssignmentAddressToInteger), shifting a negative value, casting +between incompatible pointer types (invalidPointerCast), assuming +the size of a type.

+ +

Some portability warnings depend on the platform you have selected; see +Platform.

+ +

information

+ +

Messages about the analysis itself, not about your code. If you get +information messages, your code may be fine but the Cppcheck configuration can +be improved. Fixing the configuration usually gives better results.

+ +

Examples:

    -
  • unused code/variables/functions -
  • conditions that are always true/false -
  • constness -
  • operator precedence +
  • missingInclude: an include file of your project was not + found. Add the folder to the + include paths.
  • +
  • missingIncludeSystem: a standard or system header was not + found. This is normal and you do not need to do anything; Cppcheck has + built-in knowledge of the standard library. You can hide these with the + severity toolbar or suppress the id.
  • +
  • toomanyconfigs: a file has more preprocessor configurations + than Cppcheck analyzes by default. See + Defines.
  • +
  • normalCheckLevelMaxBranches: the analysis of a function was + limited. Use the Exhaustive check level to analyze it fully.
  • +
  • messages from Analyze > Reanalyze and check library about + functions that are not configured.
-

-

performance

+

note

-
-

Suggestions for making the code faster. These suggestions are only based on common knowledge. It is not certain you'll get any measurable difference in speed by fixing these messages.

+

Notes are not warnings. They are shown as child items of a warning and +explain the path through the code that leads to it. See +Investigating warnings.

-

portability

+ +

Report types

+ +

If you work with a coding standard, you can show the results classified +according to that standard. Select the standard in View > Report:

+ +

+ + + + + + + + + + + + +
ReportClassificationsExtra columns
NormalThe Cppcheck severities described above. 
AutosarRequired, AdvisoryClassification, Guideline
Cert C, Cert C++L1, L2, L3 (the CERT priority levels; L1 is + the most severe)Level, Rule
Misra C, Misra C++ 2023Mandatory, Required, AdvisoryClassification, Guideline
Misra C++ 2008Required, Advisory, DocumentClassification, Guideline
+ +

With a compliance report type:

+
    +
  • Each warning is mapped to the guideline or rule of the standard that it + relates to. The Guideline or Rule column shows it, and the + Classification or Level column shows how strict the + guideline is.
  • +
  • The icons and the buttons in the severity toolbar follow the + classification: Mandatory and L1 use the error icon, Required and L2 the + warning icon, Advisory and L3 the style icon, and Document the + information icon.
  • +
  • Warnings that are not related to any guideline of the standard are not + shown.
  • +
-
-

portability warnings. Implementation defined behavior. 64-bit portability. Some undefined behavior that probably works "as you want". etc.

+

-

information

+

The report type only changes how results are shown; the analysis is the +same. To check the code against the rules of a coding standard, enable the +standard on the Addons tab of the +project. Open source Cppcheck has a Misra C addon; checking the other +standards needs Cppcheck Premium.

-
-

Configuration problems. If you get such output then your code is ok but your cppcheck configuration could be improved.

+ diff --git a/gui/help/standalone-analysis.html b/gui/help/standalone-analysis.html index ad7fae5fe55..bf7cc0096b3 100644 --- a/gui/help/standalone-analysis.html +++ b/gui/help/standalone-analysis.html @@ -1,17 +1,125 @@ - -Standalone analysis +Analyzing without a project + -

Standalone analysis

+

Analyzing without a project

+ +

You can analyze code quickly without creating a project file. This is +useful to try Cppcheck, or to look at a few files. For regular use a project +is better: with a properly configured project Cppcheck knows your include +paths, defines and libraries, and the analysis is more accurate. You also get +features that need a project, such as saved suppressions, tags and the build +dir. See Project files.

+ +

If a project is open, close it first with File > Close +Project File. The GUI does not let you analyze files or folders while a +project is open.

+ +

Analyzing files

+ +

Select Analyze > Files... (Ctrl+F) and select one or more source +files. The analysis starts at once.

+ +

In the same file dialog you can also select a project of your build +system. Cppcheck then analyzes the files of that project with its include +paths and defines, just as if you had imported it in a project file:

+
    +
  • a compile database (compile_commands.json),
  • +
  • a Visual Studio solution (*.sln, *.slnx) or + project (*.vcxproj). For a solution, a dialog asks which + configuration (for example Debug|x64) to analyze,
  • +
  • a Borland C++ Builder 6 project (*.bpr).
  • +
+ +

Analyzing a directory

+ +

Select Analyze > Directory... (Ctrl+D) and select a folder. +Cppcheck analyzes all source files in the folder and its subfolders. Files +with these extensions are analyzed: .c, .cpp, +.cxx, .cc, .c++, .tpp, +.txx, .ipp and .ixx.

+ +

Header files are not analyzed on their own. The code in a header is +analyzed when a source file includes it, as long as Cppcheck can find the +header.

+ +

If the folder contains a Cppcheck project file, the GUI asks if you want to +open that project instead. If there are several project files, it asks if you +want to continue without them.

+ +

Which settings are used

+ +

Without a project, the analysis uses:

+
    +
  • the preferences: number of threads, + Force checking all #ifdef configurations, Enable inline + suppressions, Check for inconclusive errors also,
  • +
  • the settings in the Analyze menu: the C and C++ standard, the + language (auto-detect, enforce C or enforce C++) and the platform.
  • +
+ +

The Analyze menu settings are remembered when you close the GUI.

+ +

Language standard

+ +

Analyze > C standard and Analyze > C++ standard select +the language version. It affects how some code is parsed and which checks +apply. For example, some functions are deprecated in newer standards, and +some library functions only exist in newer standards.

+ +

Language

+ +

With Auto-detect language the file extension decides if a file is C +or C++. Choose Enforce C or Enforce C++ to treat all files as +one language.

+ +

Platform

+ +

The platform decides the size of the basic types (short, +int, long, pointers, wchar_t and so on) +and whether char is signed. Choose the platform the code will run +on:

+
    +
  • Native: the computer you run Cppcheck on.
  • +
  • Unix 32-bit / Unix 64-bit: Linux, BSD, macOS and similar + on 32-bit or 64-bit processors.
  • +
  • Windows 32-bit ANSI / Windows 32-bit Unicode: 32-bit + Windows. In the ANSI variant the Windows "T" macros and types such as + TCHAR and _tcscpy mean the char + versions; in the Unicode variant they mean the wchar_t + versions.
  • +
  • Windows 64-bit: 64-bit Windows, with Unicode.
  • +
+ +

Limitations

+ +

Without a project:

+
    +
  • There are no include paths, so Cppcheck may not find your own headers. You + will see information messages about missing includes, and some + warnings can be missing because types and macros are unknown.
  • +
  • Suppressions made with the context menu can not be saved. The warnings + disappear from the list but are reported again in the next analysis. Use + inline suppressions in the code instead, or create a project. See + Hiding and suppressing warnings.
  • +
  • Warnings can not be tagged.
  • +
  • There is no build dir. Every analysis analyzes all files, the Since + date column is not available, and checks that need whole program + analysis, such as unused functions, are not run.
  • +
  • Addons and coding standards (Misra, Cert, ...) can not be used.
  • +
+ +

Analyzing again

-

It is possible to quickly analyze files. Open the Analyze menu and click on -either Files... or Directory....

+

After you change the code, use Analyze > Reanalyze modified files +(Ctrl+R) to analyze the files that changed, or Reanalyze all files to +analyze everything again.

-

It is recommended that you create a project for analysis. A properly configured -project will give you better analysis.

+ diff --git a/gui/help/style.css b/gui/help/style.css new file mode 100644 index 00000000000..126f42f3fe7 --- /dev/null +++ b/gui/help/style.css @@ -0,0 +1,68 @@ +/* Stylesheet for the Cppcheck GUI help. Qt's help browser only supports a + subset of CSS, so keep this simple. */ + +body { + font-family: sans-serif; + margin: 8px; +} + +h1 { + color: #1f4e79; + font-size: x-large; +} + +h2 { + color: #1f4e79; + font-size: large; + margin-top: 20px; +} + +h3 { + color: #2e75b6; + font-size: medium; + margin-top: 14px; +} + +pre { + background-color: #f3f3f3; + font-family: monospace; + margin-left: 16px; +} + +code { + font-family: monospace; +} + +table.options { + border-collapse: collapse; + border-color: #c8c8c8; + border-style: solid; +} + +table.options th { + background-color: #e4ecf5; + padding: 4px; + text-align: left; +} + +table.options td { + padding: 4px; + vertical-align: top; +} + +p.note { + background-color: #fff8dc; +} + +p.tip { + background-color: #eaf5ea; +} + +p.nav { + color: #707070; + font-size: small; +} + +p.figure { + margin-left: 16px; +} diff --git a/gui/help/suppressions.html b/gui/help/suppressions.html new file mode 100644 index 00000000000..2baf18c318b --- /dev/null +++ b/gui/help/suppressions.html @@ -0,0 +1,158 @@ + + +Hiding and suppressing warnings + + + + +

Hiding and suppressing warnings

+ +

There are several ways to get rid of warnings you do not want to see. They +differ in how long they last and where they are stored:

+ + + + + + + + + + + + + + + + + + +
MethodLastsStored inBest for
HideUntil the next analysisNowhereGetting warnings out of the way while you work
Severity buttons and filterUntil you change themGUI settingsConcentrating on some kinds of warnings
Suppress from the context menuPermanentProject fileTurning off a kind of warning for the whole project
Suppressions in the project dialogPermanentProject fileSuppressions for some files, lines or symbols
Inline suppressionsPermanentSource codeA single false warning
Excluding filesPermanentProject fileCode you do not want to analyze at all
+ +

The difference between hiding and suppressing: a hidden warning +comes back the next time you analyze the code. A suppressed warning is not +reported again until you remove the suppression.

+ + +

Hiding warnings

+ +

Select one or more warnings, right-click and choose Hide N +result(s). To hide all warnings with the same id as the selected warning, +choose Hide all with id.

+ +

+ +

Hidden warnings are not deleted. Use View > Show hidden to show +them again. They are also shown again after the next analysis.

+ +

By default, hidden warnings are not saved when you save the results to a +file. Enable Save all errors when creating report in the +preferences to save them too.

+ + +

Severity buttons and the quick filter

+ +

The buttons in the severity toolbar show or hide all warnings of a +severity, and the quick filter shows only warnings that contain some text. See +The main window. These do not change the results; +they only change what you see.

+ + +

Suppressing from the context menu

+ +

Select one or more warnings, right-click and choose Suppress selected +id(s). All warnings with the ids of the selected warnings are removed from +the list, and a suppression for each id is added to the project file. The +warnings are not reported in future analyses.

+ +

Note: this suppresses the id in all files of the +project, not only the selected warning. If you only want to suppress one +warning, use an inline suppression, or add a suppression +with a file name or line number in the project dialog.

+ +

This only works when a project is open. Without a project the warnings are +removed from the list, but nothing is saved. Critical errors, such as syntax +errors, can not be suppressed this way.

+ + +

Suppressions in the project dialog

+ +

Open File > Edit Project File... and go to the Warning +options tab. The Suppressions list shows all suppressions of the +project, including the ones made with the context menu.

+ +

+ +

Click Add to add a suppression. You must give the Error ID; +the other fields make the suppression more specific:

+
    +
  • File name: only in files that match. Wildcards * and + ? can be used, for example src/legacy/*.
  • +
  • Line number: only on this line of the file.
  • +
  • Symbol name: only for warnings about this variable or + function.
  • +
+ +

Some examples:

+ + + + + + + + +
Error IDFile nameLineEffect
unusedFunction  No unused function warnings at all, for example for a library whose + functions are called by other programs.
*src/generated/* No warnings in generated code (but the code is still analyzed).
nullPointersrc/io.c120No null pointer warning on line 120 of + src/io.c.
+ +

Double-click a suppression to edit it, or select it and click +Remove to remove it. After you click OK, the project is analyzed +again.

+ + +

Inline suppressions

+ +

An inline suppression is a comment in the source code, just before the line +with the warning, or at the end of that line:

+ +
void f()
+{
+    char *p = get_buffer();
+    // cppcheck-suppress nullPointer
+    *p = 0;
+
+    *p = 1; // cppcheck-suppress nullPointer
+}
+ +

You can suppress several ids at once, and add a comment that explains +why:

+ +
// cppcheck-suppress[nullPointer,uninitvar] get_buffer() never returns NULL
+ +

Inline suppressions are the best way to suppress a single false warning: +they stay with the code when it is moved, and the next person who reads the +code sees that the warning was looked at. See the Cppcheck manual for more +forms, for example suppressing a whole block or file.

+ +

Inline suppressions must be enabled:

+
    +
  • for a project, with Enable inline suppressions on the Warning + options tab of the project dialog (enabled by default for new + projects),
  • +
  • without a project, with Enable inline suppressions in the + preferences.
  • +
+ + +

Excluding files

+ +

To not analyze some files or folders at all, add them to Exclude source +files on the Warning options tab of the project dialog. See +Exclude source files.

+ + + + + diff --git a/gui/help/tagging.html b/gui/help/tagging.html index 7ac4e7ee8d9..4f0a86452ea 100644 --- a/gui/help/tagging.html +++ b/gui/help/tagging.html @@ -1,22 +1,68 @@ Tagging warnings +

Tagging warnings

-

You can manually categorize warnings.

+

Tags let you categorize warnings by hand. You choose the names of the tags +yourself. Some ideas:

+
    +
  • a review status: todo, checked, + fixed later,
  • +
  • your opinion of the warning: bug, false + positive, not important,
  • +
  • who should look at it: frontend, network, + team b.
  • +
-

You choose the names of the categories yourself in the project file -dialog.

+

Unlike suppressions, tags do not remove warnings. They are a way to keep +track of what you have looked at and what you have decided about each +warning.

-

If tag names are configured, then you can tag the warnings by -right-clicking on them and selecting the proper tag in the -context menu.

+

Defining tags

-

Tags are saved in the project file and will be permanent.

+

Open File > Edit Project File..., go to the Warning options +tab and enter the tag names in Warning tags, separated by semicolons:

+ +
todo;false positive;fixed later
+ +

+ +

Tag names can contain letters, digits and spaces. Tags need a project; there +are no tags when you analyze without a project.

+ +

Tagging warnings

+ +

Select one or more warnings, right-click, open the Tag submenu and +choose a tag. Choose No tag to remove the tag. The Tag submenu is +only shown if the project has tags.

+ +

+ +

The tag is shown in the Tags column. Click the column header to sort +the warnings by tag, so that warnings with the same tag are listed +together.

+ +

Where tags are stored

+ +

The tags you give to warnings are saved in the project file at once. Each +tagged warning is identified by a hash of the warning and the code of the +function it is in, so the tag stays with the warning when code elsewhere in +the file changes or lines are added above the function. If the function itself +is changed, the warning gets a new hash and the tag is lost. That is +intended: when the code has changed, the warning should be looked at +again.

+ +

Because the tags are in the project file, everyone who uses the project file +sees the same tags. Tags are also included when you save the results as +XML.

+ + - diff --git a/gui/help/tools.html b/gui/help/tools.html new file mode 100644 index 00000000000..6301283bbd0 --- /dev/null +++ b/gui/help/tools.html @@ -0,0 +1,146 @@ + + +Scratchpad, library editor and other tools + + + + +

Scratchpad, library editor and other tools

+ + +

Scratchpad

+ +

The scratchpad lets you analyze a piece of code without saving it in a file. +Use it to try out how Cppcheck handles some code, to reduce a false warning to +a small example before you report it, or to check a code snippet from a +review.

+ +

Open it with View > Show Scratchpad....

+ +

+ +
    +
  1. Type or paste C or C++ code in the editor.
  2. +
  3. Optionally enter a file name. It is mainly used to decide the language: + test.c is analyzed as C and test.cpp as C++. If + you leave it empty, the code is analyzed as C++.
  4. +
  5. Click Check.
  6. +
+ +

The results are shown in the results list of the main window, and they +replace the results that were shown before. The code is analyzed with the +settings of the open project, or with the settings of the Analyze menu +if no project is open. The code can not include your own headers, since it is +not stored in a file.

+ +

The scratchpad keeps its text while the GUI is running, so you can change +the code and click Check again.

+ + +

Library editor

+ +

A library configuration file (.cfg) tells Cppcheck how the +functions of a library behave. Cppcheck comes with configurations for many +libraries (see Libraries). For +your own libraries, or libraries that have no configuration, you can write one +yourself. The library editor helps you with the function part of the +configuration.

+ +

Open it with View > Library Editor....

+ +

+ +

Working with files

+ +

Click Open to load an existing .cfg file, Save +to save your changes and Save as to save to a new file. To start a new +configuration, add functions and click Save as.

+ +

Save your configuration in the folder of your project file. It then +appears in the Libraries list on the Types and Functions tab of +the project dialog, where you can select it.

+ +

The editor only shows the functions of a configuration. Other parts of the +file, such as memory and resource allocation functions, defines and types, are +kept when you save. If a file contains elements that the editor does not know, +it can not be opened in the editor; use a text editor for such files.

+ +

Functions

+ +

The list on the left shows the functions of the configuration. Type in +Filter to show only functions whose names contain the text. Click +Sort to sort the list by name.

+ +

Click Add to add a function. Enter the function name and the number +of arguments. If several functions have the same properties, you can enter +their names separated by commas; they then share one entry.

+ +

Select a function to see and change its properties:

+ + + + + + + + +
PropertyMeaning
CommentsYour notes about the function. They are saved as + an XML comment before the function in the file.
noreturnTrue if the function never returns, like + exit() or a fatal error handler. Then Cppcheck knows that the + code after a call is not reached. False if it always returns. + Unknown if it depends.
return value must be usedWarn if the return value is ignored, + for example for functions that return an error code or a new object.
ignore function in leaks checkingThe function does not take + ownership of a pointer that is passed to it. Without this, Cppcheck may + assume that the function frees or stores the memory, and stop tracking a + possible leak.
ArgumentsThe properties of each argument. Select an argument + and click Edit to change them.
+ +

Argument properties

+ + + + + + + + + + +
PropertyMeaning
Not boolA boolean value (for example the result of a + comparison) is wrong for this argument. Typical for pointers and + sizes.
Not nullA null pointer must not be passed.
Not uninitThe value must be initialized. For pointers this + means the data it points at is read by the function.
StringThe argument must be a zero terminated string.
Format stringThe argument is a printf style format string; + the following arguments are checked against it.
Min size of bufferThe minimum size of the buffer that is + passed. argvalue: the value of another argument (for example the + size argument of memset); mul: the product of two + arguments; strlen: the length of a string argument.
Valid valuesThe values that are allowed, for example + 0: (zero or more), 1:255 or + 0,2:5. Cppcheck warns if another value can be passed.
+ +

For all features of the configuration format, see the Cppcheck manual and +the files in the cfg folder of the Cppcheck installation. You can +edit .cfg files in a text editor too.

+ +

To find which functions in your code are not configured yet, use +Analyze > Reanalyze and check library; see +Checking the library +configuration.

+ + +

Thread details

+ +

View > Thread Details shows what each analysis thread is doing: +the file it analyzes, when it started on the file and how far it has come. +Use it to find files that take a long time to analyze. If one file takes very +long, you can for example exclude it, reduce the number of configurations with +undefines, or use a lower check +level.

+ +

The number of threads is set in the +preferences.

+ + + + + diff --git a/gui/help/troubleshooting.html b/gui/help/troubleshooting.html new file mode 100644 index 00000000000..b9b4cd99ef9 --- /dev/null +++ b/gui/help/troubleshooting.html @@ -0,0 +1,190 @@ + + +Troubleshooting + + + + +

Troubleshooting

+ +

Answers to common questions and problems.

+ +

I get many "Include file not found" messages

+ +

There are two kinds:

+
    +
  • missingIncludeSystem: a standard or system header, such as + <stdio.h> or <vector>, was not found. + This is normal. Cppcheck does not need these headers, because it knows the + standard library and the libraries you select in the project. Hide the + information severity, or suppress the id + missingIncludeSystem in the project.
  • +
  • missingInclude: one of your own headers was not found. Fix this: + add the folder of the header to the + include paths of the project, or import the project from your build + system so that Cppcheck gets the same include paths as the compiler.
  • +
+ +

Use Analyze > Check configuration (defines, includes) to get a +list of the configuration problems of the project.

+ +

Cppcheck reports a syntax error or an unknown macro

+ +

Cppcheck does not analyze a file it can not parse. A message like There +is an unknown macro here somewhere. Configuration is required. means that +the code uses a macro that Cppcheck does not know, in a place where the code +can not be parsed without knowing what the macro means. For example:

+ +
DECLARE_HANDLER(foo)    // what is this?
+{
+    ...
+}
+ +

To fix it, do one of these:

+
    +
  • add the include path of the header that defines the macro,
  • +
  • select the library that the macro belongs to (for example qt for + Q_OBJECT and signals, or windows for the + Windows API macros),
  • +
  • give the macro a value in + Defines, for example DECLARE_HANDLER(x)=void x(), or in a + library configuration file.
  • +
+ +

If the code is correct and compiles, but Cppcheck still reports a syntax +error, please report it as a Cppcheck bug.

+ +

The analysis is slow

+ +
    +
  • Use a build dir. Then + unchanged files are not analyzed again.
  • +
  • Increase the Number of threads in the + preferences.
  • +
  • Use the Reduced or Normal check level instead of + Exhaustive.
  • +
  • Make sure that Force checking all #ifdef configurations is off in + the preferences.
  • +
  • Use undefines to skip + configurations you do not need, or import a compile database: then each + file is analyzed with one configuration only.
  • +
  • Do not add system include folders (such as /usr/include) to + the include paths.
  • +
  • Exclude generated code and + 3rd party code.
  • +
  • Use View > Thread Details to find files that take long; see + Thread details.
  • +
+ +

A warning is wrong (false positive)

+ +

First check the configuration: missing include paths and missing library +configurations are common causes. For example, if your code calls a function +that never returns and Cppcheck does not know that, it can report problems in +code that is never reached. Configure the function as noreturn in a +library configuration (see Library +editor).

+ +

If the configuration is right, suppress the warning (see +Hiding and suppressing warnings) and please +report the false positive to the Cppcheck project with a small code example. +Use the scratchpad to make the example as +small as possible.

+ +

A bug that I know of is not found

+ +
    +
  • Check that the severity of the warning is shown in the severity toolbar, + that the quick filter is empty, that no warnings are hidden (View > + Show hidden) and that View > Report is Normal.
  • +
  • Check that the file was analyzed: look in the Analysis Log.
  • +
  • Check that the code was analyzed with the right configuration. If the + code is in an #ifdef block, it may only be analyzed when a + macro is defined.
  • +
  • Select the libraries that the code uses, so that Cppcheck knows how their + functions behave.
  • +
  • Try the Exhaustive check level and enable inconclusive warnings in + the preferences.
  • +
  • Bugs that span several files need a build dir (whole program + analysis).
  • +
+ +

Cppcheck can not find all bugs. If you think the bug should be found, +create a small example in the scratchpad and report it to the Cppcheck +project.

+ + +

Checking the library configuration

+ +

Select Analyze > Reanalyze and check library. The project is +analyzed again, and Cppcheck reports information messages for functions +it has no configuration for, for example:

+
    +
  • checkLibraryNoReturn: Cppcheck does not know if the function + can return. Configure noreturn for it.
  • +
  • checkLibraryFunction: the function is not configured at all. + If it is a library function, configure it so that Cppcheck can check how it + is used.
  • +
+ +

Write the missing configuration in a .cfg file with the +library editor or a text editor, put it +in the folder of the project file and select it on the Types and +Functions tab of the project.

+ +

Addons do not work

+ +
    +
  • Addons are Python scripts. Install Python, and if it is not in the PATH, + set the Python binary in the + preferences.
  • +
  • The project needs a build + dir. Without it, the analysis is stopped with the message To check + the project using addons, you need a build directory.
  • +
  • If an addon is shown as (Not found) in the project dialog, the + Cppcheck installation is incomplete.
  • +
+ +

Clang-Tidy is "not found"

+ +

Install Clang-Tidy (it is part of LLVM/Clang). If it is not in the PATH, set +the Clang path in the preferences to the +folder where clang-tidy is.

+ +

Double-clicking a warning does nothing

+ +

No editor is configured, or no default editor is selected. Add your editor +on the Applications tab of the +preferences and click Set as default. If the editor does not start, +check the executable path and the parameters.

+ +

The results are old

+ +

When you open a project with a build dir, the results of the last analysis +are shown, not a new analysis. Click Reanalyze all files to analyze the +current code.

+ +

"Failed to load std.cfg"

+ +

The GUI can not find its data files. The Cppcheck installation is broken; +reinstall Cppcheck. If you built Cppcheck yourself, make sure the +cfg folder is installed next to the program, or configure the data +folder with the --data-dir command line +option.

+ +

Where can I get more help?

+ + + + + + + diff --git a/gui/help/walkthrough.html b/gui/help/walkthrough.html index 9f27ce05f6c..dbaff99a073 100644 --- a/gui/help/walkthrough.html +++ b/gui/help/walkthrough.html @@ -1,69 +1,156 @@ -Walk through +Getting started + -

Quick walk through

+

Getting started

-This is a quick and short walk through to get you started. +

This page walks you through a first analysis: you create a project file, +run the analysis and look at the results. It takes a few minutes. The other +pages in this help explain each step in more detail.

-

Step 1: Create a project.

+

Step 1: Create a project file

-

Create a new project:

+

Select File > New Project File... (Ctrl+Shift+N). A file dialog +asks where to save the project file. Save it in the root folder of your code, +for example next to your CMakeLists.txt or Visual Studio +solution. Paths in the project file are stored relative to the project file, +so the project keeps working if you move the whole folder or check it into +version control.

-
+

When you have chosen a file name, the Project file dialog opens. A +new project automatically gets a build dir called +<name>-cppcheck-build-dir. Cppcheck stores its work files +there; it makes repeated analysis much faster and is required for some +features. See Cppcheck build dir.

-

In the Paths and Defines tab, it is recommended that you import your -project file at the top.

+

Step 2: Tell Cppcheck where the code is

-
+

Open the Paths and Defines tab. You have two choices.

-

In the Types and Functions tab, try to activate all 3rd party -libraries you use (windows, posix, ...).

+

Choice A: Import a project (recommended)

-
+

If you build your code with Visual Studio, CMake, Meson, Bear or any other +tool that can produce a compile database, import it. Click Browse... +next to Import Project and select one of:

+
    +
  • a Visual Studio solution (*.sln, *.slnx) or + project (*.vcxproj),
  • +
  • a compile database (compile_commands.json). CMake creates it + if you configure with -DCMAKE_EXPORT_COMPILE_COMMANDS=ON,
  • +
  • a Borland C++ Builder 6 project (*.bpr).
  • +
-

In the Analysis tab, leave the default settings to start with.

+

Cppcheck then reads the list of source files, the include paths, the +preprocessor defines and the language standard from the imported file. The +Paths, Include Paths and Undefines fields are disabled +because the values come from the imported project.

-

In the Warnings options tab, leave the default settings to start -with.

+

-

In the Addons tab, leave the default settings to start with.

+

Choice B: Enter the paths yourself

+

If you can not import a project, enter the information manually:

+
    +
  • Paths: click Add... and select the folders (or files) to + analyze. Cppcheck analyzes all C/C++ source files in these folders and + their subfolders.
  • +
  • Include Paths: add the folders where your own header files are. + Cppcheck needs your headers to understand types, macros and functions. + You do not need to add the standard library or system headers; Cppcheck + has built-in knowledge about them.
  • +
  • Defines: optionally enter macros, for example + DEBUG;VERSION=3.
  • +
-

Step 2: Analyze code.

+

-

When the project file has been created, the analysis will start -automatically.

+

Step 3: Select libraries

-

While analysis is performed in the background, you can investigate the -results.

+

Open the Types and Functions tab. In the Libraries list, +check the libraries your code uses, for example posix, windows, +qt, boost, gtk or sdl. A library configuration tells +Cppcheck how the functions and types in that library behave: which functions +allocate memory, which arguments must not be null, which functions never +return, and so on. This gives you more and better warnings.

-
+

Set the Platform to the target of your code if it differs from the +computer you run Cppcheck on. This matters for portability and overflow +checks, since the sizes of int, long and pointers +differ between platforms.

+

-

Step 3: Investigate warnings.

+

Step 4: Leave the rest as it is

-

In the toolbar you choose what types of warnings you want to see -(error/warning/style/performance/portability/information).

+

The Analysis, Warning options and Addons tabs have good +default values. You can come back later and change them; see +Project files for a description of every +option.

-
+

Click OK. The project file is saved. If the build dir does not exist +yet, the GUI asks if it should create it: answer Yes.

+

Step 5: Watch the analysis

-

All warnings are shown in a list. If you select a warning in the list, then -details about that warning is shown.

+

The analysis starts immediately. A progress bar above the results shows +how many files have been analyzed. You do not have to wait: warnings appear +in the list as soon as they are found, and you can start looking at them. +To stop the analysis, click the Stop button in the toolbar or press +Esc.

-

If you right click on warning(s) then you get a context menu.

+

Step 6: Look at the results

-
+

The results list groups the warnings by file. Click the arrow next to a +file name, or use View > Expand all, to see the warnings. Click a +warning to show its details and the source code in the lower part of the +window. The line with the problem is highlighted.

-

The difference of "Hide" and "Suppress" is that -suppressions are saved in the project file. The suppressed warnings will not be -shown again unless you remove the suppression. When you hide a warning then -they will be temporarily hidden; the next time you analyze your code these -warnings will be shown again.

+

+ +

Some warnings have an arrow in front of them. Expand them to see +notes: these show the path through the code that leads to the +problem, for example where a variable got the value that later causes the +bug. Click a note to jump to that line.

+ +

Use the colored buttons in the toolbar to show or hide warnings by +severity. Start with errors and warnings; they are the most likely to be +real bugs. See Severities.

+ +

+ +

Right-click a warning to get more options: open the file in your editor, +copy the warning, hide it, suppress it or tag it.

+ +

+ +

Read Investigating warnings to +learn how to work efficiently with the results.

+ +

Step 7: Fix the code and analyze again

+ +

Fix the bugs in your editor. Then click Reanalyze all files in the +toolbar. Because the project has a build dir, Cppcheck only does the full +analysis again for files that changed (or that include a changed header). For +the other files the results are taken from the build dir, so this is +fast.

+ +

If you do not agree with a warning, you can suppress it so that it is not +shown again. See Hiding and suppressing +warnings.

+ +

Next time

+ +

The project files you used recently are listed in the File menu. +When you open a project that has a build dir, the GUI first shows the results +from the last analysis. Click Reanalyze all files in the toolbar to +analyze the code again. Thanks to the build dir, files that did not change +are not analyzed again; their old results are reused.

+ + - From 9c049acb1a23cf19f387d0c4ccd37e4e6c6eba76 Mon Sep 17 00:00:00 2001 From: pduchi Date: Sun, 25 Oct 2026 19:15:18 +0100 Subject: [PATCH 13/32] Fix #12282 (Internal error: fail to parse 1.0e4931L) (#8952) Trac: https://trac.cppcheck.net/ticket/12282 A float literal out of the range of `double` stops the analysis of the whole file: Internal Error. MathLib::toDoubleNumber: conversion failed: 1.0e4931L `MathLib::toDoubleNumber()` reads the literal with an `istringstream`. For a value out of range the stream stores the largest finite value and sets `failbit`, which became the internal error. Compilers make such a literal infinity, so this does the same. Besides `long double` constants like the one in the ticket, a common trigger is glibc's `math.h` when the GCC builtins are not used: `HUGE_VAL`/`HUGE_VALF` are then `1e10000`/`1e10000f`, so any file using `INFINITY` or `HUGE_VAL` hit this. Tests: new cases in `TestMathLib::toDoubleNumber` (`1e10000`, `1e10000f`, `1e10000L`, `1.5E+400`, `1.0e4931L`); they fail without the change. --- lib/checkcondition.cpp | 4 ++++ lib/mathlib.cpp | 18 ++++++++++++++++-- lib/mathlib.h | 2 ++ lib/vf_common.cpp | 16 ++++++++++------ test/testcondition.cpp | 12 ++++++++++++ test/testmathlib.cpp | 19 +++++++++++++++++++ test/testother.cpp | 12 ++++++++++++ 7 files changed, 75 insertions(+), 8 deletions(-) diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index 57c8412cdd9..ad547cf543e 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -1301,6 +1301,10 @@ void CheckConditionImpl::checkIncorrectLogicOperator() if (isfloat && (op1 == "==" || op1 == "!=" || op2 == "==" || op2 == "!=")) continue; + // no double value to compare (1e400L would become infinity) + if (isfloat && (MathLib::isLongDoubleOutOfDoubleRange(value1) || MathLib::isLongDoubleOutOfDoubleRange(value2))) + continue; + // the expr are not the token of the value but they provide better context const double d1 = isfloat ? MathLib::toDoubleNumber(value1) : 0; const double d2 = isfloat ? MathLib::toDoubleNumber(value2) : 0; diff --git a/lib/mathlib.cpp b/lib/mathlib.cpp index c7c055899fd..9aba7118858 100644 --- a/lib/mathlib.cpp +++ b/lib/mathlib.cpp @@ -532,8 +532,15 @@ double MathLib::toDoubleNumber(const std::string &str, const Token * const tok) std::istringstream istr(str); istr.imbue(std::locale::classic()); double ret; - if (!(istr >> ret)) - throw InternalError(tok, "Internal Error. MathLib::toDoubleNumber: conversion failed: " + str); + if (!(istr >> ret)) { + // Out of the range of double, such as 1e10000 (glibc's HUGE_VAL for + // compilers other than GCC): the stream stores the largest finite + // value and fails, a compiler makes it infinity. + if (!isFloat(str) || std::fabs(ret) < std::numeric_limits::max()) + throw InternalError(tok, "Internal Error. MathLib::toDoubleNumber: conversion failed: " + str); + ret = std::copysign(std::numeric_limits::infinity(), ret); + istr.clear(); + } std::string s; if (istr >> s) { if (isDecimalFloat(str)) @@ -584,6 +591,13 @@ bool MathLib::isFloat(const std::string &str) return isDecimalFloat(str) || isFloatHex(str); } +bool MathLib::isLongDoubleOutOfDoubleRange(const std::string &str) +{ + if (str.empty() || (str.back() != 'l' && str.back() != 'L') || !isFloat(str)) + return false; + return std::isinf(toDoubleNumber(str)); +} + bool MathLib::isDecimalFloat(const std::string &str) { if (str.empty()) diff --git a/lib/mathlib.h b/lib/mathlib.h index 84338b5ce70..bfa1a5b877b 100644 --- a/lib/mathlib.h +++ b/lib/mathlib.h @@ -115,6 +115,8 @@ class CPPCHECKLIB MathLib { static bool isInt(const std::string & str); static bool isFloat(const std::string &str); + /** @brief a long double literal out of the range of double, such as 1e400L, which toDoubleNumber() makes infinity */ + static bool isLongDoubleOutOfDoubleRange(const std::string &str); static bool isDecimalFloat(const std::string &str); static bool isNegative(const std::string &str); static bool isPositive(const std::string &str); diff --git a/lib/vf_common.cpp b/lib/vf_common.cpp index b1cabcc9201..9b1d0387f38 100644 --- a/lib/vf_common.cpp +++ b/lib/vf_common.cpp @@ -139,12 +139,16 @@ namespace ValueFlow // Bad character literal } } else if (tok->isNumber() && MathLib::isFloat(tok->str())) { - Value value; - value.valueType = Value::ValueType::FLOAT; - value.floatValue = MathLib::toDoubleNumber(tok); - if (!tok->isTemplateArg()) - value.setKnown(); - setTokenValue(tok, std::move(value), settings); + // A long double literal out of the range of double (1e400L) has no + // double value: infinity would make different literals compare equal. + if (!MathLib::isLongDoubleOutOfDoubleRange(tok->str())) { + Value value; + value.valueType = Value::ValueType::FLOAT; + value.floatValue = MathLib::toDoubleNumber(tok); + if (!tok->isTemplateArg()) + value.setKnown(); + setTokenValue(tok, std::move(value), settings); + } } else if (tok->enumerator() && tok->enumerator()->value_known) { Value value(tok->enumerator()->value); if (!tok->isTemplateArg()) diff --git a/test/testcondition.cpp b/test/testcondition.cpp index b23bcc2e20b..abef2d95614 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -69,6 +69,7 @@ class TestCondition : public TestFixture { TEST_CASE(incorrectLogicOperator15); TEST_CASE(incorrectLogicOperator16); // #10070 TEST_CASE(incorrectLogicOperator17); + TEST_CASE(incorrectLogicOperator18); // #12282 TEST_CASE(secondAlwaysTrueFalseWhenFirstTrueError); TEST_CASE(incorrectLogicOp_condSwapping); TEST_CASE(testBug5895); @@ -1758,6 +1759,17 @@ class TestCondition : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void incorrectLogicOperator18() { // #12282 + // long double literals out of the range of double are different values + check("int f(long double x) {\n" + " return x > 1e400L && x < 1e500L;\n" + "}\n" + "int g() {\n" + " return 1e400L < 1e500L;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } + void incorrectLogicOperator17() { // #12471 check("struct R {\n" " void set() { i = 1; }\n" diff --git a/test/testmathlib.cpp b/test/testmathlib.cpp index 8cbe5b50019..800334926e5 100644 --- a/test/testmathlib.cpp +++ b/test/testmathlib.cpp @@ -22,6 +22,7 @@ #include "token.h" #include "tokenlist.h" +#include #include #include #include @@ -44,6 +45,7 @@ class TestMathLib : public TestFixture { TEST_CASE(isnegative); TEST_CASE(ispositive); TEST_CASE(isFloat); + TEST_CASE(isLongDoubleOutOfDoubleRange); TEST_CASE(isDecimalFloat); TEST_CASE(isGreater); TEST_CASE(isGreaterEqual); @@ -598,6 +600,16 @@ class TestMathLib : public TestFixture { // TODO: test with 128-bit values } + void isLongDoubleOutOfDoubleRange() const { + ASSERT_EQUALS(true, MathLib::isLongDoubleOutOfDoubleRange("1e400L")); + ASSERT_EQUALS(true, MathLib::isLongDoubleOutOfDoubleRange("1.0e4931l")); + ASSERT_EQUALS(false, MathLib::isLongDoubleOutOfDoubleRange("1e300L")); + ASSERT_EQUALS(false, MathLib::isLongDoubleOutOfDoubleRange("1e10000")); + ASSERT_EQUALS(false, MathLib::isLongDoubleOutOfDoubleRange("1e10000f")); + ASSERT_EQUALS(false, MathLib::isLongDoubleOutOfDoubleRange("10L")); + ASSERT_EQUALS(false, MathLib::isLongDoubleOutOfDoubleRange("")); + } + void toDoubleNumber() const { // float values ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1."), 0.001); @@ -677,6 +689,13 @@ class TestMathLib : public TestFixture { ASSERT_EQUALS_DOUBLE(static_cast('\200'), MathLib::toDoubleNumber("'\\200'"), 0.000001); ASSERT_EQUALS_DOUBLE(static_cast(L'A'), MathLib::toDoubleNumber("L'A'"), 0.000001); + // out of the range of double, like glibc's HUGE_VAL for compilers other than GCC + ASSERT_EQUALS(true, std::isinf(MathLib::toDoubleNumber("1e10000"))); + ASSERT_EQUALS(true, std::isinf(MathLib::toDoubleNumber("1e10000f"))); + ASSERT_EQUALS(true, std::isinf(MathLib::toDoubleNumber("1e10000L"))); + ASSERT_EQUALS(true, std::isinf(MathLib::toDoubleNumber("1.5E+400"))); + ASSERT_EQUALS(true, std::isinf(MathLib::toDoubleNumber("1.0e4931L"))); // #12282 + ASSERT_THROW_INTERNAL_EQUALS(MathLib::toDoubleNumber("invalid"), INTERNAL, "Internal Error. MathLib::toDoubleNumber: conversion failed: invalid"); // AppleClang before 18 reports a different error diff --git a/test/testother.cpp b/test/testother.cpp index ac0d3d5040e..e07a919dc79 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -204,6 +204,7 @@ class TestOther : public TestFixture { TEST_CASE(duplicateExpression20); TEST_CASE(duplicateExpression21); TEST_CASE(duplicateExpression22); + TEST_CASE(duplicateExpression23); // #12282 TEST_CASE(duplicateExpressionLoop); TEST_CASE(duplicateValueTernary); TEST_CASE(duplicateValueTernarySizeof); // #13773 @@ -8498,6 +8499,17 @@ class TestOther : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void duplicateExpression23() { // #12282 + // long double literals out of the range of double are different values + check("long double f() {\n" + " return 1e400L / 1e500L;\n" + "}\n" + "int g(long double x) {\n" + " return x == 1e400L || x == 1e500L;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } + void duplicateExpression22() { check("int f() {\n" // #14913 " return 0x1 | (0x2 | 0x4) | 0x1;\n" From 82b2d36d7b9c8242c893ff156a26552f45f8df64 Mon Sep 17 00:00:00 2001 From: nussaibah shaikh Date: Sun, 25 Oct 2026 23:49:21 +0530 Subject: [PATCH 14/32] Fix #15133 (MSBuild System.Math: out-of-range double to long long cast UB in fmtDouble/Round) (#8950) fmtDouble and the Round branch in ImportProject::applyMSBuildStaticFunction cast the double result of a System.Math property function to long long without a range check, so a project value like `$([System.Math]::Pow(10,30))` or `$([System.Math]::Round(1e30))` is undefined behaviour (UBSan float-cast-overflow, as noted in the AI review on #8938). fmtDouble now takes the integer path only when the value fits in long long, and Round does its half-to-even step in double and formats through fmtDouble, so in-range results are unchanged and Round(1e30) gives the same text as Pow(10,30) instead of LLONG_MIN (out-of-range values still print via std::to_string rather than MSBuild's `1E+30`, which is left for a separate change). Tested with new asserts in testMSBuildStaticFunctions, the full testrunner, and `cppcheck --project` on a crafted vcxproj with a UBSan build. I don't have Trac access, so could you create a ticket for this one? --- lib/importproject.cpp | 23 ++++++++++++----------- test/testimportproject.cpp | 6 ++++++ 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 24597834694..10cc86da96d 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -1406,9 +1406,12 @@ std::string ImportProject::applyMSBuildStaticFunction(const std::string &classNa // Format a double as an integer string when the value is whole, // otherwise use std::to_string (which gives 6 decimal places). const auto fmtDouble = [](double d) -> std::string { - const auto i = static_cast(d); - if (!(static_cast(i) < d) && !(static_cast(i) > d)) - return std::to_string(i); + // Converting a double outside the long long range is undefined behaviour + if (d >= static_cast(LLONG_MIN) && d < -static_cast(LLONG_MIN)) { + const auto i = static_cast(d); + if (!(static_cast(i) < d) && !(static_cast(i) > d)) + return std::to_string(i); + } return std::to_string(d); }; if (args.size() == 1) { @@ -1425,16 +1428,14 @@ std::string ImportProject::applyMSBuildStaticFunction(const std::string &classNa // not round-half-away-from-zero. const double fl = std::floor(x); const double frac = x - fl; - long long rounded; + double rounded; if (frac < 0.5) - rounded = static_cast(fl); + rounded = fl; else if (frac > 0.5) - rounded = static_cast(fl) + 1; - else { // exactly 0.5 -- round to nearest even integer - const auto ifl = static_cast(fl); - rounded = ((ifl % 2) == 0) ? ifl : ifl + 1; - } - return std::to_string(rounded); + rounded = fl + 1; + else // exactly 0.5 -- round to nearest even integer + rounded = (std::fabs(std::fmod(fl, 2.0)) < 1) ? fl : fl + 1; + return fmtDouble(rounded); } if (caseInsensitiveStringCompare(member, "Sqrt") == 0 && x >= 0) return fmtDouble(std::sqrt(x)); diff --git a/test/testimportproject.cpp b/test/testimportproject.cpp index 2ecdf677381..47d756db563 100644 --- a/test/testimportproject.cpp +++ b/test/testimportproject.cpp @@ -1327,6 +1327,12 @@ class TestImportProject : public TestFixture { ASSERT_EQUALS("5", cppcheck::testing::expandMSBuildExpression("$([System.Math]::Abs(5))")); ASSERT_EQUALS("2", cppcheck::testing::expandMSBuildExpression("$([System.Math]::Floor(2.9))")); ASSERT_EQUALS("3", cppcheck::testing::expandMSBuildExpression("$([System.Math]::Ceiling(2.1))")); + ASSERT_EQUALS("2", cppcheck::testing::expandMSBuildExpression("$([System.Math]::Round(2.5))")); + ASSERT_EQUALS("4", cppcheck::testing::expandMSBuildExpression("$([System.Math]::Round(3.5))")); + ASSERT_EQUALS("-2", cppcheck::testing::expandMSBuildExpression("$([System.Math]::Round(-2.5))")); + ASSERT_EQUALS("1000000000000000019884624838656.000000", cppcheck::testing::expandMSBuildExpression("$([System.Math]::Pow(10, 30))")); + ASSERT_EQUALS("1000000000000000019884624838656.000000", cppcheck::testing::expandMSBuildExpression("$([System.Math]::Round(1e30))")); + ASSERT_EQUALS("-1000000000000000019884624838656.000000", cppcheck::testing::expandMSBuildExpression("$([System.Math]::Floor(-1e30))")); // --- $([System.IO.Path]::...) --- ASSERT_EQUALS("bar.cpp", cppcheck::testing::expandMSBuildExpression("$([System.IO.Path]::GetFileName('C:/foo/bar.cpp'))")); From ffb2670c413d3a9264caa8c91267de0fcb4c433b Mon Sep 17 00:00:00 2001 From: autoantwort <41973254+autoantwort@users.noreply.github.com> Date: Sun, 25 Oct 2026 19:22:34 +0100 Subject: [PATCH 15/32] Fix #15094 SymbolDatabase: Variable::isReference() is true for function pointer returning a reference (#8931) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://trac.cppcheck.net/ticket/15094 For a function pointer returning a reference, the reference of the return type was taken as reference of the variable: ```cpp struct S { std::string& (*f)(int, int); int& (*g[2])(); }; void foo(int& (*fp)(), int&& (*fp2)()); ``` `Variable::isReference()` (and `isRValueReference()` for `fp2`) was true for all of them. `Variable::evaluate()` now drops the reference collected before the `(` of a function declarator, as it belongs to the return type. A `&` after the `(` still makes the variable a reference, so `int (*&f)()`, `int (&f)()`, `int*& r`, `int (&a)[2]` and `int& (r)` are unchanged. The `ValueType` of the function pointer is not changed: the type of a call `fp()` is derived from it, so its reference has to stay the one of the return type (clearing it caused `returnTempReference` FPs). Two places relied on the wrong flags and are adjusted: - `checkConstVariable`: a reference to a function returning a reference (`int& (&f)()`) was skipped only because it was wrongly flagged as rvalue reference. References to functions are now skipped explicitly (this also fixes the existing FP for `int (&f)()`). - Copy/move constructor detection: `Foo(Foo&& (*f)())` was a move constructor. With the fix it is a normal constructor, and parameters that are references to functions (`Foo(Foo& (&f)())`) no longer make a copy/move constructor either. Found with #8910, where it suppressed `uninitMemberVarNoCtor` for a struct with such a member (codelite in the PR test results). #8910 contains a workaround in CheckClass for this; with this PR merged it can be replaced by `var.isReference()` again. This PR was created by Claude Code (an AI coding agent) on behalf of @autoantwort. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 --- lib/checkother.cpp | 2 + lib/symboldatabase.cpp | 7 ++- test/testautovariables.cpp | 18 ++++++++ test/testother.cpp | 11 +++++ test/testsymboldatabase.cpp | 87 +++++++++++++++++++++++++++++++++++++ 5 files changed, 124 insertions(+), 1 deletion(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 4476814fcbb..a67475f45ee 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1783,6 +1783,8 @@ void CheckOtherImpl::checkConstVariable() continue; if (var->isConst()) continue; + if (Tokenizer::isFunctionPointer(var->nameToken())) // reference to function + continue; const Scope* scope = var->scope(); if (!scope) continue; diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index c1cd75f2e00..540ec5ca5da 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -917,7 +917,8 @@ void SymbolDatabase::createSymbolDatabaseCopyAndMoveConstructors() continue; const Variable* firstArg = func->getArgumentVar(0); - if (firstArg->type() == scope.definedType) { + // skip references to functions: Foo(Foo& (&f)()) + if (firstArg->type() == scope.definedType && !Token::Match(firstArg->typeEndToken(), "&|&& %name%| ) (")) { if (firstArg->isRValueReference()) func->type = FunctionType::eMoveConstructor; else if (firstArg->isReference() && !firstArg->isPointer()) @@ -2596,6 +2597,10 @@ void Variable::evaluate(const Settings& settings) } else if (tok->str() == "&&") { // Before simplification, && isn't split up setFlag(fIsRValueRef, true); setFlag(fIsReference, true); // Set also fIsReference + } else if (tok->str() == "(" && Token::simpleMatch(tok->link(), ") (")) { + // a reference before the parentheses belongs to the return type of a function pointer: int& (*f)() + setFlag(fIsRValueRef, false); + setFlag(fIsReference, false); } if (tok->str() == "<" && tok->link()) diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index d1bc3bf830f..a2fa4168ea8 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -133,6 +133,7 @@ class TestAutoVariables : public TestFixture { TEST_CASE(returnReference27); TEST_CASE(returnReference28); TEST_CASE(returnReference29); + TEST_CASE(returnReference30); // #15094 TEST_CASE(returnReferenceFunction); TEST_CASE(returnReferenceContainer); TEST_CASE(returnReferenceLiteral); @@ -1772,6 +1773,23 @@ class TestAutoVariables : public TestFixture { errout_str()); } + void returnReference30() // #15094 + { + check("int& f1(int& (*fp)()) { return fp(); }\n" + "void f2(int& (*fp)()) { int& r = fp(); r = 2; }\n" + "struct D {\n" + " int& call() { return f(); }\n" + " int& (*f)();\n" + "};\n" + "const int& f3(const int& (*fp)(int)) { return fp(1); }\n" + "int& (*g)();\n" + "int& f4() { return g(); }\n" + "typedef int& (*FP)();\n" + "int& f5(FP fp) { return fp(); }\n" + "int* f6(int& (*fp)()) { return &fp(); }\n"); + ASSERT_EQUALS("", errout_str()); + } + void returnReferenceFunction() { check("int& f(int& a) {\n" " return a;\n" diff --git a/test/testother.cpp b/test/testother.cpp index e07a919dc79..9c02c017e9f 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -4226,6 +4226,17 @@ class TestOther : public TestFixture { " int select(DS &ds) { return select(ds, [](int) {}); }\n" "};\n"); ASSERT_EQUALS("", errout_str()); + + check("int& g();\n" // reference to function + "int k();\n" + "int f1() { int& (&r)() = g; return r(); }\n" + "int f2() { int (&r)() = k; return r(); }\n" + "int& f3(int& (&f)()) { return f(); }\n" + "int f4(int&& (&f)()) { return f(); }\n" + "int f5(int (&f)()) { return f(); }\n" + "using FR = int&(&)();\n" + "void f6(FR f) { f(); }\n"); + ASSERT_EQUALS("", errout_str()); } void constParameterCallback() { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index fb89e164a74..85ee8430a77 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -1603,6 +1603,66 @@ class TestSymbolDatabase : public TestFixture { ASSERT(p->valueType()->originalTypeName == "ubFunctionPointer_fp"); ASSERT(p->valueType()->reference == Reference::None); } + { // function pointer returning a reference + GET_SYMBOL_DB("void foo(int& (*f)()) {}\n"); + const Variable* const p = db->getVariableFromVarId(1); + ASSERT(!p->isReference()); + ASSERT(p->isPointer()); + ASSERT(p->valueType()); + ASSERT(p->valueType()->pointer == 1); + } + { + GET_SYMBOL_DB("void foo(int&& (*f)()) {}\n"); + const Variable* const p = db->getVariableFromVarId(1); + ASSERT(!p->isReference()); + ASSERT(!p->isRValueReference()); + } + { + GET_SYMBOL_DB("struct S { int& (*f[2])(); };\n"); + const Variable* const p = db->getVariableFromVarId(1); + ASSERT(!p->isReference()); + ASSERT(p->isArray()); + } + { // pointer to member function returning a reference + GET_SYMBOL_DB("struct S { int& g(); };\n" + "void foo(int& (S::*pm)()) {}\n"); + const Variable* const p = db->getVariableFromVarId(1); + ASSERT(p); + ASSERT_EQUALS("pm", p->name()); + ASSERT(!p->isReference()); + } + { // parentheses that are no function declarator + GET_SYMBOL_DB("void foo(int& (r)) {}\n"); + const Variable* const p = db->functionScopes.front()->function->getArgumentVar(0); + ASSERT(p); + ASSERT(p->isReference()); + } + { + GET_SYMBOL_DB("void foo(int& UNUSED(r)) {}\n"); + const Variable* const p = db->functionScopes.front()->function->getArgumentVar(0); + ASSERT(p); + ASSERT(p->isReference()); + } + { // reference to function pointer + GET_SYMBOL_DB("void foo(int (*&f)()) {}\n"); + const Variable* const p = db->getVariableFromVarId(1); + ASSERT(p->isReference()); + ASSERT(p->isPointer()); + ASSERT(p->valueType()); + ASSERT(p->valueType()->reference == Reference::LValue); + } + { // reference to function returning a reference + GET_SYMBOL_DB("void foo(int& (&f)()) {}\n"); + const Variable* const p = db->getVariableFromVarId(1); + ASSERT(p->isReference()); + ASSERT(!p->isRValueReference()); + } + { + GET_SYMBOL_DB("void foo(int&& (&f)()) {}\n"); + const Variable* const p = db->getVariableFromVarId(1); + ASSERT(p->isReference()); + ASSERT(!p->isRValueReference()); + } } void VariableValueTypeTemplate() { @@ -2411,6 +2471,31 @@ class TestSymbolDatabase : public TestFixture { ASSERT(db && ctor && ctor->type == FunctionType::eMoveConstructor); ASSERT(ctor && ctor->retDef == nullptr); } + { + GET_SYMBOL_DB("class Foo { Foo(Foo&& (*f)()); };\n"); + const Function* ctor = tokenizer.tokens()->tokAt(3)->function(); + ASSERT(db && ctor && ctor->type == FunctionType::eConstructor); + } + { + GET_SYMBOL_DB("class Foo { Foo(Foo& (&f)()); };\n"); + const Function* ctor = tokenizer.tokens()->tokAt(3)->function(); + ASSERT(db && ctor && ctor->type == FunctionType::eConstructor); + } + { + GET_SYMBOL_DB("class Foo { Foo(Foo&& (&f)()); };\n"); + const Function* ctor = tokenizer.tokens()->tokAt(3)->function(); + ASSERT(db && ctor && ctor->type == FunctionType::eConstructor); + } + { + GET_SYMBOL_DB("class Foo { Foo(Foo (&f)()); };\n"); + const Function* ctor = tokenizer.tokens()->tokAt(3)->function(); + ASSERT(db && ctor && ctor->type == FunctionType::eConstructor); + } + { + GET_SYMBOL_DB("class Foo { Foo(Foo& (&)()); };\n"); + const Function* ctor = tokenizer.tokens()->tokAt(3)->function(); + ASSERT(db && ctor && ctor->type == FunctionType::eConstructor); + } { GET_SYMBOL_DB("void f() { extern void f(); }\n"); ASSERT(db && db->scopeList.size() == 2); @@ -9987,6 +10072,8 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS("signed long", typeOf("a = (long)32;\n", "(")); ASSERT_EQUALS("signed long", typeOf("a = (long int)32;\n", "(")); ASSERT_EQUALS("signed long long", typeOf("a = (long long)32;\n", "(")); + ASSERT_EQUALS("signed int &", typeOf("void f(int& (*fp)()) { fp(); }\n", "( ) ;")); // #15094 + ASSERT_EQUALS("signed int &&", typeOf("void f(int&& (*fp)()) { fp(); }\n", "( ) ;")); ASSERT_EQUALS("long double", typeOf("a = (long double)32;\n", "(")); ASSERT_EQUALS("char", typeOf("a = static_cast(32);\n", "(")); ASSERT_EQUALS("", typeOf("a = (unsigned x)0;\n", "(")); From 4095821f000827fdf79982fdd12ced71925863cc Mon Sep 17 00:00:00 2001 From: nussaibah shaikh Date: Sun, 25 Oct 2026 23:55:58 +0530 Subject: [PATCH 16/32] htmlreport: escape message and file name in generated pages (#8920) AnnotateCodeFormatter.wrap put the error message into the annotated source page, and main put the file name into the index, stats and per-file pages, without html_escape, so text from the checked code such as `#error ` or a file named `x.c` became live markup in the report; both now go through html_escape like the verbose text and the index message already do, and test_htmlreport.py has a test for it. --- htmlreport/cppcheck-htmlreport | 18 ++++++++-------- test/tools/htmlreport/test_htmlreport.py | 26 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/htmlreport/cppcheck-htmlreport b/htmlreport/cppcheck-htmlreport index fb263c73d12..3f8d2399da1 100755 --- a/htmlreport/cppcheck-htmlreport +++ b/htmlreport/cppcheck-htmlreport @@ -620,15 +620,15 @@ class AnnotateCodeFormatter(HtmlFormatter): # from actual message if error.get('verbose') and (error['verbose'] != error['msg']): index = t.rfind('\n') - t = t[:index] + HTML_EXPANDABLE_INCONCLUSIVE % (error['msg'], html_escape(error['verbose'].replace("\\012", '\n'))) + t[index + 1:] + t = t[:index] + HTML_EXPANDABLE_INCONCLUSIVE % (html_escape(error['msg']), html_escape(error['verbose'].replace("\\012", '\n'))) + t[index + 1:] else: - t = t.replace('\n', HTML_INCONCLUSIVE % error['msg']) + t = t.replace('\n', HTML_INCONCLUSIVE % html_escape(error['msg'])) except KeyError: if error.get('verbose') and (error['verbose'] != error['msg']): index = t.rfind('\n') - t = t[:index] + HTML_EXPANDABLE_ERROR % (error['msg'], html_escape(error['verbose'].replace("\\012", '\n'))) + t[index + 1:] + t = t[:index] + HTML_EXPANDABLE_ERROR % (html_escape(error['msg']), html_escape(error['verbose'].replace("\\012", '\n'))) + t[index + 1:] else: - t = t.replace('\n', HTML_ERROR % error['msg']) + t = t.replace('\n', HTML_ERROR % html_escape(error['msg'])) line_no = line_no + 1 yield i, t @@ -824,7 +824,7 @@ def main() -> None: if is_remote: # Construct remote URL for GitHub/GitLab # tr_str() will use the actual line number, so we can just start with line 1 - remote_url = source_dir.rstrip('/') + '/' + filename + '#L1' + remote_url = source_dir.rstrip('/') + '/' + html_escape(filename) + '#L1' files[filename] = {'errors': [], 'htmlfile': remote_url} else: files[filename] = {'errors': [], 'htmlfile': str(file_no) + '.html'} @@ -900,10 +900,10 @@ def main() -> None: (options.title, htmlFormatter.get_style_defs('.highlight'), options.title, - ': ' + filename)) + ': ' + html_escape(filename))) output_file.write(HTML_HEAD_END) - output_file.write(HTML_MENU % (filename.split('/')[-1])) + output_file.write(HTML_MENU % (html_escape(filename.split('/')[-1]))) for error in sorted(errors, key=lambda k: k['line']): output_file.write(" %s %s" % (data['htmlfile'], error['line'], error['id'], error['line'])) output_file.write(HTML_MENU_END) @@ -1006,7 +1006,7 @@ def main() -> None: for filename, data in sorted(files.items()): file_error = filename in decode_errors or filename.endswith('*') is_file = filename != '' and not file_error - row_content = filename if file_error else "%s" % (data['htmlfile'], filename) + row_content = html_escape(filename) if file_error else "%s" % (data['htmlfile'], html_escape(filename)) htmlfile = data.get('htmlfile') if is_file else None output_file.write("\n ") @@ -1122,7 +1122,7 @@ def main() -> None: if it == 0: LENGTH = len(str(i[1])) # <- length of longest number, now get the difference and try to make other numbers align to it - stats_file.write(" " * 3 + str(i[1]) + " " * (1 + LENGTH - len(str(i[1]))) + " " + i[0] + "
\n") + stats_file.write(" " * 3 + str(i[1]) + " " * (1 + LENGTH - len(str(i[1]))) + " " + html_escape(i[0]) + "
\n") it += 1 if it == 10: # print only the top 10 break diff --git a/test/tools/htmlreport/test_htmlreport.py b/test/tools/htmlreport/test_htmlreport.py index f84fd279fb3..b8c73072a70 100755 --- a/test/tools/htmlreport/test_htmlreport.py +++ b/test/tools/htmlreport/test_htmlreport.py @@ -114,6 +114,32 @@ def testSeverityFilterBar(self): self.assertIn('onclick="toggleSeverity(this)"', report) output_directory.cleanup() + def testEscape(self): + with tempfile.TemporaryDirectory() as source_directory: + source_filename = os.path.join(source_directory, 'escape.c') + with open(source_filename, 'w') as source_file: + source_file.write('#error escape\n') + + with runCheck( + source_filename, + xml_version='2' + ) as (report, output_directory): + self.assertIn('<b>escape.c', report) + self.assertNotIn('', report) + + with open(os.path.join(output_directory.name, '0.html')) as input_file: + detail_contents = input_file.read() + self.assertIn('<b>escape.c', detail_contents) + self.assertIn('<--- #error <b>escape</b>', detail_contents) + self.assertNotIn('', detail_contents) + + with open(os.path.join(output_directory.name, 'stats.html')) as input_file: + stats_contents = input_file.read() + self.assertIn('<b>escape.c', stats_contents) + self.assertNotIn('', stats_contents) + + output_directory.cleanup() + @contextlib.contextmanager def runCheck(source_filename=None, xml_version='1', xml_filename=None, checkers_filename=None): From a41a1738c803e50484efc89b4d3e2c996e387be0 Mon Sep 17 00:00:00 2001 From: autoantwort <41973254+autoantwort@users.noreply.github.com> Date: Sun, 25 Oct 2026 19:43:04 +0100 Subject: [PATCH 17/32] Fix #15080 FP uninitMemberVarNoCtor for const and reference members (#8910) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://trac.cppcheck.net/ticket/15080 ```cpp struct S { const std::array a; const std::vector::const_iterator it; }; S f(const std::vector& v) { return S{ {}, v.cbegin() }; } ``` gives `Member variable 'S::it' has no initializer. [uninitMemberVarNoCtor]`, and `struct S { int a = 0; const int b; int& c; };` warns for `b` and `c`. A non-static const or reference member without default member initializer can't stay uninitialized: for trivial types the implicit default constructor is deleted, so every instance must initialize it, and a const class type is default-constructed. These members are now skipped by the no-constructor check. Since f90a76ff3 (#15072) this also shows up for class templates whose member type is a `using` alias. This PR was created by Claude Code (an AI coding agent) on behalf of @autoantwort. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com> --- lib/checkclass.cpp | 12 +++++- test/testconstructors.cpp | 84 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 0f02016bd01..6f5bcd3a69e 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -347,19 +347,25 @@ void CheckClassImpl::constructors() // Variables with default initializers bool hasAnyDefaultInit = false; bool hasAnySelfInit = false; + bool isDefaultConstructible = true; const bool cpp14OrLater = mSettings.standards.cpp >= Standards::CPP14; for (Usage& usage : usageList) { const Variable& var = *usage.var; + // isReference() is also true for a function pointer that returns a reference + const bool isReferenceMember = var.isReference() && var.nameToken() && Token::Match(var.nameToken()->previous(), "&|&&"); // check for C++11 initializer if (var.hasDefault()) { usage.init = true; hasAnyDefaultInit = true; + } else if (!var.isStatic() && (isReferenceMember || (var.isConst() && !var.isClass()))) { + // the default constructor is deleted, so all members are initialized by every instance + isDefaultConstructible = false; } else if (cpp14OrLater && !hasAnySelfInit && isInitialized(usage, FunctionType::eConstructor)) { hasAnySelfInit = true; } } - if (!hasAnyDefaultInit && !hasAnySelfInit) + if (!isDefaultConstructible || (!hasAnyDefaultInit && !hasAnySelfInit)) continue; handleUnionMembers(usageList); @@ -373,6 +379,10 @@ void CheckClassImpl::constructors() if (var.typeScope() && var.typeScope()->numConstructors > 0) continue; + // a const member of class type is default constructed or makes the class not default constructible + if (var.isConst()) + continue; + if (diagVars.count(&var) == 0) uninitVarError(var.nameToken(), false, FunctionType::eConstructor, var.scope()->className, var.name(), false, false, true); } diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 4de49f54311..1f512b52478 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -797,6 +797,90 @@ class TestConstructors : public TestFixture { ASSERT_EQUALS("[test.cpp:4:9]: (warning) Member variable 'T::j' has no initializer. [uninitMemberVarNoCtor]\n" "[test.cpp:8:9]: (warning) Member variable 'U::k' has no initializer. [uninitMemberVarNoCtor]\n", errout_str()); + + check("struct S {\n" // #15080 + " int a = 0;\n" + " const int b;\n" + " int k;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct S {\n" + " int a = 0;\n" + " int& c;\n" + " int k;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct S {\n" + " int a = 0;\n" + " const int* d;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:3:16]: (warning) Member variable 'S::d' has no initializer. [uninitMemberVarNoCtor]\n", errout_str()); + + check("struct S {\n" + " int a = 0;\n" + " int* const p;\n" + " int k;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct S {\n" // static members don't affect the default constructor + " int a = 0;\n" + " static const int N;\n" + " static int& r;\n" + " int k;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:5:9]: (warning) Member variable 'S::k' has no initializer. [uninitMemberVarNoCtor]\n", errout_str()); + + check("struct S {\n" // function pointers returning a reference are no references + " int a = 0;\n" + " std::string& (*f)(int, int);\n" + " int& (*g[2])();\n" + " int k;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:3:20]: (warning) Member variable 'S::f' has no initializer. [uninitMemberVarNoCtor]\n" + "[test.cpp:4:12]: (warning) Member variable 'S::g' has no initializer. [uninitMemberVarNoCtor]\n" + "[test.cpp:5:9]: (warning) Member variable 'S::k' has no initializer. [uninitMemberVarNoCtor]\n", + errout_str()); + + check("struct S {\n" + " int a = 0;\n" + " int (*&f)();\n" + " int k;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct S {\n" + " int a = 0;\n" + " int (&arr)[2];\n" + " int k;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + check("typedef const unsigned int Mode;\n" + "struct S {\n" + " std::vector v;\n" + " Mode m;\n" + " int k;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct S {\n" + " std::string a;\n" + " const std::string s;\n" + " int k;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:4:9]: (warning) Member variable 'S::k' has no initializer. [uninitMemberVarNoCtor]\n", errout_str()); + + check("struct S {\n" + " const std::array a;\n" + " const std::vector::const_iterator it;\n" + "};\n" + "S f(const std::vector& v) {\n" + " return S{ {}, v.cbegin() };\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } // ticket #4290 "False Positive: style (noConstructor): The class 'foo' does not have a constructor." From 722ef6a253c0bb0bdb9c7ae2a39200c59308efe3 Mon Sep 17 00:00:00 2001 From: nussaibah shaikh Date: Mon, 26 Oct 2026 01:59:47 +0530 Subject: [PATCH 18/32] Fix #15123: clang import: reject AST nodes without the ext tokens the handlers read (#8948) Follow-up to #8939. Several `createTokens` handlers call `mExtTokens.back()`/`front()` or index relative to `size()` without checking that the node line had any ext tokens, so a `--clang` dump line with nothing after the node name (e.g. `` `-IntegerLiteral `` followed by a space) reads out of bounds. The same happens for StringLiteral, CharacterLiteral, CXXBoolLiteralExpr, LabelStmt, EnumDecl, DeclRefExpr and others, for a VarDecl that only has an address (`mExtTokens[typeIndex - 1]` with `typeIndex` 0), and for a FunctionDecl ending in `prev` (dereferences `end()`). The AstNode constructor now throws an AST internal error when the node has no ext tokens, and `createTokensVarDecl` / `createTokensFunctionDecl` throw the same error for the other two shapes. An address-only FunctionDecl / CXXMethodDecl / CXXConstructorDecl or EnumConstantDecl (`` `-FunctionDecl 0x1 ``) is rejected as well: `getSpelling()` is empty there, `addtoken("")` adds nothing and returns a null `back()`, so both handlers now check the spelling before adding any token. Real clang dumps always carry the node address, location, name and type, so they are unaffected (checked `--clang` on the samples and a few lib files). `crash2` now expects the internal error instead of silently producing no tokens. The size()-2 sites are guarded in #8939 and not touched here. --- lib/clangimport.cpp | 27 +++++++++++++++++++++++---- test/testclangimport.cpp | 26 +++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/lib/clangimport.cpp b/lib/clangimport.cpp index 495f01cdff4..4152839e939 100644 --- a/lib/clangimport.cpp +++ b/lib/clangimport.cpp @@ -336,7 +336,10 @@ namespace clangimport { public: AstNode(std::string nodeType, const std::string &ext, Data *data) : nodeType(std::move(nodeType)), mExtTokens(splitString(ext)), mData(data) - {} + { + if (mExtTokens.empty()) + throw InternalError(nullptr, "invalid AST node: " + this->nodeType, InternalError::AST); + } std::string nodeType; std::vector children; @@ -1052,7 +1055,10 @@ Token *clangimport::AstNode::createTokens(TokenList &tokenList) return nullptr; } if (nodeType == EnumConstantDecl) { - Token *nameToken = addtoken(tokenList, getSpelling()); + const std::string name = getSpelling(); + if (name.empty()) + throw InternalError(nullptr, "invalid AST node: " + nodeType, InternalError::AST); + Token *nameToken = addtoken(tokenList, name); auto *scope = const_cast(nameToken->scope()); scope->enumeratorList.emplace_back(nameToken->scope()); Enumerator *e = &scope->enumeratorList.back(); @@ -1388,6 +1394,10 @@ Token * clangimport::AstNode::createTokensCall(TokenList &tokenList) void clangimport::AstNode::createTokensFunctionDecl(TokenList &tokenList) { + // an address-only node has no name: addtoken("") adds nothing and would return a null back() + const std::string name = getSpelling(); + if (name.empty()) + throw InternalError(nullptr, "invalid AST node: " + nodeType, InternalError::AST); const bool prev = contains(mExtTokens, "prev"); const bool hasBody = !children.empty() && children.back()->nodeType == CompoundStmt; const bool isStatic = contains(mExtTokens, "static"); @@ -1409,11 +1419,14 @@ void clangimport::AstNode::createTokensFunctionDecl(TokenList &tokenList) if (mExtTokens.size() > 4 && mExtTokens[1] == "parent") addFullScopeNameTokens(tokenList, mData->getScope(mExtTokens[2])); - Token *nameToken = addtoken(tokenList, getSpelling() + getTemplateParameters()); + Token *nameToken = addtoken(tokenList, name + getTemplateParameters()); auto *nestedIn = const_cast(nameToken->scope()); if (prev) { - const std::string addr = *(std::find(mExtTokens.cbegin(), mExtTokens.cend(), "prev") + 1); + const auto it = std::find(mExtTokens.cbegin(), mExtTokens.cend(), "prev"); + if (it + 1 == mExtTokens.cend()) + throw InternalError(nullptr, "invalid AST node: " + nodeType, InternalError::AST); + const std::string addr = *(it + 1); mData->ref(addr, nameToken); } if (!nameToken->function()) { @@ -1460,6 +1473,9 @@ void clangimport::AstNode::createTokensFunctionDecl(TokenList &tokenList) AstNodePtr child = children[i]; if (child->nodeType != ParmVarDecl) continue; + // there must be a token between the address and the type + if (child->mExtTokens.size() < 3) + throw InternalError(nullptr, "invalid AST node: " + child->nodeType, InternalError::AST); if (tokenList.back() != par1) addtoken(tokenList, ","); const Type *recordType = addTypeTokens(tokenList, child->mExtTokens.back(), nestedIn); @@ -1562,6 +1578,9 @@ Token * clangimport::AstNode::createTokensVarDecl(TokenList &tokenList) int typeIndex = mExtTokens.size() - 1; while (typeIndex > 1 && std::isalpha(mExtTokens[typeIndex][0])) typeIndex--; + // there must be a name token between the address and the type + if (typeIndex < 2) + throw InternalError(nullptr, "invalid AST node: " + nodeType, InternalError::AST); const std::string type = mExtTokens[typeIndex]; const std::string name = mExtTokens[typeIndex - 1]; const Token *startToken = tokenList.back(); diff --git a/test/testclangimport.cpp b/test/testclangimport.cpp index bbbd75822f5..a22f901a261 100644 --- a/test/testclangimport.cpp +++ b/test/testclangimport.cpp @@ -144,6 +144,7 @@ class TestClangImport : public TestFixture { TEST_CASE(crash2); TEST_CASE(crash3); TEST_CASE(nullNodeInvalidLevel); + TEST_CASE(invalidExtTokens); } std::string parse(const char clang[]) { @@ -1421,7 +1422,7 @@ class TestClangImport : public TestFixture { // getSpelling() indexed mExtTokens[typeIndex - 1] without a lower-bound // check, so a node whose line carries no ext tokens (typeIndex <= 0) read // out of bounds. - (void)parse("`-RecordDecl "); // don't crash + ASSERT_THROW_INTERNAL_EQUALS(parse("`-RecordDecl "), AST, "invalid AST node: RecordDecl"); } void nullNodeInvalidLevel() { @@ -1442,6 +1443,29 @@ class TestClangImport : public TestFixture { " `-CXXRecordDecl 0x2\n"); // don't crash (void)parse("`-CXXRecordDecl 0x1"); // don't crash } + + void invalidExtTokens() { + // nodes without the ext tokens the handlers read must not index out of bounds + ASSERT_THROW_INTERNAL_EQUALS(parse("`-FunctionDecl 0x1 col:5 f 'int ()'\n" + " `-CompoundStmt 0x2 \n" + " `-ReturnStmt 0x3 \n" + " `-IntegerLiteral \n"), AST, "invalid AST node: IntegerLiteral"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-EnumDecl "), AST, "invalid AST node: EnumDecl"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-VarDecl 0x1"), AST, "invalid AST node: VarDecl"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-VarDecl 0x1 'int'"), AST, "invalid AST node: VarDecl"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-VarDecl 0x1 "), AST, "invalid AST node: VarDecl"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-FieldDecl 0x1 'int'"), AST, "invalid AST node: FieldDecl"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-FunctionDecl 0x1 col:5 f 'int ()' prev"), AST, "invalid AST node: FunctionDecl"); + // address-only declarations: getSpelling() is empty, addtoken() adds nothing and back() is null + ASSERT_THROW_INTERNAL_EQUALS(parse("`-FunctionDecl 0x1"), AST, "invalid AST node: FunctionDecl"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-CXXConstructorDecl 0x1"), AST, "invalid AST node: CXXConstructorDecl"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-CXXMethodDecl 0x1"), AST, "invalid AST node: CXXMethodDecl"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-EnumConstantDecl 0x1"), AST, "invalid AST node: EnumConstantDecl"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-FunctionDecl 0x1 col:5 f 'int ()'\n" + " `-ParmVarDecl 0x2 \n"), AST, "invalid AST node: ParmVarDecl"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-FunctionDecl 0x1 col:5 f 'int ()'\n" + " `-ParmVarDecl 0x2 'int'\n"), AST, "invalid AST node: ParmVarDecl"); + } }; REGISTER_TEST(TestClangImport) From 15fafef7f6eceb13658ebaaba2726904d2a6585d Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 26 Oct 2026 07:28:16 +0100 Subject: [PATCH 19/32] Fix #15124 FN bufferAccessOutOfBounds with wmemcpy() (#8951) Co-authored-by: chrchr-github --- cfg/gnu.cfg | 6 +++--- cfg/std.cfg | 16 ++++++++-------- test/cfg/gnu.c | 7 +++++++ test/cfg/std.c | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 11 deletions(-) diff --git a/cfg/gnu.cfg b/cfg/gnu.cfg index 9a0b1652d32..af2fff93e59 100644 --- a/cfg/gnu.cfg +++ b/cfg/gnu.cfg @@ -650,7 +650,7 @@ - + @@ -659,12 +659,12 @@ - + - + diff --git a/cfg/std.cfg b/cfg/std.cfg index 6dcf0f9f6b3..99377575428 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -3928,7 +3928,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + @@ -3974,12 +3974,12 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + - + @@ -4016,12 +4016,12 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + - + @@ -4081,13 +4081,13 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + - + @@ -4141,7 +4141,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + diff --git a/test/cfg/gnu.c b/test/cfg/gnu.c index 42b37036411..830618c241d 100644 --- a/test/cfg/gnu.c +++ b/test/cfg/gnu.c @@ -376,6 +376,13 @@ wchar_t *nullPointer_wmempcpy(wchar_t *dest, const wchar_t *src, size_t n) return wmempcpy(dest,src,n); } +void bufferAccessOutOfBounds_wmempcpy(const wchar_t *src) +{ + wchar_t buf[3]; + // cppcheck-suppress bufferAccessOutOfBounds + wmempcpy(buf, src, 5); +} + int uninitvar_getpw(uid_t uid, char *buf) { uid_t someUid; diff --git a/test/cfg/std.c b/test/cfg/std.c index 5d2e6180a4c..a8914d608a9 100644 --- a/test/cfg/std.c +++ b/test/cfg/std.c @@ -619,6 +619,20 @@ void bufferAccessOutOfBounds_wcsncpy() wcsncpy(s, L"abc", 17); } +void bufferAccessOutOfBounds_wmemcpy() +{ + wchar_t a[4]; + // cppcheck-suppress bufferAccessOutOfBounds + wmemcpy(a, L"abcd", 5); +} + +int bufferAccessOutOfBounds_wmemcmp(const wchar_t* b) +{ + const wchar_t a[4] = { L'a', L'b', L'c', L'd' }; + // cppcheck-suppress bufferAccessOutOfBounds + return wmemcmp(a, b, 5); +} + int nullPointer_wcsncmp(const wchar_t* s1, const wchar_t* s2, size_t n) { // cppcheck-suppress nullPointer @@ -2940,6 +2954,27 @@ void *bufferAccessOutOfBounds_memchr(const void *s, int c, size_t n) return memchr(s,c,n); } +bool bufferAccessOutOfBounds_wmemchr(wchar_t c) +{ + const wchar_t buf[] = {'a', 'b', 'c'}; + // cppcheck-suppress bufferAccessOutOfBounds + return wmemchr(buf, c, 5) != NULL; +} + +void bufferAccessOutOfBounds_wmemset(wchar_t c) +{ + wchar_t buf[3]; + // cppcheck-suppress bufferAccessOutOfBounds + wmemset(buf, c, 5); +} + +void bufferAccessOutOfBounds_wmemmove(const wchar_t* s) +{ + wchar_t d[3]; + // cppcheck-suppress bufferAccessOutOfBounds + wmemmove(d, s, 5); +} + void uninitvar_wmemchr(void) { const wchar_t *cs; From ee25fb20ca295b44d7ab78119e11053ea1bd781f Mon Sep 17 00:00:00 2001 From: Andrew C Aitchison <45234463+andrew-aitchison@users.noreply.github.com> Date: Mon, 26 Oct 2026 06:41:23 +0000 Subject: [PATCH 20/32] strerror is now thread safe (#8648) Before glibc 2.32, `strerror`() is not MT-Safe. (from man strerror on Ubuntu 26.04). glibc 2.32 was released on 2020-08-05 and glibc 2.43 on 2026-01-24 (from https://sourceware.org/glibc/wiki/Glibc%20Timeline) This patch stops the `threadsafety.py` addon from warning about `strerror()`. `strerror` was used in `test/cli/other_test.py` to test `threadsafety.py` so we also patch that to use a different thread-unsafe function. --- addons/threadsafety.py | 2 -- test/cli/other_test.py | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/addons/threadsafety.py b/addons/threadsafety.py index 390a245d4e1..25b2c16abe3 100755 --- a/addons/threadsafety.py +++ b/addons/threadsafety.py @@ -91,7 +91,6 @@ 'race:stdin', 'race:stdout', 'race:streams', - 'race:strerror', 'race:strsignal', 'race:strtok', 'race:tmbuf', @@ -261,7 +260,6 @@ 'siginterrupt', 'sleep', 'srand48', - 'strerror', 'strsignal', 'strtok', 'tmpnam', diff --git a/test/cli/other_test.py b/test/cli/other_test.py index c86d8cd5a81..34c61f828d4 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -482,9 +482,9 @@ def test_addon_threadsafety(tmpdir): test_file = os.path.join(tmpdir, 'test.cpp') with open(test_file, 'wt') as f: f.write(""" -extern const char* f() +extern void f() { - return strerror(1); + elf_fill(1); } """) @@ -496,7 +496,7 @@ def test_addon_threadsafety(tmpdir): assert lines == [ 'Checking {} ...'.format(test_file) ] - assert stderr == '{}:4:12: warning: strerror is MT-unsafe [threadsafety-unsafe-call]\n'.format(test_file) + assert stderr == '{}:4:5: warning: elf_fill is MT-unsafe [threadsafety-unsafe-call]\n'.format(test_file) def test_addon_naming(tmpdir): From e922c9fbb69aebd72614802927fcbd21c9b5baf5 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 26 Oct 2026 07:47:51 +0100 Subject: [PATCH 21/32] Fix #15114 FP shadowVariable (global variable prior to declaration) (#8947) --- lib/checkother.cpp | 19 ++++++++++--------- test/testother.cpp | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index a67475f45ee..936169ed47d 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -4223,12 +4223,12 @@ void CheckOtherImpl::funcArgOrderDifferent(const std::string & functionName, reportError(tokens, Severity::warning, "funcArgOrderDifferent", msg, CWE683, Certainty::normal); } -static const Token *findShadowed(const Scope *scope, const Variable& var, int linenr) +static const Token *findShadowed(const Scope *scope, const Variable& var) { if (!scope) return nullptr; for (const Variable &v : scope->varlist) { - if (scope->isExecutable() && v.nameToken()->linenr() > linenr) + if ((scope->isExecutable() || scope->type == ScopeType::eGlobal) && succeeds(v.nameToken(), var.nameToken())) continue; if (v.name() == var.name()) return v.nameToken(); @@ -4242,9 +4242,9 @@ static const Token *findShadowed(const Scope *scope, const Variable& var, int li if (scope->type == ScopeType::eLambda) return nullptr; - const Token* shadowed = findShadowed(scope->nestedIn, var, linenr); + const Token* shadowed = findShadowed(scope->nestedIn, var); if (!shadowed) - shadowed = findShadowed(scope->functionOf, var, linenr); + shadowed = findShadowed(scope->functionOf, var); return shadowed; } @@ -4278,9 +4278,9 @@ void CheckOtherImpl::checkShadowVariables() } } - const Token *shadowed = findShadowed(scope.nestedIn, var, var.nameToken()->linenr()); + const Token *shadowed = findShadowed(scope.nestedIn, var); if (!shadowed) - shadowed = findShadowed(scope.functionOf, var, var.nameToken()->linenr()); + shadowed = findShadowed(scope.functionOf, var); if (!shadowed) return; if (scope.type == ScopeType::eFunction && scope.className == var.name()) @@ -4314,9 +4314,10 @@ void CheckOtherImpl::checkShadowVariables() void CheckOtherImpl::shadowError(const Token *shadows, const std::string &shadowsType, const Token *shadowed, const std::string &shadowedType) { - ErrorPath errorPath; - errorPath.emplace_back(shadowed, "Shadowed " + shadowedType); - errorPath.emplace_back(shadows, "Shadow " + shadowsType); + ErrorPath errorPath{ + {shadowed, "Shadowed " + shadowedType}, + {shadows, "Shadow " + shadowsType} + }; const std::string &varname = shadows ? shadows->str() : shadowsType; const std::string ShadowsType = char(std::toupper(shadowsType[0])) + shadowsType.substr(1); const std::string ShadowedType = char(std::toupper(shadowedType[0])) + shadowedType.substr(1); diff --git a/test/testother.cpp b/test/testother.cpp index 9c02c017e9f..fb265ae1590 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -13555,6 +13555,24 @@ class TestOther : public TestFixture { check("struct S { void g(float f) {} void f() {} };\n"); ASSERT_EQUALS("[test.cpp:1:36] -> [test.cpp:1:25]: (style) Argument 'f' shadows outer function [shadowFunction]\n", errout_str()); + + check("int f() {\n" // #15114 + " int i = 0;\n" + " return i;\n" + "}\n" + "int i = 1;\n"); + ASSERT_EQUALS("", errout_str()); + + { + ScopedFile inc("test.h", "int pad1;\nint pad2;\nint pad3;\nint pad4;\nfloat f;\n"); + checkP("void g() {\n" + " #include \"test.h\"\n" + " {\n" + " float f;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("[test.h:5:7] -> [test.cpp:4:15]: (style) Local variable 'f' shadows outer variable [shadowVariable]\n", errout_str()); + } } void knownArgument() { From 2a82c2dc44465293472f8ae61f1464749388d96d Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 26 Oct 2026 07:55:47 +0100 Subject: [PATCH 22/32] Fix #14769 FP unreadVariable with address in chained assignment of unused variable (#8926) --- lib/checkunusedvar.cpp | 2 +- test/testunusedvar.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index 26368064c63..2add1e6eebc 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -1009,7 +1009,7 @@ void CheckUnusedVarImpl::checkFunctionVariableUsage_iterateScopes(const Scope* c const Token * const equal = skipBracketsAndMembers(tok->next()); // checked for chained assignments - if (tok != start && equal && equal->str() == "=") { + if (tok != start && (Token::simpleMatch(equal, "=") || (start->astParent() && Token::simpleMatch(start->astParent()->astParent(), "=")))) { const nonneg int varId = tok->varId(); const Variables::VariableUsage * const var = variables.find(varId); diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index f25d544c906..78ecd45ccef 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -3370,6 +3370,14 @@ class TestUnusedVar : public TestFixture { " return a;\n" "}\n"); ASSERT_EQUALS("[test.cpp:5:14]: (style) Variable 'b[c]' is assigned a value that is never used. [unreadVariable]\n", errout_str()); + + functionVariableUsage("int f() {\n" // #14769 + " int i = 2;\n" + " const int *a, *c;\n" + " a = c = &i;\n" + " return *a;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4:11]: (style) Variable 'c' is assigned a value that is never used. [unreadVariable]\n", errout_str()); } void localvar24() { // ticket #1803 From 2283e2ad0e612a1b6bd4f23ee8eeb509d6ebb44b Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 26 Oct 2026 08:45:42 +0100 Subject: [PATCH 23/32] Partial fix for #15048: shiftNegative for conditional value (#8884) --- lib/checkother.cpp | 40 +++++++++++++++++++++++----------------- lib/checkother.h | 2 +- test/testother.cpp | 19 +++++++++++++++++++ 3 files changed, 43 insertions(+), 18 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 936169ed47d..bd55de0b795 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -3530,9 +3530,11 @@ void CheckOtherImpl::redundantCopyError(const Token *tok,const std::string& varn // Checking for shift by negative values //--------------------------------------------------------------------------- -static bool isNegative(const Token *tok, const Settings &settings) +static const ValueFlow::Value* isNegative(const Token *tok, const Settings &settings) { - return tok->valueType() && tok->valueType()->sign == ValueType::SIGNED && tok->getValueLE(-1LL, settings); + if (!tok->valueType() || tok->valueType()->sign != ValueType::SIGNED) + return nullptr; + return tok->getValueLE(-1LL, settings); } void CheckOtherImpl::checkNegativeBitwiseShift() @@ -3568,24 +3570,28 @@ void CheckOtherImpl::checkNegativeBitwiseShift() if (ternary) continue; - // Get negative rhs value. preferably a value which doesn't have 'condition'. - if (portability && isNegative(tok->astOperand1(), mSettings)) - negativeBitwiseShiftError(tok, 1); - else if (isNegative(tok->astOperand2(), mSettings)) - negativeBitwiseShiftError(tok, 2); + const ValueFlow::Value* value = isNegative(tok->astOperand1(), mSettings); // lhs + if (portability && value) + negativeBitwiseShiftError(tok, true, value); + else { + value = isNegative(tok->astOperand2(), mSettings); // rhs + if (value) + negativeBitwiseShiftError(tok, false, value); + } } } -void CheckOtherImpl::negativeBitwiseShiftError(const Token *tok, int op) +void CheckOtherImpl::negativeBitwiseShiftError(const Token *tok, bool isLHS, const ValueFlow::Value* v) { - if (op == 1) - // LHS - this is used by intention in various software, if it - // is used often in a project and works as expected then this is - // a portability issue - reportError(tok, Severity::portability, "shiftNegativeLHS", "Shifting a negative value is technically undefined behaviour", CWE758, Certainty::normal); - else // RHS - reportError(tok, Severity::error, "shiftNegative", "Shifting by a negative value is undefined behaviour", CWE758, Certainty::normal); + // LHS - this is used by intention in various software, if it + // is used often in a project and works as expected then this is + // a portability issue + const char* id = isLHS ? "shiftNegativeLHS" : "shiftNegative"; + const std::string msg = isLHS ? "Shifting a negative value is technically undefined behaviour" : "Shifting by a negative value is undefined behaviour"; + const Severity severity = isLHS ? Severity::portability : (v && v->errorSeverity() && !v->conditional ? Severity::error : Severity::warning); + const ErrorPath errorPath = getErrorPath(tok, v, msg); + reportError(errorPath, severity, id, msg, CWE758, Certainty::normal); } //--------------------------------------------------------------------------- @@ -4946,8 +4952,8 @@ void CheckOther::getErrorMessages(ErrorLogger& errorLogger, const Settings &sett c.zerodivError(nullptr, nullptr); c.misusedScopeObjectError(nullptr, "varname"); c.invalidPointerCastError(nullptr, "float *", "double *", false, false); - c.negativeBitwiseShiftError(nullptr, 1); - c.negativeBitwiseShiftError(nullptr, 2); + c.negativeBitwiseShiftError(nullptr, true); + c.negativeBitwiseShiftError(nullptr, false); c.raceAfterInterlockedDecrementError(nullptr); c.invalidFreeError(nullptr, "malloc", false); c.overlappingWriteUnion(nullptr); diff --git a/lib/checkother.h b/lib/checkother.h index 823a5783fb3..61a865e9ab6 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -310,7 +310,7 @@ class CPPCHECKLIB CheckOtherImpl : public CheckImpl { void unsignedPositiveError(const Token *tok, const ValueFlow::Value *v, const std::string &varname); void pointerPositiveError(const Token *tok, const ValueFlow::Value *v); void suspiciousSemicolonError(const Token *tok); - void negativeBitwiseShiftError(const Token *tok, int op); + void negativeBitwiseShiftError(const Token *tok, bool isLHS, const ValueFlow::Value *v = nullptr); void redundantCopyError(const Token *tok, const std::string &varname); void incompleteArrayFillError(const Token* tok, const std::string& buffer, const std::string& function, bool boolean); void varFuncNullUBError(const Token *tok); diff --git a/test/testother.cpp b/test/testother.cpp index fb265ae1590..e285d8d8bd0 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -231,6 +231,7 @@ class TestOther : public TestFixture { TEST_CASE(checkRedundantCopy); TEST_CASE(checkNegativeShift); + TEST_CASE(checkNegativeShiftErrorPath); TEST_CASE(incompleteArrayFill); @@ -10537,6 +10538,24 @@ class TestOther : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void checkNegativeShiftErrorPath() { + setMultiline(); + Settings s = settings1; + s.templateLocation = "{file}:{line}:note:{info}\n"; + + check("int f(int i, bool b) {\n" + " int s = -1;\n" + " if (b)\n" + " return i;\n" + " return i << s;\n" + "}\n", dinit(CheckOptions, $.settings = &s)); + ASSERT_EQUALS("[test.cpp:5:14]: warning: Shifting by a negative value is undefined behaviour [shiftNegative]\n" + "[test.cpp:2:14]: note: Assignment 's=-1', assigned value is -1\n" + "[test.cpp:3:9]: note: Assuming condition is false\n" + "[test.cpp:5:14]: note: Shifting by a negative value is undefined behaviour\n", + errout_str()); + } + void incompleteArrayFill() { check("void f() {\n" " int a[5];\n" From 958534bd56c68f697cfefbad14d4c738c15d0e98 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 26 Oct 2026 18:10:49 +0100 Subject: [PATCH 24/32] Remove valueFlowArrayBool() (redundancy with valueFlowImpossibleValues()) (#8905) Co-authored-by: chrchr-github --- lib/valueflow.cpp | 52 ------------------------------------------ test/cli/other_test.py | 6 ++--- 2 files changed, 2 insertions(+), 56 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 96c2ba24159..7848ef4e97c 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -691,57 +691,6 @@ static void valueFlowArray(TokenList& tokenlist, const Settings& settings) } } -static bool isNonZero(const Token* tok) -{ - return tok && (!tok->hasKnownIntValue() || tok->getKnownIntValue() != 0); -} - -static const Token* getOtherOperand(const Token* tok) -{ - if (!tok) - return nullptr; - if (!tok->astParent()) - return nullptr; - if (tok->astParent()->astOperand1() != tok) - return tok->astParent()->astOperand1(); - if (tok->astParent()->astOperand2() != tok) - return tok->astParent()->astOperand2(); - return nullptr; -} - -static void valueFlowArrayBool(TokenList& tokenlist, const Settings& settings) -{ - for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { - if (tok->hasKnownIntValue()) - continue; - const Variable* var = nullptr; - bool known = false; - const auto val = - std::find_if(tok->values().cbegin(), tok->values().cend(), std::mem_fn(&ValueFlow::Value::isTokValue)); - if (val == tok->values().end()) { - var = tok->variable(); - known = true; - } else { - var = val->tokvalue->variable(); - known = val->isKnown(); - } - if (!var) - continue; - if (!var->isArray() || var->isArgument() || var->getTypeName() == "std::array") - continue; - if (isNonZero(getOtherOperand(tok)) && Token::Match(tok->astParent(), "%comp%")) - continue; - // TODO: Check for function argument - if ((astIsBool(tok->astParent()) && !Token::Match(tok->astParent(), "(|%name%")) || - (tok->astParent() && Token::Match(tok->astParent()->previous(), "if|while|for ("))) { - ValueFlow::Value value{1}; - if (known) - value.setKnown(); - setTokenValue(tok, std::move(value), settings); - } - } -} - static void valueFlowArrayElement(TokenList& tokenlist, const Settings& settings) { for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { @@ -7540,7 +7489,6 @@ void ValueFlow::setValues(TokenList& tokenlist, VFA(valueFlowSymbolicOperators(symboldatabase, settings)), VFA(valueFlowCondition(SymbolicConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions)), VFA(valueFlowSymbolicInfer(symboldatabase, settings)), - VFA(valueFlowArrayBool(tokenlist, settings)), VFA(valueFlowArrayElement(tokenlist, settings)), VFA(valueFlowRightShift(tokenlist, settings)), VFA_CPP( diff --git a/test/cli/other_test.py b/test/cli/other_test.py index 34c61f828d4..245726adad7 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -190,8 +190,6 @@ def test_progress(tmpdir): "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" @@ -1069,7 +1067,7 @@ def test_showtime_top5_summary_compdb(tmp_path): def __test_showtime_file(tmp_path, use_compdb=False, use_addons=False, use_clang_tidy=False): - exp_res = 79 + exp_res = 78 # project analysis does not call Preprocessor::getConfig() if use_compdb: exp_res -= 1 @@ -1103,7 +1101,7 @@ def test_showtime_file_clang_tidy_compdb(tmp_path): def __test_showtime_summary(tmp_path, use_compdb=False, use_addons=False, use_clang_tidy=False): - exp_res = 79 + exp_res = 78 # project analysis does not call Preprocessor::getConfig() if use_compdb: exp_res -= 1 From a777da7070abe4c2f0ba087a09a9fcb878d42556 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 26 Oct 2026 20:06:02 +0100 Subject: [PATCH 25/32] Fix #15086 syntaxError for ternary with two inequalities (#8913) --- lib/templatesimplifier.cpp | 13 +++++++++++-- test/testtokenize.cpp | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index c636cf72c43..508468c4ac7 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -394,13 +394,14 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok) return 0; if (tok->str() != "<") return 0; - if (Token::Match(tok->previous(), "%var% <")) + if (Token::Match(tok->previous(), "%var%|) <") && !(tok->linkAt(-1) && Token::simpleMatch(tok->linkAt(-1)->tokAt(-1), "operator"))) return 0; tok = tok->next(); if (!tok || tok->str() == ">") return 0; unsigned int level = 0; + unsigned int ternaryLevel = 0; while (tok) { // skip template template @@ -460,8 +461,16 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok) } // Skip '=', '?', ':' - if (Token::Match(tok, "=|?|:")) + if (Token::Match(tok, "=|?|:")) { + if (tok->str()[0] == '?') + ++ternaryLevel; + else if (tok->str()[0] == ':') { + if (ternaryLevel == 0) + return 0; + --ternaryLevel; + } tok = tok->next(); + } if (!tok) return 0; diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index cb5812e05b0..ef082afe9a7 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -240,6 +240,7 @@ class TestTokenizer : public TestFixture { TEST_CASE(vardecl33); TEST_CASE(vardecl34); TEST_CASE(vardecl35); + TEST_CASE(vardecl36); TEST_CASE(vardecl_stl_1); TEST_CASE(vardecl_stl_2); TEST_CASE(vardecl_stl_3); @@ -3051,6 +3052,38 @@ class TestTokenizer : public TestFixture { } } + void vardecl36() { + const char code[] = "struct S {\n" // #15086 + " bool f1() const;\n" + " bool f2() const;\n" + " int g() const;\n" + " int x, y;\n" + "};\n" + "bool S::f1() const {\n" + " const bool b = x ? g() < 0 : 0 > y;\n" + " return b;\n" + "}\n" + "bool S::f2() const {\n" + " const bool b = g() < x ? x != y : 0 > y;\n" + " return b;\n" + "}\n"; + const char expected[] = "struct S {\n" + "bool f1 ( ) const ;\n" + "bool f2 ( ) const ;\n" + "int g ( ) const ;\n" + "int x ; int y ;\n" + "} ;\n" + "bool S :: f1 ( ) const {\n" + "const bool b = x ? ( g ( ) < 0 ) : 0 > y ;\n" + "return b ;\n" + "}\n" + "bool S :: f2 ( ) const {\n" + "const bool b = g ( ) < x ? x != y : 0 > y ;\n" + "return b ;\n" + "}"; + ASSERT_EQUALS(expected, tokenizeAndStringify(code)); + } + void volatile_variables() { { const char code[] = "volatile int a=0;\n" From ea886b2874a80f729e11a0303eb8df96b9c5cdd4 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Tue, 27 Oct 2026 14:35:43 -0500 Subject: [PATCH 26/32] Fix 15102: Make copy-constructible classes copyable (#8705) Lots of copy constructible classes were using const and ref members which makes the classes non-copyable due to no longer supporting a copy-assignment. I replaced the ref members with a `RefThunk` class which is kind of like `std::reference_wrapper`, but it can access the member with `()` so its easier to access the members. It doesnt use `*` or `->` so it wont be confused for a possible null pointer. Now this PR doesnt replace all reference members, just for the classes that are copy-constructible. If we want to convert a class back to use reference or const members then we can delete the copy constructor and assignment. Furthermore, I enabled the clang-tidy check `cppcoreguidelines-avoid-const-or-ref-data-members` to check for these cases in the future. Here are some references explaining why this is bad practice: * https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#rc-constref * https://lesleylai.info/en/const-and-reference-member-variables/ * https://quuxplusone.github.io/blog/2022/01/23/dont-const-all-the-things/#data-members-never-const Beyond just being bad practice, this also has prevent me from doing certain things with the `ForwardAnalyzer` recently that might have improved it further such as joining or swaping a forked analyzer. I intentionally made these classes copyable for this reason(and were changed to non-copyable against [my feedback](https://github.com/cppcheck-opensource/cppcheck/pull/4868#discussion_r1127932515) as well). I understand that using references help prevent dereferencing a nullptr which is why I added a `RefThunk` class instead of using raw pointers like previously. --- .clang-tidy | 1 + Makefile | 270 +++++++++++++++++++------------------ clang-tidy.md | 1 - cli/cmdlineparser.h | 8 +- cli/processexecutor.cpp | 4 +- gui/resultitem.h | 4 +- lib/astutils.cpp | 3 +- lib/checkersreport.cpp | 18 +-- lib/checkersreport.h | 5 +- lib/checkother.cpp | 7 +- lib/checkstl.cpp | 5 +- lib/clangimport.cpp | 21 +-- lib/cppcheck.vcxproj | 1 + lib/errorlogger.h | 13 +- lib/forwardanalyzer.cpp | 27 ++-- lib/fwdanalysis.cpp | 2 +- lib/fwdanalysis.h | 3 +- lib/importproject.cpp | 12 ++ lib/preprocessor.h | 4 +- lib/programmemory.cpp | 7 +- lib/programmemory.h | 3 +- lib/refthunk.h | 61 +++++++++ lib/reverseanalyzer.cpp | 9 +- lib/symboldatabase.cpp | 32 ++--- lib/symboldatabase.h | 9 +- lib/templatesimplifier.cpp | 10 +- lib/templatesimplifier.h | 14 +- lib/token.h | 2 +- lib/tokenize.cpp | 10 +- lib/tokenize.h | 2 +- lib/tokenlist.h | 1 + lib/valueflow.cpp | 45 ++++--- lib/vf_analyzers.cpp | 11 +- oss-fuzz/Makefile | 104 +++++++------- test/fixture.cpp | 4 +- test/fixture.h | 3 +- test/helpers.h | 2 +- test/testrefthunk.cpp | 134 ++++++++++++++++++ test/testrunner.vcxproj | 1 + tools/dmake/dmake.cpp | 1 + 40 files changed, 556 insertions(+), 318 deletions(-) create mode 100644 lib/refthunk.h create mode 100644 test/testrefthunk.cpp diff --git a/.clang-tidy b/.clang-tidy index b83436861bd..aa361594f56 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -18,6 +18,7 @@ Checks: > -objc-*, -openmp-*, -zircon-*, + cppcoreguidelines-avoid-const-or-ref-data-members, cppcoreguidelines-pro-type-static-cast-downcast, cppcoreguidelines-rvalue-reference-param-not-moved, google-explicit-constructor, diff --git a/Makefile b/Makefile index e51cd58ced7..daed0997479 100644 --- a/Makefile +++ b/Makefile @@ -338,6 +338,7 @@ TESTOBJ = test/fixture.o \ test/testpreprocessor.o \ test/testprocessexecutor.o \ test/testprogrammemory.o \ + test/testrefthunk.o \ test/testregex.o \ test/testsarifreport.o \ test/testsettings.o \ @@ -483,43 +484,43 @@ check-nonneg: ###### Build -$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkuninitvar.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h +$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkuninitvar.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/refthunk.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp -$(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/tokenize.cpp -$(libcppdir)/symboldatabase.o: lib/symboldatabase.cpp lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/symboldatabase.o: lib/symboldatabase.cpp lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/symboldatabase.cpp $(libcppdir)/addoninfo.o: lib/addoninfo.cpp externals/picojson/picojson.h lib/addoninfo.h lib/config.h lib/json.h lib/path.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/addoninfo.cpp -$(libcppdir)/analyzerinfo.o: lib/analyzerinfo.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/mathlib.h lib/path.h lib/platform.h lib/standards.h lib/utils.h lib/xml.h +$(libcppdir)/analyzerinfo.o: lib/analyzerinfo.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/standards.h lib/utils.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/analyzerinfo.cpp -$(libcppdir)/astutils.o: lib/astutils.cpp lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/findtoken.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/astutils.o: lib/astutils.cpp lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/findtoken.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/astutils.cpp -$(libcppdir)/check64bit.o: lib/check64bit.cpp lib/check.h lib/check64bit.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/check64bit.o: lib/check64bit.cpp lib/check.h lib/check64bit.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/check64bit.cpp -$(libcppdir)/checkassert.o: lib/checkassert.cpp lib/astutils.h lib/check.h lib/checkassert.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkassert.o: lib/checkassert.cpp lib/astutils.h lib/check.h lib/checkassert.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkassert.cpp -$(libcppdir)/checkautovariables.o: lib/checkautovariables.cpp lib/astutils.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkautovariables.o: lib/checkautovariables.cpp lib/astutils.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkautovariables.cpp -$(libcppdir)/checkbool.o: lib/checkbool.cpp lib/astutils.h lib/check.h lib/checkbool.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkbool.o: lib/checkbool.cpp lib/astutils.h lib/check.h lib/checkbool.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbool.cpp -$(libcppdir)/checkbufferoverrun.o: lib/checkbufferoverrun.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/checkimpl.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vfvalue.h lib/xml.h +$(libcppdir)/checkbufferoverrun.o: lib/checkbufferoverrun.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/checkimpl.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbufferoverrun.cpp -$(libcppdir)/checkclass.o: lib/checkclass.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/checkclass.o: lib/checkclass.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkclass.cpp -$(libcppdir)/checkcondition.o: lib/checkcondition.cpp lib/astutils.h lib/check.h lib/checkcondition.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkcondition.o: lib/checkcondition.cpp lib/astutils.h lib/check.h lib/checkcondition.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkcondition.cpp $(libcppdir)/checkers.o: lib/checkers.cpp lib/checkers.h lib/config.h @@ -528,79 +529,79 @@ $(libcppdir)/checkers.o: lib/checkers.cpp lib/checkers.h lib/config.h $(libcppdir)/checkersidmapping.o: lib/checkersidmapping.cpp lib/checkers.h lib/config.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkersidmapping.cpp -$(libcppdir)/checkersreport.o: lib/checkersreport.cpp lib/addoninfo.h lib/checkers.h lib/checkersreport.h lib/config.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h +$(libcppdir)/checkersreport.o: lib/checkersreport.cpp lib/addoninfo.h lib/checkers.h lib/checkersreport.h lib/config.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkersreport.cpp -$(libcppdir)/checkexceptionsafety.o: lib/checkexceptionsafety.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkexceptionsafety.o: lib/checkexceptionsafety.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkexceptionsafety.cpp -$(libcppdir)/checkfunctions.o: lib/checkfunctions.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkfunctions.o: lib/checkfunctions.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkfunctions.cpp -$(libcppdir)/checkimpl.o: lib/checkimpl.cpp lib/checkers.h lib/checkimpl.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkimpl.o: lib/checkimpl.cpp lib/checkers.h lib/checkimpl.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkimpl.cpp -$(libcppdir)/checkinternal.o: lib/checkinternal.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkinternal.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkinternal.o: lib/checkinternal.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkinternal.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkinternal.cpp -$(libcppdir)/checkio.o: lib/checkio.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkio.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkio.o: lib/checkio.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkio.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkio.cpp -$(libcppdir)/checkleakautovar.o: lib/checkleakautovar.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkleakautovar.o: lib/checkleakautovar.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkleakautovar.cpp -$(libcppdir)/checkmemoryleak.o: lib/checkmemoryleak.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkmemoryleak.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkmemoryleak.o: lib/checkmemoryleak.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkmemoryleak.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkmemoryleak.cpp -$(libcppdir)/checknullpointer.o: lib/checknullpointer.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checknullpointer.o: lib/checknullpointer.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checknullpointer.cpp -$(libcppdir)/checkother.o: lib/checkother.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkother.o: lib/checkother.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkother.cpp -$(libcppdir)/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkpostfixoperator.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkpostfixoperator.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkpostfixoperator.cpp -$(libcppdir)/checks.o: lib/checks.cpp lib/check.h lib/check64bit.h lib/checkassert.h lib/checkautovariables.h lib/checkbool.h lib/checkbufferoverrun.h lib/checkclass.h lib/checkcondition.h lib/checkexceptionsafety.h lib/checkfunctions.h lib/checkimpl.h lib/checkinternal.h lib/checkio.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/checkother.h lib/checkpostfixoperator.h lib/checks.h lib/checksizeof.h lib/checkstl.h lib/checkstring.h lib/checktype.h lib/checkuninitvar.h lib/checkunusedvar.h lib/checkvaarg.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/standards.h lib/vfvalue.h +$(libcppdir)/checks.o: lib/checks.cpp lib/check.h lib/check64bit.h lib/checkassert.h lib/checkautovariables.h lib/checkbool.h lib/checkbufferoverrun.h lib/checkclass.h lib/checkcondition.h lib/checkexceptionsafety.h lib/checkfunctions.h lib/checkimpl.h lib/checkinternal.h lib/checkio.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/checkother.h lib/checkpostfixoperator.h lib/checks.h lib/checksizeof.h lib/checkstl.h lib/checkstring.h lib/checktype.h lib/checkuninitvar.h lib/checkunusedvar.h lib/checkvaarg.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/refthunk.h lib/standards.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checks.cpp -$(libcppdir)/checksizeof.o: lib/checksizeof.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checksizeof.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checksizeof.o: lib/checksizeof.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checksizeof.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checksizeof.cpp -$(libcppdir)/checkstl.o: lib/checkstl.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/checkstl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/pathanalysis.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkstl.o: lib/checkstl.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/checkstl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/pathanalysis.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstl.cpp -$(libcppdir)/checkstring.o: lib/checkstring.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstring.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkstring.o: lib/checkstring.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstring.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstring.cpp -$(libcppdir)/checktype.o: lib/checktype.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checktype.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checktype.o: lib/checktype.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checktype.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checktype.cpp -$(libcppdir)/checkuninitvar.o: lib/checkuninitvar.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/checkuninitvar.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkuninitvar.o: lib/checkuninitvar.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/checkuninitvar.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkuninitvar.cpp -$(libcppdir)/checkunusedfunctions.o: lib/checkunusedfunctions.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/astutils.h lib/checkers.h lib/checkunusedfunctions.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/checkunusedfunctions.o: lib/checkunusedfunctions.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/astutils.h lib/checkers.h lib/checkunusedfunctions.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedfunctions.cpp -$(libcppdir)/checkunusedvar.o: lib/checkunusedvar.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkunusedvar.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkunusedvar.o: lib/checkunusedvar.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkunusedvar.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedvar.cpp -$(libcppdir)/checkvaarg.o: lib/checkvaarg.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkvaarg.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkvaarg.o: lib/checkvaarg.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkvaarg.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkvaarg.cpp -$(libcppdir)/clangimport.o: lib/clangimport.cpp lib/clangimport.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/clangimport.o: lib/clangimport.cpp lib/clangimport.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/refthunk.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/clangimport.cpp $(libcppdir)/color.o: lib/color.cpp lib/color.h lib/config.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/color.cpp -$(libcppdir)/cppcheck.o: lib/cppcheck.cpp externals/picojson/picojson.h externals/simplecpp/simplecpp.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checks.h lib/checkunusedfunctions.h lib/clangimport.h lib/color.h lib/config.h lib/cppcheck.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/rule.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/version.h lib/vfvalue.h +$(libcppdir)/cppcheck.o: lib/cppcheck.cpp externals/picojson/picojson.h externals/simplecpp/simplecpp.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checks.h lib/checkunusedfunctions.h lib/clangimport.h lib/color.h lib/config.h lib/cppcheck.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/refthunk.h lib/regex.h lib/rule.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/version.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/cppcheck.cpp -$(libcppdir)/ctu.o: lib/ctu.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/ctu.o: lib/ctu.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/refthunk.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/ctu.cpp -$(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errorlogger.cpp $(libcppdir)/errortypes.o: lib/errortypes.cpp lib/config.h lib/errortypes.h lib/utils.h @@ -609,10 +610,10 @@ $(libcppdir)/errortypes.o: lib/errortypes.cpp lib/config.h lib/errortypes.h lib/ $(libcppdir)/findtoken.o: lib/findtoken.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/findtoken.h lib/library.h lib/mathlib.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/findtoken.cpp -$(libcppdir)/forwardanalyzer.o: lib/forwardanalyzer.cpp lib/analyzer.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/forwardanalyzer.o: lib/forwardanalyzer.cpp lib/analyzer.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/forwardanalyzer.cpp -$(libcppdir)/fwdanalysis.o: lib/fwdanalysis.cpp lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h +$(libcppdir)/fwdanalysis.o: lib/fwdanalysis.cpp lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/fwdanalysis.cpp $(libcppdir)/importproject.o: lib/importproject.cpp externals/picojson/picojson.h externals/tinyxml2/tinyxml2.h lib/checkers.h lib/config.h lib/filesettings.h lib/importproject.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h @@ -624,7 +625,7 @@ $(libcppdir)/infer.o: lib/infer.cpp lib/calculate.h lib/config.h lib/errortypes. $(libcppdir)/keywords.o: lib/keywords.cpp lib/config.h lib/keywords.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/keywords.cpp -$(libcppdir)/library.o: lib/library.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/library.o: lib/library.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/refthunk.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/library.cpp $(libcppdir)/mathlib.o: lib/mathlib.cpp externals/simplecpp/simplecpp.h lib/config.h lib/errortypes.h lib/mathlib.h lib/smallvector.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h @@ -633,7 +634,7 @@ $(libcppdir)/mathlib.o: lib/mathlib.cpp externals/simplecpp/simplecpp.h lib/conf $(libcppdir)/path.o: lib/path.cpp externals/simplecpp/simplecpp.h lib/config.h lib/path.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/path.cpp -$(libcppdir)/pathanalysis.o: lib/pathanalysis.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/pathanalysis.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h +$(libcppdir)/pathanalysis.o: lib/pathanalysis.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/pathanalysis.h lib/refthunk.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/pathanalysis.cpp $(libcppdir)/pathmatch.o: lib/pathmatch.cpp lib/config.h lib/path.h lib/pathmatch.h lib/standards.h @@ -642,19 +643,19 @@ $(libcppdir)/pathmatch.o: lib/pathmatch.cpp lib/config.h lib/path.h lib/pathmatc $(libcppdir)/platform.o: lib/platform.cpp externals/tinyxml2/tinyxml2.h lib/config.h lib/mathlib.h lib/path.h lib/platform.h lib/standards.h lib/utils.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/platform.cpp -$(libcppdir)/preprocessor.o: lib/preprocessor.cpp externals/simplecpp/simplecpp.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h +$(libcppdir)/preprocessor.o: lib/preprocessor.cpp externals/simplecpp/simplecpp.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/preprocessor.cpp -$(libcppdir)/programmemory.o: lib/programmemory.cpp lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/programmemory.o: lib/programmemory.cpp lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/programmemory.cpp $(libcppdir)/regex.o: lib/regex.cpp lib/config.h lib/regex.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/regex.cpp -$(libcppdir)/reverseanalyzer.o: lib/reverseanalyzer.cpp lib/analyzer.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/reverseanalyzer.o: lib/reverseanalyzer.cpp lib/analyzer.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/reverseanalyzer.cpp -$(libcppdir)/sarifreport.o: lib/sarifreport.cpp externals/picojson/picojson.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h +$(libcppdir)/sarifreport.o: lib/sarifreport.cpp externals/picojson/picojson.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/sarifreport.cpp $(libcppdir)/settings.o: lib/settings.cpp externals/picojson/picojson.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/rule.h lib/settings.h lib/standards.h lib/summaries.h lib/suppressions.h lib/utils.h lib/vfvalue.h @@ -663,34 +664,34 @@ $(libcppdir)/settings.o: lib/settings.cpp externals/picojson/picojson.h lib/addo $(libcppdir)/standards.o: lib/standards.cpp externals/simplecpp/simplecpp.h lib/config.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/standards.cpp -$(libcppdir)/summaries.o: lib/summaries.cpp lib/analyzerinfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/summaries.o: lib/summaries.cpp lib/analyzerinfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/summaries.cpp -$(libcppdir)/suppressions.o: lib/suppressions.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/suppressions.o: lib/suppressions.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/suppressions.cpp -$(libcppdir)/templatesimplifier.o: lib/templatesimplifier.cpp lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/templatesimplifier.o: lib/templatesimplifier.cpp lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/templatesimplifier.cpp $(libcppdir)/timer.o: lib/timer.cpp lib/config.h lib/timer.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/timer.cpp -$(libcppdir)/token.o: lib/token.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/token.o: lib/token.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/token.cpp -$(libcppdir)/tokenlist.o: lib/tokenlist.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/tokenlist.o: lib/tokenlist.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/tokenlist.cpp $(libcppdir)/utils.o: lib/utils.cpp lib/config.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/utils.cpp -$(libcppdir)/vf_analyzers.o: lib/vf_analyzers.cpp lib/analyzer.h lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h +$(libcppdir)/vf_analyzers.o: lib/vf_analyzers.cpp lib/analyzer.h lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_analyzers.cpp -$(libcppdir)/vf_common.o: lib/vf_common.cpp lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h +$(libcppdir)/vf_common.o: lib/vf_common.cpp lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_common.cpp -$(libcppdir)/vf_settokenvalue.o: lib/vf_settokenvalue.cpp lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h +$(libcppdir)/vf_settokenvalue.o: lib/vf_settokenvalue.cpp lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_settokenvalue.cpp $(libcppdir)/vfvalue.o: lib/vfvalue.cpp lib/config.h lib/errortypes.h lib/mathlib.h lib/smallvector.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h @@ -699,13 +700,13 @@ $(libcppdir)/vfvalue.o: lib/vfvalue.cpp lib/config.h lib/errortypes.h lib/mathli frontend/frontend.o: frontend/frontend.cpp frontend/frontend.h lib/checkers.h lib/config.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_FE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ frontend/frontend.cpp -cli/cmdlineparser.o: cli/cmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/filelister.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/rule.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h +cli/cmdlineparser.o: cli/cmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/filelister.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/refthunk.h lib/regex.h lib/rule.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cmdlineparser.cpp -cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/sehwrapper.h cli/signalhandler.h cli/singleexecutor.h cli/threadexecutor.h externals/picojson/picojson.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/sarifreport.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h +cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/sehwrapper.h cli/signalhandler.h cli/singleexecutor.h cli/threadexecutor.h externals/picojson/picojson.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/sarifreport.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cppcheckexecutor.cpp -cli/executor.o: cli/executor.cpp cli/executor.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h +cli/executor.o: cli/executor.cpp cli/executor.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/executor.cpp cli/filelister.o: cli/filelister.cpp cli/filelister.h lib/config.h lib/filesettings.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/standards.h lib/utils.h @@ -714,7 +715,7 @@ cli/filelister.o: cli/filelister.cpp cli/filelister.h lib/config.h lib/filesetti cli/main.o: cli/main.cpp cli/cppcheckexecutor.h lib/config.h lib/filesettings.h lib/mathlib.h lib/path.h lib/platform.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/main.cpp -cli/processexecutor.o: cli/processexecutor.cpp cli/executor.h cli/processexecutor.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h +cli/processexecutor.o: cli/processexecutor.cpp cli/executor.h cli/processexecutor.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/processexecutor.cpp cli/sehwrapper.o: cli/sehwrapper.cpp cli/sehwrapper.h lib/config.h lib/utils.h @@ -729,241 +730,244 @@ cli/singleexecutor.o: cli/singleexecutor.cpp cli/executor.h cli/singleexecutor.h cli/stacktrace.o: cli/stacktrace.cpp cli/stacktrace.h lib/config.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/stacktrace.cpp -cli/threadexecutor.o: cli/threadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h +cli/threadexecutor.o: cli/threadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/threadexecutor.cpp -test/fixture.o: test/fixture.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h test/options.h test/redirect.h +test/fixture.o: test/fixture.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h test/options.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/fixture.cpp test/helpers.o: test/helpers.cpp cli/filelister.h externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/checkers.h lib/config.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/helpers.cpp -test/main.o: test/main.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h +test/main.o: test/main.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/main.cpp test/options.o: test/options.cpp lib/config.h lib/timer.h test/options.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/options.cpp -test/test64bit.o: test/test64bit.cpp lib/check.h lib/check64bit.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/test64bit.o: test/test64bit.cpp lib/check.h lib/check64bit.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/test64bit.cpp -test/testanalyzerinformation.o: test/testanalyzerinformation.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h +test/testanalyzerinformation.o: test/testanalyzerinformation.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testanalyzerinformation.cpp -test/testassert.o: test/testassert.cpp lib/check.h lib/checkassert.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testassert.o: test/testassert.cpp lib/check.h lib/checkassert.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testassert.cpp -test/testastutils.o: test/testastutils.cpp lib/astutils.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testastutils.o: test/testastutils.cpp lib/astutils.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testastutils.cpp -test/testautovariables.o: test/testautovariables.cpp lib/check.h lib/checkautovariables.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testautovariables.o: test/testautovariables.cpp lib/check.h lib/checkautovariables.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testautovariables.cpp -test/testbool.o: test/testbool.cpp lib/check.h lib/checkbool.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testbool.o: test/testbool.cpp lib/check.h lib/checkbool.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbool.cpp -test/testbufferoverrun.o: test/testbufferoverrun.cpp lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testbufferoverrun.o: test/testbufferoverrun.cpp lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbufferoverrun.cpp -test/testcharvar.o: test/testcharvar.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testcharvar.o: test/testcharvar.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcharvar.cpp -test/testcheck.o: test/testcheck.cpp lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testcheck.o: test/testcheck.cpp lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcheck.cpp -test/testcheckersreport.o: test/testcheckersreport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testcheckersreport.o: test/testcheckersreport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcheckersreport.cpp -test/testclangimport.o: test/testclangimport.cpp lib/check.h lib/checkers.h lib/clangimport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testclangimport.o: test/testclangimport.cpp lib/check.h lib/checkers.h lib/clangimport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclangimport.cpp -test/testclass.o: test/testclass.cpp lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testclass.o: test/testclass.cpp lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclass.cpp -test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/rule.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/regex.h lib/rule.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcmdlineparser.cpp -test/testcolor.o: test/testcolor.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testcolor.o: test/testcolor.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcolor.cpp -test/testcondition.o: test/testcondition.cpp lib/check.h lib/checkcondition.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testcondition.o: test/testcondition.cpp lib/check.h lib/checkcondition.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcondition.cpp -test/testconstructors.o: test/testconstructors.cpp lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testconstructors.o: test/testconstructors.cpp lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testconstructors.cpp -test/testcppcheck.o: test/testcppcheck.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testcppcheck.o: test/testcppcheck.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcppcheck.cpp -test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h +test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testerrorlogger.cpp -test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testexceptionsafety.cpp -test/testexecutor.o: test/testexecutor.cpp cli/executor.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testexecutor.o: test/testexecutor.cpp cli/executor.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testexecutor.cpp -test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilelister.cpp -test/testfilesettings.o: test/testfilesettings.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testfilesettings.o: test/testfilesettings.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilesettings.cpp -test/testfrontend.o: test/testfrontend.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testfrontend.o: test/testfrontend.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfrontend.cpp -test/testfunctions.o: test/testfunctions.cpp lib/check.h lib/checkers.h lib/checkfunctions.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testfunctions.o: test/testfunctions.cpp lib/check.h lib/checkers.h lib/checkfunctions.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfunctions.cpp -test/testgarbage.o: test/testgarbage.cpp lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testgarbage.o: test/testgarbage.cpp lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testgarbage.cpp -test/testimportproject.o: test/testimportproject.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testimportproject.o: test/testimportproject.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testimportproject.cpp -test/testincompletestatement.o: test/testincompletestatement.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testincompletestatement.o: test/testincompletestatement.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testincompletestatement.cpp -test/testinternal.o: test/testinternal.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkinternal.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testinternal.o: test/testinternal.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkinternal.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testinternal.cpp -test/testio.o: test/testio.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkio.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testio.o: test/testio.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkio.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testio.cpp -test/testleakautovar.o: test/testleakautovar.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkleakautovar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testleakautovar.o: test/testleakautovar.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkleakautovar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testleakautovar.cpp -test/testlibrary.o: test/testlibrary.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testlibrary.o: test/testlibrary.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testlibrary.cpp -test/testmathlib.o: test/testmathlib.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testmathlib.o: test/testmathlib.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testmathlib.cpp -test/testmemleak.o: test/testmemleak.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkmemoryleak.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testmemleak.o: test/testmemleak.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkmemoryleak.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testmemleak.cpp -test/testnullpointer.o: test/testnullpointer.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testnullpointer.o: test/testnullpointer.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testnullpointer.cpp -test/testoptions.o: test/testoptions.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h +test/testoptions.o: test/testoptions.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testoptions.cpp -test/testother.o: test/testother.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testother.o: test/testother.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testother.cpp -test/testpath.o: test/testpath.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testpath.o: test/testpath.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpath.cpp -test/testpathmatch.o: test/testpathmatch.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testpathmatch.o: test/testpathmatch.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpathmatch.cpp -test/testplatform.o: test/testplatform.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h +test/testplatform.o: test/testplatform.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testplatform.cpp -test/testpostfixoperator.o: test/testpostfixoperator.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkpostfixoperator.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testpostfixoperator.o: test/testpostfixoperator.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkpostfixoperator.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpostfixoperator.cpp -test/testpreprocessor.o: test/testpreprocessor.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testpreprocessor.o: test/testpreprocessor.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpreprocessor.cpp -test/testprocessexecutor.o: test/testprocessexecutor.cpp cli/executor.h cli/processexecutor.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testprocessexecutor.o: test/testprocessexecutor.cpp cli/executor.h cli/processexecutor.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testprocessexecutor.cpp -test/testprogrammemory.o: test/testprogrammemory.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testprogrammemory.o: test/testprogrammemory.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testprogrammemory.cpp -test/testregex.o: test/testregex.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testrefthunk.o: test/testrefthunk.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testrefthunk.cpp + +test/testregex.o: test/testregex.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testregex.cpp -test/testsarifreport.o: test/testsarifreport.cpp externals/picojson/picojson.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testsarifreport.o: test/testsarifreport.cpp externals/picojson/picojson.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsarifreport.cpp -test/testsettings.o: test/testsettings.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsettings.o: test/testsettings.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsettings.cpp -test/testsimplifytemplate.o: test/testsimplifytemplate.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifytemplate.o: test/testsimplifytemplate.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytemplate.cpp -test/testsimplifytokens.o: test/testsimplifytokens.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifytokens.o: test/testsimplifytokens.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytokens.cpp -test/testsimplifytypedef.o: test/testsimplifytypedef.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifytypedef.o: test/testsimplifytypedef.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytypedef.cpp -test/testsimplifyusing.o: test/testsimplifyusing.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifyusing.o: test/testsimplifyusing.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifyusing.cpp -test/testsingleexecutor.o: test/testsingleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testsingleexecutor.o: test/testsingleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsingleexecutor.cpp -test/testsizeof.o: test/testsizeof.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checksizeof.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsizeof.o: test/testsizeof.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checksizeof.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsizeof.cpp -test/teststandards.o: test/teststandards.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/teststandards.o: test/teststandards.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststandards.cpp -test/teststl.o: test/teststl.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/teststl.o: test/teststl.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststl.cpp -test/teststring.o: test/teststring.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstring.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/teststring.o: test/teststring.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstring.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststring.cpp -test/testsummaries.o: test/testsummaries.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/summaries.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsummaries.o: test/testsummaries.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/summaries.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsummaries.cpp -test/testsuppressions.o: test/testsuppressions.cpp cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/singleexecutor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsuppressions.o: test/testsuppressions.cpp cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/singleexecutor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsuppressions.cpp -test/testsymboldatabase.o: test/testsymboldatabase.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsymboldatabase.o: test/testsymboldatabase.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsymboldatabase.cpp -test/testthreadexecutor.o: test/testthreadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testthreadexecutor.o: test/testthreadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testthreadexecutor.cpp -test/testtimer.o: test/testtimer.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/timer.h lib/utils.h test/fixture.h test/redirect.h +test/testtimer.o: test/testtimer.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/timer.h lib/utils.h test/fixture.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtimer.cpp -test/testtoken.o: test/testtoken.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtoken.o: test/testtoken.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtoken.cpp -test/testtokenize.o: test/testtokenize.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtokenize.o: test/testtokenize.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenize.cpp -test/testtokenlist.o: test/testtokenlist.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtokenlist.o: test/testtokenlist.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenlist.cpp -test/testtokenrange.o: test/testtokenrange.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtokenrange.o: test/testtokenrange.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenrange.cpp -test/testtype.o: test/testtype.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checktype.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testtype.o: test/testtype.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checktype.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtype.cpp -test/testuninitvar.o: test/testuninitvar.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testuninitvar.o: test/testuninitvar.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testuninitvar.cpp -test/testunusedfunctions.o: test/testunusedfunctions.cpp lib/check.h lib/checkers.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testunusedfunctions.o: test/testunusedfunctions.cpp lib/check.h lib/checkers.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedfunctions.cpp -test/testunusedprivfunc.o: test/testunusedprivfunc.cpp lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testunusedprivfunc.o: test/testunusedprivfunc.cpp lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedprivfunc.cpp -test/testunusedvar.o: test/testunusedvar.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkunusedvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testunusedvar.o: test/testunusedvar.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkunusedvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedvar.cpp -test/testutils.o: test/testutils.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testutils.o: test/testutils.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testutils.cpp -test/testvaarg.o: test/testvaarg.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkvaarg.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testvaarg.o: test/testvaarg.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkvaarg.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvaarg.cpp -test/testvalueflow.o: test/testvalueflow.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testvalueflow.o: test/testvalueflow.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvalueflow.cpp -test/testvarid.o: test/testvarid.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testvarid.o: test/testvarid.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvarid.cpp -test/testvfvalue.o: test/testvfvalue.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testvfvalue.o: test/testvfvalue.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvfvalue.cpp externals/simplecpp/simplecpp.o: externals/simplecpp/simplecpp.cpp externals/simplecpp/simplecpp.h diff --git a/clang-tidy.md b/clang-tidy.md index f00a39cde12..fe6a6eb7140 100644 --- a/clang-tidy.md +++ b/clang-tidy.md @@ -138,7 +138,6 @@ Does not improve the readability. To be evaluated (need to remove exclusion). `cppcoreguidelines-missing-std-forward`
-`cppcoreguidelines-avoid-const-or-ref-data-members`
`cppcoreguidelines-macro-usage`
`cppcoreguidelines-pro-type-member-init`
`cppcoreguidelines-prefer-member-initializer`
diff --git a/cli/cmdlineparser.h b/cli/cmdlineparser.h index 54e7ae4b0aa..e712c3035ff 100644 --- a/cli/cmdlineparser.h +++ b/cli/cmdlineparser.h @@ -56,6 +56,8 @@ class CmdLineParser { * @param suppressions Suppressions instance that keeps the suppressions */ CmdLineParser(CmdLineLogger &logger, Settings &settings, Suppressions &suppressions); + CmdLineParser(const CmdLineParser &) = delete; + CmdLineParser &operator=(const CmdLineParser &) = delete; enum class Result : std::uint8_t { Success, Exit, Fail }; @@ -152,10 +154,10 @@ class CmdLineParser { void outputFormatOptionMixingError() const; - CmdLineLogger &mLogger; + CmdLineLogger& mLogger; - Settings &mSettings; - Suppressions &mSuppressions; + Settings& mSettings; + Suppressions& mSuppressions; protected: std::vector mPathNames; diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp index 959d16d37ec..eb50177ef1e 100644 --- a/cli/processexecutor.cpp +++ b/cli/processexecutor.cpp @@ -172,8 +172,8 @@ namespace { writeToPipeInternal(type, data.c_str(), len); } - const int mWpipe; - const bool mDebug; + int mWpipe; + bool mDebug; }; } diff --git a/gui/resultitem.h b/gui/resultitem.h index e0c212b2138..9c9b0b82af3 100644 --- a/gui/resultitem.h +++ b/gui/resultitem.h @@ -53,8 +53,8 @@ class ResultItem : public QStandardItem return mIconFileName; } private: - const Type mType; - const int mErrorPathIndex; + Type mType; + int mErrorPathIndex; QString mIconFileName; }; diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 31c8d2e0e2d..e2e19b6bd91 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -26,6 +26,7 @@ #include "infer.h" #include "library.h" #include "mathlib.h" +#include "refthunk.h" #include "settings.h" #include "symboldatabase.h" #include "token.h" @@ -3141,7 +3142,7 @@ namespace { }; struct ExpressionChangedSkipDeadCode { - const Library& library; + RefThunk library; const std::function(const Token* tok)>* evaluate; ExpressionChangedSkipDeadCode(const Library& library, const std::function(const Token* tok)>& evaluate) diff --git a/lib/checkersreport.cpp b/lib/checkersreport.cpp index f2c4a84653f..9779bdd93c6 100644 --- a/lib/checkersreport.cpp +++ b/lib/checkersreport.cpp @@ -129,19 +129,19 @@ void CheckersReport::countCheckers() mActiveCheckersCount = mAllCheckersCount = 0; for (const auto& checkReq: checkers::allCheckers) { - if (mActiveCheckers.count(checkReq.first) > 0) + if (mActiveCheckers().count(checkReq.first) > 0) ++mActiveCheckersCount; ++mAllCheckersCount; } - for (const auto& addonInfo: mSettings.addonInfos) { + for (const auto& addonInfo: mSettings().addonInfos) { for (const auto& checkReq: addonInfo.checkers) { - if (mActiveCheckers.count(checkReq.first) > 0) + if (mActiveCheckers().count(checkReq.first) > 0) ++mActiveCheckersCount; ++mAllCheckersCount; } } - if (mSettings.addons.count("misra")) { + if (mSettings().addons.count("misra")) { const bool doUnusedFunctionOnly = Settings::unusedFunctionOnly(); for (const checkers::MisraInfo& info: checkers::misraC2012Rules) { const std::string rule = std::to_string(info.a) + "." + std::to_string(info.b); @@ -185,7 +185,7 @@ std::string CheckersReport::getReport(const std::string& criticalErrors) const } for (const auto& checkReq: checkers::allCheckers) { const std::string& checker = checkReq.first; - const bool active = mActiveCheckers.count(checkReq.first) > 0; + const bool active = mActiveCheckers().count(checkReq.first) > 0; const std::string& req = checkReq.second; fout << (active ? "Yes " : "No ") << checker; if (!active && !req.empty()) @@ -193,12 +193,12 @@ std::string CheckersReport::getReport(const std::string& criticalErrors) const fout << std::endl; } - for (const auto& addonInfo: mSettings.addonInfos) { + for (const auto& addonInfo: mSettings().addonInfos) { if (addonInfo.checkers.empty()) continue; fout << std::endl << std::endl; std::string title; - if (mSettings.premium && addonInfo.name == "premiumaddon.json") + if (mSettings().premium && addonInfo.name == "premiumaddon.json") title = "Cppcheck Premium"; else { title = addonInfo.name; @@ -217,7 +217,7 @@ std::string CheckersReport::getReport(const std::string& criticalErrors) const for (const auto& checkReq: addonInfo.checkers) { const std::string& checker = checkReq.first; - const bool active = mActiveCheckers.count(checkReq.first) > 0; + const bool active = mActiveCheckers().count(checkReq.first) > 0; const std::string& req = checkReq.second; fout << (active ? "Yes " : "No ") << checker; if (!active && !req.empty()) @@ -238,7 +238,7 @@ std::string CheckersReport::getXmlReport(const std::string& criticalErrors) cons ret += " \n"; ret += " \n"; const int misraCVersion = getMisraCVersion(mSettings); - for (std::string checker: mActiveCheckers) { + for (std::string checker: mActiveCheckers()) { if (checker.compare(0,8,"Misra C:") == 0) checker = "Misra C " + std::to_string(misraCVersion) + ":" + checker.substr(8); ret += " \n"; diff --git a/lib/checkersreport.h b/lib/checkersreport.h index b189a7f1ebd..179653d3d51 100644 --- a/lib/checkersreport.h +++ b/lib/checkersreport.h @@ -20,6 +20,7 @@ #define checkersReportH #include "config.h" +#include "refthunk.h" #include #include @@ -37,8 +38,8 @@ class CPPCHECKLIB CheckersReport { std::string getXmlReport(const std::string& criticalErrors) const; private: - const Settings& mSettings; - const std::set& mActiveCheckers; + RefThunk mSettings; + RefThunk> mActiveCheckers; void countCheckers(); diff --git a/lib/checkother.cpp b/lib/checkother.cpp index bd55de0b795..1589b3b7dea 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -24,6 +24,7 @@ #include "fwdanalysis.h" #include "library.h" #include "mathlib.h" +#include "refthunk.h" #include "platform.h" #include "settings.h" #include "standards.h" @@ -4600,7 +4601,7 @@ struct UnionMember { : name(name) , size(size) {} - const std::string &name; + RefThunk name; size_t size; }; @@ -4610,7 +4611,7 @@ struct Union { , name(scope.className) {} const Scope *scope; - const std::string &name; + RefThunk name; std::vector members; const UnionMember *largestMember() const { @@ -4719,7 +4720,7 @@ void CheckOtherImpl::unionZeroInitError(const Token *tok, "Zero initializing union '$symbol' does not guarantee " + "its complete storage to be zero initialized as its largest member " + "is not declared as the first member. Consider making " + - largestMember.name + " the first member or favor memset()."); + largestMember.name() + " the first member or favor memset()."); } //----------------------------------------------------------------------------- diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index aa08725430a..a4e8a92c188 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -22,6 +22,7 @@ #include "errortypes.h" #include "library.h" #include "mathlib.h" +#include "refthunk.h" #include "pathanalysis.h" #include "settings.h" #include "standards.h" @@ -2884,7 +2885,7 @@ namespace { private: const Token* mBodyTok; const Token* mLoopVar{}; - const Settings& mSettings; + RefThunk mSettings; std::set mVarsChanged; public: @@ -2907,7 +2908,7 @@ namespace { int n = 1 + (astIsPointer(tok) ? 1 : 0); for (int i = 0; i < n; i++) { bool inconclusive = false; - if (isVariableChangedByFunctionCall(tok, i, mSettings.library, &inconclusive)) + if (isVariableChangedByFunctionCall(tok, i, mSettings().library, &inconclusive)) return true; if (inconclusive) return true; diff --git a/lib/clangimport.cpp b/lib/clangimport.cpp index 4152839e939..0043f5a3cde 100644 --- a/lib/clangimport.cpp +++ b/lib/clangimport.cpp @@ -20,6 +20,7 @@ #include "errortypes.h" #include "mathlib.h" +#include "refthunk.h" #include "standards.h" #include "symboldatabase.h" #include "token.h" @@ -241,8 +242,8 @@ namespace clangimport { , mSymbolDatabase(symbolDatabase) {} - const Settings &mSettings; - SymbolDatabase &mSymbolDatabase; + RefThunk mSettings; + RefThunk mSymbolDatabase; int enumValue = 0; @@ -665,7 +666,7 @@ const ::Type * clangimport::AstNode::addTypeTokens(TokenList &tokenList, const s for (const Token *typeToken = tokenList.back(); Token::Match(typeToken, "&|*|%name%"); typeToken = typeToken->previous()) { if (!typeToken->isName()) continue; - const ::Type *recordType = scope->symdb.findVariableType(scope, typeToken); + const ::Type *recordType = scope->symdb().findVariableType(scope, typeToken); if (recordType) { const_cast(typeToken)->type(recordType); return recordType; @@ -694,7 +695,7 @@ void clangimport::AstNode::addFullScopeNameTokens(TokenList &tokenList, const Sc const Scope *clangimport::AstNode::getNestedInScope(TokenList &tokenList) { if (!tokenList.back()) - return &mData->mSymbolDatabase.scopeList.front(); + return &mData->mSymbolDatabase().scopeList.front(); if (tokenList.back()->str() == "}" && mData->mNotScope.find(tokenList.back()) == mData->mNotScope.end()) return tokenList.back()->scope()->nestedIn; return tokenList.back()->scope(); @@ -1096,8 +1097,8 @@ Token *clangimport::AstNode::createTokens(TokenList &tokenList) const_cast(enumscope->bodyEnd)->deletePrevious(); // Create enum type - mData->mSymbolDatabase.typeList.emplace_back(enumtok, enumscope, enumtok->scope()); - enumscope->definedType = &mData->mSymbolDatabase.typeList.back(); + mData->mSymbolDatabase().typeList.emplace_back(enumtok, enumscope, enumtok->scope()); + enumscope->definedType = &mData->mSymbolDatabase().typeList.back(); if (nametok) const_cast(enumtok->scope())->definedTypesMap[nametok->str()] = enumscope->definedType; @@ -1268,8 +1269,8 @@ Token *clangimport::AstNode::createTokens(TokenList &tokenList) } Scope *recordScope = createScope(tokenList, ScopeType::eStruct, children, classDef); - mData->mSymbolDatabase.typeList.emplace_back(classDef, recordScope, classDef->scope()); - recordScope->definedType = &mData->mSymbolDatabase.typeList.back(); + mData->mSymbolDatabase().typeList.emplace_back(classDef, recordScope, classDef->scope()); + recordScope->definedType = &mData->mSymbolDatabase().typeList.back(); if (!recordName.empty()) { recordScope->className = recordName; const_cast(classDef->scope())->definedTypesMap[recordName] = recordScope->definedType; @@ -1562,8 +1563,8 @@ void clangimport::AstNode::createTokensForCXXRecord(TokenList &tokenList) const std::string addr = mExtTokens[0]; mData->scopeDecl(addr, scope); scope->className = className; - mData->mSymbolDatabase.typeList.emplace_back(classToken, scope, classToken->scope()); - scope->definedType = &mData->mSymbolDatabase.typeList.back(); + mData->mSymbolDatabase().typeList.emplace_back(classToken, scope, classToken->scope()); + scope->definedType = &mData->mSymbolDatabase().typeList.back(); const_cast(classToken->scope())->definedTypesMap[className] = scope->definedType; } addtoken(tokenList, ";"); diff --git a/lib/cppcheck.vcxproj b/lib/cppcheck.vcxproj index 553392c53c2..6957309e40f 100644 --- a/lib/cppcheck.vcxproj +++ b/lib/cppcheck.vcxproj @@ -166,6 +166,7 @@ + diff --git a/lib/errorlogger.h b/lib/errorlogger.h index 4b62d1b3218..fa5ad67c7c1 100644 --- a/lib/errorlogger.h +++ b/lib/errorlogger.h @@ -23,6 +23,7 @@ #include "config.h" #include "errortypes.h" +#include "refthunk.h" #include #include @@ -320,7 +321,7 @@ class CPPCHECKLIB ProgressReporter { ~ProgressReporter() { if (mReportProgressInterval < 0) return; - mErrorLogger.reportProgress(mFilename, mStage.c_str(), 100); + mErrorLogger().reportProgress(mFilename, mStage.c_str(), 100); } void report(int value) { @@ -328,17 +329,17 @@ class CPPCHECKLIB ProgressReporter { return; const std::time_t t = std::time(nullptr); if (t >= mLastTime + mReportProgressInterval) { - mErrorLogger.reportProgress(mFilename, mStage.c_str(), value); + mErrorLogger().reportProgress(mFilename, mStage.c_str(), value); mLastTime = t; mLastValue = value; } } private: - ErrorLogger& mErrorLogger; - const int mReportProgressInterval; - const std::string mFilename; - const std::string mStage; + RefThunk mErrorLogger; + int mReportProgressInterval; + std::string mFilename; + std::string mStage; std::time_t mLastTime{0}; int mLastValue{-1}; }; diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index 3398d2fe723..88cee242c8c 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -24,6 +24,7 @@ #include "errorlogger.h" #include "errortypes.h" #include "mathlib.h" +#include "refthunk.h" #include "settings.h" #include "symboldatabase.h" #include "token.h" @@ -50,9 +51,9 @@ namespace { : analyzer(analyzer), tokenList(tokenList), errorLogger(errorLogger), settings(settings) {} ValuePtr analyzer; - const TokenList& tokenList; - ErrorLogger& errorLogger; - const Settings& settings; + RefThunk tokenList; + RefThunk errorLogger; + RefThunk settings; Analyzer::Action actions; bool analyzeOnly{}; bool analyzeTerminate{}; @@ -148,7 +149,7 @@ namespace { traverseRecursive(tok->astOperand2(), f, traverseUnknown); traverseRecursive(tok->astOperand1(), f, traverseUnknown); return Break(Analyzer::Terminate::Escape); - } else if (Token::Match(tok, "%name% (") && isEscapeFunction(tok, settings.library)) { + } else if (Token::Match(tok, "%name% (") && isEscapeFunction(tok, settings().library)) { // Traverse the parameters of the function before escaping traverseRecursive(tok->next()->astOperand2(), f, traverseUnknown); return Break(Analyzer::Terminate::Escape); @@ -356,7 +357,7 @@ namespace { bool isEscapeScope(const Token* endBlock, bool& unknown) const { const Token* ftok = nullptr; - const bool r = isReturnScope(endBlock, settings.library, &ftok); + const bool r = isReturnScope(endBlock, settings().library, &ftok); if (!r && ftok) unknown = true; return r; @@ -721,9 +722,9 @@ namespace { } } else if (tok->isControlFlowKeyword() && Token::Match(tok, "if|while|for (") && Token::simpleMatch(tok->linkAt(1), ") {")) { - if ((settings.vfOptions.maxForwardBranches > 0) && (++branchCount > settings.vfOptions.maxForwardBranches)) { + if ((settings().vfOptions.maxForwardBranches > 0) && (++branchCount > settings().vfOptions.maxForwardBranches)) { // TODO: should be logged on function-level instead of file-level - if (settings.severity.isEnabled(Severity::information)) { + if (settings().severity.isEnabled(Severity::information)) { reportError(Severity::information, "normalCheckLevelMaxBranches", "Limiting analysis of branches. Use --check-level=exhaustive to analyze all branches."); } return Break(Analyzer::Terminate::Bail); @@ -825,8 +826,8 @@ namespace { // Carry the then-fork forward, unless a limit is hit - then only the linear main // path continues (no bail). forkDepth bounds nesting, forkBudget total. <0 = off. assert(forkBudget != nullptr); - const int forkDepthLimit = settings.vfOptions.maxForwardConditionForkDepth; - const int forkBudgetLimit = settings.vfOptions.maxForwardConditionForks; + const int forkDepthLimit = settings().vfOptions.maxForwardConditionForkDepth; + const int forkBudgetLimit = settings().vfOptions.maxForwardConditionForks; const bool depthOk = forkDepthLimit < 0 || forkDepth < forkDepthLimit; const bool budgetOk = forkBudgetLimit < 0 || *forkBudget < forkBudgetLimit; if (pThen != Progress::Break && !thenBranch.isEscape() && depthOk && budgetOk) { @@ -918,10 +919,10 @@ namespace { return Progress::Continue; } - void reportError(Severity severity, const std::string& id, const std::string& msg) { - ErrorMessage::FileLocation loc(tokenList.getSourceFilePath(), 0, 0); - const ErrorMessage errmsg({std::move(loc)}, tokenList.getSourceFilePath(), severity, msg, id, Certainty::normal); - errorLogger.reportErr(errmsg); + void reportError(Severity severity, const std::string& id, const std::string& msg) const { + ErrorMessage::FileLocation loc(tokenList().getSourceFilePath(), 0, 0); + const ErrorMessage errmsg({std::move(loc)}, tokenList().getSourceFilePath(), severity, msg, id, Certainty::normal); + errorLogger().reportErr(errmsg); } static bool isFunctionCall(const Token* tok) diff --git a/lib/fwdanalysis.cpp b/lib/fwdanalysis.cpp index 07ba7cc2e59..7b7987e2e91 100644 --- a/lib/fwdanalysis.cpp +++ b/lib/fwdanalysis.cpp @@ -293,7 +293,7 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token * while (argnr < args.size() && args[argnr] != parent) argnr++; if (argnr < args.size()) { - if (mSettings.library.getArgDirection(ftok->astOperand1(), argnr + 1, /*indirect*/ 1) == Library::ArgumentChecks::Direction::DIR_OUT) + if (mSettings().library.getArgDirection(ftok->astOperand1(), argnr + 1, /*indirect*/ 1) == Library::ArgumentChecks::Direction::DIR_OUT) continue; } } diff --git a/lib/fwdanalysis.h b/lib/fwdanalysis.h index e8e27e576b5..b57e36ba34b 100644 --- a/lib/fwdanalysis.h +++ b/lib/fwdanalysis.h @@ -22,6 +22,7 @@ //--------------------------------------------------------------------------- #include "config.h" +#include "refthunk.h" #include #include @@ -77,7 +78,7 @@ class FwdAnalysis { Result check(const Token *expr, const Token *startToken, const Token *endToken) const; Result checkRecursive(const Token *expr, const Token *startToken, const Token *endToken, const std::set &exprVarIds, bool local, bool inInnerClass, int depth=0) const; - const Settings &mSettings; + RefThunk mSettings; enum class What : std::uint8_t { Reassign, UnusedValue } mWhat = What::Reassign; }; diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 10cc86da96d..a53760c1a32 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -1554,6 +1554,8 @@ struct ImportProject::PropertyValueExpander { PropertyValueExpander(ImportProject &project, const PropertiesMap &vars, std::string str, bool unknownAsEmpty = false) : mProject(project), mVars(vars), mStr(std::move(str)), mUnknownAsEmpty(unknownAsEmpty) {} + PropertyValueExpander(const PropertyValueExpander &) = delete; + PropertyValueExpander &operator=(const PropertyValueExpander &) = delete; bool hasValue(const std::string &name) const { if (mVars.count(name)) @@ -2357,6 +2359,8 @@ class ImportProject::ConditionParser { public: ConditionParser(ImportProject &project, const std::string &condition, const PropertiesMap &properties) : mProject(project), mCondition(condition), mVariables(properties) {} + ConditionParser(const ConditionParser &) = delete; + ConditionParser &operator=(const ConditionParser &) = delete; bool parse() { const std::string value = parseOr(); @@ -3142,6 +3146,8 @@ namespace { , thisFileFullPath(properties["MSBuildThisFileFullPath"]) { setMSBuildThis(filename, properties); } + MSBuildThis(const MSBuildThis &) = delete; + MSBuildThis &operator=(const MSBuildThis &) = delete; static void setMSBuildThis(const std::string &filename, PropertiesMap &properties) { // Normalize once so all subsequent path ops can assume '/' separators. @@ -3175,6 +3181,8 @@ namespace { explicit DiscoveringGuard(bool &flag) : mFlag(flag) { mFlag = true; } + DiscoveringGuard(const DiscoveringGuard &) = delete; + DiscoveringGuard &operator=(const DiscoveringGuard &) = delete; ~DiscoveringGuard() { mFlag = false; @@ -3187,6 +3195,8 @@ namespace { ImportStackGuard(std::unordered_set &stack, std::string key) : mStack(stack), mKey(std::move(key)) {} + ImportStackGuard(const ImportStackGuard &) = delete; + ImportStackGuard &operator=(const ImportStackGuard &) = delete; ~ImportStackGuard() { mStack.erase(mKey); @@ -3205,6 +3215,8 @@ namespace { : mCurrent(current), mPrev(current) { mCurrent = std::move(next); } + CurrentFileGuard(const CurrentFileGuard &) = delete; + CurrentFileGuard &operator=(const CurrentFileGuard &) = delete; ~CurrentFileGuard() { mCurrent = std::move(mPrev); diff --git a/lib/preprocessor.h b/lib/preprocessor.h index 91a0b7e7d37..5df52934dfc 100644 --- a/lib/preprocessor.h +++ b/lib/preprocessor.h @@ -105,6 +105,8 @@ class CPPCHECKLIB WARN_UNUSED Preprocessor { static char macroChar; Preprocessor(simplecpp::TokenList& tokens, const Settings& settings, ErrorLogger &errorLogger, Standards::Language lang); + Preprocessor(const Preprocessor &) = delete; + Preprocessor &operator=(const Preprocessor &) = delete; void inlineSuppressions(SuppressionList &suppressions) const; @@ -182,7 +184,7 @@ class CPPCHECKLIB WARN_UNUSED Preprocessor { simplecpp::TokenList& mTokens; const Settings& mSettings; - ErrorLogger &mErrorLogger; + ErrorLogger& mErrorLogger; simplecpp::FileDataCache mFileCache; diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 142385ac641..0d84dc053a8 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -23,6 +23,7 @@ #include "infer.h" #include "library.h" #include "mathlib.h" +#include "refthunk.h" #include "settings.h" #include "standards.h" #include "symboldatabase.h" @@ -588,7 +589,7 @@ ProgramMemoryState::FindChangedFn ProgramMemoryState::getCachedFindExpressionCha // variable follows the same path) and memoizes those evals in evalCache for the closure's lifetime. using EvalCache = std::map>; const std::shared_ptr cache = changedCache; - const Settings* const sp = &settings; + const Settings* const sp = &settings(); ProgramMemory snapshot = state; const std::shared_ptr evalCache = skipDeadCode ? std::make_shared() : nullptr; return [cache, sp, snapshot, skipDeadCode, evalCache](const Token* expr, @@ -1358,7 +1359,7 @@ static void pruneConditions(std::vector& conds, namespace { struct Executor { ProgramMemory* pm; - const Settings& settings; + RefThunk settings; // Values tracked by the forward/reverse analysis. A tracked value is the authoritative // current value of its expression and takes precedence over the program memory. const ProgramMemory::Map* vars = nullptr; @@ -1762,7 +1763,7 @@ namespace { BuiltinLibraryFunction lf = getBuiltinLibraryFunction(ftok->str()); if (lf) return lf(args); - const std::string& returnValue = settings.library.returnValue(ftok); + const std::string& returnValue = settings().library.returnValue(ftok); if (!returnValue.empty()) { std::unordered_map arg_map; int argn = 0; diff --git a/lib/programmemory.h b/lib/programmemory.h index de81d0bc901..f3133a53c31 100644 --- a/lib/programmemory.h +++ b/lib/programmemory.h @@ -21,6 +21,7 @@ #include "config.h" #include "mathlib.h" +#include "refthunk.h" #include "vfvalue.h" // needed for alias #include @@ -179,7 +180,7 @@ struct ProgramMemoryState { ProgramMemory state; std::map origins; - const Settings& settings; + RefThunk settings; // Memoized findExpressionChanged() pre-filter; structural, so never invalidated. std::shared_ptr changedCache; diff --git a/lib/refthunk.h b/lib/refthunk.h new file mode 100644 index 00000000000..5b2e4d0d5c0 --- /dev/null +++ b/lib/refthunk.h @@ -0,0 +1,61 @@ +/* -*- C++ -*- + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2026 Cppcheck team. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//--------------------------------------------------------------------------- +#ifndef refthunkH +#define refthunkH +//--------------------------------------------------------------------------- + +#include + +/** + * Reference wrapper whose operator() returns the referenced object. + * + * It is constructed from a reference and converts implicitly back to one + * (like std::reference_wrapper), so it can replace a reference data member + * without changing the constructor or call sites that pass the member to + * functions taking T&. Unlike a reference member it is copyable and + * assignable; assignment rebinds it. + */ +template +struct RefThunk { + RefThunk() = delete; + + // cppcheck-suppress noExplicitConstructor + // NOLINTNEXTLINE(google-explicit-constructor) + constexpr RefThunk(T& t) noexcept : mPtr(std::addressof(t)) {} + RefThunk(T&& t) = delete; + + constexpr T& operator()() const noexcept { + return *mPtr; + } + + constexpr T& get() const noexcept { + return *mPtr; + } + + // NOLINTNEXTLINE(google-explicit-constructor) + constexpr operator T&() const noexcept { + return *mPtr; + } + +private: + T* mPtr; +}; + +#endif diff --git a/lib/reverseanalyzer.cpp b/lib/reverseanalyzer.cpp index 0c3c966f2b2..d6e9480adb7 100644 --- a/lib/reverseanalyzer.cpp +++ b/lib/reverseanalyzer.cpp @@ -23,6 +23,7 @@ #include "errortypes.h" #include "forwardanalyzer.h" #include "mathlib.h" +#include "refthunk.h" #include "settings.h" #include "symboldatabase.h" #include "token.h" @@ -41,9 +42,9 @@ namespace { : analyzer(analyzer), tokenlist(tokenlist), errorLogger(errorLogger), settings(settings) {} ValuePtr analyzer; - const TokenList& tokenlist; - ErrorLogger& errorLogger; - const Settings& settings; + RefThunk tokenlist; + RefThunk errorLogger; + RefThunk settings; std::pair evalCond(const Token* tok) const { std::vector result = analyzer->evaluate(tok); @@ -265,7 +266,7 @@ namespace { // Assignment to } else if (lhsAction.matches() && !assignTok->astOperand2()->hasKnownIntValue() && assignTok->astOperand2()->exprId() > 0 && - isConstExpression(assignTok->astOperand2(), settings.library)) { + isConstExpression(assignTok->astOperand2(), settings().library)) { const std::string info = "Assignment to '" + assignTok->expressionString() + "'"; ValuePtr a = analyzer->reanalyze(assignTok->astOperand2(), info); if (a) { diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 540ec5ca5da..78fd044cc7b 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -3036,10 +3036,10 @@ static bool typesMatch( const Token *&new_second) { // get first type - const Type* first_type = first_scope->symdb.findType(first_token, first_scope, /*lookOutside*/ true); + const Type* first_type = first_scope->symdb().findType(first_token, first_scope, /*lookOutside*/ true); if (first_type) { // get second type - const Type* second_type = second_scope->symdb.findType(second_token, second_scope, /*lookOutside*/ true); + const Type* second_type = second_scope->symdb().findType(second_token, second_scope, /*lookOutside*/ true); // check if types match if (first_type == second_type) { const Token* tok1 = first_token; @@ -3835,7 +3835,7 @@ const Token *Type::initBaseInfo(const Token *tok, const Token *tok1) } } - const Type * baseType = classScope->symdb.findType(base.nameTok, enclosingScope); + const Type * baseType = classScope->symdb().findType(base.nameTok, enclosingScope); if (baseType && !baseType->findDependency(this)) base.type = baseType; @@ -4696,7 +4696,7 @@ void SymbolDatabase::printXml(std::ostream &out) const static const Type* findVariableTypeIncludingUsedNamespaces(const Scope* scope, const Token* typeTok) { - const Type* argType = scope->symdb.findVariableType(scope, typeTok); + const Type* argType = scope->symdb().findVariableType(scope, typeTok); if (argType) return argType; @@ -4704,7 +4704,7 @@ static const Type* findVariableTypeIncludingUsedNamespaces(const Scope* scope, c while (scope) { for (const Scope::UsingInfo &ui : scope->usingList) { if (ui.scope) { - argType = scope->symdb.findVariableType(ui.scope, typeTok); + argType = scope->symdb().findVariableType(ui.scope, typeTok); if (argType) return argType; } @@ -4777,7 +4777,7 @@ void Function::addArguments(const Scope *scope) while (Token::Match(typeTok, "const|volatile|enum|struct|::")) typeTok = typeTok->next(); if (Token::Match(typeTok, ",|)")) { // #8333 - scope->symdb.mTokenizer.syntaxError(typeTok); + scope->symdb().mTokenizer.syntaxError(typeTok); } if (Token::Match(typeTok, "%type% <") && Token::Match(typeTok->linkAt(1), "> :: %type%")) typeTok = typeTok->linkAt(1)->tokAt(2); @@ -4796,7 +4796,7 @@ void Function::addArguments(const Scope *scope) endTok = nameTok->previous(); if (hasBody()) - scope->symdb.debugMessage(nameTok, "varid0", "Function::addArguments found argument \'" + nameTok->str() + "\' with varid 0."); + scope->symdb().debugMessage(nameTok, "varid0", "Function::addArguments found argument \'" + nameTok->str() + "\' with varid 0."); } else endTok = typeTok; } else @@ -4827,7 +4827,7 @@ void Function::addArguments(const Scope *scope) if (startTok == nameTok) break; - argumentList.emplace_back(nameTok, startTok, endTok, count++, AccessControl::Argument, argType, functionScope, scope->symdb.mSettings); + argumentList.emplace_back(nameTok, startTok, endTok, count++, AccessControl::Argument, argType, functionScope, scope->symdb().mSettings); if (tok->str() == ")") { // check for a variadic function or a variadic template function @@ -5071,7 +5071,7 @@ void Scope::addVariable(const Token *token_, const Token *start_, const Token *e // keep possible size_t -> int truncation outside emplace_back() to have a single line // C4267 VC++ warning instead of several dozens lines const int varIndex = varlist.size(); - varlist.emplace_back(token_, start_, end_, varIndex, access_, type_, scope_, scope_->symdb.mSettings); + varlist.emplace_back(token_, start_, end_, varIndex, access_, type_, scope_, scope_->symdb().mSettings); } // Get variable list.. @@ -5084,7 +5084,7 @@ void Scope::getVariableList() // global scope else if (type == ScopeType::eGlobal) - getVariableList(symdb.mTokenizer.tokens(), nullptr); + getVariableList(symdb().mTokenizer.tokens(), nullptr); // forward declaration else @@ -5229,7 +5229,7 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess) const Token *typestart = tok; // C++17 structured bindings - if (tok && tok->isCpp() && (symdb.mSettings.standards.cpp >= Standards::CPP17) && Token::Match(tok, "auto &|&&| [")) { + if (tok && tok->isCpp() && (symdb().mSettings.standards.cpp >= Standards::CPP17) && Token::Match(tok, "auto &|&&| [")) { const Token *typeend = Token::findsimplematch(typestart, "[")->previous(); for (tok = typeend->tokAt(2); Token::Match(tok, "%name%|,"); tok = tok->next()) { if (tok->varId()) @@ -5255,7 +5255,7 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess) if (vartok->varId() == 0) { if (!vartok->isBoolean()) - symdb.debugMessage(vartok, "varid0", "Scope::checkVariable found variable \'" + vartok->str() + "\' with varid 0."); + symdb().debugMessage(vartok, "varid0", "Scope::checkVariable found variable \'" + vartok->str() + "\' with varid 0."); return tok; } @@ -5281,7 +5281,7 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess) } if (Token::Match(tok2, ", %name%")) { if (tok2->next()->varId() == 0) { - symdb.debugMessage(tok2->next(), "varid0", "Scope::checkVariable found variable \'" + tok2->strAt(1) + "\' with varid 0."); + symdb().debugMessage(tok2->next(), "varid0", "Scope::checkVariable found variable \'" + tok2->strAt(1) + "\' with varid 0."); return tok; } addVariable(tok2->next(), typestart, vartok->previous(), varaccess, vType, this); @@ -5371,7 +5371,7 @@ bool Scope::isVariableDeclaration(const Token* const tok, const Token*& vartok, if (isCPP && Token::Match(tok, "throw|new")) return false; - const bool isCPP11 = isCPP && symdb.mSettings.standards.cpp >= Standards::CPP11; + const bool isCPP11 = isCPP && symdb().mSettings.standards.cpp >= Standards::CPP11; if (isCPP11 && tok->str() == "using") return false; @@ -7673,7 +7673,7 @@ static const Token* parsedecl(const Token* type, valuetype->container = container; } else { const Scope *scope = type->scope(); - valuetype->typeScope = scope->symdb.findScope(typeTokens.front(), scope); + valuetype->typeScope = scope->symdb().findScope(typeTokens.front(), scope); if (valuetype->typeScope) valuetype->type = (scope->type == ScopeType::eClass) ? ValueType::Type::RECORD : ValueType::Type::NONSTD; } @@ -9055,5 +9055,5 @@ void SymbolDatabase::getErrorMessages(ErrorLogger& /*errorLogger*/) { // TODO //SymbolDatabase symdb; - //symdb.returnImplicitIntError(nullptr); + //symdb().returnImplicitIntError(nullptr); } diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 08c5382929e..832bcddeab3 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -25,6 +25,7 @@ #include "errortypes.h" #include "library.h" #include "mathlib.h" +#include "refthunk.h" #include "sourcelocation.h" #include "token.h" #include "utils.h" @@ -1045,7 +1046,7 @@ class CPPCHECKLIB Scope { Scope(const SymbolDatabase &symdb_, const Token *classDef_, const Scope *nestedIn_); Scope(const SymbolDatabase &symdb_, const Token *classDef_, const Scope *nestedIn_, ScopeType type_, const Token *start_); - const SymbolDatabase& symdb; + RefThunk symdb; std::string className; const Token* classDef{}; ///< class/struct/union/namespace token const Token* bodyStart{}; ///< '{' token @@ -1349,6 +1350,8 @@ class CPPCHECKLIB SymbolDatabase { public: explicit SymbolDatabase(Tokenizer& tokenizer); ~SymbolDatabase(); + SymbolDatabase(const SymbolDatabase &) = delete; + SymbolDatabase &operator=(const SymbolDatabase &) = delete; /** @brief Information about all namespaces/classes/structures */ std::list scopeList; @@ -1518,8 +1521,8 @@ class CPPCHECKLIB SymbolDatabase { std::list checkedFuncs) const; Tokenizer& mTokenizer; - const Settings &mSettings; - ErrorLogger &mErrorLogger; + const Settings& mSettings; + ErrorLogger& mErrorLogger; /** variable symbol table */ std::vector mVariableList; diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 508468c4ac7..c59fdf288f7 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -71,7 +71,7 @@ namespace { return tokenAndName.token() == mToken; } private: - const Token * const mToken; + const Token * mToken; }; class FindName { @@ -81,7 +81,7 @@ namespace { return tokenAndName.name() == mName; } private: - const std::string mName; + std::string mName; }; class FindFullName { @@ -91,7 +91,7 @@ namespace { return tokenAndName.fullName() == mFullName; } private: - const std::string mFullName; + std::string mFullName; }; } @@ -281,7 +281,7 @@ TemplateSimplifier::TemplateSimplifier(Tokenizer &tokenizer) mErrorLogger(mTokenizer.getErrorLogger()) {} -void TemplateSimplifier::checkComplicatedSyntaxErrorsInTemplates() +void TemplateSimplifier::checkComplicatedSyntaxErrorsInTemplates() const { // check for more complicated syntax errors when using templates.. for (const Token *tok = mTokenList.front(); tok; tok = tok->next()) { @@ -2733,7 +2733,7 @@ static bool validTokenEnd(bool bounded, const Token *tok, const Token *backToken // TODO: This is not the correct class for simplifyCalculations(), so it // should be moved away. -bool TemplateSimplifier::simplifyCalculations(Token* frontToken, const Token *backToken, bool isTemplate) +bool TemplateSimplifier::simplifyCalculations(Token* frontToken, const Token *backToken, bool isTemplate) const { bool ret = false; const bool bounded = frontToken || backToken; diff --git a/lib/templatesimplifier.h b/lib/templatesimplifier.h index 3c5fed3ea1c..3dc8b6bf1fd 100644 --- a/lib/templatesimplifier.h +++ b/lib/templatesimplifier.h @@ -47,6 +47,8 @@ struct newInstantiation; class CPPCHECKLIB TemplateSimplifier { public: explicit TemplateSimplifier(Tokenizer &tokenizer); + TemplateSimplifier(const TemplateSimplifier &) = delete; + TemplateSimplifier &operator=(const TemplateSimplifier &) = delete; const std::string& dump() const { return mDump; @@ -58,7 +60,7 @@ class CPPCHECKLIB TemplateSimplifier { /** */ - void checkComplicatedSyntaxErrorsInTemplates(); + void checkComplicatedSyntaxErrorsInTemplates() const; /** * is the token pointing at a template parameters block @@ -333,7 +335,7 @@ class CPPCHECKLIB TemplateSimplifier { * @return true if modifications to token-list are done. * false if no modifications are done. */ - bool simplifyCalculations(Token* frontToken = nullptr, const Token *backToken = nullptr, bool isTemplate = true); + bool simplifyCalculations(Token* frontToken = nullptr, const Token *backToken = nullptr, bool isTemplate = true) const; /** Simplify template instantiation arguments. * @param start first token of arguments @@ -504,10 +506,10 @@ class CPPCHECKLIB TemplateSimplifier { const std::string &indent = " ") const; void printOut(const std::string &text = "") const; - Tokenizer &mTokenizer; - TokenList &mTokenList; - const Settings &mSettings; - ErrorLogger &mErrorLogger; + Tokenizer& mTokenizer; + TokenList& mTokenList; + const Settings& mSettings; + ErrorLogger& mErrorLogger; bool mChanged{}; std::list mTemplateDeclarations; diff --git a/lib/token.h b/lib/token.h index fd4804ec980..3df24a86cb6 100644 --- a/lib/token.h +++ b/lib/token.h @@ -60,7 +60,7 @@ struct ReferenceToken; struct ScopeInfo2 { ScopeInfo2(std::string name_, const Token *bodyEnd_, std::set usingNamespaces_ = std::set()) : name(std::move(name_)), bodyEnd(bodyEnd_), usingNamespaces(std::move(usingNamespaces_)) {} std::string name; - const Token* const bodyEnd{}; + const Token* bodyEnd{}; std::set usingNamespaces; }; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 7e9b80454ef..6262bb7032a 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -70,10 +70,10 @@ namespace { VarIdScopeInfo(bool isExecutable, bool isStructInit, bool isEnum, nonneg int startVarid) : isExecutable(isExecutable), isStructInit(isStructInit), isEnum(isEnum), startVarid(startVarid) {} - const bool isExecutable{}; - const bool isStructInit{}; - const bool isEnum{}; - const nonneg int startVarid{}; + bool isExecutable{}; + bool isStructInit{}; + bool isEnum{}; + nonneg int startVarid{}; }; } @@ -3632,7 +3632,7 @@ bool Tokenizer::simplifyTokens1(const std::string &configuration, int fileIndex) //--------------------------------------------------------------------------- -void Tokenizer::findComplicatedSyntaxErrorsInTemplates() +void Tokenizer::findComplicatedSyntaxErrorsInTemplates() const { validate(); mTemplateSimplifier->checkComplicatedSyntaxErrorsInTemplates(); diff --git a/lib/tokenize.h b/lib/tokenize.h index f7f6ddbecae..36f4e48c751 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -327,7 +327,7 @@ class CPPCHECKLIB Tokenizer { void checkForEnumsWithTypedef(); - void findComplicatedSyntaxErrorsInTemplates(); + void findComplicatedSyntaxErrorsInTemplates() const; protected: /** diff --git a/lib/tokenlist.h b/lib/tokenlist.h index f5b652f3506..e2cbb1b3cb7 100644 --- a/lib/tokenlist.h +++ b/lib/tokenlist.h @@ -228,6 +228,7 @@ class CPPCHECKLIB TokenList { std::vector mOrigFiles; /** settings */ + // NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members) - TokenList is move-only const Settings& mSettings; /** File is known to be C/C++ code */ diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 7848ef4e97c..4be7a13dbc7 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -89,6 +89,7 @@ #include "infer.h" #include "library.h" #include "mathlib.h" +#include "refthunk.h" #include "path.h" #include "platform.h" #include "programmemory.h" @@ -7251,10 +7252,10 @@ struct ValueFlowState { : tokenlist(tokenlist), symboldatabase(symboldatabase), errorLogger(errorLogger), settings(settings) {} - TokenList& tokenlist; - SymbolDatabase& symboldatabase; - ErrorLogger& errorLogger; - const Settings& settings; + RefThunk tokenlist; + RefThunk symboldatabase; + RefThunk errorLogger; + RefThunk settings; std::set skippedFunctions; }; @@ -7290,31 +7291,31 @@ struct ValueFlowPassRunner { bool run(std::initializer_list> passes) const { std::size_t values = 0; - std::size_t n = state.settings.vfOptions.maxIterations; - const bool doProgress = state.settings.reportProgress >= 0; + std::size_t n = state.settings().vfOptions.maxIterations; + const bool doProgress = state.settings().reportProgress >= 0; while (n > 0 && values != getTotalValues()) { values = getTotalValues(); - const std::size_t passnum = state.settings.vfOptions.maxIterations - n + 1; + const std::size_t passnum = state.settings().vfOptions.maxIterations - n + 1; const std::string passnum_s = std::to_string(passnum); if (std::any_of(passes.begin(), passes.end(), [&](const ValuePtr& pass) { // the string concatination is a hot spot in TestIO::testScanfArgument and TestIO::testPrintfArgumentVariables std::string stage = doProgress ? std::string("ValueFlow::") + pass->name() + (' ' + passnum_s) : ""; - ProgressReporter progressReporter(state.errorLogger, state.settings.reportProgress, state.tokenlist.getSourceFilePath(), std::move(stage)); + ProgressReporter progressReporter(state.errorLogger, state.settings().reportProgress, state.tokenlist().getSourceFilePath(), std::move(stage)); return run(pass, passnum); })) return true; --n; } - if (state.settings.debugwarnings) { + if (state.settings().debugwarnings) { if (n == 0 && values != getTotalValues()) { - ErrorMessage::FileLocation loc(state.tokenlist.getFiles()[0], 0, 0); + ErrorMessage::FileLocation loc(state.tokenlist().getFiles()[0], 0, 0); ErrorMessage errmsg({std::move(loc)}, "", Severity::debug, "ValueFlow maximum iterations exceeded", "valueFlowMaxIterations", Certainty::normal); - state.errorLogger.reportErr(errmsg); + state.errorLogger().reportErr(errmsg); } } return false; @@ -7327,7 +7328,7 @@ struct ValueFlowPassRunner { // TODO: add bailout message return true; } - if (!state.tokenlist.isCPP() && pass->cpp()) + if (!state.tokenlist().isCPP() && pass->cpp()) return false; if (timerResults) { std::string name = pass->name(); @@ -7346,15 +7347,15 @@ struct ValueFlowPassRunner { std::size_t getTotalValues() const { std::size_t n = 1; - for (Token* tok = state.tokenlist.front(); tok; tok = tok->next()) + for (Token* tok = state.tokenlist().front(); tok; tok = tok->next()) n += tok->values().size(); return n; } void setSkippedFunctions() { - if (state.settings.vfOptions.maxIfCount > 0) { - for (const Scope* functionScope : state.symboldatabase.functionScopes) { + if (state.settings().vfOptions.maxIfCount > 0) { + for (const Scope* functionScope : state.symboldatabase().functionScopes) { int countIfScopes = 0; std::vector scopes{functionScope}; while (!scopes.empty()) { @@ -7366,22 +7367,22 @@ struct ValueFlowPassRunner { ++countIfScopes; } } - if (countIfScopes > state.settings.vfOptions.maxIfCount) { + if (countIfScopes > state.settings().vfOptions.maxIfCount) { state.skippedFunctions.emplace(functionScope); - if (state.settings.severity.isEnabled(Severity::information)) { + if (state.settings().severity.isEnabled(Severity::information)) { const std::string& functionName = functionScope->className; std::list callstack( 1, - ErrorMessage::FileLocation(functionScope->bodyStart, &state.tokenlist)); + ErrorMessage::FileLocation(functionScope->bodyStart, &state.tokenlist())); const ErrorMessage errmsg(std::move(callstack), - state.tokenlist.getSourceFilePath(), + state.tokenlist().getSourceFilePath(), Severity::information, "Limiting ValueFlow analysis in function '" + functionName + "' since it is too complex. " "Please specify --check-level=exhaustive to perform full analysis.", "checkLevelNormal", // TODO: use more specific ID Certainty::normal); - state.errorLogger.reportErr(errmsg); + state.errorLogger().reportErr(errmsg); } } } @@ -7390,8 +7391,8 @@ struct ValueFlowPassRunner { void setStopTime() { - if (state.settings.vfOptions.maxTime >= 0) - stop = Clock::now() + std::chrono::seconds{state.settings.vfOptions.maxTime}; + if (state.settings().vfOptions.maxTime >= 0) + stop = Clock::now() + std::chrono::seconds{state.settings().vfOptions.maxTime}; } ValueFlowState state; diff --git a/lib/vf_analyzers.cpp b/lib/vf_analyzers.cpp index b2ef2abe1ea..bc988051c3d 100644 --- a/lib/vf_analyzers.cpp +++ b/lib/vf_analyzers.cpp @@ -24,6 +24,7 @@ #include "config.h" #include "library.h" #include "mathlib.h" +#include "refthunk.h" #include "programmemory.h" #include "smallvector.h" #include "settings.h" @@ -59,10 +60,10 @@ static bool isDereferenceOp(const Token* tok) } struct ValueFlowAnalyzer : Analyzer { - const Settings& settings; + RefThunk settings; ProgramMemoryState pms; - explicit ValueFlowAnalyzer(const Settings& s) : settings(s), pms(settings) {} + explicit ValueFlowAnalyzer(const Settings& s) : settings(s), pms(s) {} virtual const ValueFlow::Value* getValue(const Token* tok) const = 0; virtual ValueFlow::Value* getValue(const Token* tok) = 0; @@ -1325,7 +1326,7 @@ struct ExpressionAnalyzer : SingleValueFlowAnalyzer { } void setupExprVarIds(const Token* start, int depth = 0) { - if (depth > settings.vfOptions.maxExprVarIdDepth) { + if (depth > settings().vfOptions.maxExprVarIdDepth) { // TODO: add bailout message return; } @@ -1561,7 +1562,7 @@ struct ContainerExpressionAnalyzer : ExpressionAnalyzer { if (action == Library::Container::Action::PUSH || action == Library::Container::Action::POP || action == Library::Container::Action::APPEND) { // TODO: handle more actions? std::vector args = getArguments(tok->tokAt(3)); bool isVariadic = false; - if (const Library::Function* libFunc = settings.library.getFunction(tok->tokAt(2))) { + if (const Library::Function* libFunc = settings().library.getFunction(tok->tokAt(2))) { const auto& argChecks = libFunc->argumentChecks; isVariadic = argChecks.find(-1) != argChecks.end() && argChecks.at(-1).variadic; } @@ -1609,7 +1610,7 @@ struct ContainerExpressionAnalyzer : ExpressionAnalyzer { case Library::Container::Action::APPEND: { std::vector args = getArguments(tok->astParent()->tokAt(2)); if (args.size() == 1) // TODO: handle overloads - n = ValueFlow::valueFlowGetStrLength(tok->astParent()->tokAt(3), settings.library); + n = ValueFlow::valueFlowGetStrLength(tok->astParent()->tokAt(3), settings().library); if (n == 0) // TODO: handle known empty append val->setPossible(); break; diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index 7413910834f..5b8a1d159d4 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -153,43 +153,43 @@ simplecpp.o: ../externals/simplecpp/simplecpp.cpp ../externals/simplecpp/simplec tinyxml2.o: ../externals/tinyxml2/tinyxml2.cpp ../externals/tinyxml2/tinyxml2.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -w -D_LARGEFILE_SOURCE -c -o $@ ../externals/tinyxml2/tinyxml2.cpp -$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkuninitvar.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/programmemory.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h +$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkuninitvar.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/programmemory.h ../lib/refthunk.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp -$(libcppdir)/tokenize.o: ../lib/tokenize.cpp ../externals/simplecpp/simplecpp.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/tokenize.o: ../lib/tokenize.cpp ../externals/simplecpp/simplecpp.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/tokenize.cpp -$(libcppdir)/symboldatabase.o: ../lib/symboldatabase.cpp ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/keywords.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/symboldatabase.o: ../lib/symboldatabase.cpp ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/keywords.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/symboldatabase.cpp $(libcppdir)/addoninfo.o: ../lib/addoninfo.cpp ../externals/picojson/picojson.h ../lib/addoninfo.h ../lib/config.h ../lib/json.h ../lib/path.h ../lib/standards.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/addoninfo.cpp -$(libcppdir)/analyzerinfo.o: ../lib/analyzerinfo.cpp ../externals/tinyxml2/tinyxml2.h ../lib/analyzerinfo.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/standards.h ../lib/utils.h ../lib/xml.h +$(libcppdir)/analyzerinfo.o: ../lib/analyzerinfo.cpp ../externals/tinyxml2/tinyxml2.h ../lib/analyzerinfo.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/refthunk.h ../lib/standards.h ../lib/utils.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/analyzerinfo.cpp -$(libcppdir)/astutils.o: ../lib/astutils.cpp ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/findtoken.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vfvalue.h +$(libcppdir)/astutils.o: ../lib/astutils.cpp ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/findtoken.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/astutils.cpp -$(libcppdir)/check64bit.o: ../lib/check64bit.cpp ../lib/check.h ../lib/check64bit.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/check64bit.o: ../lib/check64bit.cpp ../lib/check.h ../lib/check64bit.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/check64bit.cpp -$(libcppdir)/checkassert.o: ../lib/checkassert.cpp ../lib/astutils.h ../lib/check.h ../lib/checkassert.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkassert.o: ../lib/checkassert.cpp ../lib/astutils.h ../lib/check.h ../lib/checkassert.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkassert.cpp -$(libcppdir)/checkautovariables.o: ../lib/checkautovariables.cpp ../lib/astutils.h ../lib/check.h ../lib/checkautovariables.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkautovariables.o: ../lib/checkautovariables.cpp ../lib/astutils.h ../lib/check.h ../lib/checkautovariables.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkautovariables.cpp -$(libcppdir)/checkbool.o: ../lib/checkbool.cpp ../lib/astutils.h ../lib/check.h ../lib/checkbool.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkbool.o: ../lib/checkbool.cpp ../lib/astutils.h ../lib/check.h ../lib/checkbool.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbool.cpp -$(libcppdir)/checkbufferoverrun.o: ../lib/checkbufferoverrun.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/check.h ../lib/checkbufferoverrun.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/checkbufferoverrun.o: ../lib/checkbufferoverrun.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/check.h ../lib/checkbufferoverrun.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbufferoverrun.cpp -$(libcppdir)/checkclass.o: ../lib/checkclass.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/checkclass.o: ../lib/checkclass.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkclass.cpp -$(libcppdir)/checkcondition.o: ../lib/checkcondition.cpp ../lib/astutils.h ../lib/check.h ../lib/checkcondition.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkcondition.o: ../lib/checkcondition.cpp ../lib/astutils.h ../lib/check.h ../lib/checkcondition.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkcondition.cpp $(libcppdir)/checkers.o: ../lib/checkers.cpp ../lib/checkers.h ../lib/config.h @@ -198,79 +198,79 @@ $(libcppdir)/checkers.o: ../lib/checkers.cpp ../lib/checkers.h ../lib/config.h $(libcppdir)/checkersidmapping.o: ../lib/checkersidmapping.cpp ../lib/checkers.h ../lib/config.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkersidmapping.cpp -$(libcppdir)/checkersreport.o: ../lib/checkersreport.cpp ../lib/addoninfo.h ../lib/checkers.h ../lib/checkersreport.h ../lib/config.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/standards.h ../lib/utils.h +$(libcppdir)/checkersreport.o: ../lib/checkersreport.cpp ../lib/addoninfo.h ../lib/checkers.h ../lib/checkersreport.h ../lib/config.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/standards.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkersreport.cpp -$(libcppdir)/checkexceptionsafety.o: ../lib/checkexceptionsafety.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkexceptionsafety.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkexceptionsafety.o: ../lib/checkexceptionsafety.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkexceptionsafety.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkexceptionsafety.cpp -$(libcppdir)/checkfunctions.o: ../lib/checkfunctions.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkfunctions.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkfunctions.o: ../lib/checkfunctions.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkfunctions.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkfunctions.cpp -$(libcppdir)/checkimpl.o: ../lib/checkimpl.cpp ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkimpl.o: ../lib/checkimpl.cpp ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkimpl.cpp -$(libcppdir)/checkinternal.o: ../lib/checkinternal.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkinternal.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkinternal.o: ../lib/checkinternal.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkinternal.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkinternal.cpp -$(libcppdir)/checkio.o: ../lib/checkio.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkio.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkio.o: ../lib/checkio.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkio.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkio.cpp -$(libcppdir)/checkleakautovar.o: ../lib/checkleakautovar.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkleakautovar.h ../lib/checkmemoryleak.h ../lib/checknullpointer.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkleakautovar.o: ../lib/checkleakautovar.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkleakautovar.h ../lib/checkmemoryleak.h ../lib/checknullpointer.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkleakautovar.cpp -$(libcppdir)/checkmemoryleak.o: ../lib/checkmemoryleak.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkmemoryleak.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkmemoryleak.o: ../lib/checkmemoryleak.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkmemoryleak.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkmemoryleak.cpp -$(libcppdir)/checknullpointer.o: ../lib/checknullpointer.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checknullpointer.o: ../lib/checknullpointer.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checknullpointer.cpp -$(libcppdir)/checkother.o: ../lib/checkother.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkother.o: ../lib/checkother.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkother.cpp -$(libcppdir)/checkpostfixoperator.o: ../lib/checkpostfixoperator.cpp ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkpostfixoperator.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkpostfixoperator.o: ../lib/checkpostfixoperator.cpp ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkpostfixoperator.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkpostfixoperator.cpp -$(libcppdir)/checks.o: ../lib/checks.cpp ../lib/check.h ../lib/check64bit.h ../lib/checkassert.h ../lib/checkautovariables.h ../lib/checkbool.h ../lib/checkbufferoverrun.h ../lib/checkclass.h ../lib/checkcondition.h ../lib/checkexceptionsafety.h ../lib/checkfunctions.h ../lib/checkimpl.h ../lib/checkinternal.h ../lib/checkio.h ../lib/checkleakautovar.h ../lib/checkmemoryleak.h ../lib/checknullpointer.h ../lib/checkother.h ../lib/checkpostfixoperator.h ../lib/checks.h ../lib/checksizeof.h ../lib/checkstl.h ../lib/checkstring.h ../lib/checktype.h ../lib/checkuninitvar.h ../lib/checkunusedvar.h ../lib/checkvaarg.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/standards.h ../lib/vfvalue.h +$(libcppdir)/checks.o: ../lib/checks.cpp ../lib/check.h ../lib/check64bit.h ../lib/checkassert.h ../lib/checkautovariables.h ../lib/checkbool.h ../lib/checkbufferoverrun.h ../lib/checkclass.h ../lib/checkcondition.h ../lib/checkexceptionsafety.h ../lib/checkfunctions.h ../lib/checkimpl.h ../lib/checkinternal.h ../lib/checkio.h ../lib/checkleakautovar.h ../lib/checkmemoryleak.h ../lib/checknullpointer.h ../lib/checkother.h ../lib/checkpostfixoperator.h ../lib/checks.h ../lib/checksizeof.h ../lib/checkstl.h ../lib/checkstring.h ../lib/checktype.h ../lib/checkuninitvar.h ../lib/checkunusedvar.h ../lib/checkvaarg.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/refthunk.h ../lib/standards.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checks.cpp -$(libcppdir)/checksizeof.o: ../lib/checksizeof.cpp ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checksizeof.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checksizeof.o: ../lib/checksizeof.cpp ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checksizeof.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checksizeof.cpp -$(libcppdir)/checkstl.o: ../lib/checkstl.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/checkstl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/pathanalysis.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkstl.o: ../lib/checkstl.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/checkstl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/pathanalysis.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstl.cpp -$(libcppdir)/checkstring.o: ../lib/checkstring.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkstring.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkstring.o: ../lib/checkstring.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkstring.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstring.cpp -$(libcppdir)/checktype.o: ../lib/checktype.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checktype.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checktype.o: ../lib/checktype.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checktype.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checktype.cpp -$(libcppdir)/checkuninitvar.o: ../lib/checkuninitvar.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/checkuninitvar.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkuninitvar.o: ../lib/checkuninitvar.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/checkuninitvar.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkuninitvar.cpp -$(libcppdir)/checkunusedfunctions.o: ../lib/checkunusedfunctions.cpp ../externals/tinyxml2/tinyxml2.h ../lib/analyzerinfo.h ../lib/astutils.h ../lib/checkers.h ../lib/checkunusedfunctions.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/checkunusedfunctions.o: ../lib/checkunusedfunctions.cpp ../externals/tinyxml2/tinyxml2.h ../lib/analyzerinfo.h ../lib/astutils.h ../lib/checkers.h ../lib/checkunusedfunctions.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedfunctions.cpp -$(libcppdir)/checkunusedvar.o: ../lib/checkunusedvar.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkunusedvar.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkunusedvar.o: ../lib/checkunusedvar.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkunusedvar.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedvar.cpp -$(libcppdir)/checkvaarg.o: ../lib/checkvaarg.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkvaarg.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkvaarg.o: ../lib/checkvaarg.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkvaarg.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkvaarg.cpp -$(libcppdir)/clangimport.o: ../lib/clangimport.cpp ../lib/clangimport.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/clangimport.o: ../lib/clangimport.cpp ../lib/clangimport.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/refthunk.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/clangimport.cpp $(libcppdir)/color.o: ../lib/color.cpp ../lib/color.h ../lib/config.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/color.cpp -$(libcppdir)/cppcheck.o: ../lib/cppcheck.cpp ../externals/picojson/picojson.h ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/analyzerinfo.h ../lib/check.h ../lib/checkers.h ../lib/checks.h ../lib/checkunusedfunctions.h ../lib/clangimport.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/regex.h ../lib/rule.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/version.h ../lib/vfvalue.h +$(libcppdir)/cppcheck.o: ../lib/cppcheck.cpp ../externals/picojson/picojson.h ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/analyzerinfo.h ../lib/check.h ../lib/checkers.h ../lib/checks.h ../lib/checkunusedfunctions.h ../lib/clangimport.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/refthunk.h ../lib/regex.h ../lib/rule.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/version.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/cppcheck.cpp -$(libcppdir)/ctu.o: ../lib/ctu.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/check.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/ctu.o: ../lib/ctu.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/check.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/refthunk.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/ctu.cpp -$(libcppdir)/errorlogger.o: ../lib/errorlogger.cpp ../externals/tinyxml2/tinyxml2.h ../lib/check.h ../lib/checkers.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/errorlogger.o: ../lib/errorlogger.cpp ../externals/tinyxml2/tinyxml2.h ../lib/check.h ../lib/checkers.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errorlogger.cpp $(libcppdir)/errortypes.o: ../lib/errortypes.cpp ../lib/config.h ../lib/errortypes.h ../lib/utils.h @@ -279,10 +279,10 @@ $(libcppdir)/errortypes.o: ../lib/errortypes.cpp ../lib/config.h ../lib/errortyp $(libcppdir)/findtoken.o: ../lib/findtoken.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/findtoken.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/findtoken.cpp -$(libcppdir)/forwardanalyzer.o: ../lib/forwardanalyzer.cpp ../lib/analyzer.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/forwardanalyzer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h +$(libcppdir)/forwardanalyzer.o: ../lib/forwardanalyzer.cpp ../lib/analyzer.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/forwardanalyzer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/forwardanalyzer.cpp -$(libcppdir)/fwdanalysis.o: ../lib/fwdanalysis.cpp ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/fwdanalysis.o: ../lib/fwdanalysis.cpp ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/fwdanalysis.cpp $(libcppdir)/importproject.o: ../lib/importproject.cpp ../externals/picojson/picojson.h ../externals/tinyxml2/tinyxml2.h ../lib/checkers.h ../lib/config.h ../lib/filesettings.h ../lib/importproject.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/pathmatch.h ../lib/platform.h ../lib/settings.h ../lib/standards.h ../lib/suppressions.h ../lib/utils.h ../lib/xml.h @@ -294,7 +294,7 @@ $(libcppdir)/infer.o: ../lib/infer.cpp ../lib/calculate.h ../lib/config.h ../lib $(libcppdir)/keywords.o: ../lib/keywords.cpp ../lib/config.h ../lib/keywords.h ../lib/standards.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/keywords.cpp -$(libcppdir)/library.o: ../lib/library.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/library.o: ../lib/library.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/refthunk.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/library.cpp $(libcppdir)/mathlib.o: ../lib/mathlib.cpp ../externals/simplecpp/simplecpp.h ../lib/config.h ../lib/errortypes.h ../lib/mathlib.h ../lib/smallvector.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h @@ -303,7 +303,7 @@ $(libcppdir)/mathlib.o: ../lib/mathlib.cpp ../externals/simplecpp/simplecpp.h .. $(libcppdir)/path.o: ../lib/path.cpp ../externals/simplecpp/simplecpp.h ../lib/config.h ../lib/path.h ../lib/standards.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/path.cpp -$(libcppdir)/pathanalysis.o: ../lib/pathanalysis.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/pathanalysis.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/pathanalysis.o: ../lib/pathanalysis.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/pathanalysis.h ../lib/refthunk.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/pathanalysis.cpp $(libcppdir)/pathmatch.o: ../lib/pathmatch.cpp ../lib/config.h ../lib/path.h ../lib/pathmatch.h ../lib/standards.h @@ -312,19 +312,19 @@ $(libcppdir)/pathmatch.o: ../lib/pathmatch.cpp ../lib/config.h ../lib/path.h ../ $(libcppdir)/platform.o: ../lib/platform.cpp ../externals/tinyxml2/tinyxml2.h ../lib/config.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/standards.h ../lib/utils.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/platform.cpp -$(libcppdir)/preprocessor.o: ../lib/preprocessor.cpp ../externals/simplecpp/simplecpp.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/settings.h ../lib/standards.h ../lib/suppressions.h ../lib/utils.h +$(libcppdir)/preprocessor.o: ../lib/preprocessor.cpp ../externals/simplecpp/simplecpp.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/refthunk.h ../lib/settings.h ../lib/standards.h ../lib/suppressions.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/preprocessor.cpp -$(libcppdir)/programmemory.o: ../lib/programmemory.cpp ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vfvalue.h +$(libcppdir)/programmemory.o: ../lib/programmemory.cpp ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/programmemory.cpp $(libcppdir)/regex.o: ../lib/regex.cpp ../lib/config.h ../lib/regex.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/regex.cpp -$(libcppdir)/reverseanalyzer.o: ../lib/reverseanalyzer.cpp ../lib/analyzer.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/forwardanalyzer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h +$(libcppdir)/reverseanalyzer.o: ../lib/reverseanalyzer.cpp ../lib/analyzer.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/forwardanalyzer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/reverseanalyzer.cpp -$(libcppdir)/sarifreport.o: ../lib/sarifreport.cpp ../externals/picojson/picojson.h ../lib/check.h ../lib/checkers.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/sarifreport.h ../lib/settings.h ../lib/standards.h ../lib/utils.h +$(libcppdir)/sarifreport.o: ../lib/sarifreport.cpp ../externals/picojson/picojson.h ../lib/check.h ../lib/checkers.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/sarifreport.h ../lib/settings.h ../lib/standards.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/sarifreport.cpp $(libcppdir)/settings.o: ../lib/settings.cpp ../externals/picojson/picojson.h ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/rule.h ../lib/settings.h ../lib/standards.h ../lib/summaries.h ../lib/suppressions.h ../lib/utils.h ../lib/vfvalue.h @@ -333,34 +333,34 @@ $(libcppdir)/settings.o: ../lib/settings.cpp ../externals/picojson/picojson.h .. $(libcppdir)/standards.o: ../lib/standards.cpp ../externals/simplecpp/simplecpp.h ../lib/config.h ../lib/standards.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/standards.cpp -$(libcppdir)/summaries.o: ../lib/summaries.cpp ../lib/analyzerinfo.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/summaries.o: ../lib/summaries.cpp ../lib/analyzerinfo.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/summaries.cpp -$(libcppdir)/suppressions.o: ../lib/suppressions.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/pathmatch.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/suppressions.o: ../lib/suppressions.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/pathmatch.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/suppressions.cpp -$(libcppdir)/templatesimplifier.o: ../lib/templatesimplifier.cpp ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/templatesimplifier.o: ../lib/templatesimplifier.cpp ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/templatesimplifier.cpp $(libcppdir)/timer.o: ../lib/timer.cpp ../lib/config.h ../lib/timer.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/timer.cpp -$(libcppdir)/token.o: ../lib/token.cpp ../externals/simplecpp/simplecpp.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/tokenrange.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/token.o: ../lib/token.cpp ../externals/simplecpp/simplecpp.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/tokenrange.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/token.cpp -$(libcppdir)/tokenlist.o: ../lib/tokenlist.cpp ../externals/simplecpp/simplecpp.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/keywords.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/tokenlist.o: ../lib/tokenlist.cpp ../externals/simplecpp/simplecpp.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/keywords.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/tokenlist.cpp $(libcppdir)/utils.o: ../lib/utils.cpp ../lib/config.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/utils.cpp -$(libcppdir)/vf_analyzers.o: ../lib/vf_analyzers.cpp ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h +$(libcppdir)/vf_analyzers.o: ../lib/vf_analyzers.cpp ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_analyzers.cpp -$(libcppdir)/vf_common.o: ../lib/vf_common.cpp ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h +$(libcppdir)/vf_common.o: ../lib/vf_common.cpp ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_common.cpp -$(libcppdir)/vf_settokenvalue.o: ../lib/vf_settokenvalue.cpp ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h +$(libcppdir)/vf_settokenvalue.o: ../lib/vf_settokenvalue.cpp ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_settokenvalue.cpp $(libcppdir)/vfvalue.o: ../lib/vfvalue.cpp ../lib/config.h ../lib/errortypes.h ../lib/mathlib.h ../lib/smallvector.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h diff --git a/test/fixture.cpp b/test/fixture.cpp index de42837a56e..a561b4fc28f 100644 --- a/test/fixture.cpp +++ b/test/fixture.cpp @@ -509,7 +509,7 @@ TestFixture::SettingsBuilder& TestFixture::SettingsBuilder::library(const char l if (REDUNDANT_CHECK && std::find(settings.libraries.cbegin(), settings.libraries.cend(), lib) != settings.libraries.cend()) throw std::runtime_error("redundant setting: libraries (" + std::string(lib) + ")"); // TODO: exename is not yet set - const Library::ErrorCode lib_error = settings.library.load(fixture.exename.c_str(), lib).errorcode; + const Library::ErrorCode lib_error = settings.library.load(fixture().exename.c_str(), lib).errorcode; if (lib_error != Library::ErrorCode::OK) throw std::runtime_error("loading library '" + std::string(lib) + "' failed - " + std::to_string(static_cast(lib_error))); // strip extension @@ -531,7 +531,7 @@ TestFixture::SettingsBuilder& TestFixture::SettingsBuilder::platform(Platform::T std::string errstr; // TODO: exename is not yet set - if (!settings.platform.set(platformStr, errstr, {fixture.exename})) + if (!settings.platform.set(platformStr, errstr, {fixture().exename})) throw std::runtime_error("platform '" + platformStr + "' not found"); return *this; } diff --git a/test/fixture.h b/test/fixture.h index c5828033fd7..3d1e96562ba 100644 --- a/test/fixture.h +++ b/test/fixture.h @@ -25,6 +25,7 @@ #include "config.h" #include "errorlogger.h" #include "errortypes.h" +#include "refthunk.h" #include "platform.h" #include "settings.h" #include "standards.h" @@ -239,7 +240,7 @@ class TestFixture : public ErrorLogger { private: SettingsBuilder& libraryxml(const char xmldata[], std::size_t len); - const TestFixture &fixture; + RefThunk fixture; Settings settings; static constexpr bool REDUNDANT_CHECK = false; diff --git a/test/helpers.h b/test/helpers.h index a08eb3f1572..cd4cde7af1c 100644 --- a/test/helpers.h +++ b/test/helpers.h @@ -136,7 +136,7 @@ class SimpleTokenList } private: - const Settings settings; + Settings settings; TokenList list; }; diff --git a/test/testrefthunk.cpp b/test/testrefthunk.cpp new file mode 100644 index 00000000000..f9ae525295a --- /dev/null +++ b/test/testrefthunk.cpp @@ -0,0 +1,134 @@ +/* + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2026 Cppcheck team. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "fixture.h" +#include "refthunk.h" + +#include +#include + +class TestRefThunk : public TestFixture { +public: + TestRefThunk() : TestFixture("TestRefThunk") {} + +private: + void run() override { + TEST_CASE(callAccess); + TEST_CASE(getReference); + TEST_CASE(referenceConversion); + TEST_CASE(memberAccess); + TEST_CASE(mutation); + TEST_CASE(copyConstruct); + TEST_CASE(copyAssign); + TEST_CASE(rebind); + TEST_CASE(convertToConst); + TEST_CASE(functionArguments); + } + + void callAccess() const { + int x = 42; + const RefThunk p(x); + ASSERT_EQUALS(42, p()); + ASSERT(&p() == &x); + } + + void getReference() const { + int x = 1; + const RefThunk p(x); + ASSERT(&p.get() == &x); + p.get() = 2; + ASSERT_EQUALS(2, x); + } + + void referenceConversion() const { + int x = 1; + const RefThunk p(x); + int& ref = p; + ASSERT(&ref == &x); + ref = 2; + ASSERT_EQUALS(2, x); + } + + void memberAccess() const { + const std::string s = "abc"; + const RefThunk p(s); + ASSERT_EQUALS(3, p().size()); + ASSERT_EQUALS("abc", p()); + } + + void mutation() const { + std::string s = "abc"; + const RefThunk p(s); + p() += "d"; + p().push_back('e'); + ASSERT_EQUALS("abcde", s); + } + + void copyConstruct() const { + int x = 1; + const RefThunk p(x); + const RefThunk q(p); + ASSERT(&q() == &x); + } + + void copyAssign() const { + int x = 1; + int y = 2; + RefThunk p(x); + const RefThunk q(y); + ASSERT(&p() == &x); + p = q; + ASSERT(&p() == &y); + ASSERT_EQUALS(2, p()); + } + + void rebind() const { + int x = 1; + int y = 2; + RefThunk p(x); + ASSERT(&p() == &x); + // assignment rebinds, like std::reference_wrapper - it does not write through + p = y; + ASSERT(&p() == &y); + ASSERT_EQUALS(1, x); + } + + void convertToConst() const { + int x = 1; + const RefThunk p(x); + const RefThunk cp(p); + ASSERT(&cp() == &x); + const int& ref = cp; + ASSERT(&ref == &x); + } + + static std::size_t refArg(const std::string& s) { + return s.size(); + } + + void functionArguments() const { + std::string s = "abcd"; + const RefThunk p(s); + // implicit conversion to reference, like std::reference_wrapper + ASSERT_EQUALS(4, refArg(p)); + // explicit access through operator() + ASSERT_EQUALS(4, refArg(p())); + } +}; + +REGISTER_TEST(TestRefThunk) diff --git a/test/testrunner.vcxproj b/test/testrunner.vcxproj index 1c5230c5535..2ce6a97d9c4 100755 --- a/test/testrunner.vcxproj +++ b/test/testrunner.vcxproj @@ -87,6 +87,7 @@ + diff --git a/tools/dmake/dmake.cpp b/tools/dmake/dmake.cpp index eaf0a727646..f9e638385e7 100644 --- a/tools/dmake/dmake.cpp +++ b/tools/dmake/dmake.cpp @@ -502,6 +502,7 @@ int main(int argc, char **argv) libfiles_h.emplace("findtoken.h"); libfiles_h.emplace("json.h"); libfiles_h.emplace("matchcompiler.h"); + libfiles_h.emplace("refthunk.h"); libfiles_h.emplace("precompiled.h"); libfiles_h.emplace("rule.h"); libfiles_h.emplace("smallvector.h"); From 03bb21e9c9f4cba0cccae3e707c3e3c84b693cc6 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Wed, 28 Oct 2026 03:43:15 -0500 Subject: [PATCH 27/32] Follow up 15102 Fix compilation error with RefThunk (#8972) --- lib/vf_analyzers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vf_analyzers.cpp b/lib/vf_analyzers.cpp index bc988051c3d..27c27934f31 100644 --- a/lib/vf_analyzers.cpp +++ b/lib/vf_analyzers.cpp @@ -358,7 +358,7 @@ struct ValueFlowAnalyzer : Analyzer { if (dst) { const size_t sz = dst->getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer); if (sz > 0 && sz < sizeof(MathLib::biguint)) { - MathLib::bigint newvalue = ValueFlow::truncateIntValue(value->intvalue, sz, dst, settings.platform); + MathLib::bigint newvalue = ValueFlow::truncateIntValue(value->intvalue, sz, dst, settings().platform); /* Handle overflow/underflow for value bounds */ if (value->bound != ValueFlow::Value::Bound::Point) { From 99a4e0d20e54950b9bea9eac3394c42ca09fd307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Wed, 28 Oct 2026 14:14:00 +0100 Subject: [PATCH 28/32] Fix #15129: Improve matching performance for hash based suppressions (#8970) Makes it so that hash based suppressions are indexed by hash. Matching hash based suppressions is now O(1) (ignoring collisions) instead of O(n). For large code bases using baseline suppressions (which may be in the number of tens of thousands) this leads to a substantial speed up. We could probably speed up matching of other suppressions in the future as well, but I assume these are in general manually added and won't even get close to the same number as baseline suppressions. Also fixed a bug in ProcessExecutor that would cause new suppressions to be added unintentionally. --- cli/processexecutor.cpp | 2 +- lib/suppressions.cpp | 79 ++++++++++++++++++++++++++++----------- lib/suppressions.h | 18 +++++++-- test/cli/other_test.py | 34 +++++++++++++++++ test/testsuppressions.cpp | 31 +++++++++++++++ 5 files changed, 138 insertions(+), 26 deletions(-) diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp index eb50177ef1e..f0f01bcffe7 100644 --- a/cli/processexecutor.cpp +++ b/cli/processexecutor.cpp @@ -96,7 +96,7 @@ namespace { { if (suppr.isInline) writeToPipe(REPORT_SUPPR_INLINE, suppressionToString(suppr)); - else if (suppr.checked) + else if (suppr.checked && suppr.hash == 0) writeToPipe(REPORT_SUPPR, suppressionToString(suppr)); } } diff --git a/lib/suppressions.cpp b/lib/suppressions.cpp index c3569e40d85..0089510c86f 100644 --- a/lib/suppressions.cpp +++ b/lib/suppressions.cpp @@ -32,7 +32,6 @@ #include // std::isdigit, std::isalnum, etc #include #include -#include // std::bind, std::placeholders #include #include #include @@ -325,14 +324,27 @@ std::string SuppressionList::addSuppressionLine(const std::string &line) } } +SuppressionList::Suppression *SuppressionList::findSameParameters(const Suppression &suppression) +{ + const std::vector *candidates = &mNonHashSuppressions; + if (suppression.hash > 0) { + const auto it = mHashSuppressions.find(suppression.hash); + if (it == mHashSuppressions.end()) + return nullptr; + candidates = &it->second; + } + const auto found = std::find_if(candidates->cbegin(), candidates->cend(), [&](const Suppression *s) { + return suppression.isSameParameters(*s); + }); + return found != candidates->cend() ? *found : nullptr; +} + std::string SuppressionList::addSuppression(SuppressionList::Suppression suppression) { std::lock_guard lg(mSuppressionsSync); // Check if suppression is already in list - auto foundSuppression = std::find_if(mSuppressions.begin(), mSuppressions.end(), - std::bind(&Suppression::isSameParameters, &suppression, std::placeholders::_1)); - if (foundSuppression != mSuppressions.end()) { + if (findSameParameters(suppression)) { return "suppression '" + suppression.toString() + "' already exists"; } @@ -356,6 +368,12 @@ std::string SuppressionList::addSuppression(SuppressionList::Suppression suppres mSuppressions.push_back(std::move(suppression)); + Suppression *const added = &mSuppressions.back(); + if (added->hash > 0) + mHashSuppressions[added->hash].push_back(added); + else + mNonHashSuppressions.push_back(added); + return ""; } @@ -374,9 +392,8 @@ bool SuppressionList::updateSuppressionState(const SuppressionList::Suppression& std::lock_guard lg(mSuppressionsSync); // Check if suppression is already in list - auto foundSuppression = std::find_if(mSuppressions.begin(), mSuppressions.end(), - std::bind(&Suppression::isSameParameters, &suppression, std::placeholders::_1)); - if (foundSuppression != mSuppressions.end()) { + Suppression *const foundSuppression = findSameParameters(suppression); + if (foundSuppression) { if (suppression.checked) foundSuppression->checked = true; if (suppression.matched) @@ -525,13 +542,21 @@ bool SuppressionList::isSuppressed(const SuppressionList::ErrorMessage &errmsg, // TODO: handle unmatchedPolyspaceSuppression? const bool unmatchedSuppression(errmsg.errorId == "unmatchedSuppression"); bool returnValue = false; - for (Suppression &s : mSuppressions) { - if (!global && !s.isLocal()) - continue; - if (unmatchedSuppression && s.errorId != errmsg.errorId) - continue; - if (s.isMatch(errmsg)) - returnValue = true; + const auto match = [&](const std::vector &suppressions) { + for (Suppression *s : suppressions) { + if (!global && !s->isLocal()) + continue; + if (unmatchedSuppression && s->errorId != errmsg.errorId) + continue; + if (s->isMatch(errmsg)) + returnValue = true; + } + }; + match(mNonHashSuppressions); + if (errmsg.hash != 0) { + const auto it = mHashSuppressions.find(errmsg.hash); + if (it != mHashSuppressions.end()) + match(it->second); } return returnValue; } @@ -540,13 +565,21 @@ bool SuppressionList::isSuppressedExplicitly(const SuppressionList::ErrorMessage { std::lock_guard lg(mSuppressionsSync); - for (Suppression &s : mSuppressions) { - if (!global && !s.isLocal()) - continue; - if (s.errorId != errmsg.errorId) // Error id must match exactly - continue; - if (s.isMatch(errmsg)) - return true; + const auto match = [&](const std::vector &suppressions) { + return std::any_of(suppressions.cbegin(), suppressions.cend(), [&](Suppression *s) { + if (!global && !s->isLocal()) + return false; + if (s->errorId != errmsg.errorId) // Error id must match exactly + return false; + return s->isMatch(errmsg); + }); + }; + if (match(mNonHashSuppressions)) + return true; + if (errmsg.hash != 0) { + const auto it = mHashSuppressions.find(errmsg.hash); + if (it != mHashSuppressions.end()) + return match(it->second); } return false; } @@ -687,7 +720,9 @@ void SuppressionList::markUnmatchedInlineSuppressionsAsChecked(const TokenList & if (currFileIdx != tok->fileIndex() || currLineNr != tok->linenr()) { currLineNr = tok->linenr(); currFileIdx = tok->fileIndex(); - for (auto &suppression : mSuppressions) { + // checked is not used for hash suppressions + for (Suppression *s : mNonHashSuppressions) { + Suppression &suppression = *s; if (suppression.type == SuppressionList::Type::unique) { if (!suppression.checked && (suppression.lineNumber == currLineNr) && (suppression.fileName == tokenlist.file(tok))) { suppression.checked = true; diff --git a/lib/suppressions.h b/lib/suppressions.h index ef5f9c4e405..42955ab7b91 100644 --- a/lib/suppressions.h +++ b/lib/suppressions.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -51,14 +52,14 @@ class CPPCHECKLIB SuppressionList { }; struct CPPCHECKLIB ErrorMessage { - std::size_t hash; + std::size_t hash{}; std::string errorId; void setFileName(std::string s); const std::string &getFileName() const { return mFileName; } - int lineNumber; // TODO: need to be unsigned - Certainty certainty; + int lineNumber{}; // TODO: need to be unsigned + Certainty certainty{}; std::string symbolNames; std::set macroNames; @@ -294,9 +295,20 @@ class CPPCHECKLIB SuppressionList { void markUnmatchedInlineSuppressionsAsChecked(const TokenList &tokenlist); private: + /** + * @brief Find a suppression with the same parameters. mSuppressionsSync must be locked. + * @param suppression the suppression to look for + * @return the found suppression, or nullptr + */ + Suppression *findSameParameters(const Suppression &suppression); + mutable std::mutex mSuppressionsSync; /** @brief List of error which the user doesn't want to see. */ std::list mSuppressions; + /** @brief Suppressions in mSuppressions with hash > 0, indexed by hash */ + std::unordered_map> mHashSuppressions; + /** @brief Suppressions in mSuppressions with hash == 0 */ + std::vector mNonHashSuppressions; }; struct Suppressions diff --git a/test/cli/other_test.py b/test/cli/other_test.py index 245726adad7..0123a97128e 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -4925,6 +4925,40 @@ def test_ipc_inline_suppressions(tmp_path): assert stdout_lines == stdout_exp assert stderr.splitlines() == [] + +@pytest.mark.skipif(sys.platform == 'win32', reason="requires ProcessExecutor") +def test_ipc_hash_suppressions(tmp_path): + test_file = tmp_path / 'test.c' + with open(test_file, "w") as f: + f.write('void f() { int x = 1; }') + + _, _, stderr = cppcheck(['--enable=style', '--xml-version=3', str(test_file)]) + error_hash = ElementTree.fromstring(stderr).find('.//error').get('hash') + + suppr_file = tmp_path / 'suppr.xml' + with open(suppr_file, "w") as f: + f.write(f'unreadVariable{test_file}{error_hash}') + + args = [ + '-q', + '--debug-ipc', + '-j2', + '--executor=process', + '--no-cppcheck-build-dir', + '--enable=style', + f'--suppress-xml={suppr_file}', + str(test_file) + ] + + exitcode, stdout, stderr = cppcheck(args) + assert exitcode == 0 + # the hash suppression is not sent to the parent + assert stdout.splitlines() == [ + 'writeToPipe - 5 - 0', + 'handleRead - 5 - 0' + ] + assert stderr.splitlines() == [] + test_redundant_file_reads_params = [ ([], 3), (['--suppress=zerodiv'], 1), diff --git a/test/testsuppressions.cpp b/test/testsuppressions.cpp index 9460999adb1..fbdcb6307e5 100644 --- a/test/testsuppressions.cpp +++ b/test/testsuppressions.cpp @@ -117,6 +117,7 @@ class TestSuppressions : public TestFixture { TEST_CASE(addSuppressionDuplicate); TEST_CASE(updateSuppressionState); TEST_CASE(addSuppressionLineMultiple); + TEST_CASE(hashSuppression); TEST_CASE(suppressionsParseXmlFile); TEST_CASE(xmlMacroSuppressions); @@ -1959,6 +1960,36 @@ class TestSuppressions : public TestFixture { } } + void hashSuppression() const { + SuppressionList supprs; + SuppressionList::Suppression s; + s.errorId = "id"; + s.hash = 1; + ASSERT_EQUALS("", supprs.addSuppression(s)); + ASSERT_EQUALS("suppression 'id' already exists", supprs.addSuppression(s)); + ASSERT_EQUALS(true, supprs.updateSuppressionState(s)); + s.hash = 2; + ASSERT_EQUALS(false, supprs.updateSuppressionState(s)); + // same hash, different id + s.errorId = "id2"; + s.hash = 1; + ASSERT_EQUALS("", supprs.addSuppression(s)); + ASSERT_EQUALS(true, supprs.updateSuppressionState(s)); + + SuppressionList::ErrorMessage error = errorMessage("id"); + error.hash = 1; + ASSERT_EQUALS(true, supprs.isSuppressed(error)); + error.hash = 2; + ASSERT_EQUALS(false, supprs.isSuppressed(error)); + error.hash = 0; + ASSERT_EQUALS(false, supprs.isSuppressed(error)); + error.hash = 1; + error.errorId = "id2"; + ASSERT_EQUALS(true, supprs.isSuppressed(error)); + error.errorId = "id3"; + ASSERT_EQUALS(false, supprs.isSuppressed(error)); + } + void addSuppressionLineMultiple() const { SuppressionList supprlist; From 6a3faa9dc76064b1dcc05ae23748ca0a50f196bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Thu, 29 Oct 2026 14:00:56 +0100 Subject: [PATCH 29/32] Fix #15105: False negative: uninitMemberVar with inherited constructor (#8937) --- lib/checkclass.cpp | 94 +++++++++++++++++++++++- lib/checkclass.h | 2 +- test/testconstructors.cpp | 150 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 242 insertions(+), 4 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 6f5bcd3a69e..223bde3b452 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -195,6 +195,65 @@ void CheckClassImpl::handleUnionMembers(std::vector& usageList) } } +static std::vector getInheritedConstructors(const Scope *scope) +{ + std::vector result; + + if (!scope || !scope->bodyStart || !scope->definedType) + return result; + + const auto isInherited = [](const Function &baseCtor, const Scope *scope) { + if (baseCtor.type != FunctionType::eConstructor || baseCtor.argCount() == 0) + return false; + if (baseCtor.isDelete() || baseCtor.access == AccessControl::Private) + return false; + return std::none_of(scope->functionList.cbegin(), scope->functionList.cend(), [&](const Function &func) { + return func.isConstructor() && func.argCount() == baseCtor.argCount() && + func.argsMatch(baseCtor.nestedIn, baseCtor.argDef, func.argDef, "", 0); + }); + }; + + const std::vector &bases = scope->definedType->derivedFrom; + const Token *baseName = nullptr; + const std::list *baseFuncs = nullptr; + for (const Token *tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { + if (Token::Match(tok, "using %name%")) { + const auto base = std::find_if( + bases.cbegin(), + bases.cend(), + [&tok](const Type::BaseInfo &info) { + return info.name == tok->strAt(1); + } + ); + if (base != bases.cend() && base->type && base->type->classScope) { + baseName = tok->next(); + baseFuncs = &base->type->classScope->functionList; + } + continue; + } + + if (tok->str() == ";") { + baseName = nullptr; + continue; + } + + if (tok->str() == "{") { + baseName = nullptr; + tok = tok->link(); + continue; + } + + if (baseName && Token::Match(tok, "%name% :: %name% ;") && + tok->str() == baseName->str() && tok->strAt(2) == baseName->str() && + std::any_of(baseFuncs->cbegin(), baseFuncs->cend(), [&](const Function &func) { + return isInherited(func, scope); + })) + result.push_back(tok->tokAt(2)); + } + + return result; +} + //--------------------------------------------------------------------------- // ClassCheck: Check that all class constructors are ok. //--------------------------------------------------------------------------- @@ -223,9 +282,11 @@ void CheckClassImpl::constructors() }); }); + const std::vector inheritedCtors = getInheritedConstructors(scope); + // There are no constructors. std::set diagVars; - if (scope->numConstructors == 0 && printStyle && !usedInUnion) { + if (scope->numConstructors == 0 && inheritedCtors.empty() && printStyle && !usedInUnion) { // If there is a private variable, there should be a constructor.. int needInit = 0, haveInit = 0; std::vector uninitVars; @@ -339,6 +400,30 @@ void CheckClassImpl::constructors() } } + if (!inheritedCtors.empty()) { + clearAllVar(usageList); + + for (Usage &usage : usageList) { + if (usage.var->hasDefault()) + usage.init = true; + } + + handleUnionMembers(usageList); + + // Inherited constructors don't initialize members of the derived class + for (const Token *baseCtorTok : inheritedCtors) { + for (const Usage &usage : usageList) { + if (isInitialized(usage, FunctionType::eConstructor)) + continue; + const Variable& var = *usage.var; + if (var.typeScope() && var.typeScope()->numConstructors > 0) + continue; + uninitVarError(baseCtorTok, false, FunctionType::eConstructor, var.scope()->className, var.name(), scope != var.scope(), false, false, true); + diagVars.emplace(&var); + } + } + } + if (scope->numConstructors == 0) { // Mark all variables not used @@ -1182,12 +1267,15 @@ void CheckClassImpl::noExplicitConstructorError(const Token *tok, const std::str reportError(tok, Severity::style, "noExplicitConstructor", "$symbol:" + classname + '\n' + message + '\n' + verbose, CWE398, Certainty::normal); } -void CheckClassImpl::uninitVarError(const Token *tok, bool isprivate, FunctionType functionType, const std::string &classname, const std::string &varname, bool derived, bool inconclusive, bool noCtor) +void CheckClassImpl::uninitVarError(const Token *tok, bool isprivate, FunctionType functionType, const std::string &classname, const std::string &varname, bool derived, bool inconclusive, bool noCtor, bool inheritedCtor) { std::string message("Member variable '$symbol' "); if (noCtor) message += "has no initializer."; - else { + else if (inheritedCtor) { + message += tok ? "is not initialized in the constructor inherited from '" + tok->str() + "'." : + "is not initialized in the inherited constructor."; + } else { message += "is not initialized in the "; if (functionType == FunctionType::eCopyConstructor) message += "copy "; diff --git a/lib/checkclass.h b/lib/checkclass.h index 0aa8fc29da3..74f61ee4705 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -182,7 +182,7 @@ class CPPCHECKLIB CheckClassImpl : public CheckImpl { void noCopyConstructorError(const Scope *scope, bool isdefault, const Token *alloc, bool inconclusive); void noOperatorEqError(const Scope *scope, bool isdefault, const Token *alloc, bool inconclusive); void noDestructorError(const Scope *scope, bool isdefault, const Token *alloc); - void uninitVarError(const Token *tok, bool isprivate, FunctionType functionType, const std::string &classname, const std::string &varname, bool derived, bool inconclusive, bool noCtor = false); + void uninitVarError(const Token *tok, bool isprivate, FunctionType functionType, const std::string &classname, const std::string &varname, bool derived, bool inconclusive, bool noCtor = false, bool inheritedCtor = false); void uninitVarError(const Token *tok, const std::string &classname, const std::string &varname); void missingMemberCopyError(const Token *tok, FunctionType functionType, const std::string& classname, const std::string& varname); void operatorEqVarError(const Token *tok, const std::string &classname, const std::string &varname, bool inconclusive); diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 1f512b52478..8668772b199 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -232,6 +232,18 @@ class TestConstructors : public TestFixture { TEST_CASE(uninitTemplate1); // ticket #7372 TEST_CASE(unknownTemplateType); + + TEST_CASE(inheritedCtor1); + TEST_CASE(inheritedCtor2); + TEST_CASE(inheritedCtor3); + TEST_CASE(inheritedCtor4); + TEST_CASE(inheritedCtor5); + TEST_CASE(inheritedCtor6); + TEST_CASE(inheritedCtor7); + TEST_CASE(inheritedCtor8); + TEST_CASE(inheritedCtor9); + TEST_CASE(inheritedCtor10); + TEST_CASE(inheritedCtor11); } @@ -4732,6 +4744,144 @@ class TestConstructors : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void inheritedCtor1() { + check("struct Base { Base(int); };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:3:17]: (warning) Member variable 'Derived::x' is not initialized in the constructor inherited from 'Base'. [uninitMemberVar]\n", errout_str()); + } + + void inheritedCtor2() { + check("struct Base { Base(int); };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " int x = 0;\n" + " int y{};\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + } + + void inheritedCtor3() { + check("struct Base { Base(int); };\n" + "struct S { S(); int i; };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " S s;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + } + + void inheritedCtor4() { + check("struct Base { Base(int); };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " int x = 0;\n" + " int y;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:3:17]: (warning) Member variable 'Derived::y' is not initialized in the constructor inherited from 'Base'. [uninitMemberVar]\n", errout_str()); + } + + void inheritedCtor5() { + check("struct Base { Base(int); };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " Derived() : x(0) {}\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:3:17]: (warning) Member variable 'Derived::x' is not initialized in the constructor inherited from 'Base'. [uninitMemberVar]\n", errout_str()); + } + + void inheritedCtor6() { + check("struct A { A(int); };\n" + "struct B { B(double); };\n" + "struct D : A, B {\n" + " using A::A;\n" + " using B::B;\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:4:14]: (warning) Member variable 'D::x' is not initialized in the constructor inherited from 'A'. [uninitMemberVar]\n" + "[test.cpp:5:14]: (warning) Member variable 'D::x' is not initialized in the constructor inherited from 'B'. [uninitMemberVar]\n", + errout_str()); + } + + void inheritedCtor7() { + check("struct Base { void f(); };\n" + "struct Derived : Base {\n" + " using Base::f;\n" + " int x = 0;\n" + " int y;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:5:9]: (warning) Member variable 'Derived::y' has no initializer. [uninitMemberVarNoCtor]\n", errout_str()); + } + + void inheritedCtor8() { + check("struct Base { Base(int); };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " Derived(int i) : Base(i), x(0) {}\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct Base { Base(int); Base(double); };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " Derived(int i) : Base(i), x(0) {}\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:3:17]: (warning) Member variable 'Derived::x' is not initialized in the constructor inherited from 'Base'. [uninitMemberVar]\n", errout_str()); + } + + void inheritedCtor9() { + check("struct Base { Base(); };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct Base {};\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct Base { Base(const Base&); Base(Base&&); };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + } + + void inheritedCtor10() { + check("struct Base { Base(int) = delete; };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + check("class Base { Base(int); };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + } + + void inheritedCtor11() { + check("namespace X { struct Base { Base(int); }; }\n" + "struct Derived : X::Base {\n" + " using X::Base::Base;\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:3:20]: (warning) Member variable 'Derived::x' is not initialized in the constructor inherited from 'Base'. [uninitMemberVar]\n", errout_str()); + } + }; REGISTER_TEST(TestConstructors) From 23ebc5e0a6288200c9605bed96800fd8443819d8 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 29 Oct 2026 14:18:37 +0100 Subject: [PATCH 30/32] Add test for #12468 (#8978) --- test/cfg/qt.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/cfg/qt.cpp b/test/cfg/qt.cpp index a850a93f7f2..fe2f48e3175 100644 --- a/test/cfg/qt.cpp +++ b/test/cfg/qt.cpp @@ -83,6 +83,12 @@ void assertWithSideEffect_QDir_exists(const char *path) { // #14720 (void)dir; } +void assertWithSideEffect_QDir_mkdir(const char *path) { // #12468 + QDir dir; + // cppcheck-suppress [assertWithSideEffect, checkLibraryNoReturn] // TODO: #8329 + Q_ASSERT(dir.mkdir(path)); +} + void unusedVariable_QTransform() { // cppcheck-suppress unusedVariable From 761d61376e290722b9ae8b18ced8c34bbe876af7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Thu, 29 Oct 2026 15:15:18 +0100 Subject: [PATCH 31/32] Fix #15107: Exporting XML via GUI escapes special characters twice. (#8943) --- gui/test/data/xmlfiles/xmlreport_v2.xml | 6 ++-- gui/test/resultstree/testresultstree.cpp | 6 ---- gui/test/xmlreportv2/testxmlreportv2.cpp | 37 ++++++++++++++++++++++++ gui/test/xmlreportv2/testxmlreportv2.h | 1 + gui/xmlreport.cpp | 22 -------------- gui/xmlreport.h | 14 --------- gui/xmlreportv2.cpp | 24 +++++++-------- 7 files changed, 51 insertions(+), 59 deletions(-) diff --git a/gui/test/data/xmlfiles/xmlreport_v2.xml b/gui/test/data/xmlfiles/xmlreport_v2.xml index 31af1a92cff..e8e03c3adbb 100644 --- a/gui/test/data/xmlfiles/xmlreport_v2.xml +++ b/gui/test/data/xmlfiles/xmlreport_v2.xml @@ -2,10 +2,10 @@ - + - + @@ -15,7 +15,7 @@ - + diff --git a/gui/test/resultstree/testresultstree.cpp b/gui/test/resultstree/testresultstree.cpp index e2e40517f69..c4a7d3080c0 100644 --- a/gui/test/resultstree/testresultstree.cpp +++ b/gui/test/resultstree/testresultstree.cpp @@ -106,12 +106,6 @@ Application& ApplicationList::getApplication(const int /*unused*/) { const Application& ApplicationList::getApplication(const int index) const { return mApplications.at(index); } -QString XmlReport::quoteMessage(const QString &message) { - return message; -} -QString XmlReport::unquoteMessage(const QString &message) { - return message; -} XmlReport::XmlReport(const QString& filename) : Report(filename) {} // NOLINTNEXTLINE(performance-unnecessary-value-param) void ThreadResult::finishCheck(CheckThread::Details /*unused*/) { diff --git a/gui/test/xmlreportv2/testxmlreportv2.cpp b/gui/test/xmlreportv2/testxmlreportv2.cpp index 2dc0927b870..d157a4bef6d 100644 --- a/gui/test/xmlreportv2/testxmlreportv2.cpp +++ b/gui/test/xmlreportv2/testxmlreportv2.cpp @@ -21,7 +21,9 @@ #include "erroritem.h" #include "xmlreportv2.h" +#include #include +#include #include void TestXmlReportV2::readXml() const @@ -53,4 +55,39 @@ void TestXmlReportV2::readXml() const QCOMPARE(item2.message, QString("Mismatching allocation and deallocation: k")); } +void TestXmlReportV2::writeXmlEscaping() const +{ + QTemporaryDir dir; + const QString path = dir.path() + "/results.xml"; + + ErrorItem item; + item.errorId = "id"; + item.severity = Severity::style; + item.summary = "\"x\" & ""; + item.message = item.summary; + QErrorPathItem loc; + loc.file = "a&b.cpp"; + loc.line = 1; + item.errorPath << loc; + { + XmlReportV2 report(path, QString()); + QVERIFY(report.create()); + report.writeHeader(); + report.writeError(item); + report.writeFooter(); + } + + QFile file(path); + QVERIFY(file.open(QIODevice::ReadOnly)); + QVERIFY(file.readAll().contains("msg=\""x" & <y> &quot;\"")); + + XmlReportV2 report(path, QString()); + QVERIFY(report.open()); + const QList errors = report.read(); + QCOMPARE(errors.size(), 1); + QCOMPARE(errors[0].summary, item.summary); + QCOMPARE(errors[0].message, item.message); + QCOMPARE(errors[0].errorPath[0].file, loc.file); +} + QTEST_MAIN(TestXmlReportV2) diff --git a/gui/test/xmlreportv2/testxmlreportv2.h b/gui/test/xmlreportv2/testxmlreportv2.h index 9b864239414..9662bd00b27 100644 --- a/gui/test/xmlreportv2/testxmlreportv2.h +++ b/gui/test/xmlreportv2/testxmlreportv2.h @@ -23,4 +23,5 @@ class TestXmlReportV2 : public QObject { private slots: void readXml() const; + void writeXmlEscaping() const; }; diff --git a/gui/xmlreport.cpp b/gui/xmlreport.cpp index c5f00fc5bb7..8d184ca6658 100644 --- a/gui/xmlreport.cpp +++ b/gui/xmlreport.cpp @@ -32,28 +32,6 @@ XmlReport::XmlReport(const QString &filename) : Report(filename) {} -QString XmlReport::quoteMessage(const QString &message) -{ - QString quotedMessage(message); - quotedMessage.replace("&", "&"); - quotedMessage.replace("\"", """); - quotedMessage.replace("'", "'"); - quotedMessage.replace("<", "<"); - quotedMessage.replace(">", ">"); - return quotedMessage; -} - -QString XmlReport::unquoteMessage(const QString &message) -{ - QString quotedMessage(message); - quotedMessage.replace("&", "&"); - quotedMessage.replace(""", "\""); - quotedMessage.replace("'", "'"); - quotedMessage.replace("<", "<"); - quotedMessage.replace(">", ">"); - return quotedMessage; -} - int XmlReport::determineVersion(const QString &filename) { QFile file; diff --git a/gui/xmlreport.h b/gui/xmlreport.h index 2483b1b7471..83c222291ab 100644 --- a/gui/xmlreport.h +++ b/gui/xmlreport.h @@ -42,20 +42,6 @@ class XmlReport : public Report { */ virtual QList read() = 0; - /** - * @brief Quote the message. - * @param message Message to quote. - * @return quoted message. - */ - static QString quoteMessage(const QString &message); - - /** - * @brief Unquote the message. - * @param message Message to quote. - * @return quoted message. - */ - static QString unquoteMessage(const QString &message); - /** * @brief Get the XML report format version from the file. * @param filename Filename of the report file. diff --git a/gui/xmlreportv2.cpp b/gui/xmlreportv2.cpp index abf6aa361ba..b707b6d44dd 100644 --- a/gui/xmlreportv2.cpp +++ b/gui/xmlreportv2.cpp @@ -132,10 +132,8 @@ void XmlReportV2::writeError(const ErrorItem &error) // Don't localize severity so we can read these files mXmlWriter->writeAttribute(SeverityAttribute, GuiSeverity::toString(error.severity)); - const QString summary = XmlReport::quoteMessage(error.summary); - mXmlWriter->writeAttribute(MsgAttribute, summary); - const QString message = XmlReport::quoteMessage(error.message); - mXmlWriter->writeAttribute(VerboseAttribute, message); + mXmlWriter->writeAttribute(MsgAttribute, error.summary); + mXmlWriter->writeAttribute(VerboseAttribute, error.message); if (error.inconclusive) mXmlWriter->writeAttribute(InconclusiveAttribute, "true"); if (!error.remark.isEmpty()) @@ -145,7 +143,7 @@ void XmlReportV2::writeError(const ErrorItem &error) if (error.hash > 0) mXmlWriter->writeAttribute(HashAttribute, QString::number(error.hash)); if (!error.file0.isEmpty()) - mXmlWriter->writeAttribute(IncludedFromFilenameAttribute, quoteMessage(error.file0)); + mXmlWriter->writeAttribute(IncludedFromFilenameAttribute, error.file0); if (!error.sinceDate.isEmpty()) mXmlWriter->writeAttribute(SinceDateAttribute, error.sinceDate); if (!error.tags.isEmpty()) @@ -155,12 +153,12 @@ void XmlReportV2::writeError(const ErrorItem &error) mXmlWriter->writeStartElement(LocationElementName); QString file = QDir::toNativeSeparators(error.errorPath[i].file); - mXmlWriter->writeAttribute(FilenameAttribute, XmlReport::quoteMessage(file)); + mXmlWriter->writeAttribute(FilenameAttribute, file); mXmlWriter->writeAttribute(LineAttribute, QString::number(error.errorPath[i].line)); if (error.errorPath[i].column > 0) mXmlWriter->writeAttribute(ColumnAttribute, QString::number(error.errorPath[i].column)); if (error.errorPath.count() > 1) - mXmlWriter->writeAttribute(InfoAttribute, XmlReport::quoteMessage(error.errorPath[i].info)); + mXmlWriter->writeAttribute(InfoAttribute, error.errorPath[i].info); mXmlWriter->writeEndElement(); } @@ -228,10 +226,8 @@ ErrorItem XmlReportV2::readError(const QXmlStreamReader *reader) QXmlStreamAttributes attribs = reader->attributes(); item.errorId = attribs.value(QString(), IdAttribute).toString(); item.severity = GuiSeverity::fromString(attribs.value(QString(), SeverityAttribute).toString()); - const QString summary = attribs.value(QString(), MsgAttribute).toString(); - item.summary = XmlReport::unquoteMessage(summary); - const QString message = attribs.value(QString(), VerboseAttribute).toString(); - item.message = XmlReport::unquoteMessage(message); + item.summary = attribs.value(QString(), MsgAttribute).toString(); + item.message = attribs.value(QString(), VerboseAttribute).toString(); if (attribs.hasAttribute(QString(), InconclusiveAttribute)) item.inconclusive = true; if (attribs.hasAttribute(QString(), RemarkAttribute)) @@ -258,14 +254,14 @@ ErrorItem XmlReportV2::readError(const QXmlStreamReader *reader) QXmlStreamAttributes attribs = mXmlReader->attributes(); QString file0 = attribs.value(QString(), IncludedFromFilenameAttribute).toString(); if (!file0.isEmpty()) - item.file0 = XmlReport::unquoteMessage(file0); + item.file0 = file0; QErrorPathItem loc; - loc.file = XmlReport::unquoteMessage(attribs.value(QString(), FilenameAttribute).toString()); + loc.file = attribs.value(QString(), FilenameAttribute).toString(); loc.line = attribs.value(QString(), LineAttribute).toString().toUInt(); if (attribs.hasAttribute(QString(), ColumnAttribute)) loc.column = attribs.value(QString(), ColumnAttribute).toString().toInt(); if (attribs.hasAttribute(QString(), InfoAttribute)) - loc.info = XmlReport::unquoteMessage(attribs.value(QString(), InfoAttribute).toString()); + loc.info = attribs.value(QString(), InfoAttribute).toString(); item.errorPath.push_front(loc); } break; From a05c30b81113f898b1ed493556324aa0cdf00d2c Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Sat, 7 Nov 2026 19:36:38 +0100 Subject: [PATCH 32/32] Fix --- lib/tokenize.cpp | 9 ++++++++- test/testtokenize.cpp | 6 +++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 6262bb7032a..8dc552c55f8 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -9427,8 +9427,15 @@ void Tokenizer::simplifyFunctionTryCatch() if (!Token::Match(tok, "try {|:")) continue; const Token* par = tok->previous(); - while (par && !Token::Match(par, "[);]")) + while (par && !Token::Match(par, "[);]")) { + if (par->str() == ">") { + if (const Token* ob = par->findOpeningBracket()) { + par = ob; + continue; + } + } par = par->previous(); + } if (!TokenList::isFunctionHead(par, "try")) // TODO: this is supposed to a list of characters and not strings continue; diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index ef082afe9a7..00e53ac1e0f 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -2036,6 +2036,7 @@ class TestTokenizer : public TestFixture { "void i ( ) & override { try { } catch ( ... ) { } }\n" "void j ( ) const && override { try { } catch ( ... ) { } }\n" "auto k ( ) . std :: nullptr_t override { try { } catch ( ... ) { } }\n" + "auto l ( ) . W < decltype ( 1 ) > override { try { } catch ( ... ) { } }\n" "} ;", tokenizeAndStringify("struct D : B {\n" " void f() override try {} catch (...) {}\n" @@ -2043,8 +2044,11 @@ class TestTokenizer : public TestFixture { " void i() & override try {} catch (...) {}\n" " void j() const && override try {} catch (...) {}\n" " auto k() -> std::nullptr_t override try {} catch (...) {}\n" + " auto l() -> W override try {} catch (...) {}\n" "};\n")); - ASSERT_EQUALS("[test.cpp:6:5]: (debug) auto token with no type. [autoNoType]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:6:5]: (debug) auto token with no type. [autoNoType]\n" + "[test.cpp:7:5]: (debug) auto token with no type. [autoNoType]\n", + errout_str()); } // Simplify "((..))" into "(..)"

If you want to get started, look at the walk through.