From c3dff6af67dbed0a110e6d9b1b34954ab8fcda82 Mon Sep 17 00:00:00 2001 From: glank Date: Fri, 15 Aug 2025 12:47:30 +0200 Subject: [PATCH 1/5] Optimize load --- simplecpp.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index 25d0d3c3..00fbc180 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -3173,15 +3173,20 @@ simplecpp::FileDataCache simplecpp::load(const simplecpp::TokenList &rawtokens, const bool systemheader = (htok->str()[0] == '<'); const std::string header(htok->str().substr(1U, htok->str().size() - 2U)); - FileData *const filedata = cache.get(sourcefile, header, dui, systemheader, filenames, outputList).first; - if (!filedata) + const auto loadResult = cache.get(sourcefile, header, dui, systemheader, filenames, outputList); + const bool loaded = loadResult.second; + FileData *const filedata = loadResult.first; + + if (!loaded) + continue; + + if (!filedata->tokens.front()) continue; if (dui.removeComments) filedata->tokens.removeComments(); - if (filedata->tokens.front()) - filelist.push_back(filedata->tokens.front()); + filelist.push_back(filedata->tokens.front()); } return cache; From 9f7cb3fdc4dbfab16c3a8fd58dbab915f933b6e6 Mon Sep 17 00:00:00 2001 From: glank Date: Fri, 15 Aug 2025 15:40:10 +0200 Subject: [PATCH 2/5] Add test --- simplecpp.cpp | 4 +-- simplecpp.h | 87 +++++++++++++++++++++++++-------------------------- test.cpp | 42 +++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 47 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index 00fbc180..f79e061e 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -3109,15 +3109,13 @@ bool simplecpp::FileDataCache::getFileId(const std::string &path, FileID &id) #endif } -simplecpp::FileDataCache simplecpp::load(const simplecpp::TokenList &rawtokens, std::vector &filenames, const simplecpp::DUI &dui, simplecpp::OutputList *outputList) +simplecpp::FileDataCache simplecpp::load(const simplecpp::TokenList &rawtokens, std::vector &filenames, const simplecpp::DUI &dui, simplecpp::OutputList *outputList, FileDataCache cache) { #ifdef SIMPLECPP_WINDOWS if (dui.clearIncludeCache) nonExistingFilesCache.clear(); #endif - FileDataCache cache; - std::list filelist; // -include files diff --git a/simplecpp.h b/simplecpp.h index 76487d6c..8268fa8d 100644 --- a/simplecpp.h +++ b/simplecpp.h @@ -353,49 +353,6 @@ namespace simplecpp { bool removeComments; /** remove comment tokens from included files */ }; - SIMPLECPP_LIB long long characterLiteralToLL(const std::string& str); - - SIMPLECPP_LIB FileDataCache load(const TokenList &rawtokens, std::vector &filenames, const DUI &dui, OutputList *outputList = nullptr); - - /** - * Preprocess - * @todo simplify interface - * @param output TokenList that receives the preprocessing output - * @param rawtokens Raw tokenlist for top sourcefile - * @param files internal data of simplecpp - * @param cache output from simplecpp::load() - * @param dui defines, undefs, and include paths - * @param outputList output: list that will receive output messages - * @param macroUsage output: macro usage - * @param ifCond output: #if/#elif expressions - */ - SIMPLECPP_LIB void preprocess(TokenList &output, const TokenList &rawtokens, std::vector &files, FileDataCache &cache, const DUI &dui, OutputList *outputList = nullptr, std::list *macroUsage = nullptr, std::list *ifCond = nullptr); - - /** - * Deallocate data - */ - SIMPLECPP_LIB void cleanup(FileDataCache &cache); - - /** Simplify path */ - SIMPLECPP_LIB std::string simplifyPath(std::string path); - - /** Convert Cygwin path to Windows path */ - SIMPLECPP_LIB std::string convertCygwinToWindowsPath(const std::string &cygwinPath); - - /** Returns the C version a given standard */ - SIMPLECPP_LIB cstd_t getCStd(const std::string &std); - - /** Returns the C++ version a given standard */ - SIMPLECPP_LIB cppstd_t getCppStd(const std::string &std); - - /** Returns the __STDC_VERSION__ value for a given standard */ - SIMPLECPP_LIB std::string getCStdString(const std::string &std); - SIMPLECPP_LIB std::string getCStdString(cstd_t std); - - /** Returns the __cplusplus value for a given standard */ - SIMPLECPP_LIB std::string getCppStdString(const std::string &std); - SIMPLECPP_LIB std::string getCppStdString(cppstd_t std); - struct SIMPLECPP_LIB FileData { /** The canonical filename associated with this data */ std::string filename; @@ -503,8 +460,50 @@ namespace simplecpp { container_type mData; name_map_type mNameMap; id_map_type mIdMap; - }; + + SIMPLECPP_LIB long long characterLiteralToLL(const std::string& str); + + SIMPLECPP_LIB FileDataCache load(const TokenList &rawtokens, std::vector &filenames, const DUI &dui, OutputList *outputList = nullptr, FileDataCache cache = {}); + + /** + * Preprocess + * @todo simplify interface + * @param output TokenList that receives the preprocessing output + * @param rawtokens Raw tokenlist for top sourcefile + * @param files internal data of simplecpp + * @param cache output from simplecpp::load() + * @param dui defines, undefs, and include paths + * @param outputList output: list that will receive output messages + * @param macroUsage output: macro usage + * @param ifCond output: #if/#elif expressions + */ + SIMPLECPP_LIB void preprocess(TokenList &output, const TokenList &rawtokens, std::vector &files, FileDataCache &cache, const DUI &dui, OutputList *outputList = nullptr, std::list *macroUsage = nullptr, std::list *ifCond = nullptr); + + /** + * Deallocate data + */ + SIMPLECPP_LIB void cleanup(FileDataCache &cache); + + /** Simplify path */ + SIMPLECPP_LIB std::string simplifyPath(std::string path); + + /** Convert Cygwin path to Windows path */ + SIMPLECPP_LIB std::string convertCygwinToWindowsPath(const std::string &cygwinPath); + + /** Returns the C version a given standard */ + SIMPLECPP_LIB cstd_t getCStd(const std::string &std); + + /** Returns the C++ version a given standard */ + SIMPLECPP_LIB cppstd_t getCppStd(const std::string &std); + + /** Returns the __STDC_VERSION__ value for a given standard */ + SIMPLECPP_LIB std::string getCStdString(const std::string &std); + SIMPLECPP_LIB std::string getCStdString(cstd_t std); + + /** Returns the __cplusplus value for a given standard */ + SIMPLECPP_LIB std::string getCppStdString(const std::string &std); + SIMPLECPP_LIB std::string getCppStdString(cppstd_t std); } #if defined(_MSC_VER) diff --git a/test.cpp b/test.cpp index de9f250b..65ab8dec 100644 --- a/test.cpp +++ b/test.cpp @@ -2087,6 +2087,47 @@ static void systemInclude() ASSERT_EQUALS("", toString(outputList)); } +static void circularInclude() +{ + std::vector files; + simplecpp::FileDataCache cache; + + { + const char *path = "test.h"; + const char code[] = + "#ifndef TEST_H\n" + "#define TEST_H\n" + "#include \"a/a.h\"\n" + "#endif\n" + ; + cache.insert({path, makeTokenList(code, files, path)}); + } + + { + const char *path = "a/a.h"; + const char code[] = + "#ifndef A_H\n" + "#define A_H\n" + "#include \"../test.h\"\n" + "#endif\n" + ; + cache.insert({path, makeTokenList(code, files, path)}); + } + + simplecpp::OutputList outputList; + { + std::vector filenames; + simplecpp::DUI dui; + + const char code[] = "#include \"test.h\"\n"; + const simplecpp::TokenList rawtokens = makeTokenList(code, files, "test.cpp"); + + simplecpp::load(rawtokens, filenames, dui, &outputList, std::move(cache)); + } + + ASSERT_EQUALS("", toString(outputList)); +} + static void multiline1() { const char code[] = "#define A \\\n" @@ -3314,6 +3355,7 @@ int main(int argc, char **argv) TEST_CASE(missingHeader4); TEST_CASE(nestedInclude); TEST_CASE(systemInclude); + TEST_CASE(circularInclude); TEST_CASE(nullDirective1); TEST_CASE(nullDirective2); From 942d254e862aab3bf863b71fd340e810bda98cd2 Mon Sep 17 00:00:00 2001 From: glank Date: Fri, 15 Aug 2025 15:53:35 +0200 Subject: [PATCH 3/5] Fix nit --- simplecpp.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index f79e061e..fd327549 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -3173,11 +3173,12 @@ simplecpp::FileDataCache simplecpp::load(const simplecpp::TokenList &rawtokens, const auto loadResult = cache.get(sourcefile, header, dui, systemheader, filenames, outputList); const bool loaded = loadResult.second; - FileData *const filedata = loadResult.first; if (!loaded) continue; + FileData *const filedata = loadResult.first; + if (!filedata->tokens.front()) continue; From 1fb9feda561e124f2997253d17b43f5f6cdf8357 Mon Sep 17 00:00:00 2001 From: glank Date: Fri, 15 Aug 2025 16:05:01 +0200 Subject: [PATCH 4/5] Fix clang-tidy issues --- test.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test.cpp b/test.cpp index 65ab8dec..83fbe148 100644 --- a/test.cpp +++ b/test.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #define STRINGIZE_(x) #x @@ -2093,7 +2094,7 @@ static void circularInclude() simplecpp::FileDataCache cache; { - const char *path = "test.h"; + const char *const path = "test.h"; const char code[] = "#ifndef TEST_H\n" "#define TEST_H\n" @@ -2104,7 +2105,7 @@ static void circularInclude() } { - const char *path = "a/a.h"; + const char *const path = "a/a.h"; const char code[] = "#ifndef A_H\n" "#define A_H\n" @@ -2117,7 +2118,7 @@ static void circularInclude() simplecpp::OutputList outputList; { std::vector filenames; - simplecpp::DUI dui; + const simplecpp::DUI dui; const char code[] = "#include \"test.h\"\n"; const simplecpp::TokenList rawtokens = makeTokenList(code, files, "test.cpp"); From ffda6fd0f54da19c88206cec36c833a500019788 Mon Sep 17 00:00:00 2001 From: glank Date: Fri, 15 Aug 2025 21:03:22 +0200 Subject: [PATCH 5/5] Add preprocess step to circularInclude test --- test.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test.cpp b/test.cpp index 83fbe148..ccb653ca 100644 --- a/test.cpp +++ b/test.cpp @@ -2116,6 +2116,7 @@ static void circularInclude() } simplecpp::OutputList outputList; + simplecpp::TokenList tokens2(files); { std::vector filenames; const simplecpp::DUI dui; @@ -2123,7 +2124,8 @@ static void circularInclude() const char code[] = "#include \"test.h\"\n"; const simplecpp::TokenList rawtokens = makeTokenList(code, files, "test.cpp"); - simplecpp::load(rawtokens, filenames, dui, &outputList, std::move(cache)); + cache = simplecpp::load(rawtokens, filenames, dui, &outputList, std::move(cache)); + simplecpp::preprocess(tokens2, rawtokens, files, cache, dui, &outputList); } ASSERT_EQUALS("", toString(outputList));