From ea2e716f33df1f09f0b02f3e398fca29b37e3860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Sun, 21 Apr 2024 15:59:20 +0200 Subject: [PATCH] added `FileWithDetails` to store resolved input path in (#6285) --- Makefile | 12 ++++--- cli/cmdlineparser.cpp | 28 +++++++-------- cli/cmdlineparser.h | 4 +-- cli/cppcheckexecutor.cpp | 12 +++---- cli/cppcheckexecutor.h | 5 +-- cli/executor.cpp | 2 +- cli/executor.h | 5 +-- cli/filelister.cpp | 23 ++++++------ cli/filelister.h | 7 ++-- cli/processexecutor.cpp | 24 ++++++------- cli/processexecutor.h | 3 +- cli/singleexecutor.cpp | 12 +++---- cli/singleexecutor.h | 3 +- cli/threadexecutor.cpp | 16 ++++----- cli/threadexecutor.h | 3 +- gui/checkthread.cpp | 12 +++---- gui/compliancereportdialog.cpp | 2 +- gui/threadresult.cpp | 4 +-- lib/analyzerinfo.cpp | 4 +-- lib/cppcheck.cpp | 20 +++++------ lib/cppcheck.h | 7 ++-- lib/filesettings.h | 41 ++++++++++++++++++++- lib/importproject.cpp | 31 ++++++++-------- test/helpers.cpp | 5 +-- test/testcppcheck.cpp | 3 +- test/testfilelister.cpp | 15 ++++---- test/testfilesettings.cpp | 65 ++++++++++++++++++++++++++++++++++ test/testimportproject.cpp | 23 ++++++------ test/testprocessexecutor.cpp | 14 +++----- test/testrunner.vcxproj | 1 + test/testsingleexecutor.cpp | 15 ++++---- test/testsuppressions.cpp | 26 ++++++-------- test/testthreadexecutor.cpp | 14 +++----- tools/dmake/dmake.cpp | 9 ++--- 34 files changed, 285 insertions(+), 185 deletions(-) create mode 100644 test/testfilesettings.cpp diff --git a/Makefile b/Makefile index f482051b8fa..0f039a3f112 100644 --- a/Makefile +++ b/Makefile @@ -293,6 +293,7 @@ TESTOBJ = test/fixture.o \ test/testerrorlogger.o \ test/testexceptionsafety.o \ test/testfilelister.o \ + test/testfilesettings.o \ test/testfunctions.o \ test/testgarbage.o \ test/testimportproject.o \ @@ -660,7 +661,7 @@ cli/cppcheckexecutorseh.o: cli/cppcheckexecutorseh.cpp cli/cppcheckexecutor.h cl cli/executor.o: cli/executor.cpp cli/executor.h lib/addoninfo.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 $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/executor.cpp -cli/filelister.o: cli/filelister.cpp cli/filelister.h lib/config.h lib/path.h lib/pathmatch.h lib/standards.h lib/utils.h +cli/filelister.o: cli/filelister.cpp cli/filelister.h lib/config.h lib/filesettings.h lib/path.h lib/pathmatch.h lib/platform.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/filelister.cpp cli/main.o: cli/main.cpp cli/cppcheckexecutor.h lib/config.h lib/errortypes.h lib/filesettings.h lib/platform.h lib/standards.h lib/utils.h @@ -684,7 +685,7 @@ cli/threadexecutor.o: cli/threadexecutor.cpp cli/executor.h cli/threadexecutor.h test/fixture.o: test/fixture.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/cppcheck.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 lib/xml.h test/fixture.h test/options.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/fixture.cpp -test/helpers.o: test/helpers.cpp cli/filelister.h externals/simplecpp/simplecpp.h lib/addoninfo.h lib/config.h lib/errortypes.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/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/helpers.h +test/helpers.o: test/helpers.cpp cli/filelister.h externals/simplecpp/simplecpp.h lib/addoninfo.h lib/config.h lib/errortypes.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/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/helpers.cpp test/main.o: test/main.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.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/suppressions.h lib/utils.h test/fixture.h test/options.h @@ -750,9 +751,12 @@ test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h l test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/addoninfo.h lib/check.h lib/checkexceptionsafety.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testexceptionsafety.cpp -test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/addoninfo.h lib/check.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/suppressions.h lib/utils.h test/fixture.h +test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/addoninfo.h lib/check.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/suppressions.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilelister.cpp +test/testfilesettings.o: test/testfilesettings.cpp lib/addoninfo.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h + $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilesettings.cpp + test/testfunctions.o: test/testfunctions.cpp lib/addoninfo.h lib/check.h lib/checkfunctions.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfunctions.cpp @@ -897,6 +901,6 @@ externals/simplecpp/simplecpp.o: externals/simplecpp/simplecpp.cpp externals/sim externals/tinyxml2/tinyxml2.o: externals/tinyxml2/tinyxml2.cpp externals/tinyxml2/tinyxml2.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) -w -c -o $@ externals/tinyxml2/tinyxml2.cpp -tools/dmake/dmake.o: tools/dmake/dmake.cpp cli/filelister.h lib/config.h lib/pathmatch.h lib/utils.h +tools/dmake/dmake.o: tools/dmake/dmake.cpp cli/filelister.h lib/config.h lib/filesettings.h lib/pathmatch.h lib/platform.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ tools/dmake/dmake.cpp diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index c1232a95cb2..4f2209e11f6 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -204,7 +204,7 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[]) if (!mSettings.fileFilters.empty()) { // filter only for the selected filenames from all project files std::copy_if(fileSettingsRef.cbegin(), fileSettingsRef.cend(), std::back_inserter(fileSettings), [&](const FileSettings &fs) { - return matchglobs(mSettings.fileFilters, fs.filename); + return matchglobs(mSettings.fileFilters, fs.filename()); }); if (fileSettings.empty()) { mLogger.printError("could not find any files matching the filter."); @@ -219,11 +219,11 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[]) // sort the markup last std::copy_if(fileSettings.cbegin(), fileSettings.cend(), std::back_inserter(mFileSettings), [&](const FileSettings &fs) { - return !mSettings.library.markupFile(fs.filename) || !mSettings.library.processMarkupAfterCode(fs.filename); + return !mSettings.library.markupFile(fs.filename()) || !mSettings.library.processMarkupAfterCode(fs.filename()); }); std::copy_if(fileSettings.cbegin(), fileSettings.cend(), std::back_inserter(mFileSettings), [&](const FileSettings &fs) { - return mSettings.library.markupFile(fs.filename) && mSettings.library.processMarkupAfterCode(fs.filename); + return mSettings.library.markupFile(fs.filename()) && mSettings.library.processMarkupAfterCode(fs.filename()); }); if (mFileSettings.empty()) { @@ -233,7 +233,7 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[]) } if (!pathnamesRef.empty()) { - std::list> filesResolved; + std::list filesResolved; // TODO: this needs to be inlined into PathMatch as it depends on the underlying filesystem #if defined(_WIN32) // For Windows we want case-insensitive path matching @@ -264,19 +264,19 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[]) { auto it = filesResolved.begin(); while (it != filesResolved.end()) { - const std::string& name = it->first; + const std::string& name = it->path(); // TODO: log if duplicated files were dropped - filesResolved.erase(std::remove_if(std::next(it), filesResolved.end(), [&](const std::pair& entry) { - return entry.first == name; + filesResolved.erase(std::remove_if(std::next(it), filesResolved.end(), [&](const FileWithDetails& entry) { + return entry.path() == name; }), filesResolved.end()); ++it; } } - std::list> files; + std::list files; if (!mSettings.fileFilters.empty()) { - std::copy_if(filesResolved.cbegin(), filesResolved.cend(), std::inserter(files, files.end()), [&](const decltype(filesResolved)::value_type& entry) { - return matchglobs(mSettings.fileFilters, entry.first); + std::copy_if(filesResolved.cbegin(), filesResolved.cend(), std::inserter(files, files.end()), [&](const FileWithDetails& entry) { + return matchglobs(mSettings.fileFilters, entry.path()); }); if (files.empty()) { mLogger.printError("could not find any files matching the filter."); @@ -288,12 +288,12 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[]) } // sort the markup last - std::copy_if(files.cbegin(), files.cend(), std::inserter(mFiles, mFiles.end()), [&](const decltype(files)::value_type& entry) { - return !mSettings.library.markupFile(entry.first) || !mSettings.library.processMarkupAfterCode(entry.first); + std::copy_if(files.cbegin(), files.cend(), std::inserter(mFiles, mFiles.end()), [&](const FileWithDetails& entry) { + return !mSettings.library.markupFile(entry.path()) || !mSettings.library.processMarkupAfterCode(entry.path()); }); - std::copy_if(files.cbegin(), files.cend(), std::inserter(mFiles, mFiles.end()), [&](const decltype(files)::value_type& entry) { - return mSettings.library.markupFile(entry.first) && mSettings.library.processMarkupAfterCode(entry.first); + std::copy_if(files.cbegin(), files.cend(), std::inserter(mFiles, mFiles.end()), [&](const FileWithDetails& entry) { + return mSettings.library.markupFile(entry.path()) && mSettings.library.processMarkupAfterCode(entry.path()); }); if (mFiles.empty()) { diff --git a/cli/cmdlineparser.h b/cli/cmdlineparser.h index b7229eb35d8..f7d240b55cc 100644 --- a/cli/cmdlineparser.h +++ b/cli/cmdlineparser.h @@ -84,7 +84,7 @@ class CmdLineParser { /** * Return the files user gave to command line. */ - const std::list>& getFiles() const { + const std::list& getFiles() const { return mFiles; } @@ -159,7 +159,7 @@ class CmdLineParser { CmdLineLogger &mLogger; std::vector mPathNames; - std::list> mFiles; + std::list mFiles; std::list mFileSettings; std::vector mIgnoredPaths; Settings &mSettings; diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 5ce0023a201..6047647fcd5 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -218,7 +218,7 @@ int CppCheckExecutor::check_wrapper(const Settings& settings) return check_internal(settings); } -bool CppCheckExecutor::reportSuppressions(const Settings &settings, const SuppressionList& suppressions, bool unusedFunctionCheckEnabled, const std::list> &files, const std::list& fileSettings, ErrorLogger& errorLogger) { +bool CppCheckExecutor::reportSuppressions(const Settings &settings, const SuppressionList& suppressions, bool unusedFunctionCheckEnabled, const std::list &files, const std::list& fileSettings, ErrorLogger& errorLogger) { const auto& suppr = suppressions.getSuppressions(); if (std::any_of(suppr.begin(), suppr.end(), [](const SuppressionList::Suppression& s) { return s.errorId == "unmatchedSuppression" && s.fileName.empty() && s.lineNumber == SuppressionList::Suppression::NO_LINE; @@ -230,14 +230,14 @@ bool CppCheckExecutor::reportSuppressions(const Settings &settings, const Suppre // the two inputs may only be used exclusively assert(!(!files.empty() && !fileSettings.empty())); - for (std::list>::const_iterator i = files.cbegin(); i != files.cend(); ++i) { + for (std::list::const_iterator i = files.cbegin(); i != files.cend(); ++i) { err |= SuppressionList::reportUnmatchedSuppressions( - suppressions.getUnmatchedLocalSuppressions(i->first, unusedFunctionCheckEnabled), errorLogger); + suppressions.getUnmatchedLocalSuppressions(i->path(), unusedFunctionCheckEnabled), errorLogger); } for (std::list::const_iterator i = fileSettings.cbegin(); i != fileSettings.cend(); ++i) { err |= SuppressionList::reportUnmatchedSuppressions( - suppressions.getUnmatchedLocalSuppressions(i->filename, unusedFunctionCheckEnabled), errorLogger); + suppressions.getUnmatchedLocalSuppressions(i->filename(), unusedFunctionCheckEnabled), errorLogger); } } err |= SuppressionList::reportUnmatchedSuppressions(suppressions.getUnmatchedGlobalSuppressions(unusedFunctionCheckEnabled), errorLogger); @@ -260,8 +260,8 @@ int CppCheckExecutor::check_internal(const Settings& settings) const if (!settings.buildDir.empty()) { std::list fileNames; - for (std::list>::const_iterator i = mFiles.cbegin(); i != mFiles.cend(); ++i) - fileNames.emplace_back(i->first); + for (std::list::const_iterator i = mFiles.cbegin(); i != mFiles.cend(); ++i) + fileNames.emplace_back(i->path()); AnalyzerInformation::writeFilesTxt(settings.buildDir, fileNames, settings.userDefines, mFileSettings); } diff --git a/cli/cppcheckexecutor.h b/cli/cppcheckexecutor.h index e3c1772e22b..86d938c58b9 100644 --- a/cli/cppcheckexecutor.h +++ b/cli/cppcheckexecutor.h @@ -31,6 +31,7 @@ class Settings; class ErrorLogger; class SuppressionList; +class FileWithDetails; /** * This class works as an example of how CppCheck can be used in external @@ -81,7 +82,7 @@ class CppCheckExecutor { protected: - static bool reportSuppressions(const Settings &settings, const SuppressionList& suppressions, bool unusedFunctionCheckEnabled, const std::list> &files, const std::list& fileSettings, ErrorLogger& errorLogger); + static bool reportSuppressions(const Settings &settings, const SuppressionList& suppressions, bool unusedFunctionCheckEnabled, const std::list &files, const std::list& fileSettings, ErrorLogger& errorLogger); /** * Wrapper around check_internal @@ -106,7 +107,7 @@ class CppCheckExecutor { /** * Filename associated with size of file */ - std::list> mFiles; + std::list mFiles; std::list mFileSettings; diff --git a/cli/executor.cpp b/cli/executor.cpp index e24eb191bb4..d60e901e8e9 100644 --- a/cli/executor.cpp +++ b/cli/executor.cpp @@ -30,7 +30,7 @@ struct FileSettings; -Executor::Executor(const std::list> &files, const std::list& fileSettings, const Settings &settings, SuppressionList &suppressions, ErrorLogger &errorLogger) +Executor::Executor(const std::list &files, const std::list& fileSettings, const Settings &settings, SuppressionList &suppressions, ErrorLogger &errorLogger) : mFiles(files), mFileSettings(fileSettings), mSettings(settings), mSuppressions(suppressions), mErrorLogger(errorLogger) { // the two inputs may only be used exclusively diff --git a/cli/executor.h b/cli/executor.h index 91b14361a18..74cf3c49c9c 100644 --- a/cli/executor.h +++ b/cli/executor.h @@ -31,6 +31,7 @@ class ErrorLogger; class ErrorMessage; class SuppressionList; struct FileSettings; +class FileWithDetails; /// @addtogroup CLI /// @{ @@ -41,7 +42,7 @@ struct FileSettings; */ class Executor { public: - Executor(const std::list> &files, const std::list& fileSettings, const Settings &settings, SuppressionList &suppressions, ErrorLogger &errorLogger); + Executor(const std::list &files, const std::list& fileSettings, const Settings &settings, SuppressionList &suppressions, ErrorLogger &errorLogger); virtual ~Executor() = default; Executor(const Executor &) = delete; @@ -67,7 +68,7 @@ class Executor { */ bool hasToLog(const ErrorMessage &msg); - const std::list> &mFiles; + const std::list &mFiles; const std::list& mFileSettings; const Settings &mSettings; SuppressionList &mSuppressions; diff --git a/cli/filelister.cpp b/cli/filelister.cpp index 1f94ea77f57..81f8e51020e 100644 --- a/cli/filelister.cpp +++ b/cli/filelister.cpp @@ -18,6 +18,7 @@ #include "filelister.h" +#include "filesettings.h" #include "path.h" #include "pathmatch.h" #include "utils.h" @@ -40,12 +41,12 @@ // When compiling Unicode targets WinAPI automatically uses *W Unicode versions // of called functions. Thus, we explicitly call *A versions of the functions. -std::string FileLister::recursiveAddFiles(std::list>&files, const std::string &path, const std::set &extra, const PathMatch& ignored) +std::string FileLister::recursiveAddFiles(std::list&files, const std::string &path, const std::set &extra, const PathMatch& ignored) { return addFiles(files, path, extra, true, ignored); } -std::string FileLister::addFiles(std::list>&files, const std::string &path, const std::set &extra, bool recursive, const PathMatch& ignored) +std::string FileLister::addFiles(std::list&files, const std::string &path, const std::set &extra, bool recursive, const PathMatch& ignored) { if (path.empty()) return "no path specified"; @@ -122,15 +123,15 @@ std::string FileLister::addFiles(std::list>& // Directory if (recursive) { if (!ignored.match(fname)) { - std::list> filesSorted; + std::list filesSorted; std::string err = FileLister::recursiveAddFiles(filesSorted, fname, extra, ignored); if (!err.empty()) return err; // files inside directories need to be sorted as the filesystem doesn't provide a stable order - filesSorted.sort([](const decltype(filesSorted)::value_type& a, const decltype(filesSorted)::value_type& b) { - return a.first < b.first; + filesSorted.sort([](const FileWithDetails& a, const FileWithDetails& b) { + return a.path() < b.path(); }); files.insert(files.end(), std::make_move_iterator(filesSorted.begin()), std::make_move_iterator(filesSorted.end())); @@ -165,7 +166,7 @@ std::string FileLister::addFiles(std::list>& #include #include -static std::string addFiles2(std::list> &files, +static std::string addFiles2(std::list &files, const std::string &path, const std::set &extra, bool recursive, @@ -188,7 +189,7 @@ static std::string addFiles2(std::list> &fil std::string new_path = path; new_path += '/'; - std::list> filesSorted; + std::list filesSorted; while (const dirent* dir_result = readdir(dir)) { if ((std::strcmp(dir_result->d_name, ".") == 0) || @@ -224,8 +225,8 @@ static std::string addFiles2(std::list> &fil } // files inside directories need to be sorted as the filesystem doesn't provide a stable order - filesSorted.sort([](const decltype(filesSorted)::value_type& a, const decltype(filesSorted)::value_type& b) { - return a.first < b.first; + filesSorted.sort([](const FileWithDetails& a, const FileWithDetails& b) { + return a.path() < b.path(); }); files.insert(files.end(), std::make_move_iterator(filesSorted.begin()), std::make_move_iterator(filesSorted.end())); @@ -235,12 +236,12 @@ static std::string addFiles2(std::list> &fil return ""; } -std::string FileLister::recursiveAddFiles(std::list> &files, const std::string &path, const std::set &extra, const PathMatch& ignored) +std::string FileLister::recursiveAddFiles(std::list &files, const std::string &path, const std::set &extra, const PathMatch& ignored) { return addFiles(files, path, extra, true, ignored); } -std::string FileLister::addFiles(std::list> &files, const std::string &path, const std::set &extra, bool recursive, const PathMatch& ignored) +std::string FileLister::addFiles(std::list &files, const std::string &path, const std::set &extra, bool recursive, const PathMatch& ignored) { if (path.empty()) return "no path specified"; diff --git a/cli/filelister.h b/cli/filelister.h index c17dea3c378..81f6d6ff8fa 100644 --- a/cli/filelister.h +++ b/cli/filelister.h @@ -26,6 +26,7 @@ #include class PathMatch; +class FileWithDetails; /// @addtogroup CLI /// @{ @@ -43,7 +44,7 @@ class FileLister { * @param ignored ignored paths * @return On success, an empty string is returned. On error, a error message is returned. */ - static std::string recursiveAddFiles(std::list> &files, const std::string &path, const PathMatch& ignored) { + static std::string recursiveAddFiles(std::list &files, const std::string &path, const PathMatch& ignored) { const std::set extra; return recursiveAddFiles(files, path, extra, ignored); } @@ -59,7 +60,7 @@ class FileLister { * @param ignored ignored paths * @return On success, an empty string is returned. On error, a error message is returned. */ - static std::string recursiveAddFiles(std::list> &files, const std::string &path, const std::set &extra, const PathMatch& ignored); + static std::string recursiveAddFiles(std::list &files, const std::string &path, const std::set &extra, const PathMatch& ignored); /** * @brief (Recursively) add source files to a map. @@ -73,7 +74,7 @@ class FileLister { * @param ignored ignored paths * @return On success, an empty string is returned. On error, a error message is returned. */ - static std::string addFiles(std::list> &files, const std::string &path, const std::set &extra, bool recursive, const PathMatch& ignored); + static std::string addFiles(std::list &files, const std::string &path, const std::set &extra, bool recursive, const PathMatch& ignored); }; /// @} diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp index bf270f54a8b..912f15c6b63 100644 --- a/cli/processexecutor.cpp +++ b/cli/processexecutor.cpp @@ -63,7 +63,7 @@ enum class Color; using std::memset; -ProcessExecutor::ProcessExecutor(const std::list> &files, const std::list& fileSettings, const Settings &settings, SuppressionList &suppressions, ErrorLogger &errorLogger, CppCheck::ExecuteCmdFn executeCommand) +ProcessExecutor::ProcessExecutor(const std::list &files, const std::list& fileSettings, const Settings &settings, SuppressionList &suppressions, ErrorLogger &errorLogger, CppCheck::ExecuteCmdFn executeCommand) : Executor(files, fileSettings, settings, suppressions, errorLogger) , mExecuteCommand(std::move(executeCommand)) { @@ -233,15 +233,15 @@ unsigned int ProcessExecutor::check() unsigned int fileCount = 0; unsigned int result = 0; - const std::size_t totalfilesize = std::accumulate(mFiles.cbegin(), mFiles.cend(), std::size_t(0), [](std::size_t v, const std::pair& p) { - return v + p.second; + const std::size_t totalfilesize = std::accumulate(mFiles.cbegin(), mFiles.cend(), std::size_t(0), [](std::size_t v, const FileWithDetails& p) { + return v + p.size(); }); std::list rpipes; std::map childFile; std::map pipeFile; std::size_t processedsize = 0; - std::list>::const_iterator iFile = mFiles.cbegin(); + std::list::const_iterator iFile = mFiles.cbegin(); std::list::const_iterator iFileSettings = mFileSettings.cbegin(); for (;;) { // Start a new child @@ -286,7 +286,7 @@ unsigned int ProcessExecutor::check() fileChecker.analyseClangTidy(*iFileSettings); } else { // Read file from a file - resultOfCheck = fileChecker.check(iFile->first); + resultOfCheck = fileChecker.check(iFile->path()); // TODO: call analyseClangTidy()? } @@ -297,12 +297,12 @@ unsigned int ProcessExecutor::check() close(pipes[1]); rpipes.push_back(pipes[0]); if (iFileSettings != mFileSettings.end()) { - childFile[pid] = iFileSettings->filename + ' ' + iFileSettings->cfg; - pipeFile[pipes[0]] = iFileSettings->filename + ' ' + iFileSettings->cfg; + childFile[pid] = iFileSettings->filename() + ' ' + iFileSettings->cfg; + pipeFile[pipes[0]] = iFileSettings->filename() + ' ' + iFileSettings->cfg; ++iFileSettings; } else { - childFile[pid] = iFile->first; - pipeFile[pipes[0]] = iFile->first; + childFile[pid] = iFile->path(); + pipeFile[pipes[0]] = iFile->path(); ++iFile; } } @@ -330,11 +330,11 @@ unsigned int ProcessExecutor::check() std::size_t size = 0; if (p != pipeFile.end()) { pipeFile.erase(p); - const auto fs = std::find_if(mFiles.cbegin(), mFiles.cend(), [&name](const std::pair& entry) { - return entry.first == name; + const auto fs = std::find_if(mFiles.cbegin(), mFiles.cend(), [&name](const FileWithDetails& entry) { + return entry.path() == name; }); if (fs != mFiles.end()) { - size = fs->second; + size = fs->size(); } } diff --git a/cli/processexecutor.h b/cli/processexecutor.h index 2f160dcc3e2..9e94557c5b8 100644 --- a/cli/processexecutor.h +++ b/cli/processexecutor.h @@ -31,6 +31,7 @@ class Settings; class ErrorLogger; class SuppressionList; struct FileSettings; +class FileWithDetails; /// @addtogroup CLI /// @{ @@ -41,7 +42,7 @@ struct FileSettings; */ class ProcessExecutor : public Executor { public: - ProcessExecutor(const std::list> &files, const std::list& fileSettings, const Settings &settings, SuppressionList &suppressions, ErrorLogger &errorLogger, CppCheck::ExecuteCmdFn executeCommand); + ProcessExecutor(const std::list &files, const std::list& fileSettings, const Settings &settings, SuppressionList &suppressions, ErrorLogger &errorLogger, CppCheck::ExecuteCmdFn executeCommand); ProcessExecutor(const ProcessExecutor &) = delete; ProcessExecutor& operator=(const ProcessExecutor &) = delete; diff --git a/cli/singleexecutor.cpp b/cli/singleexecutor.cpp index 91ec65c1e48..da3e0fcc34a 100644 --- a/cli/singleexecutor.cpp +++ b/cli/singleexecutor.cpp @@ -30,7 +30,7 @@ class ErrorLogger; -SingleExecutor::SingleExecutor(CppCheck &cppcheck, const std::list> &files, const std::list& fileSettings, const Settings &settings, SuppressionList &suppressions, ErrorLogger &errorLogger) +SingleExecutor::SingleExecutor(CppCheck &cppcheck, const std::list &files, const std::list& fileSettings, const Settings &settings, SuppressionList &suppressions, ErrorLogger &errorLogger) : Executor(files, fileSettings, settings, suppressions, errorLogger) , mCppcheck(cppcheck) { @@ -42,16 +42,16 @@ unsigned int SingleExecutor::check() { unsigned int result = 0; - const std::size_t totalfilesize = std::accumulate(mFiles.cbegin(), mFiles.cend(), std::size_t(0), [](std::size_t v, const std::pair& f) { - return v + f.second; + const std::size_t totalfilesize = std::accumulate(mFiles.cbegin(), mFiles.cend(), std::size_t(0), [](std::size_t v, const FileWithDetails& f) { + return v + f.size(); }); std::size_t processedsize = 0; unsigned int c = 0; - for (std::list>::const_iterator i = mFiles.cbegin(); i != mFiles.cend(); ++i) { - result += mCppcheck.check(i->first); - processedsize += i->second; + for (std::list::const_iterator i = mFiles.cbegin(); i != mFiles.cend(); ++i) { + result += mCppcheck.check(i->path()); + processedsize += i->size(); ++c; if (!mSettings.quiet) reportStatus(c, mFiles.size(), processedsize, totalfilesize); diff --git a/cli/singleexecutor.h b/cli/singleexecutor.h index e42b78ffa08..b1d9ef5c67f 100644 --- a/cli/singleexecutor.h +++ b/cli/singleexecutor.h @@ -31,11 +31,12 @@ class Settings; class CppCheck; class SuppressionList; struct FileSettings; +class FileWithDetails; class SingleExecutor : public Executor { public: - SingleExecutor(CppCheck &cppcheck, const std::list> &files, const std::list& fileSettings, const Settings &settings, SuppressionList &suppressions, ErrorLogger &errorLogger); + SingleExecutor(CppCheck &cppcheck, const std::list &files, const std::list& fileSettings, const Settings &settings, SuppressionList &suppressions, ErrorLogger &errorLogger); SingleExecutor(const SingleExecutor &) = delete; SingleExecutor& operator=(const SingleExecutor &) = delete; diff --git a/cli/threadexecutor.cpp b/cli/threadexecutor.cpp index 8edd5cf146b..4525166d508 100644 --- a/cli/threadexecutor.cpp +++ b/cli/threadexecutor.cpp @@ -39,7 +39,7 @@ enum class Color; -ThreadExecutor::ThreadExecutor(const std::list> &files, const std::list& fileSettings, const Settings &settings, SuppressionList &suppressions, ErrorLogger &errorLogger, CppCheck::ExecuteCmdFn executeCommand) +ThreadExecutor::ThreadExecutor(const std::list &files, const std::list& fileSettings, const Settings &settings, SuppressionList &suppressions, ErrorLogger &errorLogger, CppCheck::ExecuteCmdFn executeCommand) : Executor(files, fileSettings, settings, suppressions, errorLogger) , mExecuteCommand(std::move(executeCommand)) { @@ -81,24 +81,24 @@ class SyncLogForwarder : public ErrorLogger class ThreadData { public: - ThreadData(ThreadExecutor &threadExecutor, ErrorLogger &errorLogger, const Settings &settings, const std::list> &files, const std::list &fileSettings, CppCheck::ExecuteCmdFn executeCommand) + ThreadData(ThreadExecutor &threadExecutor, ErrorLogger &errorLogger, const Settings &settings, const std::list &files, const std::list &fileSettings, CppCheck::ExecuteCmdFn executeCommand) : mFiles(files), mFileSettings(fileSettings), mSettings(settings), mExecuteCommand(std::move(executeCommand)), logForwarder(threadExecutor, errorLogger) { mItNextFile = mFiles.begin(); mItNextFileSettings = mFileSettings.begin(); mTotalFiles = mFiles.size() + mFileSettings.size(); - mTotalFileSize = std::accumulate(mFiles.cbegin(), mFiles.cend(), std::size_t(0), [](std::size_t v, const std::pair& p) { - return v + p.second; + mTotalFileSize = std::accumulate(mFiles.cbegin(), mFiles.cend(), std::size_t(0), [](std::size_t v, const FileWithDetails& p) { + return v + p.size(); }); } bool next(const std::string *&file, const FileSettings *&fs, std::size_t &fileSize) { std::lock_guard l(mFileSync); if (mItNextFile != mFiles.end()) { - file = &mItNextFile->first; + file = &mItNextFile->path(); fs = nullptr; - fileSize = mItNextFile->second; + fileSize = mItNextFile->size(); ++mItNextFile; return true; } @@ -140,8 +140,8 @@ class ThreadData } private: - const std::list> &mFiles; - std::list>::const_iterator mItNextFile; + const std::list &mFiles; + std::list::const_iterator mItNextFile; const std::list &mFileSettings; std::list::const_iterator mItNextFileSettings; diff --git a/cli/threadexecutor.h b/cli/threadexecutor.h index 9658beb767d..c2233783951 100644 --- a/cli/threadexecutor.h +++ b/cli/threadexecutor.h @@ -31,6 +31,7 @@ class Settings; class ErrorLogger; class SuppressionList; struct FileSettings; +class FileWithDetails; /// @addtogroup CLI /// @{ @@ -43,7 +44,7 @@ class ThreadExecutor : public Executor { friend class SyncLogForwarder; public: - ThreadExecutor(const std::list> &files, const std::list& fileSettings, const Settings &settings, SuppressionList &suppressions, ErrorLogger &errorLogger, CppCheck::ExecuteCmdFn executeCommand); + ThreadExecutor(const std::list &files, const std::list& fileSettings, const Settings &settings, SuppressionList &suppressions, ErrorLogger &errorLogger, CppCheck::ExecuteCmdFn executeCommand); ThreadExecutor(const ThreadExecutor &) = delete; ThreadExecutor& operator=(const ThreadExecutor &) = delete; diff --git a/gui/checkthread.cpp b/gui/checkthread.cpp index 7d8d22ebca4..daea0556859 100644 --- a/gui/checkthread.cpp +++ b/gui/checkthread.cpp @@ -111,9 +111,9 @@ void CheckThread::run() if (!mFiles.isEmpty() || mAnalyseWholeProgram) { mAnalyseWholeProgram = false; qDebug() << "Whole program analysis"; - std::list> files2; + std::list files2; std::transform(mFiles.cbegin(), mFiles.cend(), std::back_inserter(files2), [&](const QString& file) { - return std::pair{file.toStdString(), 0}; + return FileWithDetails{file.toStdString(), 0}; }); mCppcheck.analyseWholeProgram(mCppcheck.settings().buildDir, files2, {}); mFiles.clear(); @@ -133,11 +133,11 @@ void CheckThread::run() } FileSettings fileSettings = mResult.getNextFileSettings(); - while (!fileSettings.filename.empty() && mState == Running) { - file = QString::fromStdString(fileSettings.filename); + while (!fileSettings.filename().empty() && mState == Running) { + file = QString::fromStdString(fileSettings.filename()); qDebug() << "Checking file" << file; mCppcheck.check(fileSettings); - runAddonsAndTools(&fileSettings, QString::fromStdString(fileSettings.filename)); + runAddonsAndTools(&fileSettings, QString::fromStdString(fileSettings.filename())); emit fileChecked(file); if (mState == Running) @@ -214,7 +214,7 @@ void CheckThread::runAddonsAndTools(const FileSettings *fileSettings, const QStr const std::string &buildDir = mCppcheck.settings().buildDir; if (!buildDir.empty()) { - analyzerInfoFile = QString::fromStdString(AnalyzerInformation::getAnalyzerInfoFile(buildDir, fileSettings->filename, fileSettings->cfg)); + analyzerInfoFile = QString::fromStdString(AnalyzerInformation::getAnalyzerInfoFile(buildDir, fileSettings->filename(), fileSettings->cfg)); QStringList args2(args); args2.insert(0,"-E"); diff --git a/gui/compliancereportdialog.cpp b/gui/compliancereportdialog.cpp index ff3812f352f..242f72ca5b7 100644 --- a/gui/compliancereportdialog.cpp +++ b/gui/compliancereportdialog.cpp @@ -177,7 +177,7 @@ void ComplianceReportDialog::save() QDir dir(inf.absoluteDir()); for (const FileSettings& fs: p.fileSettings) - fileList.addFile(dir.relativeFilePath(QString::fromStdString(fs.filename))); + fileList.addFile(dir.relativeFilePath(QString::fromStdString(fs.filename()))); } QSet allFiles; diff --git a/gui/threadresult.cpp b/gui/threadresult.cpp index bc807e9717d..bbb373e9519 100644 --- a/gui/threadresult.cpp +++ b/gui/threadresult.cpp @@ -72,7 +72,7 @@ FileSettings ThreadResult::getNextFileSettings() { std::lock_guard locker(mutex); if (mFileSettings.empty()) { - return FileSettings(); + return FileSettings(""); } const FileSettings fs = mFileSettings.front(); mFileSettings.pop_front(); @@ -107,7 +107,7 @@ void ThreadResult::setProject(const ImportProject &prj) // Determine the total size of all of the files to check, so that we can // show an accurate progress estimate mMaxProgress = std::accumulate(prj.fileSettings.begin(), prj.fileSettings.end(), quint64{ 0 }, [](quint64 v, const FileSettings& fs) { - return v + QFile(QString::fromStdString(fs.filename)).size(); + return v + QFile(QString::fromStdString(fs.filename())).size(); }); } diff --git a/lib/analyzerinfo.cpp b/lib/analyzerinfo.cpp index 9b5b06c27f4..9c97788b021 100644 --- a/lib/analyzerinfo.cpp +++ b/lib/analyzerinfo.cpp @@ -59,8 +59,8 @@ void AnalyzerInformation::writeFilesTxt(const std::string &buildDir, const std:: } for (const FileSettings &fs : fileSettings) { - const std::string afile = getFilename(fs.filename); - fout << afile << ".a" << (++fileCount[afile]) << ":" << fs.cfg << ":" << Path::simplifyPath(Path::fromNativeSeparators(fs.filename)) << std::endl; + const std::string afile = getFilename(fs.filename()); + fout << afile << ".a" << (++fileCount[afile]) << ":" << fs.cfg << ":" << Path::simplifyPath(Path::fromNativeSeparators(fs.filename())) << std::endl; } } diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 17948db683a..60eb88951d2 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -578,12 +578,12 @@ unsigned int CppCheck::check(const FileSettings &fs) if (mSettings.clang) { temp.mSettings.includePaths.insert(temp.mSettings.includePaths.end(), fs.systemIncludePaths.cbegin(), fs.systemIncludePaths.cend()); // TODO: propagate back suppressions - const unsigned int returnValue = temp.check(Path::simplifyPath(fs.filename)); + const unsigned int returnValue = temp.check(Path::simplifyPath(fs.filename())); if (mUnusedFunctionsCheck) mUnusedFunctionsCheck->updateFunctionData(*temp.mUnusedFunctionsCheck); return returnValue; } - const unsigned int returnValue = temp.checkFile(Path::simplifyPath(fs.filename), fs.cfg); + const unsigned int returnValue = temp.checkFile(Path::simplifyPath(fs.filename()), fs.cfg); mSettings.supprs.nomsg.addSuppressions(temp.mSettings.supprs.nomsg.getSuppressions()); if (mUnusedFunctionsCheck) mUnusedFunctionsCheck->updateFunctionData(*temp.mUnusedFunctionsCheck); @@ -1460,14 +1460,14 @@ void CppCheck::executeAddons(const std::vector& files, const std::s } } -void CppCheck::executeAddonsWholeProgram(const std::list> &files) +void CppCheck::executeAddonsWholeProgram(const std::list &files) { if (mSettings.addons.empty()) return; std::vector ctuInfoFiles; for (const auto &f: files) { - const std::string &dumpFileName = getDumpFileName(mSettings, f.first); + const std::string &dumpFileName = getDumpFileName(mSettings, f.path()); ctuInfoFiles.push_back(getCtuInfoFileName(dumpFileName)); } @@ -1668,7 +1668,7 @@ void CppCheck::analyseClangTidy(const FileSettings &fileSettings) constexpr char exe[] = "clang-tidy"; #endif - const std::string args = "-quiet -checks=*,-clang-analyzer-*,-llvm* \"" + fileSettings.filename + "\" -- " + allIncludes + allDefines; + const std::string args = "-quiet -checks=*,-clang-analyzer-*,-llvm* \"" + fileSettings.filename() + "\" -- " + allIncludes + allDefines; std::string output; if (const int exitcode = mExecuteCommand(exe, split(args), emptyString, output)) { std::cerr << "Failed to execute '" << exe << "' (exitcode: " << std::to_string(exitcode) << ")" << std::endl; @@ -1680,7 +1680,7 @@ void CppCheck::analyseClangTidy(const FileSettings &fileSettings) std::string line; if (!mSettings.buildDir.empty()) { - const std::string analyzerInfoFile = AnalyzerInformation::getAnalyzerInfoFile(mSettings.buildDir, fileSettings.filename, emptyString); + const std::string analyzerInfoFile = AnalyzerInformation::getAnalyzerInfoFile(mSettings.buildDir, fileSettings.filename(), emptyString); std::ofstream fcmd(analyzerInfoFile + ".clang-tidy-cmd"); fcmd << istr.str(); } @@ -1755,7 +1755,7 @@ bool CppCheck::analyseWholeProgram() return errors && (mExitCode > 0); } -unsigned int CppCheck::analyseWholeProgram(const std::string &buildDir, const std::list> &files, const std::list& fileSettings) +unsigned int CppCheck::analyseWholeProgram(const std::string &buildDir, const std::list &files, const std::list& fileSettings) { executeAddonsWholeProgram(files); // TODO: pass FileSettings if (buildDir.empty()) { @@ -1825,16 +1825,16 @@ unsigned int CppCheck::analyseWholeProgram(const std::string &buildDir, const st return mExitCode; } -void CppCheck::removeCtuInfoFiles(const std::list> &files, const std::list& fileSettings) +void CppCheck::removeCtuInfoFiles(const std::list &files, const std::list& fileSettings) { if (mSettings.buildDir.empty()) { for (const auto& f: files) { - const std::string &dumpFileName = getDumpFileName(mSettings, f.first); + const std::string &dumpFileName = getDumpFileName(mSettings, f.path()); const std::string &ctuInfoFileName = getCtuInfoFileName(dumpFileName); std::remove(ctuInfoFileName.c_str()); } for (const auto& fs: fileSettings) { - const std::string &dumpFileName = getDumpFileName(mSettings, fs.filename); + const std::string &dumpFileName = getDumpFileName(mSettings, fs.filename()); const std::string &ctuInfoFileName = getCtuInfoFileName(dumpFileName); std::remove(ctuInfoFileName.c_str()); } diff --git a/lib/cppcheck.h b/lib/cppcheck.h index 486f77bc9a6..2ca1f0238e9 100644 --- a/lib/cppcheck.h +++ b/lib/cppcheck.h @@ -44,6 +44,7 @@ enum class SHOWTIME_MODES; struct FileSettings; class CheckUnusedFunctions; class Tokenizer; +class FileWithDetails; namespace simplecpp { class TokenList; } @@ -142,10 +143,10 @@ class CPPCHECKLIB CppCheck : ErrorLogger { void analyseClangTidy(const FileSettings &fileSettings); /** analyse whole program use .analyzeinfo files */ - unsigned int analyseWholeProgram(const std::string &buildDir, const std::list> &files, const std::list& fileSettings); + unsigned int analyseWholeProgram(const std::string &buildDir, const std::list &files, const std::list& fileSettings); /** Remove *.ctu-info files */ - void removeCtuInfoFiles(const std::list>& files, const std::list& fileSettings); // cppcheck-suppress functionConst // has side effects + void removeCtuInfoFiles(const std::list& files, const std::list& fileSettings); // cppcheck-suppress functionConst // has side effects static void resetTimerResults(); static void printTimerResults(SHOWTIME_MODES mode); @@ -192,7 +193,7 @@ class CPPCHECKLIB CppCheck : ErrorLogger { /** * Execute addons */ - void executeAddonsWholeProgram(const std::list> &files); + void executeAddonsWholeProgram(const std::list &files); #ifdef HAVE_RULES /** diff --git a/lib/filesettings.h b/lib/filesettings.h index 11ac5b5c513..d6edc1e443d 100644 --- a/lib/filesettings.h +++ b/lib/filesettings.h @@ -25,11 +25,50 @@ #include #include #include +#include + +class FileWithDetails +{ +public: + explicit FileWithDetails(std::string path) + : FileWithDetails(std::move(path), 0) + {} + + FileWithDetails(std::string path, std::size_t size) + : mPath(std::move(path)) + , mSize(size) + {} + + const std::string& path() const + { + return mPath; + } + + std::size_t size() const + { + return mSize; + } +private: + std::string mPath; + std::size_t mSize; +}; /** File settings. Multiple configurations for a file is allowed. */ struct CPPCHECKLIB FileSettings { + explicit FileSettings(std::string path) + : file(std::move(path)) + {} + + FileSettings(std::string path, std::size_t size) + : file(std::move(path), size) + {} + std::string cfg; - std::string filename; + FileWithDetails file; + const std::string& filename() const + { + return file.path(); + } std::string defines; // TODO: handle differently std::string cppcheckDefines() const { diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 47c55e09a44..6a30ae46850 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -46,17 +46,17 @@ void ImportProject::ignorePaths(const std::vector &ipaths) for (std::list::iterator it = fileSettings.begin(); it != fileSettings.end();) { bool ignore = false; for (std::string i : ipaths) { - if (it->filename.size() > i.size() && it->filename.compare(0,i.size(),i)==0) { + if (it->filename().size() > i.size() && it->filename().compare(0,i.size(),i)==0) { ignore = true; break; } - if (isValidGlobPattern(i) && matchglob(i, it->filename)) { + if (isValidGlobPattern(i) && matchglob(i, it->filename())) { ignore = true; break; } if (!Path::isAbsolute(i)) { i = mPath + i; - if (it->filename.size() > i.size() && it->filename.compare(0,i.size(),i)==0) { + if (it->filename().size() > i.size() && it->filename().compare(0,i.size(),i)==0) { ignore = true; break; } @@ -398,22 +398,23 @@ bool ImportProject::importCompileCommands(std::istream &istr) if (!Path::acceptFile(file)) continue; - FileSettings fs; + std::string path; if (Path::isAbsolute(file)) - fs.filename = Path::simplifyPath(file); + path = Path::simplifyPath(file); #ifdef _WIN32 else if (file[0] == '/' && directory.size() > 2 && std::isalpha(directory[0]) && directory[1] == ':') // directory: C:\foo\bar // file: /xy/z.c // => c:/xy/z.c - fs.filename = Path::simplifyPath(directory.substr(0,2) + file); + path = Path::simplifyPath(directory.substr(0,2) + file); #endif else - fs.filename = Path::simplifyPath(directory + file); - if (!sourceFileExists(fs.filename)) { - printError("'" + fs.filename + "' from compilation database does not exist"); + path = Path::simplifyPath(directory + file); + if (!sourceFileExists(path)) { + printError("'" + path + "' from compilation database does not exist"); return false; } + FileSettings fs{std::move(path)}; fsParseCommand(fs, command); // read settings; -D, -I, -U, -std, -m*, -f* std::map variables; fsSetIncludePaths(fs, directory, fs.includePaths, variables); @@ -759,8 +760,7 @@ bool ImportProject::importVcxproj(const std::string &filename, std::map basePaths{Path::fromNativeSeparators(Path::getCurrentPath())}; for (auto &fs: fileSettings) { - fs.filename = Path::getRelativePath(fs.filename, basePaths); + fs.file = FileWithDetails{Path::getRelativePath(fs.filename(), basePaths)}; for (auto &includePath: fs.includePaths) includePath = Path::getRelativePath(includePath, basePaths); } diff --git a/test/helpers.cpp b/test/helpers.cpp index a2fe44c0ab1..85391067d4f 100644 --- a/test/helpers.cpp +++ b/test/helpers.cpp @@ -19,6 +19,7 @@ #include "helpers.h" #include "filelister.h" +#include "filesettings.h" #include "path.h" #include "pathmatch.h" #include "preprocessor.h" @@ -82,14 +83,14 @@ ScopedFile::~ScopedFile() { // TODO: remove all files // TODO: simplify the function call // hack to be able to delete *.plist output files - std::list> files; + std::list files; const std::string res = FileLister::addFiles(files, mPath, {".plist"}, false, PathMatch({})); if (!res.empty()) { std::cout << "ScopedFile(" << mPath + ") - generating file list failed (" << res << ")" << std::endl; } for (const auto &f : files) { - const std::string &file = f.first; + const std::string &file = f.path(); const int rm_f_res = std::remove(file.c_str()); if (rm_f_res != 0) { std::cout << "ScopedFile(" << mPath + ") - could not delete '" << file << "' (" << rm_f_res << ")" << std::endl; diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp index 4916a9242e4..47f7319d162 100644 --- a/test/testcppcheck.cpp +++ b/test/testcppcheck.cpp @@ -122,8 +122,7 @@ class TestCppcheck : public TestFixture { ErrorLogger2 errorLogger; CppCheck cppcheck(errorLogger, false, {}); - FileSettings fs; - fs.filename = file.path(); + FileSettings fs{file.path()}; ASSERT_EQUALS(1, cppcheck.check(fs)); // TODO: how to properly disable these warnings? errorLogger.ids.erase(std::remove_if(errorLogger.ids.begin(), errorLogger.ids.end(), [](const std::string& id) { diff --git a/test/testfilelister.cpp b/test/testfilelister.cpp index 22590cb94e1..7eb5bb4e09b 100644 --- a/test/testfilelister.cpp +++ b/test/testfilelister.cpp @@ -17,6 +17,7 @@ */ #include "filelister.h" +#include "filesettings.h" #include "path.h" #include "pathmatch.h" #include "fixture.h" @@ -58,7 +59,7 @@ class TestFileLister : public TestFixture { const std::string adddir = findBaseDir() + "."; // Recursively add add files.. - std::list> files; + std::list files; std::vector masks; PathMatch matcher(std::move(masks)); std::string err = FileLister::recursiveAddFiles(files, adddir, matcher); @@ -75,8 +76,8 @@ class TestFileLister : public TestFixture { #endif const auto find_file = [&](const std::string& name) { - return std::find_if(files.cbegin(), files.cend(), [&name](const std::pair& entry) { - return entry.first == name; + return std::find_if(files.cbegin(), files.cend(), [&name](const FileWithDetails& entry) { + return entry.path() == name; }); }; @@ -92,7 +93,7 @@ class TestFileLister : public TestFixture { } void recursiveAddFilesEmptyPath() const { - std::list> files; + std::list files; const std::string err = FileLister::recursiveAddFiles(files, "", PathMatch({})); ASSERT_EQUALS("no path specified", err); } @@ -100,7 +101,7 @@ class TestFileLister : public TestFixture { void excludeFile1() const { const std::string basedir = findBaseDir(); - std::list> files; + std::list files; std::vector ignored{"lib/token.cpp"}; PathMatch matcher(ignored); std::string err = FileLister::recursiveAddFiles(files, basedir + "lib/token.cpp", matcher); @@ -111,13 +112,13 @@ class TestFileLister : public TestFixture { void excludeFile2() const { const std::string basedir = findBaseDir(); - std::list> files; + std::list files; std::vector ignored; PathMatch matcher(ignored); std::string err = FileLister::recursiveAddFiles(files, basedir + "lib/token.cpp", matcher); ASSERT_EQUALS("", err); ASSERT_EQUALS(1, files.size()); - ASSERT_EQUALS(basedir + "lib/token.cpp", files.begin()->first); + ASSERT_EQUALS(basedir + "lib/token.cpp", files.begin()->path()); } // TODO: test errors diff --git a/test/testfilesettings.cpp b/test/testfilesettings.cpp new file mode 100644 index 00000000000..a7764ca1034 --- /dev/null +++ b/test/testfilesettings.cpp @@ -0,0 +1,65 @@ +/* + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2024 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 "filesettings.h" +#include "fixture.h" + +class TestFileSettings : public TestFixture { +public: + TestFileSettings() : TestFixture("TestFileSettings") {} + +private: + void run() override { + TEST_CASE(path); + } + + void path() const { + { + const FileWithDetails p{"file.cpp"}; + ASSERT_EQUALS("file.cpp", p.path()); + ASSERT_EQUALS(0, p.size()); + } + { + const FileWithDetails p{"file.cpp", 123}; + ASSERT_EQUALS("file.cpp", p.path()); + ASSERT_EQUALS(123, p.size()); + } + { + const FileWithDetails p{"in/file.cpp"}; + ASSERT_EQUALS("in/file.cpp", p.path()); + ASSERT_EQUALS(0, p.size()); + } + { + const FileWithDetails p{"in\\file.cpp"}; + ASSERT_EQUALS("in\\file.cpp", p.path()); + ASSERT_EQUALS(0, p.size()); + } + { + const FileWithDetails p{"in/../file.cpp"}; + ASSERT_EQUALS("in/../file.cpp", p.path()); + ASSERT_EQUALS(0, p.size()); + } + { + const FileWithDetails p{"in\\..\\file.cpp"}; + ASSERT_EQUALS("in\\..\\file.cpp", p.path()); + ASSERT_EQUALS(0, p.size()); + } + } +}; + +REGISTER_TEST(TestFileSettings) diff --git a/test/testimportproject.cpp b/test/testimportproject.cpp index 466805b598f..8486a1351d0 100644 --- a/test/testimportproject.cpp +++ b/test/testimportproject.cpp @@ -69,7 +69,7 @@ class TestImportProject : public TestFixture { } void setDefines() const { - FileSettings fs; + FileSettings fs{""}; ImportProject::fsSetDefines(fs, "A"); ASSERT_EQUALS("A=1", fs.defines); @@ -85,7 +85,7 @@ class TestImportProject : public TestFixture { } void setIncludePaths1() const { - FileSettings fs; + FileSettings fs{""}; std::list in(1, "../include"); std::map variables; ImportProject::fsSetIncludePaths(fs, "abc/def/", in, variables); @@ -94,7 +94,7 @@ class TestImportProject : public TestFixture { } void setIncludePaths2() const { - FileSettings fs; + FileSettings fs{""}; std::list in(1, "$(SolutionDir)other"); std::map variables; variables["SolutionDir"] = "c:/abc/"; @@ -104,7 +104,7 @@ class TestImportProject : public TestFixture { } void setIncludePaths3() const { // macro names are case insensitive - FileSettings fs; + FileSettings fs{""}; std::list in(1, "$(SOLUTIONDIR)other"); std::map variables; variables["SolutionDir"] = "c:/abc/"; @@ -140,7 +140,7 @@ class TestImportProject : public TestFixture { TestImporter importer; ASSERT_EQUALS(true, importer.importCompileCommands(istr)); ASSERT_EQUALS(1, importer.fileSettings.size()); - ASSERT_EQUALS("C:/bar.c", importer.fileSettings.cbegin()->filename); + ASSERT_EQUALS("C:/bar.c", importer.fileSettings.cbegin()->filename()); #else constexpr char json[] = R"([{ "directory": "/foo", @@ -151,7 +151,7 @@ class TestImportProject : public TestFixture { TestImporter importer; ASSERT_EQUALS(true, importer.importCompileCommands(istr)); ASSERT_EQUALS(1, importer.fileSettings.size()); - ASSERT_EQUALS("/bar.c", importer.fileSettings.cbegin()->filename); + ASSERT_EQUALS("/bar.c", importer.fileSettings.cbegin()->filename()); #endif } @@ -166,7 +166,7 @@ class TestImportProject : public TestFixture { TestImporter importer; ASSERT_EQUALS(true, importer.importCompileCommands(istr)); ASSERT_EQUALS(1, importer.fileSettings.size()); - ASSERT_EQUALS("/tmp/src.c", importer.fileSettings.cbegin()->filename); + ASSERT_EQUALS("/tmp/src.c", importer.fileSettings.cbegin()->filename()); } void importCompileCommands4() const { @@ -328,7 +328,7 @@ class TestImportProject : public TestFixture { TestImporter importer; ASSERT_EQUALS(true, importer.importCompileCommands(istr)); ASSERT_EQUALS(1, importer.fileSettings.size()); - ASSERT_EQUALS("/tmp/src.c", importer.fileSettings.cbegin()->filename); + ASSERT_EQUALS("/tmp/src.c", importer.fileSettings.cbegin()->filename()); } void importCompileCommandsNoCommandSection() const { @@ -371,9 +371,8 @@ class TestImportProject : public TestFixture { } void ignorePaths() const { - FileSettings fs1, fs2; - fs1.filename = "foo/bar"; - fs2.filename = "qwe/rty"; + FileSettings fs1{"foo/bar"}; + FileSettings fs2{"qwe/rty"}; TestImporter project; project.fileSettings = {std::move(fs1), std::move(fs2)}; @@ -382,7 +381,7 @@ class TestImportProject : public TestFixture { project.ignorePaths({"foo/*"}); ASSERT_EQUALS(1, project.fileSettings.size()); - ASSERT_EQUALS("qwe/rty", project.fileSettings.front().filename); + ASSERT_EQUALS("qwe/rty", project.fileSettings.front().filename()); project.ignorePaths({ "*e/r*" }); ASSERT_EQUALS(0, project.fileSettings.size()); diff --git a/test/testprocessexecutor.cpp b/test/testprocessexecutor.cpp index c29bd323767..c62253ab359 100644 --- a/test/testprocessexecutor.cpp +++ b/test/testprocessexecutor.cpp @@ -68,15 +68,13 @@ class TestProcessExecutorBase : public TestFixture { void check(unsigned int jobs, int files, int result, const std::string &data, const CheckOptions& opt = make_default_obj{}) { std::list fileSettings; - std::list> filelist; + std::list filelist; if (opt.filesList.empty()) { for (int i = 1; i <= files; ++i) { std::string f_s = fprefix() + "_" + std::to_string(i) + ".cpp"; filelist.emplace_back(f_s, data.size()); if (useFS) { - FileSettings fs; - fs.filename = std::move(f_s); - fileSettings.emplace_back(std::move(fs)); + fileSettings.emplace_back(std::move(f_s), data.size()); } } } @@ -85,9 +83,7 @@ class TestProcessExecutorBase : public TestFixture { { filelist.emplace_back(f, data.size()); if (useFS) { - FileSettings fs; - fs.filename = f; - fileSettings.emplace_back(std::move(fs)); + fileSettings.emplace_back(f, data.size()); } } } @@ -112,8 +108,8 @@ class TestProcessExecutorBase : public TestFixture { std::vector> scopedfiles; scopedfiles.reserve(filelist.size()); - for (std::list>::const_iterator i = filelist.cbegin(); i != filelist.cend(); ++i) - scopedfiles.emplace_back(new ScopedFile(i->first, data)); + for (std::list::const_iterator i = filelist.cbegin(); i != filelist.cend(); ++i) + scopedfiles.emplace_back(new ScopedFile(i->path(), data)); // clear files list so only fileSettings are used if (useFS) diff --git a/test/testrunner.vcxproj b/test/testrunner.vcxproj index 06cbbd96667..ca0cb73244f 100755 --- a/test/testrunner.vcxproj +++ b/test/testrunner.vcxproj @@ -63,6 +63,7 @@ + diff --git a/test/testsingleexecutor.cpp b/test/testsingleexecutor.cpp index 33e44b5cf23..6c85c50d239 100644 --- a/test/testsingleexecutor.cpp +++ b/test/testsingleexecutor.cpp @@ -73,15 +73,13 @@ class TestSingleExecutorBase : public TestFixture { void check(int files, int result, const std::string &data, const CheckOptions& opt = make_default_obj{}) { std::list fileSettings; - std::list> filelist; + std::list filelist; if (opt.filesList.empty()) { for (int i = 1; i <= files; ++i) { std::string f_s = fprefix() + "_" + zpad3(i) + ".cpp"; filelist.emplace_back(f_s, data.size()); if (useFS) { - FileSettings fs; - fs.filename = std::move(f_s); - fileSettings.emplace_back(std::move(fs)); + fileSettings.emplace_back(std::move(f_s), data.size()); } } } @@ -90,9 +88,8 @@ class TestSingleExecutorBase : public TestFixture { { filelist.emplace_back(f, data.size()); if (useFS) { - FileSettings fs; - fs.filename = f; - fileSettings.emplace_back(std::move(fs)); + + fileSettings.emplace_back(f, data.size()); } } } @@ -118,8 +115,8 @@ class TestSingleExecutorBase : public TestFixture { std::vector> scopedfiles; scopedfiles.reserve(filelist.size()); - for (std::list>::const_iterator i = filelist.cbegin(); i != filelist.cend(); ++i) - scopedfiles.emplace_back(new ScopedFile(i->first, data)); + for (std::list::const_iterator i = filelist.cbegin(); i != filelist.cend(); ++i) + scopedfiles.emplace_back(new ScopedFile(i->path(), data)); // clear files list so only fileSettings are used if (useFS) diff --git a/test/testsuppressions.cpp b/test/testsuppressions.cpp index b0d94c7c016..5e31520ce96 100644 --- a/test/testsuppressions.cpp +++ b/test/testsuppressions.cpp @@ -229,13 +229,11 @@ class TestSuppressions : public TestFixture { unsigned int _checkSuppression(std::map &f, bool useFS, const std::string &suppression = emptyString) { std::list fileSettings; - std::list> filelist; + std::list filelist; for (std::map::const_iterator i = f.cbegin(); i != f.cend(); ++i) { filelist.emplace_back(i->first, i->second.size()); if (useFS) { - FileSettings fs; - fs.filename = i->first; - fileSettings.emplace_back(std::move(fs)); + fileSettings.emplace_back(i->first, i->second.size()); } } @@ -279,12 +277,10 @@ class TestSuppressions : public TestFixture { unsigned int _checkSuppressionThreads(const char code[], bool useFS, const std::string &suppression = emptyString) { std::list fileSettings; - std::list> filelist; + std::list filelist; filelist.emplace_back("test.cpp", strlen(code)); if (useFS) { - FileSettings fs; - fs.filename = "test.cpp"; - fileSettings.emplace_back(std::move(fs)); + fileSettings.emplace_back("test.cpp", strlen(code)); } /*const*/ auto settings = dinit(Settings, @@ -298,8 +294,8 @@ class TestSuppressions : public TestFixture { std::vector> scopedfiles; scopedfiles.reserve(filelist.size()); - for (std::list>::const_iterator i = filelist.cbegin(); i != filelist.cend(); ++i) - scopedfiles.emplace_back(new ScopedFile(i->first, code)); + for (std::list::const_iterator i = filelist.cbegin(); i != filelist.cend(); ++i) + scopedfiles.emplace_back(new ScopedFile(i->path(), code)); // clear files list so only fileSettings are used if (useFS) @@ -325,12 +321,10 @@ class TestSuppressions : public TestFixture { unsigned int _checkSuppressionProcesses(const char code[], bool useFS, const std::string &suppression = emptyString) { std::list fileSettings; - std::list> filelist; + std::list filelist; filelist.emplace_back("test.cpp", strlen(code)); if (useFS) { - FileSettings fs; - fs.filename = "test.cpp"; - fileSettings.emplace_back(std::move(fs)); + fileSettings.emplace_back("test.cpp", strlen(code)); } /*const*/ auto settings = dinit(Settings, @@ -344,8 +338,8 @@ class TestSuppressions : public TestFixture { std::vector> scopedfiles; scopedfiles.reserve(filelist.size()); - for (std::list>::const_iterator i = filelist.cbegin(); i != filelist.cend(); ++i) - scopedfiles.emplace_back(new ScopedFile(i->first, code)); + for (std::list::const_iterator i = filelist.cbegin(); i != filelist.cend(); ++i) + scopedfiles.emplace_back(new ScopedFile(i->path(), code)); // clear files list so only fileSettings are used if (useFS) diff --git a/test/testthreadexecutor.cpp b/test/testthreadexecutor.cpp index af66a711777..f353158457b 100644 --- a/test/testthreadexecutor.cpp +++ b/test/testthreadexecutor.cpp @@ -68,15 +68,13 @@ class TestThreadExecutorBase : public TestFixture { void check(unsigned int jobs, int files, int result, const std::string &data, const CheckOptions& opt = make_default_obj{}) { std::list fileSettings; - std::list> filelist; + std::list filelist; if (opt.filesList.empty()) { for (int i = 1; i <= files; ++i) { std::string f_s = fprefix() + "_" + std::to_string(i) + ".cpp"; filelist.emplace_back(f_s, data.size()); if (useFS) { - FileSettings fs; - fs.filename = std::move(f_s); - fileSettings.emplace_back(std::move(fs)); + fileSettings.emplace_back(std::move(f_s), data.size()); } } } @@ -85,9 +83,7 @@ class TestThreadExecutorBase : public TestFixture { { filelist.emplace_back(f, data.size()); if (useFS) { - FileSettings fs; - fs.filename = f; - fileSettings.emplace_back(std::move(fs)); + fileSettings.emplace_back(f, data.size()); } } } @@ -113,8 +109,8 @@ class TestThreadExecutorBase : public TestFixture { std::vector> scopedfiles; scopedfiles.reserve(filelist.size()); - for (std::list>::const_iterator i = filelist.cbegin(); i != filelist.cend(); ++i) - scopedfiles.emplace_back(new ScopedFile(i->first, data)); + for (std::list::const_iterator i = filelist.cbegin(); i != filelist.cend(); ++i) + scopedfiles.emplace_back(new ScopedFile(i->path(), data)); // clear files list so only fileSettings are used if (useFS) diff --git a/tools/dmake/dmake.cpp b/tools/dmake/dmake.cpp index 6de023f5cea..458c8ca1cad 100644 --- a/tools/dmake/dmake.cpp +++ b/tools/dmake/dmake.cpp @@ -33,6 +33,7 @@ #include "config.h" #include "../cli/filelister.h" +#include "../lib/filesettings.h" #include "../lib/pathmatch.h" #include "../lib/utils.h" @@ -159,7 +160,7 @@ static void compilefiles(std::ostream &fout, const std::vector &fil static std::string getCppFiles(std::vector &files, const std::string &path, bool recursive) { - std::list> filelist; + std::list filelist; const std::set extra; const std::vector masks; const PathMatch matcher(masks); @@ -168,9 +169,9 @@ static std::string getCppFiles(std::vector &files, const std::strin return err; // add *.cpp files to the "files" vector.. - for (const std::pair file : filelist) { - if (endsWith(file.first, ".cpp")) - files.push_back(file.first); + for (const auto& file : filelist) { + if (endsWith(file.path(), ".cpp")) + files.push_back(file.path()); } return ""; }