diff --git a/simplecpp.cpp b/simplecpp.cpp index ef891eb1..3fb515ec 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -654,8 +654,6 @@ static const std::string COMMENT_END("*/"); void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, OutputList *outputList) { - std::stack loc; - unsigned int multiline = 0U; const Token *oldLastToken = nullptr; @@ -697,59 +695,44 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, if (oldLastToken != cback()) { oldLastToken = cback(); - const Token * const llTok = isLastLinePreprocessor(); - if (!llTok) + + // #line 3 + // #line 3 "file.c" + // #3 + // #3 "file.c" + const Token * ppTok = isLastLinePreprocessor(); + if (!ppTok) continue; - const Token * const llNextToken = llTok->next; - if (!llTok->next) + + const auto advanceAndSkipComments = [](const Token* tok) { + do { + tok = tok->next; + } while (tok && tok->comment); + return tok; + }; + + // skip # + ppTok = advanceAndSkipComments(ppTok); + if (!ppTok) continue; - 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; - } - // TODO: add support for "# 3" - // #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()) - { - location = loc.top(); - loc.pop(); - } + + if (ppTok->str() == "line") + ppTok = advanceAndSkipComments(ppTok); + + if (!ppTok || !ppTok->number) + continue; + + const unsigned int line = std::atol(ppTok->str().c_str()); + ppTok = advanceAndSkipComments(ppTok); + + unsigned int fileindex; + + if (ppTok && ppTok->str()[0] == '\"') + fileindex = fileIndex(replaceAll(ppTok->str().substr(1U, ppTok->str().size() - 2U),"\\\\","\\")); + else + fileindex = location.fileIndex; + + lineDirective(fileindex, line, &location); } continue; diff --git a/test.cpp b/test.cpp index 69e08781..73a07ba4 100644 --- a/test.cpp +++ b/test.cpp @@ -2097,7 +2097,8 @@ static void location8() "# 3\n" "__LINE__ __FILE__\n"; ASSERT_EQUALS("\n" - "2 \"\"", // TODO: should say 3 + "\n" + "3 \"\"", preprocess(code)); } @@ -2138,7 +2139,16 @@ static void location11() preprocess(code)); } -// TODO: test #file/#endfile +static void location12() +{ + const char code[] = + "/**//**/#/**//**/line/**//**/3/**//**/\"file.c\"/**/\n" + "__LINE__ __FILE__\n"; + ASSERT_EQUALS("\n" + "#line 3 \"file.c\"\n" + "3 \"file.c\"", + preprocess(code)); +} static void missingHeader1() { @@ -3576,6 +3586,7 @@ int main(int argc, char **argv) TEST_CASE(location9); TEST_CASE(location10); TEST_CASE(location11); + TEST_CASE(location12); TEST_CASE(missingHeader1); TEST_CASE(missingHeader2);