From 0bf6e860634f24a7845057f565ead1ee5375d241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 18 Mar 2025 13:57:40 +0100 Subject: [PATCH 1/8] simplecpp --- externals/simplecpp/simplecpp.cpp | 137 ++++++++++++++++++++++++------ 1 file changed, 109 insertions(+), 28 deletions(-) diff --git a/externals/simplecpp/simplecpp.cpp b/externals/simplecpp/simplecpp.cpp index 2316c42b95a..9d37d838eba 100755 --- a/externals/simplecpp/simplecpp.cpp +++ b/externals/simplecpp/simplecpp.cpp @@ -43,6 +43,8 @@ #ifdef SIMPLECPP_WINDOWS #include #undef ERROR +#else +#include #endif #if __cplusplus >= 201103L @@ -147,6 +149,12 @@ static unsigned long long stringToULL(const std::string &s) return ret; } +// TODO: added an undercore since this conflicts with a function of the same name in utils.h from Cppcheck source when building Cppcheck with MSBuild +static bool startsWith_(const std::string &s, const std::string &p) +{ + return (s.size() >= p.size()) && std::equal(p.begin(), p.end(), s.begin()); +} + static bool endsWith(const std::string &s, const std::string &e) { return (s.size() >= e.size()) && std::equal(e.rbegin(), e.rend(), s.rbegin()); @@ -2334,17 +2342,12 @@ namespace simplecpp { namespace simplecpp { #ifdef __CYGWIN__ - bool startsWith(const std::string &str, const std::string &s) - { - return (str.size() >= s.size() && str.compare(0, s.size(), s) == 0); - } - std::string convertCygwinToWindowsPath(const std::string &cygwinPath) { std::string windowsPath; std::string::size_type pos = 0; - if (cygwinPath.size() >= 11 && startsWith(cygwinPath, "/cygdrive/")) { + if (cygwinPath.size() >= 11 && startsWith_(cygwinPath, "/cygdrive/")) { const unsigned char driveLetter = cygwinPath[10]; if (std::isalpha(driveLetter)) { if (cygwinPath.size() == 11) { @@ -2681,6 +2684,54 @@ static bool isCpp17OrLater(const simplecpp::DUI &dui) return !std_ver.empty() && (std_ver >= "201703L"); } + +static std::string currentDirectoryOSCalc() { +#ifdef SIMPLECPP_WINDOWS + TCHAR NPath[MAX_PATH]; + GetCurrentDirectory(MAX_PATH, NPath); +#ifdef _UNICODE + // convert the result from TCHAR* to char* + char NPathA[MAX_PATH]; + ::WideCharToMultiByte(CP_ACP, 0, NPath, lstrlen(NPath), NPathA, MAX_PATH, NULL, NULL); + return NPathA; +#else + // in this case, TCHAR* is just defined to be a char* + return NPath; +#endif +#else + const std::size_t size = 1024; + char the_path[size]; + getcwd(the_path, size); + return the_path; +#endif +} + +static const std::string& currentDirectory() { + static const std::string curdir = simplecpp::simplifyPath(currentDirectoryOSCalc()); + return curdir; +} + +static std::string toAbsolutePath(const std::string& path) { + if (path.empty()) { + return path;// preserve error file path that is indicated by an empty string + } + if (!isAbsolutePath(path)) { + return simplecpp::simplifyPath(currentDirectory() + "/" + path); + } + // otherwise + return simplecpp::simplifyPath(path); +} + +static std::pair extractRelativePathFromAbsolute(const std::string& absolutepath) { + static const std::string prefix = currentDirectory() + "/"; + if (startsWith_(absolutepath, prefix)) { + const std::size_t size = prefix.size(); + return std::make_pair(absolutepath.substr(size, absolutepath.size() - size), true); + } + // otherwise + return std::make_pair("", false); +} + static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const std::string &sourcefile, const std::string &header, bool systemheader); static void simplifyHasInclude(simplecpp::TokenList &expr, const simplecpp::DUI &dui) { @@ -3099,9 +3150,12 @@ static std::string openHeader(std::ifstream &f, const std::string &path) static std::string getRelativeFileName(const std::string &sourcefile, const std::string &header) { + std::string path; if (sourcefile.find_first_of("\\/") != std::string::npos) - return simplecpp::simplifyPath(sourcefile.substr(0, sourcefile.find_last_of("\\/") + 1U) + header); - return simplecpp::simplifyPath(header); + path = sourcefile.substr(0, sourcefile.find_last_of("\\/") + 1U) + header; + else + path = header; + return simplecpp::simplifyPath(path); } static std::string openHeaderRelative(std::ifstream &f, const std::string &sourcefile, const std::string &header) @@ -3111,7 +3165,7 @@ static std::string openHeaderRelative(std::ifstream &f, const std::string &sourc static std::string getIncludePathFileName(const std::string &includePath, const std::string &header) { - std::string path = includePath; + std::string path = toAbsolutePath(includePath); if (!path.empty() && path[path.size()-1U]!='/' && path[path.size()-1U]!='\\') path += '/'; return path + header; @@ -3120,9 +3174,9 @@ static std::string getIncludePathFileName(const std::string &includePath, const static std::string openHeaderIncludePath(std::ifstream &f, const simplecpp::DUI &dui, const std::string &header) { for (std::list::const_iterator it = dui.includePaths.begin(); it != dui.includePaths.end(); ++it) { - std::string simplePath = openHeader(f, getIncludePathFileName(*it, header)); - if (!simplePath.empty()) - return simplePath; + std::string path = openHeader(f, getIncludePathFileName(*it, header)); + if (!path.empty()) + return path; } return ""; } @@ -3132,49 +3186,76 @@ static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const if (isAbsolutePath(header)) return openHeader(f, header); - std::string ret; - if (systemheader) { - ret = openHeaderIncludePath(f, dui, header); - return ret; + // always return absolute path for systemheaders + return toAbsolutePath(openHeaderIncludePath(f, dui, header)); } + std::string ret; + ret = openHeaderRelative(f, sourcefile, header); if (ret.empty()) - return openHeaderIncludePath(f, dui, header); + return toAbsolutePath(openHeaderIncludePath(f, dui, header));// in a similar way to system headers return ret; } -static std::string getFileName(const std::map &filedata, const std::string &sourcefile, const std::string &header, const simplecpp::DUI &dui, bool systemheader) +static std::string findPathInMapBothRelativeAndAbsolute(const std::map &filedata, const std::string& path) { + // here there are two possibilities - either we match this from absolute path or from a relative one + if (filedata.find(path) != filedata.end()) {// try first to respect the exact match + return path; + } + // otherwise - try to use the normalize to the correct representation + if (isAbsolutePath(path)) { + const std::pair relativeExtractedResult = extractRelativePathFromAbsolute(path); + if (relativeExtractedResult.second) { + const std::string relativePath = relativeExtractedResult.first; + if (filedata.find(relativePath) != filedata.end()) { + return relativePath; + } + } + } else { + const std::string absolutePath = toAbsolutePath(path); + if (filedata.find(absolutePath) != filedata.end()) + return absolutePath; + } + // otherwise + return ""; +} + +static std::string getFileIdPath(const std::map &filedata, const std::string &sourcefile, const std::string &header, const simplecpp::DUI &dui, bool systemheader) { if (filedata.empty()) { return ""; } if (isAbsolutePath(header)) { - return (filedata.find(header) != filedata.end()) ? simplecpp::simplifyPath(header) : ""; + const std::string simplifiedHeaderPath = simplecpp::simplifyPath(header); + return (filedata.find(simplifiedHeaderPath) != filedata.end()) ? simplifiedHeaderPath : ""; } if (!systemheader) { - const std::string relativeFilename = getRelativeFileName(sourcefile, header); - if (filedata.find(relativeFilename) != filedata.end()) - return relativeFilename; + const std::string relativeOrAbsoluteFilename = getRelativeFileName(sourcefile, header);// unknown if absolute or relative, but always simplified + const std::string match = findPathInMapBothRelativeAndAbsolute(filedata, relativeOrAbsoluteFilename); + if (!match.empty()) { + return match; + } } for (std::list::const_iterator it = dui.includePaths.begin(); it != dui.includePaths.end(); ++it) { - std::string s = simplecpp::simplifyPath(getIncludePathFileName(*it, header)); - if (filedata.find(s) != filedata.end()) - return s; + const std::string match = findPathInMapBothRelativeAndAbsolute(filedata, simplecpp::simplifyPath(getIncludePathFileName(*it, header))); + if (!match.empty()) { + return match; + } } if (systemheader && filedata.find(header) != filedata.end()) - return header; + return header;// system header that its file wasn't found in the included paths but alreasy in the filedata - return this as is return ""; } static bool hasFile(const std::map &filedata, const std::string &sourcefile, const std::string &header, const simplecpp::DUI &dui, bool systemheader) { - return !getFileName(filedata, sourcefile, header, dui, systemheader).empty(); + return !getFileIdPath(filedata, sourcefile, header, dui, systemheader).empty(); } std::map simplecpp::load(const simplecpp::TokenList &rawtokens, std::vector &filenames, const simplecpp::DUI &dui, simplecpp::OutputList *outputList) @@ -3530,7 +3611,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL const bool systemheader = (inctok->str()[0] == '<'); const std::string header(realFilename(inctok->str().substr(1U, inctok->str().size() - 2U))); - std::string header2 = getFileName(filedata, rawtok->location.file(), header, dui, systemheader); + std::string header2 = getFileIdPath(filedata, rawtok->location.file(), header, dui, systemheader); if (header2.empty()) { // try to load file.. std::ifstream f; From 6d06551e29c6f9ebd04dcfc805909f2202777353 Mon Sep 17 00:00:00 2001 From: Tal Hadad Date: Mon, 7 Apr 2025 14:52:57 +0300 Subject: [PATCH 2/8] dumping current directory test --- lib/preprocessor.cpp | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index db00e18a8d6..7d6e09d9d69 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -906,6 +906,29 @@ void Preprocessor::error(const std::string &filename, unsigned int linenr, const Certainty::normal)); } +#if defined (__WIN32__) +#define NOMINMAX +#include +#endif + +static std::string currentDirectoryOSCalc_2() { +#if defined (__WIN32__) + TCHAR NPath[MAX_PATH]; + GetCurrentDirectory(MAX_PATH, NPath); +#ifdef _UNICODE + // convert the result from TCHAR* to char* + char NPathA[MAX_PATH]; + ::WideCharToMultiByte(CP_ACP, 0, NPath, lstrlen(NPath), NPathA, MAX_PATH, NULL, NULL); + return NPathA; +#else + // in this case, TCHAR* is just defined to be a char* + return NPath; +#endif +#else + return ""; +#endif +} + // Report that include is missing void Preprocessor::missingInclude(const std::string &filename, unsigned int linenr, const std::string &header, HeaderTypes headerType) { @@ -917,9 +940,9 @@ void Preprocessor::missingInclude(const std::string &filename, unsigned int line locationList.emplace_back(filename, linenr, 0); } ErrorMessage errmsg(std::move(locationList), mFile0, Severity::information, - (headerType==SystemHeader) ? + ((headerType==SystemHeader) ? "Include file: <" + header + "> not found. Please note: Cppcheck does not need standard library headers to get proper results." : - "Include file: \"" + header + "\" not found.", + "Include file: \"" + header + "\" not found.") + " current dir: " + currentDirectoryOSCalc_2(), (headerType==SystemHeader) ? "missingIncludeSystem" : "missingInclude", Certainty::normal); mErrorLogger.reportErr(errmsg); From a51c9ab7bc5caffa46cce65f36c1b93ecd183596 Mon Sep 17 00:00:00 2001 From: Tal Hadad Date: Mon, 7 Apr 2025 15:09:13 +0300 Subject: [PATCH 3/8] Revert "dumping current directory test" This reverts commit 6d06551e29c6f9ebd04dcfc805909f2202777353. --- lib/preprocessor.cpp | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 7d6e09d9d69..db00e18a8d6 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -906,29 +906,6 @@ void Preprocessor::error(const std::string &filename, unsigned int linenr, const Certainty::normal)); } -#if defined (__WIN32__) -#define NOMINMAX -#include -#endif - -static std::string currentDirectoryOSCalc_2() { -#if defined (__WIN32__) - TCHAR NPath[MAX_PATH]; - GetCurrentDirectory(MAX_PATH, NPath); -#ifdef _UNICODE - // convert the result from TCHAR* to char* - char NPathA[MAX_PATH]; - ::WideCharToMultiByte(CP_ACP, 0, NPath, lstrlen(NPath), NPathA, MAX_PATH, NULL, NULL); - return NPathA; -#else - // in this case, TCHAR* is just defined to be a char* - return NPath; -#endif -#else - return ""; -#endif -} - // Report that include is missing void Preprocessor::missingInclude(const std::string &filename, unsigned int linenr, const std::string &header, HeaderTypes headerType) { @@ -940,9 +917,9 @@ void Preprocessor::missingInclude(const std::string &filename, unsigned int line locationList.emplace_back(filename, linenr, 0); } ErrorMessage errmsg(std::move(locationList), mFile0, Severity::information, - ((headerType==SystemHeader) ? + (headerType==SystemHeader) ? "Include file: <" + header + "> not found. Please note: Cppcheck does not need standard library headers to get proper results." : - "Include file: \"" + header + "\" not found.") + " current dir: " + currentDirectoryOSCalc_2(), + "Include file: \"" + header + "\" not found.", (headerType==SystemHeader) ? "missingIncludeSystem" : "missingInclude", Certainty::normal); mErrorLogger.reportErr(errmsg); From 098c5f6533917e9bca83862efd25e485aa934b2d Mon Sep 17 00:00:00 2001 From: Tal Hadad Date: Mon, 7 Apr 2025 15:10:32 +0300 Subject: [PATCH 4/8] fix OS calc of current dir --- externals/simplecpp/simplecpp.cpp | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/externals/simplecpp/simplecpp.cpp b/externals/simplecpp/simplecpp.cpp index 9d37d838eba..a898d9165fd 100755 --- a/externals/simplecpp/simplecpp.cpp +++ b/externals/simplecpp/simplecpp.cpp @@ -2686,24 +2686,17 @@ static bool isCpp17OrLater(const simplecpp::DUI &dui) static std::string currentDirectoryOSCalc() { -#ifdef SIMPLECPP_WINDOWS - TCHAR NPath[MAX_PATH]; - GetCurrentDirectory(MAX_PATH, NPath); -#ifdef _UNICODE - // convert the result from TCHAR* to char* - char NPathA[MAX_PATH]; - ::WideCharToMultiByte(CP_ACP, 0, NPath, lstrlen(NPath), NPathA, MAX_PATH, NULL, NULL); - return NPathA; -#else - // in this case, TCHAR* is just defined to be a char* - return NPath; -#endif + const std::size_t size = 4096; + char currentPath[size]; + +#ifndef _WIN32 + if (getcwd(currentPath, size) != nullptr) #else - const std::size_t size = 1024; - char the_path[size]; - getcwd(the_path, size); - return the_path; + if (_getcwd(currentPath, size) != nullptr) #endif + return std::string(currentPath); + + return ""; } static const std::string& currentDirectory() { From c71156f0d7b167093a9bb0491079fd20628dbc28 Mon Sep 17 00:00:00 2001 From: Tal Hadad Date: Mon, 7 Apr 2025 15:15:16 +0300 Subject: [PATCH 5/8] add missing include in windows --- externals/simplecpp/simplecpp.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/externals/simplecpp/simplecpp.cpp b/externals/simplecpp/simplecpp.cpp index a898d9165fd..312fe955fbf 100755 --- a/externals/simplecpp/simplecpp.cpp +++ b/externals/simplecpp/simplecpp.cpp @@ -41,6 +41,7 @@ #include #ifdef SIMPLECPP_WINDOWS +#include #include #undef ERROR #else From 0bf81be84a708ec7a0862d92d84102536f5d27e5 Mon Sep 17 00:00:00 2001 From: Tal Hadad Date: Mon, 7 Apr 2025 15:37:11 +0300 Subject: [PATCH 6/8] apply the missing include only for _WIN32 --- externals/simplecpp/simplecpp.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/externals/simplecpp/simplecpp.cpp b/externals/simplecpp/simplecpp.cpp index 312fe955fbf..d558d6e1764 100755 --- a/externals/simplecpp/simplecpp.cpp +++ b/externals/simplecpp/simplecpp.cpp @@ -41,7 +41,9 @@ #include #ifdef SIMPLECPP_WINDOWS +#ifdef _WIN32 #include +#endif #include #undef ERROR #else From 068b825aecabca906a197de2d6c93f16068a88c8 Mon Sep 17 00:00:00 2001 From: Tal Hadad Date: Mon, 7 Apr 2025 15:46:46 +0300 Subject: [PATCH 7/8] simplify and fix includes (e.g. for cygwen) --- externals/simplecpp/simplecpp.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/externals/simplecpp/simplecpp.cpp b/externals/simplecpp/simplecpp.cpp index d558d6e1764..ef8d87e9332 100755 --- a/externals/simplecpp/simplecpp.cpp +++ b/externals/simplecpp/simplecpp.cpp @@ -40,10 +40,8 @@ #include #include -#ifdef SIMPLECPP_WINDOWS #ifdef _WIN32 #include -#endif #include #undef ERROR #else From b31bcb2b231fd7c7fe8ed6ebea154ecab4f20ce3 Mon Sep 17 00:00:00 2001 From: Tal Hadad Date: Mon, 7 Apr 2025 15:57:54 +0300 Subject: [PATCH 8/8] include windows.h always if in SIMPLECPP_WINDOWS --- externals/simplecpp/simplecpp.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/externals/simplecpp/simplecpp.cpp b/externals/simplecpp/simplecpp.cpp index ef8d87e9332..25c4124a65b 100755 --- a/externals/simplecpp/simplecpp.cpp +++ b/externals/simplecpp/simplecpp.cpp @@ -42,12 +42,15 @@ #ifdef _WIN32 #include -#include -#undef ERROR #else #include #endif +#ifdef SIMPLECPP_WINDOWS +#include +#undef ERROR +#endif + #if __cplusplus >= 201103L #define OVERRIDE override #define EXPLICIT explicit