From 245636f906e8709a8d45c6c3fe3a0888eb2157b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Sun, 10 Nov 2024 15:06:26 +0100 Subject: [PATCH 01/27] fix #12771 --- cli/processexecutor.cpp | 22 ++++++++++++++++------ lib/filesettings.h | 4 ++++ lib/importproject.cpp | 25 +++++++++++++++++++++++++ lib/importproject.h | 1 + 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp index 2ca13fa9e4e..ac887975a20 100644 --- a/cli/processexecutor.cpp +++ b/cli/processexecutor.cpp @@ -239,9 +239,12 @@ 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 FileWithDetails& p) { - return v + p.size(); + std::size_t totalfilesize = std::accumulate(mFileSettings.cbegin(), mFileSettings.cend(), std::size_t(0), [](std::size_t v, const FileSettings& fs) { + return v + fs.filesize(); }); + for (const auto &f : mFiles) { + totalfilesize += f.size(); + } std::list rpipes; std::map childFile; @@ -336,11 +339,18 @@ unsigned int ProcessExecutor::check() std::size_t size = 0; if (p != pipeFile.cend()) { pipeFile.erase(p); - const auto fs = std::find_if(mFiles.cbegin(), mFiles.cend(), [&name](const FileWithDetails& entry) { - return entry.path() == name; + const auto fs = std::find_if(mFileSettings.cbegin(), mFileSettings.cend(), [&name](const FileSettings& entry) { + return entry.filename() == name.substr(0, name.find(' ')); }); - if (fs != mFiles.end()) { - size = fs->size(); + if (fs == mFileSettings.cend()) { + const auto fwd = std::find_if(mFiles.cbegin(), mFiles.cend(), [&name](const FileWithDetails &entry) { + return entry.path() == name.substr(0, name.find(' ')); + }); + if (fwd != mFiles.cend()) { + size = fwd->size(); + } + } else { + size = fs->filesize(); } } diff --git a/lib/filesettings.h b/lib/filesettings.h index 5b3039cd4e7..3add3ad63d1 100644 --- a/lib/filesettings.h +++ b/lib/filesettings.h @@ -99,6 +99,10 @@ struct CPPCHECKLIB FileSettings { { return file.spath(); } + std::size_t filesize() const + { + return file.size(); + } std::string defines; // TODO: handle differently std::string cppcheckDefines() const { diff --git a/lib/importproject.cpp b/lib/importproject.cpp index e4bfc8b42cd..ca251b03729 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -37,6 +37,9 @@ #include #include +#include +#include + #include "xml.h" #include "json.h" @@ -194,11 +197,13 @@ ImportProject::Type ImportProject::import(const std::string &filename, Settings if (endsWith(filename, ".json")) { if (importCompileCommands(fin)) { setRelativePaths(filename); + setFileSizes(); return ImportProject::Type::COMPILE_DB; } } else if (endsWith(filename, ".sln")) { if (importSln(fin, mPath, fileFilters)) { setRelativePaths(filename); + setFileSizes(); return ImportProject::Type::VS_SLN; } } else if (endsWith(filename, ".vcxproj")) { @@ -206,16 +211,19 @@ ImportProject::Type ImportProject::import(const std::string &filename, Settings std::vector sharedItemsProjects; if (importVcxproj(filename, variables, emptyString, fileFilters, sharedItemsProjects)) { setRelativePaths(filename); + setFileSizes(); return ImportProject::Type::VS_VCXPROJ; } } else if (endsWith(filename, ".bpr")) { if (importBcb6Prj(filename)) { setRelativePaths(filename); + setFileSizes(); return ImportProject::Type::BORLAND; } } else if (settings && endsWith(filename, ".cppcheck")) { if (importCppcheckGuiProject(fin, settings)) { setRelativePaths(filename); + setFileSizes(); return ImportProject::Type::CPPCHECK_GUI; } } else { @@ -1495,3 +1503,20 @@ bool ImportProject::sourceFileExists(const std::string &file) { return Path::isFile(file); } + +void ImportProject::setFileSizes() +{ + for (auto &fs : fileSettings) { + int statResult; +#ifdef _WIN32 + struct _stat statBuf; + statResult = _stat(fs.filename().c_str(), &statBuf); +#else + struct stat statBuf; + statResult = stat(fs.filename().c_str(), &statBuf); +#endif + if (statResult == 0) { + fs.file = FileWithDetails(fs.file.path(), statBuf.st_size); + } + } +} diff --git a/lib/importproject.h b/lib/importproject.h index ef8c44f8d7b..71cff32e370 100644 --- a/lib/importproject.h +++ b/lib/importproject.h @@ -117,6 +117,7 @@ class CPPCHECKLIB WARN_UNUSED ImportProject { static void printError(const std::string &message); void setRelativePaths(const std::string &filename); + void setFileSizes(); std::string mPath; std::set mAllVSConfigs; From c35fd05de8461c1d3d12cd9f2ea10381758f37c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 11 Nov 2024 11:19:17 +0100 Subject: [PATCH 02/27] fix #12771 for ThreadExecutor --- cli/threadexecutor.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cli/threadexecutor.cpp b/cli/threadexecutor.cpp index a7758314cf7..1e5186de527 100644 --- a/cli/threadexecutor.cpp +++ b/cli/threadexecutor.cpp @@ -90,6 +90,9 @@ class ThreadData mTotalFileSize = std::accumulate(mFiles.cbegin(), mFiles.cend(), std::size_t(0), [](std::size_t v, const FileWithDetails& p) { return v + p.size(); }); + for (const auto &fs : mFileSettings) { + mTotalFileSize += fs.filesize(); + } } bool next(const FileWithDetails *&file, const FileSettings *&fs, std::size_t &fileSize) { @@ -104,7 +107,7 @@ class ThreadData if (mItNextFileSettings != mFileSettings.end()) { file = nullptr; fs = &(*mItNextFileSettings); - fileSize = 0; + fileSize = mItNextFileSettings->filesize(); ++mItNextFileSettings; return true; } From 53d75850b407a29e386e26f72783c595f01baec8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 11 Nov 2024 11:48:38 +0100 Subject: [PATCH 03/27] use _stati64 on 64 bit windows --- lib/importproject.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/importproject.cpp b/lib/importproject.cpp index ca251b03729..237e1c38e45 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -1509,8 +1509,13 @@ void ImportProject::setFileSizes() for (auto &fs : fileSettings) { int statResult; #ifdef _WIN32 +#ifdef _WIN64 + struct _stati64 statBuf; + statResult = _stati64(fs.filename().c_str(), &statBuf); +#else struct _stat statBuf; statResult = _stat(fs.filename().c_str(), &statBuf); +#endif #else struct stat statBuf; statResult = stat(fs.filename().c_str(), &statBuf); From b25503d6e3941dac5da9884079406ad0cee25cac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 11 Nov 2024 12:43:48 +0100 Subject: [PATCH 04/27] move (most of the) file size logic to FileWithDetails --- Makefile | 4 +++ cli/filelister.cpp | 8 +++--- lib/cppcheck.vcxproj | 2 ++ lib/filesettings.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++ lib/filesettings.h | 18 +++++++++++++ lib/importproject.cpp | 17 +----------- oss-fuzz/Makefile | 4 +++ 7 files changed, 95 insertions(+), 20 deletions(-) create mode 100644 lib/filesettings.cpp diff --git a/Makefile b/Makefile index c01dc8df126..6fc2b6c0e23 100644 --- a/Makefile +++ b/Makefile @@ -221,6 +221,7 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/ctu.o \ $(libcppdir)/errorlogger.o \ $(libcppdir)/errortypes.o \ + $(libcppdir)/filesettings.o \ $(libcppdir)/forwardanalyzer.o \ $(libcppdir)/fwdanalysis.o \ $(libcppdir)/importproject.o \ @@ -571,6 +572,9 @@ $(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h li $(libcppdir)/errortypes.o: lib/errortypes.cpp lib/config.h lib/errortypes.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errortypes.cpp +$(libcppdir)/filesettings.o: lib/filesettings.cpp lib/config.h lib/filesettings.h lib/path.h lib/platform.h lib/standards.h lib/utils.h + $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/filesettings.cpp + $(libcppdir)/forwardanalyzer.o: lib/forwardanalyzer.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/color.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/suppressions.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 diff --git a/cli/filelister.cpp b/cli/filelister.cpp index 841f84ae89e..12b3c97a12f 100644 --- a/cli/filelister.cpp +++ b/cli/filelister.cpp @@ -232,11 +232,11 @@ static std::string addFiles2(std::list &files, } else { Standards::Language lang = Standards::Language::None; if (Path::acceptFile(new_path, extra, &lang) && !ignored.match(new_path)) { - if (stat(new_path.c_str(), &file_stat) == -1) { - const int err = errno; - return "could not stat file '" + new_path + "' (errno: " + std::to_string(err) + ")"; + files.emplace_back(new_path, lang); + std::string err = files.back().updateSize(); + if (!err.empty()) { + return err; } - files.emplace_back(new_path, lang, file_stat.st_size); } } } diff --git a/lib/cppcheck.vcxproj b/lib/cppcheck.vcxproj index 6074eb664cb..b88a2718d4f 100644 --- a/lib/cppcheck.vcxproj +++ b/lib/cppcheck.vcxproj @@ -66,6 +66,7 @@ + @@ -139,6 +140,7 @@ + diff --git a/lib/filesettings.cpp b/lib/filesettings.cpp new file mode 100644 index 00000000000..5f0221ae3f7 --- /dev/null +++ b/lib/filesettings.cpp @@ -0,0 +1,62 @@ +/* + * 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 +#include +#include + +#ifdef _WIN32 + +#ifdef _WIN64 + +std::string FileWithDetails::updateSize() { + struct _stati64 buf; + if (_stati64(mPath.c_str(), &buf) < 0) { + return "could not stat file '" + mPath + "': (errno: " + std::to_string(errno) + ")"; + } + mSize = buf.st_size; + return ""; +} + +#else + +std::string FileWithDetails::updateSize() { + struct _stat buf; + if (_stat(mPath.c_str(), &buf) < 0) { + return "could not stat file '" + mPath + "': (errno: " + std::to_string(errno) + ")"; + } + mSize = buf.st_size; + return ""; +} + +#endif + +#else + +std::string FileWithDetails::updateSize() { + struct stat buf; + if (stat(mPath.c_str(), &buf) < 0) { + return "could not stat file '" + mPath + "': (errno: " + std::to_string(errno) + ")"; + } + mSize = buf.st_size; + return ""; +} + +#endif diff --git a/lib/filesettings.h b/lib/filesettings.h index 3add3ad63d1..ffe76bec2b2 100644 --- a/lib/filesettings.h +++ b/lib/filesettings.h @@ -47,6 +47,15 @@ class FileWithDetails throw std::runtime_error("empty path specified"); } + FileWithDetails(std::string path, Standards::Language lang) + : mPath(std::move(path)) + , mPathSimplified(Path::simplifyPath(mPath)) + , mLang(lang) + { + if (mPath.empty()) + throw std::runtime_error("empty path specified"); + } + const std::string& path() const { return mPath; @@ -71,6 +80,9 @@ class FileWithDetails { return mLang; } + + std::string updateSize(); + private: std::string mPath; std::string mPathSimplified; @@ -103,6 +115,12 @@ struct CPPCHECKLIB FileSettings { { return file.size(); } + + std::string updateFileSize() + { + return file.updateSize(); + } + std::string defines; // TODO: handle differently std::string cppcheckDefines() const { diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 237e1c38e45..bee71536354 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -1507,21 +1507,6 @@ bool ImportProject::sourceFileExists(const std::string &file) void ImportProject::setFileSizes() { for (auto &fs : fileSettings) { - int statResult; -#ifdef _WIN32 -#ifdef _WIN64 - struct _stati64 statBuf; - statResult = _stati64(fs.filename().c_str(), &statBuf); -#else - struct _stat statBuf; - statResult = _stat(fs.filename().c_str(), &statBuf); -#endif -#else - struct stat statBuf; - statResult = stat(fs.filename().c_str(), &statBuf); -#endif - if (statResult == 0) { - fs.file = FileWithDetails(fs.file.path(), statBuf.st_size); - } + fs.updateFileSize(); } } diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index 4203c9deb46..ffde74f4ac7 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -74,6 +74,7 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/ctu.o \ $(libcppdir)/errorlogger.o \ $(libcppdir)/errortypes.o \ + $(libcppdir)/filesettings.o \ $(libcppdir)/forwardanalyzer.o \ $(libcppdir)/fwdanalysis.o \ $(libcppdir)/importproject.o \ @@ -267,6 +268,9 @@ $(libcppdir)/errorlogger.o: ../lib/errorlogger.cpp ../externals/tinyxml2/tinyxml $(libcppdir)/errortypes.o: ../lib/errortypes.cpp ../lib/config.h ../lib/errortypes.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errortypes.cpp +$(libcppdir)/filesettings.o: ../lib/filesettings.cpp ../lib/config.h ../lib/filesettings.h ../lib/path.h ../lib/platform.h ../lib/standards.h ../lib/utils.h + $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/filesettings.cpp + $(libcppdir)/forwardanalyzer.o: ../lib/forwardanalyzer.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/color.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/suppressions.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 From 09936cacfadb48efdce16d79e3b69dc8da608dc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 11 Nov 2024 14:10:24 +0100 Subject: [PATCH 05/27] use accumulate --- cli/processexecutor.cpp | 7 +++---- cli/threadexecutor.cpp | 5 ++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp index ac887975a20..767048f6eec 100644 --- a/cli/processexecutor.cpp +++ b/cli/processexecutor.cpp @@ -239,12 +239,11 @@ unsigned int ProcessExecutor::check() unsigned int fileCount = 0; unsigned int result = 0; - std::size_t totalfilesize = std::accumulate(mFileSettings.cbegin(), mFileSettings.cend(), std::size_t(0), [](std::size_t v, const FileSettings& fs) { + std::size_t totalfilesize = std::accumulate(mFiles.cbegin(), mFiles.cend(), std::size_t(0), [](std::size_t v, const FileWithDetails& fwd) { + return v + fwd.size(); + }) + std::accumulate(mFileSettings.cbegin(), mFileSettings.cend(), std::size_t(0), [](std::size_t v, const FileSettings& fs) { return v + fs.filesize(); }); - for (const auto &f : mFiles) { - totalfilesize += f.size(); - } std::list rpipes; std::map childFile; diff --git a/cli/threadexecutor.cpp b/cli/threadexecutor.cpp index 1e5186de527..3b66d295fa6 100644 --- a/cli/threadexecutor.cpp +++ b/cli/threadexecutor.cpp @@ -89,10 +89,9 @@ class ThreadData mTotalFiles = mFiles.size() + mFileSettings.size(); mTotalFileSize = std::accumulate(mFiles.cbegin(), mFiles.cend(), std::size_t(0), [](std::size_t v, const FileWithDetails& p) { return v + p.size(); + }) + std::accumulate(mFileSettings.cbegin(), mFileSettings.cend(), std::size_t(0), [](std::size_t v, const FileSettings& p) { + return v + p.filesize(); }); - for (const auto &fs : mFileSettings) { - mTotalFileSize += fs.filesize(); - } } bool next(const FileWithDetails *&file, const FileSettings *&fs, std::size_t &fileSize) { From 45715882adbb06e38d95825b622e1c683a178120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 11 Nov 2024 15:11:32 +0100 Subject: [PATCH 06/27] update dmake dependencies --- Makefile | 4 ++-- oss-fuzz/Makefile | 2 +- tools/dmake/CMakeLists.txt | 1 + tools/dmake/dmake.cpp | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 6fc2b6c0e23..f24ce9ecb6a 100644 --- a/Makefile +++ b/Makefile @@ -361,7 +361,7 @@ check: all checkcfg: cppcheck validateCFG ./test/cfg/runtests.sh -dmake: tools/dmake/dmake.o cli/filelister.o $(libcppdir)/pathmatch.o $(libcppdir)/path.o $(libcppdir)/utils.o externals/simplecpp/simplecpp.o +dmake: tools/dmake/dmake.o cli/filelister.o $(libcppdir)/pathmatch.o $(libcppdir)/path.o $(libcppdir)/utils.o externals/simplecpp/simplecpp.o $(libcppdir)/filesettings.o $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) run-dmake: dmake @@ -572,7 +572,7 @@ $(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h li $(libcppdir)/errortypes.o: lib/errortypes.cpp lib/config.h lib/errortypes.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errortypes.cpp -$(libcppdir)/filesettings.o: lib/filesettings.cpp lib/config.h lib/filesettings.h lib/path.h lib/platform.h lib/standards.h lib/utils.h +$(libcppdir)/filesettings.o: lib/filesettings.cpp lib/config.h lib/filesettings.h lib/path.h lib/platform.h lib/standards.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/filesettings.cpp $(libcppdir)/forwardanalyzer.o: lib/forwardanalyzer.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/color.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/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueptr.h lib/vfvalue.h diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index ffde74f4ac7..b8f3e3f50ea 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -268,7 +268,7 @@ $(libcppdir)/errorlogger.o: ../lib/errorlogger.cpp ../externals/tinyxml2/tinyxml $(libcppdir)/errortypes.o: ../lib/errortypes.cpp ../lib/config.h ../lib/errortypes.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errortypes.cpp -$(libcppdir)/filesettings.o: ../lib/filesettings.cpp ../lib/config.h ../lib/filesettings.h ../lib/path.h ../lib/platform.h ../lib/standards.h ../lib/utils.h +$(libcppdir)/filesettings.o: ../lib/filesettings.cpp ../lib/config.h ../lib/filesettings.h ../lib/path.h ../lib/platform.h ../lib/standards.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/filesettings.cpp $(libcppdir)/forwardanalyzer.o: ../lib/forwardanalyzer.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/color.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/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h diff --git a/tools/dmake/CMakeLists.txt b/tools/dmake/CMakeLists.txt index 5af693eb179..054a86d02f2 100644 --- a/tools/dmake/CMakeLists.txt +++ b/tools/dmake/CMakeLists.txt @@ -13,6 +13,7 @@ endforeach() add_executable(dmake EXCLUDE_FROM_ALL dmake.cpp ${CMAKE_SOURCE_DIR}/cli/filelister.cpp + ${CMAKE_SOURCE_DIR}/lib/filesettings.cpp ${srcs_tools} $ ) diff --git a/tools/dmake/dmake.cpp b/tools/dmake/dmake.cpp index df833b6e750..92af28ff2e9 100644 --- a/tools/dmake/dmake.cpp +++ b/tools/dmake/dmake.cpp @@ -758,7 +758,7 @@ int main(int argc, char **argv) fout << "\t./testrunner -q\n\n"; fout << "checkcfg:\tcppcheck validateCFG\n"; fout << "\t./test/cfg/runtests.sh\n\n"; - fout << "dmake:\ttools/dmake/dmake.o cli/filelister.o $(libcppdir)/pathmatch.o $(libcppdir)/path.o $(libcppdir)/utils.o externals/simplecpp/simplecpp.o\n"; + fout << "dmake:\ttools/dmake/dmake.o cli/filelister.o $(libcppdir)/pathmatch.o $(libcppdir)/path.o $(libcppdir)/utils.o externals/simplecpp/simplecpp.o $(libcppdir)/filesettings.o\n"; fout << "\t$(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)\n\n"; fout << "run-dmake: dmake\n"; fout << "\t./dmake" << (release ? " --release" : "") << "\n\n"; // Make CI in release builds happy From 8129131a527925cb69da73ee6e882bb48891971d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 11 Nov 2024 15:16:12 +0100 Subject: [PATCH 07/27] add const --- cli/processexecutor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp index 767048f6eec..7ab5a4bd2c1 100644 --- a/cli/processexecutor.cpp +++ b/cli/processexecutor.cpp @@ -239,7 +239,7 @@ unsigned int ProcessExecutor::check() unsigned int fileCount = 0; unsigned int result = 0; - std::size_t totalfilesize = std::accumulate(mFiles.cbegin(), mFiles.cend(), std::size_t(0), [](std::size_t v, const FileWithDetails& fwd) { + const std::size_t totalfilesize = std::accumulate(mFiles.cbegin(), mFiles.cend(), std::size_t(0), [](std::size_t v, const FileWithDetails& fwd) { return v + fwd.size(); }) + std::accumulate(mFileSettings.cbegin(), mFileSettings.cend(), std::size_t(0), [](std::size_t v, const FileSettings& fs) { return v + fs.filesize(); From 8f5df680e1b6246f48d45621fbc9d9a0d55711cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 11 Nov 2024 15:18:39 +0100 Subject: [PATCH 08/27] remove unused includes --- lib/importproject.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/importproject.cpp b/lib/importproject.cpp index bee71536354..877886e925e 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -37,9 +37,6 @@ #include #include -#include -#include - #include "xml.h" #include "json.h" From 8cd166ddbb52759b42f0fb88ed9aff420207f411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Thu, 14 Nov 2024 14:14:38 +0100 Subject: [PATCH 09/27] add test --- test/cli/other_test.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/cli/other_test.py b/test/cli/other_test.py index 598151b5b6f..5cc422f5a49 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -196,6 +196,17 @@ def test_progress_j(tmpdir): assert stdout == "Checking {} ...\n".format(test_file) assert stderr == "" +def test_progress_proj_j(tmpdir): + args = ['--project=proj2/proj2.cppcheck', '-j2'] + + exitcode, stdout, stderr = cppcheck(args) + + progress_lines = '\n'.join(list(filter(lambda l: not l.startswith("Checking"), stdout.split('\n')))) + + assert (progress_lines == + "1/2 files checked 76% done\n" + "2/2 files checked 100% done\n") + assert exitcode == 0 def test_execute_addon_failure_py_auto(tmpdir): test_file = os.path.join(tmpdir, 'test.cpp') From 393383230d994a1cd20e3b8d261fbab380a156b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Thu, 14 Nov 2024 14:34:48 +0100 Subject: [PATCH 10/27] move test --- test/cli/other_test.py | 11 ----------- test/cli/proj2_test.py | 7 +++++++ 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/test/cli/other_test.py b/test/cli/other_test.py index 5cc422f5a49..598151b5b6f 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -196,17 +196,6 @@ def test_progress_j(tmpdir): assert stdout == "Checking {} ...\n".format(test_file) assert stderr == "" -def test_progress_proj_j(tmpdir): - args = ['--project=proj2/proj2.cppcheck', '-j2'] - - exitcode, stdout, stderr = cppcheck(args) - - progress_lines = '\n'.join(list(filter(lambda l: not l.startswith("Checking"), stdout.split('\n')))) - - assert (progress_lines == - "1/2 files checked 76% done\n" - "2/2 files checked 100% done\n") - assert exitcode == 0 def test_execute_addon_failure_py_auto(tmpdir): test_file = os.path.join(tmpdir, 'test.cpp') diff --git a/test/cli/proj2_test.py b/test/cli/proj2_test.py index c9516d9ddbf..3cc1ef61c5b 100644 --- a/test/cli/proj2_test.py +++ b/test/cli/proj2_test.py @@ -85,6 +85,13 @@ def test_absolute_path(tmp_path): assert stdout.find('Checking %s ...' % file1) >= 0 assert stdout.find('Checking %s ...' % file2) >= 0 +def test_progress_threads(): + create_compile_commands() + ret, stdout, _ = cppcheck(['--project=' + os.path.realpath('proj2/' + COMPILE_COMMANDS_JSON), '-j2']) + assert ret == 0, stdout + assert stdout.find('1/2 files checked 76% done') >= 0 + assert stdout.find('2/2 files checked 100% done') >= 0 + def test_gui_project_loads_compile_commands_1(tmp_path): proj_dir = tmp_path / 'proj2' shutil.copytree(__proj_dir, proj_dir) From 037c6addc43e7aecb7aee075465bb012533ba2ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 18 Nov 2024 12:48:44 +0100 Subject: [PATCH 11/27] rebase --- test/cli/proj2_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cli/proj2_test.py b/test/cli/proj2_test.py index 3cc1ef61c5b..ff0a70992fd 100644 --- a/test/cli/proj2_test.py +++ b/test/cli/proj2_test.py @@ -86,8 +86,8 @@ def test_absolute_path(tmp_path): assert stdout.find('Checking %s ...' % file2) >= 0 def test_progress_threads(): - create_compile_commands() - ret, stdout, _ = cppcheck(['--project=' + os.path.realpath('proj2/' + COMPILE_COMMANDS_JSON), '-j2']) + __create_compile_commands() + ret, stdout, _ = cppcheck(['--project=' + os.path.realpath('proj2/' + __COMPILE_COMMANDS_JSON), '-j2']) assert ret == 0, stdout assert stdout.find('1/2 files checked 76% done') >= 0 assert stdout.find('2/2 files checked 100% done') >= 0 From 037cffefb01da3b5df8cde7e5e239f3c3562646b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 18 Nov 2024 12:58:32 +0100 Subject: [PATCH 12/27] fix path --- test/cli/proj2_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cli/proj2_test.py b/test/cli/proj2_test.py index ff0a70992fd..aae2fe434f8 100644 --- a/test/cli/proj2_test.py +++ b/test/cli/proj2_test.py @@ -87,7 +87,7 @@ def test_absolute_path(tmp_path): def test_progress_threads(): __create_compile_commands() - ret, stdout, _ = cppcheck(['--project=' + os.path.realpath('proj2/' + __COMPILE_COMMANDS_JSON), '-j2']) + ret, stdout, _ = cppcheck(['--project=' + os.path.join(__proj_dir, __COMPILE_COMMANDS_JSON), '-j2'], cwd=__script_dir) assert ret == 0, stdout assert stdout.find('1/2 files checked 76% done') >= 0 assert stdout.find('2/2 files checked 100% done') >= 0 From 3b7ed5031aecaef2d76ba722c528022bec185b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 18 Nov 2024 13:44:29 +0100 Subject: [PATCH 13/27] calculate percentage in test --- test/cli/proj2_test.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/cli/proj2_test.py b/test/cli/proj2_test.py index aae2fe434f8..d92c12f6a75 100644 --- a/test/cli/proj2_test.py +++ b/test/cli/proj2_test.py @@ -86,10 +86,12 @@ def test_absolute_path(tmp_path): assert stdout.find('Checking %s ...' % file2) >= 0 def test_progress_threads(): + size1 = os.path.getsize(os.path.join(__proj_dir, 'a', 'a.c')) + size2 = os.path.getsize(os.path.join(__proj_dir, 'b', 'b.c')) __create_compile_commands() ret, stdout, _ = cppcheck(['--project=' + os.path.join(__proj_dir, __COMPILE_COMMANDS_JSON), '-j2'], cwd=__script_dir) assert ret == 0, stdout - assert stdout.find('1/2 files checked 76% done') >= 0 + assert stdout.find('1/2 files checked %d%% done' % (100 * size1 // (size1 + size2))) >= 0 assert stdout.find('2/2 files checked 100% done') >= 0 def test_gui_project_loads_compile_commands_1(tmp_path): From 11f768514ff61a0896749fb83129fe35f2a29582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Tue, 19 Nov 2024 09:25:03 +0100 Subject: [PATCH 14/27] account for different file orders --- test/cli/proj2_test.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/cli/proj2_test.py b/test/cli/proj2_test.py index d92c12f6a75..ee96a50de2f 100644 --- a/test/cli/proj2_test.py +++ b/test/cli/proj2_test.py @@ -88,10 +88,12 @@ def test_absolute_path(tmp_path): def test_progress_threads(): size1 = os.path.getsize(os.path.join(__proj_dir, 'a', 'a.c')) size2 = os.path.getsize(os.path.join(__proj_dir, 'b', 'b.c')) + perc1 = 100 * size1 // (size1 + size2) + perc2 = 100 * size2 // (size1 + size2) __create_compile_commands() ret, stdout, _ = cppcheck(['--project=' + os.path.join(__proj_dir, __COMPILE_COMMANDS_JSON), '-j2'], cwd=__script_dir) assert ret == 0, stdout - assert stdout.find('1/2 files checked %d%% done' % (100 * size1 // (size1 + size2))) >= 0 + assert stdout.find('1/2 files checked %d%% done' % perc1) >= 0 or stdout.find('1/2 files checked %d%% done' % perc2) >= 0 assert stdout.find('2/2 files checked 100% done') >= 0 def test_gui_project_loads_compile_commands_1(tmp_path): From 5a97406b2e18e552dde52159723c292c187b1395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Tue, 19 Nov 2024 11:54:09 +0100 Subject: [PATCH 15/27] account for spaces in filenames --- cli/processexecutor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp index 7ab5a4bd2c1..966bc099d1f 100644 --- a/cli/processexecutor.cpp +++ b/cli/processexecutor.cpp @@ -339,11 +339,11 @@ unsigned int ProcessExecutor::check() if (p != pipeFile.cend()) { pipeFile.erase(p); const auto fs = std::find_if(mFileSettings.cbegin(), mFileSettings.cend(), [&name](const FileSettings& entry) { - return entry.filename() == name.substr(0, name.find(' ')); + return name.find(entry.filename() + " ") == 0; }); if (fs == mFileSettings.cend()) { const auto fwd = std::find_if(mFiles.cbegin(), mFiles.cend(), [&name](const FileWithDetails &entry) { - return entry.path() == name.substr(0, name.find(' ')); + return name.find(entry.path() + " ") == 0; }); if (fwd != mFiles.cend()) { size = fwd->size(); From 758b7edd24f0eca357e28e53400178a746066c91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Sun, 22 Dec 2024 15:25:35 +0100 Subject: [PATCH 16/27] move filesize logic to path.cpp --- Makefile | 4 --- lib/cppcheck.vcxproj | 2 -- lib/filesettings.cpp | 62 -------------------------------------------- lib/filesettings.h | 9 ++++++- lib/path.cpp | 36 +++++++++++++++++++++++++ lib/path.h | 7 +++++ oss-fuzz/Makefile | 4 --- 7 files changed, 51 insertions(+), 73 deletions(-) delete mode 100644 lib/filesettings.cpp diff --git a/Makefile b/Makefile index f24ce9ecb6a..4294a25f5e8 100644 --- a/Makefile +++ b/Makefile @@ -221,7 +221,6 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/ctu.o \ $(libcppdir)/errorlogger.o \ $(libcppdir)/errortypes.o \ - $(libcppdir)/filesettings.o \ $(libcppdir)/forwardanalyzer.o \ $(libcppdir)/fwdanalysis.o \ $(libcppdir)/importproject.o \ @@ -572,9 +571,6 @@ $(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h li $(libcppdir)/errortypes.o: lib/errortypes.cpp lib/config.h lib/errortypes.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errortypes.cpp -$(libcppdir)/filesettings.o: lib/filesettings.cpp lib/config.h lib/filesettings.h lib/path.h lib/platform.h lib/standards.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/filesettings.cpp - $(libcppdir)/forwardanalyzer.o: lib/forwardanalyzer.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/color.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/suppressions.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 diff --git a/lib/cppcheck.vcxproj b/lib/cppcheck.vcxproj index b88a2718d4f..6074eb664cb 100644 --- a/lib/cppcheck.vcxproj +++ b/lib/cppcheck.vcxproj @@ -66,7 +66,6 @@ - @@ -140,7 +139,6 @@ - diff --git a/lib/filesettings.cpp b/lib/filesettings.cpp deleted file mode 100644 index 5f0221ae3f7..00000000000 --- a/lib/filesettings.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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 -#include -#include - -#ifdef _WIN32 - -#ifdef _WIN64 - -std::string FileWithDetails::updateSize() { - struct _stati64 buf; - if (_stati64(mPath.c_str(), &buf) < 0) { - return "could not stat file '" + mPath + "': (errno: " + std::to_string(errno) + ")"; - } - mSize = buf.st_size; - return ""; -} - -#else - -std::string FileWithDetails::updateSize() { - struct _stat buf; - if (_stat(mPath.c_str(), &buf) < 0) { - return "could not stat file '" + mPath + "': (errno: " + std::to_string(errno) + ")"; - } - mSize = buf.st_size; - return ""; -} - -#endif - -#else - -std::string FileWithDetails::updateSize() { - struct stat buf; - if (stat(mPath.c_str(), &buf) < 0) { - return "could not stat file '" + mPath + "': (errno: " + std::to_string(errno) + ")"; - } - mSize = buf.st_size; - return ""; -} - -#endif diff --git a/lib/filesettings.h b/lib/filesettings.h index ffe76bec2b2..77ca2e199eb 100644 --- a/lib/filesettings.h +++ b/lib/filesettings.h @@ -81,7 +81,14 @@ class FileWithDetails return mLang; } - std::string updateSize(); + std::string updateSize() + { + ssize_t ssize = Path::fileSize(mPath); + if (ssize < 0) + return "could not stat file '" + mPath + "': (errno: " + std::to_string(errno) + ")"; + mSize = ssize; + return ""; + } private: std::string mPath; diff --git a/lib/path.cpp b/lib/path.cpp index 3a1d517db36..06a86f66f49 100644 --- a/lib/path.cpp +++ b/lib/path.cpp @@ -439,3 +439,39 @@ std::string Path::join(const std::string& path1, const std::string& path2) { return path2; return ((path1.back() == '/') ? path1 : (path1 + "/")) + path2; } + +#ifdef _WIN32 + +# ifdef _WIN64 + +ssize_t Path::fileSize(const std::string &filePath) { + struct _stati64 buf; + if (_stati64(filePath.c_str(), &buf) < 0) { + return -1; + } + return buf.st_size; +} + +# else + +ssize_t Path::fileSize(const std::string &filePath) { + struct _stat buf; + if (_stat(filePath.c_str(), &buf) < 0) { + return -1; + } + return buf.st_size; +} + +# endif + +#else + +ssize_t Path::fileSize(const std::string &filePath) { + struct stat buf; + if (stat(filePath.c_str(), &buf) < 0) { + return -1; + } + return buf.st_size; +} + +#endif diff --git a/lib/path.h b/lib/path.h index db22773ed65..6d91fdfd980 100644 --- a/lib/path.h +++ b/lib/path.h @@ -203,6 +203,13 @@ class CPPCHECKLIB Path { * join 2 paths with '/' separators */ static std::string join(const std::string& path1, const std::string& path2); + + /** + * @brief Get the size of a file + * @param filePath path to the file, or -1 if the file cannot be accessed + * @return size of file + */ + static ssize_t fileSize(const std::string &filePath); }; /// @} diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index b8f3e3f50ea..4203c9deb46 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -74,7 +74,6 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/ctu.o \ $(libcppdir)/errorlogger.o \ $(libcppdir)/errortypes.o \ - $(libcppdir)/filesettings.o \ $(libcppdir)/forwardanalyzer.o \ $(libcppdir)/fwdanalysis.o \ $(libcppdir)/importproject.o \ @@ -268,9 +267,6 @@ $(libcppdir)/errorlogger.o: ../lib/errorlogger.cpp ../externals/tinyxml2/tinyxml $(libcppdir)/errortypes.o: ../lib/errortypes.cpp ../lib/config.h ../lib/errortypes.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errortypes.cpp -$(libcppdir)/filesettings.o: ../lib/filesettings.cpp ../lib/config.h ../lib/filesettings.h ../lib/path.h ../lib/platform.h ../lib/standards.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/filesettings.cpp - $(libcppdir)/forwardanalyzer.o: ../lib/forwardanalyzer.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/color.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/suppressions.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 From 4dc6684fb0d827ba0c84c641e55046aaaa032eb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Sun, 22 Dec 2024 16:00:20 +0100 Subject: [PATCH 17/27] set file sizes in CmdLineParser::fillSettingsFromArgs --- cli/cmdlineparser.cpp | 6 ++++++ lib/importproject.cpp | 12 ------------ 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 0bc0052f576..dd13d1ef7f3 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -245,6 +245,9 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[]) if (mSettings.library.markupFile(fs.filename())) { fs.file.setLang(Standards::Language::C); } + std::string error = fs.updateFileSize(); + if (!error.empty()) + mLogger.printError(error); } // sort the markup last @@ -350,6 +353,9 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[]) if (mSettings.library.markupFile(f.path())) { f.setLang(Standards::Language::C); } + std::string error = f.updateSize(); + if (!error.empty()) + mLogger.printError(error); } // sort the markup last diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 877886e925e..e4bfc8b42cd 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -194,13 +194,11 @@ ImportProject::Type ImportProject::import(const std::string &filename, Settings if (endsWith(filename, ".json")) { if (importCompileCommands(fin)) { setRelativePaths(filename); - setFileSizes(); return ImportProject::Type::COMPILE_DB; } } else if (endsWith(filename, ".sln")) { if (importSln(fin, mPath, fileFilters)) { setRelativePaths(filename); - setFileSizes(); return ImportProject::Type::VS_SLN; } } else if (endsWith(filename, ".vcxproj")) { @@ -208,19 +206,16 @@ ImportProject::Type ImportProject::import(const std::string &filename, Settings std::vector sharedItemsProjects; if (importVcxproj(filename, variables, emptyString, fileFilters, sharedItemsProjects)) { setRelativePaths(filename); - setFileSizes(); return ImportProject::Type::VS_VCXPROJ; } } else if (endsWith(filename, ".bpr")) { if (importBcb6Prj(filename)) { setRelativePaths(filename); - setFileSizes(); return ImportProject::Type::BORLAND; } } else if (settings && endsWith(filename, ".cppcheck")) { if (importCppcheckGuiProject(fin, settings)) { setRelativePaths(filename); - setFileSizes(); return ImportProject::Type::CPPCHECK_GUI; } } else { @@ -1500,10 +1495,3 @@ bool ImportProject::sourceFileExists(const std::string &file) { return Path::isFile(file); } - -void ImportProject::setFileSizes() -{ - for (auto &fs : fileSettings) { - fs.updateFileSize(); - } -} From ccad3f0d7dc51fb0f040b7e72536b183abf275aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Sun, 22 Dec 2024 16:39:31 +0100 Subject: [PATCH 18/27] store filesize in pipeFile map --- cli/processexecutor.cpp | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp index 966bc099d1f..5dd11c59a0b 100644 --- a/cli/processexecutor.cpp +++ b/cli/processexecutor.cpp @@ -247,7 +247,7 @@ unsigned int ProcessExecutor::check() std::list rpipes; std::map childFile; - std::map pipeFile; + std::map> pipeFile; std::size_t processedsize = 0; auto iFile = mFiles.cbegin(); auto iFileSettings = mFileSettings.cbegin(); @@ -306,11 +306,11 @@ unsigned int ProcessExecutor::check() rpipes.push_back(pipes[0]); if (iFileSettings != mFileSettings.end()) { childFile[pid] = iFileSettings->filename() + ' ' + iFileSettings->cfg; - pipeFile[pipes[0]] = iFileSettings->filename() + ' ' + iFileSettings->cfg; + pipeFile[pipes[0]] = { iFileSettings->filename() + ' ' + iFileSettings->cfg, iFileSettings->filesize() }; ++iFileSettings; } else { childFile[pid] = iFile->path(); - pipeFile[pipes[0]] = iFile->path(); + pipeFile[pipes[0]] = { iFile->path(), iFile->size() }; ++iFile; } } @@ -329,28 +329,16 @@ unsigned int ProcessExecutor::check() while (rp != rpipes.cend()) { if (FD_ISSET(*rp, &rfds)) { std::string name; - const auto p = utils::as_const(pipeFile).find(*rp); + std::size_t size = 0; + const std::map>::const_iterator p = pipeFile.find(*rp); if (p != pipeFile.cend()) { - name = p->second; + name = p->second.first; + size = p->second.second; } const bool readRes = handleRead(*rp, result, name); if (!readRes) { - std::size_t size = 0; if (p != pipeFile.cend()) { pipeFile.erase(p); - const auto fs = std::find_if(mFileSettings.cbegin(), mFileSettings.cend(), [&name](const FileSettings& entry) { - return name.find(entry.filename() + " ") == 0; - }); - if (fs == mFileSettings.cend()) { - const auto fwd = std::find_if(mFiles.cbegin(), mFiles.cend(), [&name](const FileWithDetails &entry) { - return name.find(entry.path() + " ") == 0; - }); - if (fwd != mFiles.cend()) { - size = fwd->size(); - } - } else { - size = fs->filesize(); - } } fileCount++; From 456de9611e5649831e3ef8f85dfeb8e87bea8b00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Sun, 22 Dec 2024 16:43:05 +0100 Subject: [PATCH 19/27] remove -j2 in progress test --- test/cli/proj2_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cli/proj2_test.py b/test/cli/proj2_test.py index ee96a50de2f..0dee35655c3 100644 --- a/test/cli/proj2_test.py +++ b/test/cli/proj2_test.py @@ -85,13 +85,13 @@ def test_absolute_path(tmp_path): assert stdout.find('Checking %s ...' % file1) >= 0 assert stdout.find('Checking %s ...' % file2) >= 0 -def test_progress_threads(): +def test_progress(): size1 = os.path.getsize(os.path.join(__proj_dir, 'a', 'a.c')) size2 = os.path.getsize(os.path.join(__proj_dir, 'b', 'b.c')) perc1 = 100 * size1 // (size1 + size2) perc2 = 100 * size2 // (size1 + size2) __create_compile_commands() - ret, stdout, _ = cppcheck(['--project=' + os.path.join(__proj_dir, __COMPILE_COMMANDS_JSON), '-j2'], cwd=__script_dir) + ret, stdout, _ = cppcheck(['--project=' + os.path.join(__proj_dir, __COMPILE_COMMANDS_JSON)], cwd=__script_dir) assert ret == 0, stdout assert stdout.find('1/2 files checked %d%% done' % perc1) >= 0 or stdout.find('1/2 files checked %d%% done' % perc2) >= 0 assert stdout.find('2/2 files checked 100% done') >= 0 From 2e09d444da4d140982e742f8038f75c6a272d3c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Sun, 22 Dec 2024 17:11:17 +0100 Subject: [PATCH 20/27] update dmake --- Makefile | 2 +- tools/dmake/CMakeLists.txt | 1 - tools/dmake/dmake.cpp | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 4294a25f5e8..c01dc8df126 100644 --- a/Makefile +++ b/Makefile @@ -360,7 +360,7 @@ check: all checkcfg: cppcheck validateCFG ./test/cfg/runtests.sh -dmake: tools/dmake/dmake.o cli/filelister.o $(libcppdir)/pathmatch.o $(libcppdir)/path.o $(libcppdir)/utils.o externals/simplecpp/simplecpp.o $(libcppdir)/filesettings.o +dmake: tools/dmake/dmake.o cli/filelister.o $(libcppdir)/pathmatch.o $(libcppdir)/path.o $(libcppdir)/utils.o externals/simplecpp/simplecpp.o $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) run-dmake: dmake diff --git a/tools/dmake/CMakeLists.txt b/tools/dmake/CMakeLists.txt index 054a86d02f2..5af693eb179 100644 --- a/tools/dmake/CMakeLists.txt +++ b/tools/dmake/CMakeLists.txt @@ -13,7 +13,6 @@ endforeach() add_executable(dmake EXCLUDE_FROM_ALL dmake.cpp ${CMAKE_SOURCE_DIR}/cli/filelister.cpp - ${CMAKE_SOURCE_DIR}/lib/filesettings.cpp ${srcs_tools} $ ) diff --git a/tools/dmake/dmake.cpp b/tools/dmake/dmake.cpp index 92af28ff2e9..df833b6e750 100644 --- a/tools/dmake/dmake.cpp +++ b/tools/dmake/dmake.cpp @@ -758,7 +758,7 @@ int main(int argc, char **argv) fout << "\t./testrunner -q\n\n"; fout << "checkcfg:\tcppcheck validateCFG\n"; fout << "\t./test/cfg/runtests.sh\n\n"; - fout << "dmake:\ttools/dmake/dmake.o cli/filelister.o $(libcppdir)/pathmatch.o $(libcppdir)/path.o $(libcppdir)/utils.o externals/simplecpp/simplecpp.o $(libcppdir)/filesettings.o\n"; + fout << "dmake:\ttools/dmake/dmake.o cli/filelister.o $(libcppdir)/pathmatch.o $(libcppdir)/path.o $(libcppdir)/utils.o externals/simplecpp/simplecpp.o\n"; fout << "\t$(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)\n\n"; fout << "run-dmake: dmake\n"; fout << "\t./dmake" << (release ? " --release" : "") << "\n\n"; // Make CI in release builds happy From 46e2a80997b1867a3155b8844e7daef86690086f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Sun, 22 Dec 2024 17:54:30 +0100 Subject: [PATCH 21/27] don't use ssize_t --- lib/filesettings.h | 2 +- lib/path.cpp | 6 +++--- lib/path.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/filesettings.h b/lib/filesettings.h index 77ca2e199eb..0fcd66c9fbe 100644 --- a/lib/filesettings.h +++ b/lib/filesettings.h @@ -83,7 +83,7 @@ class FileWithDetails std::string updateSize() { - ssize_t ssize = Path::fileSize(mPath); + long long ssize = Path::fileSize(mPath); if (ssize < 0) return "could not stat file '" + mPath + "': (errno: " + std::to_string(errno) + ")"; mSize = ssize; diff --git a/lib/path.cpp b/lib/path.cpp index 06a86f66f49..bafc8922f58 100644 --- a/lib/path.cpp +++ b/lib/path.cpp @@ -444,7 +444,7 @@ std::string Path::join(const std::string& path1, const std::string& path2) { # ifdef _WIN64 -ssize_t Path::fileSize(const std::string &filePath) { +long long Path::fileSize(const std::string &filePath) { struct _stati64 buf; if (_stati64(filePath.c_str(), &buf) < 0) { return -1; @@ -454,7 +454,7 @@ ssize_t Path::fileSize(const std::string &filePath) { # else -ssize_t Path::fileSize(const std::string &filePath) { +long long Path::fileSize(const std::string &filePath) { struct _stat buf; if (_stat(filePath.c_str(), &buf) < 0) { return -1; @@ -466,7 +466,7 @@ ssize_t Path::fileSize(const std::string &filePath) { #else -ssize_t Path::fileSize(const std::string &filePath) { +long long Path::fileSize(const std::string &filePath) { struct stat buf; if (stat(filePath.c_str(), &buf) < 0) { return -1; diff --git a/lib/path.h b/lib/path.h index 6d91fdfd980..13a5b25e2c3 100644 --- a/lib/path.h +++ b/lib/path.h @@ -209,7 +209,7 @@ class CPPCHECKLIB Path { * @param filePath path to the file, or -1 if the file cannot be accessed * @return size of file */ - static ssize_t fileSize(const std::string &filePath); + static long long fileSize(const std::string &filePath); }; /// @} From 006c9f405a402550b29638a2c0b358fef9bb0a00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Sun, 22 Dec 2024 18:26:44 +0100 Subject: [PATCH 22/27] fix typo --- lib/path.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/path.h b/lib/path.h index 13a5b25e2c3..175adcd8a3d 100644 --- a/lib/path.h +++ b/lib/path.h @@ -206,8 +206,8 @@ class CPPCHECKLIB Path { /** * @brief Get the size of a file - * @param filePath path to the file, or -1 if the file cannot be accessed - * @return size of file + * @param filePath path to the file + * @return size of file, or -1 if the file cannot be accessed */ static long long fileSize(const std::string &filePath); }; From cd4ff8a99e95cc1890ae84b9907b5069b7d7586d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Sun, 22 Dec 2024 18:24:59 +0100 Subject: [PATCH 23/27] base percentage on file size in SingleExecutor --- cli/singleexecutor.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cli/singleexecutor.cpp b/cli/singleexecutor.cpp index 216fe1fec48..59a098a97bf 100644 --- a/cli/singleexecutor.cpp +++ b/cli/singleexecutor.cpp @@ -44,6 +44,8 @@ unsigned int SingleExecutor::check() 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::accumulate(mFileSettings.cbegin(), mFileSettings.cend(), std::size_t(0), [](std::size_t v, const FileSettings& fs) { + return v + fs.filesize(); }); std::size_t processedsize = 0; @@ -62,9 +64,10 @@ unsigned int SingleExecutor::check() // check all files of the project for (const FileSettings &fs : mFileSettings) { result += mCppcheck.check(fs); + processedsize += fs.filesize(); ++c; if (!mSettings.quiet) - reportStatus(c, mFileSettings.size(), c, mFileSettings.size()); + reportStatus(c, mFileSettings.size(), processedsize, totalfilesize); if (mSettings.clangTidy) mCppcheck.analyseClangTidy(fs); } From a9570aeefec4890a7233ced8b35394cd98008d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Thu, 26 Dec 2024 13:13:13 +0100 Subject: [PATCH 24/27] add test for .cppcheck files --- test/cli/proj2_test.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/test/cli/proj2_test.py b/test/cli/proj2_test.py index 0dee35655c3..363d9a12b53 100644 --- a/test/cli/proj2_test.py +++ b/test/cli/proj2_test.py @@ -85,7 +85,7 @@ def test_absolute_path(tmp_path): assert stdout.find('Checking %s ...' % file1) >= 0 assert stdout.find('Checking %s ...' % file2) >= 0 -def test_progress(): +def test_progress_json(): size1 = os.path.getsize(os.path.join(__proj_dir, 'a', 'a.c')) size2 = os.path.getsize(os.path.join(__proj_dir, 'b', 'b.c')) perc1 = 100 * size1 // (size1 + size2) @@ -96,6 +96,17 @@ def test_progress(): assert stdout.find('1/2 files checked %d%% done' % perc1) >= 0 or stdout.find('1/2 files checked %d%% done' % perc2) >= 0 assert stdout.find('2/2 files checked 100% done') >= 0 +def test_progress_cppcheck(): + size1 = os.path.getsize(os.path.join(__proj_dir, 'a', 'a.c')) + size2 = os.path.getsize(os.path.join(__proj_dir, 'b', 'b.c')) + perc1 = 100 * size1 // (size1 + size2) + perc2 = 100 * size2 // (size1 + size2) + __create_compile_commands() + ret, stdout, _ = cppcheck(['--project=proj2/proj2.cppcheck'], cwd=__script_dir) + assert ret == 0, stdout + assert stdout.find('1/2 files checked %d%% done' % perc1) >= 0 or stdout.find('1/2 files checked %d%% done' % perc2) >= 0 + assert stdout.find('2/2 files checked 100% done') >= 0 + def test_gui_project_loads_compile_commands_1(tmp_path): proj_dir = tmp_path / 'proj2' shutil.copytree(__proj_dir, proj_dir) From feb624b7226ececb2dc3c741b15907e844595fca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Fri, 3 Jan 2025 12:45:18 +0100 Subject: [PATCH 25/27] Update test/cli/proj2_test.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Oliver Stöneberg --- test/cli/proj2_test.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/test/cli/proj2_test.py b/test/cli/proj2_test.py index 363d9a12b53..f0d681c36e9 100644 --- a/test/cli/proj2_test.py +++ b/test/cli/proj2_test.py @@ -85,24 +85,28 @@ def test_absolute_path(tmp_path): assert stdout.find('Checking %s ...' % file1) >= 0 assert stdout.find('Checking %s ...' % file2) >= 0 -def test_progress_json(): - size1 = os.path.getsize(os.path.join(__proj_dir, 'a', 'a.c')) - size2 = os.path.getsize(os.path.join(__proj_dir, 'b', 'b.c')) +def test_progress_json(tmp_path): + proj_dir = tmp_path / 'proj2' + shutil.copytree(__proj_dir, proj_dir) + size1 = os.path.getsize(os.path.join(proj_dir, 'a', 'a.c')) + size2 = os.path.getsize(os.path.join(proj_dir, 'b', 'b.c')) perc1 = 100 * size1 // (size1 + size2) perc2 = 100 * size2 // (size1 + size2) - __create_compile_commands() - ret, stdout, _ = cppcheck(['--project=' + os.path.join(__proj_dir, __COMPILE_COMMANDS_JSON)], cwd=__script_dir) + __create_compile_commands(proj_dir) + ret, stdout, _ = cppcheck(['--project=' + os.path.join(proj_dir, __COMPILE_COMMANDS_JSON)], cwd=tmp_path) assert ret == 0, stdout assert stdout.find('1/2 files checked %d%% done' % perc1) >= 0 or stdout.find('1/2 files checked %d%% done' % perc2) >= 0 assert stdout.find('2/2 files checked 100% done') >= 0 -def test_progress_cppcheck(): - size1 = os.path.getsize(os.path.join(__proj_dir, 'a', 'a.c')) - size2 = os.path.getsize(os.path.join(__proj_dir, 'b', 'b.c')) +def test_progress_cppcheck(tmp_path): + proj_dir = tmp_path / 'proj2' + shutil.copytree(__proj_dir, proj_dir) + size1 = os.path.getsize(os.path.join(proj_dir, 'a', 'a.c')) + size2 = os.path.getsize(os.path.join(proj_dir, 'b', 'b.c')) perc1 = 100 * size1 // (size1 + size2) perc2 = 100 * size2 // (size1 + size2) - __create_compile_commands() - ret, stdout, _ = cppcheck(['--project=proj2/proj2.cppcheck'], cwd=__script_dir) + __create_compile_commands(proj_dir) + ret, stdout, _ = cppcheck(['--project=proj2/proj2.cppcheck'], cwd=tmp_path) assert ret == 0, stdout assert stdout.find('1/2 files checked %d%% done' % perc1) >= 0 or stdout.find('1/2 files checked %d%% done' % perc2) >= 0 assert stdout.find('2/2 files checked 100% done') >= 0 From c3a9e9c656836fa2164c71d47f889beb7cb43ff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Fri, 3 Jan 2025 13:43:12 +0100 Subject: [PATCH 26/27] fix FileWithDetails constructor --- lib/filesettings.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/filesettings.h b/lib/filesettings.h index 0fcd66c9fbe..799bbf6ecca 100644 --- a/lib/filesettings.h +++ b/lib/filesettings.h @@ -51,6 +51,7 @@ class FileWithDetails : mPath(std::move(path)) , mPathSimplified(Path::simplifyPath(mPath)) , mLang(lang) + , mSize(0) { if (mPath.empty()) throw std::runtime_error("empty path specified"); From 2ddba93ee28d788627bedad1afbee2987d5b02df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Sat, 4 Jan 2025 12:48:12 +0100 Subject: [PATCH 27/27] add test for files specified on command line --- test/cli/proj2_test.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/cli/proj2_test.py b/test/cli/proj2_test.py index f0d681c36e9..336908820b0 100644 --- a/test/cli/proj2_test.py +++ b/test/cli/proj2_test.py @@ -111,6 +111,20 @@ def test_progress_cppcheck(tmp_path): assert stdout.find('1/2 files checked %d%% done' % perc1) >= 0 or stdout.find('1/2 files checked %d%% done' % perc2) >= 0 assert stdout.find('2/2 files checked 100% done') >= 0 +def test_progress_cli(tmp_path): + proj_dir = tmp_path / 'proj2' + shutil.copytree(__proj_dir, proj_dir) + path1 = os.path.join(proj_dir, 'a', 'a.c') + path2 = os.path.join(proj_dir, 'b', 'b.c') + size1 = os.path.getsize(path1) + size2 = os.path.getsize(path2) + perc1 = 100 * size1 // (size1 + size2) + perc2 = 100 * size2 // (size1 + size2) + ret, stdout, _ = cppcheck([path1, path2], cwd=tmp_path) + assert ret == 0, stdout + assert stdout.find('1/2 files checked %d%% done' % perc1) >= 0 or stdout.find('1/2 files checked %d%% done' % perc2) >= 0 + assert stdout.find('2/2 files checked 100% done') >= 0 + def test_gui_project_loads_compile_commands_1(tmp_path): proj_dir = tmp_path / 'proj2' shutil.copytree(__proj_dir, proj_dir)