From e8c9b14ae7a40f7441fc701bba50c80c5cdf6ea6 Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 16 Aug 2025 00:55:33 +0200 Subject: [PATCH 1/3] optimized handling of file and line preprocessor directives --- simplecpp.cpp | 78 +++++++++++++++++++++++++-------------------------- simplecpp.h | 3 +- 2 files changed, 39 insertions(+), 42 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index 7774fd29..887775e8 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -697,22 +697,35 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, if (oldLastToken != cback()) { oldLastToken = cback(); - if (!isLastLinePreprocessor()) + const Token * const llTok = isLastLinePreprocessor(); + if (!llTok) continue; - const std::string lastline(lastLine()); - if (lastline == "# file %str%") { + const Token * const llNextToken = llTok->next; + if (!llTok->next) + continue; + // #file "file.c" + if (llNextToken->str() == "file" && + llNextToken->next && + llNextToken->next->str()[0] == '\"') + { const Token *strtok = cback(); while (strtok->comment) strtok = strtok->previous; loc.push(location); location.fileIndex = fileIndex(strtok->str().substr(1U, strtok->str().size() - 2U)); location.line = 1U; - } else if (lastline == "# line %num%") { - const Token *numtok = cback(); - while (numtok->comment) - numtok = numtok->previous; - lineDirective(location.fileIndex, std::atol(numtok->str().c_str()), &location); - } else if (lastline == "# %num% %str%" || lastline == "# line %num% %str%") { + } + // #3 "file.c" + // #line 3 "file.c" + else if ((llNextToken->number && + llNextToken->next && + llNextToken->next->str()[0] == '\"') || + (llNextToken->str() == "line" && + llNextToken->next && + llNextToken->next->number && + llNextToken->next->next && + llNextToken->next->next->str()[0] == '\"')) + { const Token *strtok = cback(); while (strtok->comment) strtok = strtok->previous; @@ -722,8 +735,19 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, lineDirective(fileIndex(replaceAll(strtok->str().substr(1U, strtok->str().size() - 2U),"\\\\","\\")), std::atol(numtok->str().c_str()), &location); } + // #line 3 + else if (llNextToken->str() == "line" && + llNextToken->next && + llNextToken->next->number) + { + const Token *numtok = cback(); + while (numtok->comment) + numtok = numtok->previous; + lineDirective(location.fileIndex, std::atol(numtok->str().c_str()), &location); + } // #endfile - else if (lastline == "# endfile" && !loc.empty()) { + else if (llNextToken->str() == "endfile" && !loc.empty()) + { location = loc.top(); loc.pop(); } @@ -1418,34 +1442,6 @@ std::string simplecpp::TokenList::readUntil(Stream &stream, const Location &loca return ret; } -std::string simplecpp::TokenList::lastLine(int maxsize) const -{ - std::string ret; - int count = 0; - for (const Token *tok = cback(); ; tok = tok->previous) { - if (!sameline(tok, cback())) { - break; - } - if (tok->comment) - continue; - if (++count > maxsize) - return ""; - if (!ret.empty()) - ret += ' '; - // add tokens in reverse for performance reasons - if (tok->str()[0] == '\"') - ret += "%rts%"; // %str% - else if (tok->number) - ret += "%mun%"; // %num% - else { - ret += tok->str(); - std::reverse(ret.end() - tok->str().length(), ret.end()); - } - } - std::reverse(ret.begin(), ret.end()); - return ret; -} - const simplecpp::Token* simplecpp::TokenList::lastLineTok(int maxsize) const { const Token* prevTok = nullptr; @@ -1462,10 +1458,12 @@ const simplecpp::Token* simplecpp::TokenList::lastLineTok(int maxsize) const return prevTok; } -bool simplecpp::TokenList::isLastLinePreprocessor(int maxsize) const +const simplecpp::Token* simplecpp::TokenList::isLastLinePreprocessor(int maxsize) const { const Token * const prevTok = lastLineTok(maxsize); - return prevTok && prevTok->op == '#'; + if (prevTok && prevTok->op == '#') + return prevTok; + return nullptr; } unsigned int simplecpp::TokenList::fileIndex(const std::string &filename) diff --git a/simplecpp.h b/simplecpp.h index 7e556657..e164fa90 100644 --- a/simplecpp.h +++ b/simplecpp.h @@ -359,9 +359,8 @@ namespace simplecpp { std::string readUntil(Stream &stream, const Location &location, char start, char end, OutputList *outputList); void lineDirective(unsigned int fileIndex, unsigned int line, Location *location); - std::string lastLine(int maxsize=1000) const; const Token* lastLineTok(int maxsize=1000) const; - bool isLastLinePreprocessor(int maxsize=1000) const; + const Token* isLastLinePreprocessor(int maxsize=1000) const; unsigned int fileIndex(const std::string &filename); From 38618cfd0ae201eb2bf82a53a0802bba6804c872 Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 23 Aug 2025 11:37:06 +0200 Subject: [PATCH 2/3] avoid some redundant checks in preprocessor directive handling --- simplecpp.cpp | 80 +++++++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index 887775e8..6aa449e4 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -703,47 +703,45 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, const Token * const llNextToken = llTok->next; if (!llTok->next) continue; - // #file "file.c" - if (llNextToken->str() == "file" && - llNextToken->next && - llNextToken->next->str()[0] == '\"') - { - const Token *strtok = cback(); - while (strtok->comment) - strtok = strtok->previous; - loc.push(location); - location.fileIndex = fileIndex(strtok->str().substr(1U, strtok->str().size() - 2U)); - location.line = 1U; - } - // #3 "file.c" - // #line 3 "file.c" - else if ((llNextToken->number && - llNextToken->next && - llNextToken->next->str()[0] == '\"') || - (llNextToken->str() == "line" && - llNextToken->next && - llNextToken->next->number && - llNextToken->next->next && - llNextToken->next->next->str()[0] == '\"')) - { - const Token *strtok = cback(); - while (strtok->comment) - strtok = strtok->previous; - const Token *numtok = strtok->previous; - while (numtok->comment) - numtok = numtok->previous; - lineDirective(fileIndex(replaceAll(strtok->str().substr(1U, strtok->str().size() - 2U),"\\\\","\\")), - std::atol(numtok->str().c_str()), &location); - } - // #line 3 - else if (llNextToken->str() == "line" && - llNextToken->next && - llNextToken->next->number) - { - const Token *numtok = cback(); - while (numtok->comment) - numtok = numtok->previous; - lineDirective(location.fileIndex, std::atol(numtok->str().c_str()), &location); + if (llNextToken->next) { + // #file "file.c" + if (llNextToken->str() == "file" && + llNextToken->next->str()[0] == '\"') + { + const Token *strtok = cback(); + while (strtok->comment) + strtok = strtok->previous; + loc.push(location); + location.fileIndex = fileIndex(strtok->str().substr(1U, strtok->str().size() - 2U)); + location.line = 1U; + } + // #3 "file.c" + // #line 3 "file.c" + else if ((llNextToken->number && + llNextToken->next->str()[0] == '\"') || + (llNextToken->str() == "line" && + llNextToken->next->number && + llNextToken->next->next && + llNextToken->next->next->str()[0] == '\"')) + { + const Token *strtok = cback(); + while (strtok->comment) + strtok = strtok->previous; + const Token *numtok = strtok->previous; + while (numtok->comment) + numtok = numtok->previous; + lineDirective(fileIndex(replaceAll(strtok->str().substr(1U, strtok->str().size() - 2U),"\\\\","\\")), + std::atol(numtok->str().c_str()), &location); + } + // #line 3 + else if (llNextToken->str() == "line" && + llNextToken->next->number) + { + const Token *numtok = cback(); + while (numtok->comment) + numtok = numtok->previous; + lineDirective(location.fileIndex, std::atol(numtok->str().c_str()), &location); + } } // #endfile else if (llNextToken->str() == "endfile" && !loc.empty()) From 5a42c89b60ca0009210722d03ac0a91dfe8313fe Mon Sep 17 00:00:00 2001 From: firewave Date: Wed, 24 Sep 2025 00:29:22 +0200 Subject: [PATCH 3/3] removed unnecessary `lastLineTok()` call --- simplecpp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index 6aa449e4..8f1879ef 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -762,8 +762,8 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, TokenString currentToken; if (cback() && cback()->location.line == location.line && cback()->previous && cback()->previous->op == '#') { - const Token* const llTok = lastLineTok(); - if (llTok && llTok->op == '#' && llTok->next && (llTok->next->str() == "error" || llTok->next->str() == "warning")) { + const Token* const ppTok = cback()->previous; + if (ppTok->next && (ppTok->next->str() == "error" || ppTok->next->str() == "warning")) { char prev = ' '; while (stream.good() && (prev == '\\' || (ch != '\r' && ch != '\n'))) { currentToken += ch;