From b387ae80f11e8645e38810b28209daef90e54503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 12 Jul 2022 22:58:52 +0200 Subject: [PATCH] Fixed whole program analysis --- Makefile | 4 +++ lib/analyzerinfo.cpp | 44 +++++++++++++++++--------------- lib/analyzerinfo.h | 2 ++ lib/path.cpp | 8 ++++++ lib/path.h | 5 ++++ test/testanalyzerinformation.cpp | 43 +++++++++++++++++++++++++++++++ test/testpath.cpp | 9 +++++++ test/testrunner.vcxproj | 3 ++- 8 files changed, 96 insertions(+), 22 deletions(-) create mode 100644 test/testanalyzerinformation.cpp diff --git a/Makefile b/Makefile index 9d0d5cd44..782a4ff2f 100644 --- a/Makefile +++ b/Makefile @@ -217,6 +217,7 @@ CLIOBJ = cli/cmdlineparser.o \ TESTOBJ = test/options.o \ test/test64bit.o \ + test/testanalyzerinformation.o \ test/testassert.o \ test/testastutils.o \ test/testautovariables.o \ @@ -596,6 +597,9 @@ test/options.o: test/options.cpp test/options.h test/test64bit.o: test/test64bit.cpp lib/check.h lib/check64bit.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/test64bit.o test/test64bit.cpp +test/testanalyzerinformation.o: test/testanalyzerinformation.cpp lib/analyzerinfo.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/platform.h lib/suppressions.h lib/utils.h test/testsuite.h + $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testanalyzerinformation.o test/testanalyzerinformation.cpp + test/testassert.o: test/testassert.cpp lib/check.h lib/checkassert.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testassert.o test/testassert.cpp diff --git a/lib/analyzerinfo.cpp b/lib/analyzerinfo.cpp index 882820c47..1cd3a4652 100644 --- a/lib/analyzerinfo.cpp +++ b/lib/analyzerinfo.cpp @@ -95,34 +95,36 @@ static bool skipAnalysis(const std::string &analyzerInfoFile, std::size_t hash, return true; } +std::string AnalyzerInformation::getAnalyzerInfoFileFromFilesTxt(std::istream& filesTxt, const std::string &sourcefile, const std::string &cfg) +{ + std::string line; + const std::string end(':' + cfg + ':' + Path::simplifyPath(sourcefile)); + while (std::getline(filesTxt,line)) { + if (line.size() <= end.size() + 2U) + continue; + if (!endsWith(line, end.c_str(), end.size())) + continue; + return line.substr(0,line.find(':')); + } + return ""; +} + std::string AnalyzerInformation::getAnalyzerInfoFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg) { - const std::string files(buildDir + "/files.txt"); - std::ifstream fin(files); + std::ifstream fin(Path::join(buildDir, "files.txt")); if (fin.is_open()) { - std::string line; - const std::string end(':' + cfg + ':' + sourcefile); - while (std::getline(fin,line)) { - if (line.size() <= end.size() + 2U) - continue; - if (!endsWith(line, end.c_str(), end.size())) - continue; - std::ostringstream ostr; - ostr << buildDir << '/' << line.substr(0,line.find(':')); - return ostr.str(); - } + const std::string& ret = getAnalyzerInfoFileFromFilesTxt(fin, sourcefile, cfg); + if (!ret.empty()) + return Path::join(buildDir, ret); } - std::string filename = Path::fromNativeSeparators(buildDir); - if (!endsWith(filename, '/')) - filename += '/'; const std::string::size_type pos = sourcefile.rfind('/'); - if (pos == std::string::npos) - filename += sourcefile; + std::string filename; + if (pos != std::string::npos) + filename = sourcefile; else - filename += sourcefile.substr(pos+1); - filename += ".analyzerinfo"; - return filename; + filename = sourcefile.substr(pos + 1); + return Path::join(buildDir, filename) + ".analyzerinfo"; } bool AnalyzerInformation::analyzeFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg, std::size_t hash, std::list *errors) diff --git a/lib/analyzerinfo.h b/lib/analyzerinfo.h index 13e9c0a68..26b0ae151 100644 --- a/lib/analyzerinfo.h +++ b/lib/analyzerinfo.h @@ -58,6 +58,8 @@ public: void reportErr(const ErrorMessage &msg, bool verbose); void setFileInfo(const std::string &check, const std::string &fileInfo); static std::string getAnalyzerInfoFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg); +protected: + static std::string getAnalyzerInfoFileFromFilesTxt(std::istream& filesTxt, const std::string &sourcefile, const std::string &cfg); private: std::ofstream mOutputStream; std::string mAnalyzerInfoFile; diff --git a/lib/path.cpp b/lib/path.cpp index b61d1e909..5a382a28f 100644 --- a/lib/path.cpp +++ b/lib/path.cpp @@ -241,3 +241,11 @@ bool Path::fileExists(const std::string &file) std::ifstream f(file.c_str()); return f.is_open(); } + +std::string Path::join(std::string path1, std::string path2) { + if (path1.empty() || path2.empty()) + return path1 + path2; + if (path2.front() == '/') + return path2; + return ((path1.back() == '/') ? path1 : (path1 + "/")) + path2; +} diff --git a/lib/path.h b/lib/path.h index 734e3ecdc..095d63054 100644 --- a/lib/path.h +++ b/lib/path.h @@ -179,6 +179,11 @@ public: * @return true if given path is a File */ static bool fileExists(const std::string &file); + + /** + * join 2 paths with '/' separators + */ + static std::string join(std::string path1, std::string path2); }; /// @} diff --git a/test/testanalyzerinformation.cpp b/test/testanalyzerinformation.cpp new file mode 100644 index 000000000..0c310e024 --- /dev/null +++ b/test/testanalyzerinformation.cpp @@ -0,0 +1,43 @@ +/* + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2022 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 "analyzerinfo.h" +#include "testsuite.h" +#include + +class TestAnalyzerInformation : public TestFixture, private AnalyzerInformation { +public: + TestAnalyzerInformation() : TestFixture("TestAnalyzerInformation") {} + +private: + + void run() override { + TEST_CASE(getAnalyzerInfoFile); + } + + void getAnalyzerInfoFile() const { + const char filesTxt[] = "file1.a4::file1.c\n"; + std::istringstream f1(filesTxt); + ASSERT_EQUALS("file1.a4", getAnalyzerInfoFileFromFilesTxt(f1, "file1.c", "")); + std::istringstream f2(filesTxt); + ASSERT_EQUALS("file1.a4", getAnalyzerInfoFileFromFilesTxt(f2, "./file1.c", "")); + } +}; + +REGISTER_TEST(TestAnalyzerInformation) diff --git a/test/testpath.cpp b/test/testpath.cpp index c746695ef..4afaf49cd 100644 --- a/test/testpath.cpp +++ b/test/testpath.cpp @@ -37,6 +37,7 @@ private: TEST_CASE(is_c); TEST_CASE(is_cpp); TEST_CASE(get_path_from_filename); + TEST_CASE(join); } void removeQuotationMarks() const { @@ -141,6 +142,14 @@ private: ASSERT_EQUALS("a/b/c/", Path::getPathFromFilename("a/b/c/index.h")); ASSERT_EQUALS("a/b/c/", Path::getPathFromFilename("a/b/c/")); } + + void join() const { + ASSERT_EQUALS("a", Path::join("a", "")); + ASSERT_EQUALS("a", Path::join("", "a")); + ASSERT_EQUALS("a/b", Path::join("a", "b")); + ASSERT_EQUALS("a/b", Path::join("a/", "b")); + ASSERT_EQUALS("/b", Path::join("a", "/b")); + } }; REGISTER_TEST(TestPath) diff --git a/test/testrunner.vcxproj b/test/testrunner.vcxproj index 14bc3a539..478dab868 100755 --- a/test/testrunner.vcxproj +++ b/test/testrunner.vcxproj @@ -33,6 +33,7 @@ + @@ -316,4 +317,4 @@ - \ No newline at end of file +