Skip to content

Commit 23f66f2

Browse files
committed
refs #507 - cleaned up and improved parsing of line preprocessor directive [skip ci]
1 parent 06b4e10 commit 23f66f2

File tree

2 files changed

+50
-35
lines changed

2 files changed

+50
-35
lines changed

simplecpp.cpp

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -697,42 +697,44 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename,
697697

698698
if (oldLastToken != cback()) {
699699
oldLastToken = cback();
700-
const Token * const llTok = isLastLinePreprocessor();
701-
if (!llTok)
700+
701+
// #line 3
702+
// #line 3 "file.c"
703+
// #3
704+
// #3 "file.c"
705+
const Token * ppTok = isLastLinePreprocessor();
706+
if (!ppTok)
702707
continue;
703-
const Token * const llNextToken = llTok->next;
704-
if (!llTok->next)
708+
709+
const auto advanceAndSkipComments = [](const Token* tok) {
710+
do {
711+
tok = tok->next;
712+
} while(tok && tok->comment);
713+
return tok;
714+
};
715+
716+
// skip #
717+
ppTok = advanceAndSkipComments(ppTok);
718+
if (!ppTok)
705719
continue;
706-
if (llNextToken->next) {
707-
// TODO: add support for "# 3"
708-
// #3 "file.c"
709-
// #line 3 "file.c"
710-
if ((llNextToken->number &&
711-
llNextToken->next->str()[0] == '\"') ||
712-
(llNextToken->str() == "line" &&
713-
llNextToken->next->number &&
714-
llNextToken->next->next &&
715-
llNextToken->next->next->str()[0] == '\"'))
716-
{
717-
const Token *strtok = cback();
718-
while (strtok->comment)
719-
strtok = strtok->previous;
720-
const Token *numtok = strtok->previous;
721-
while (numtok->comment)
722-
numtok = numtok->previous;
723-
lineDirective(fileIndex(replaceAll(strtok->str().substr(1U, strtok->str().size() - 2U),"\\\\","\\")),
724-
std::atol(numtok->str().c_str()), &location);
725-
}
726-
// #line 3
727-
else if (llNextToken->str() == "line" &&
728-
llNextToken->next->number)
729-
{
730-
const Token *numtok = cback();
731-
while (numtok->comment)
732-
numtok = numtok->previous;
733-
lineDirective(location.fileIndex, std::atol(numtok->str().c_str()), &location);
734-
}
735-
}
720+
721+
if (ppTok->str() == "line")
722+
ppTok = advanceAndSkipComments(ppTok);
723+
724+
if (!ppTok || !ppTok->number)
725+
continue;
726+
727+
const unsigned int line = std::atol(ppTok->str().c_str());
728+
ppTok = advanceAndSkipComments(ppTok);
729+
730+
unsigned int fileindex;
731+
732+
if (ppTok && ppTok->str()[0] == '\"')
733+
fileindex = fileIndex(replaceAll(ppTok->str().substr(1U, ppTok->str().size() - 2U),"\\\\","\\"));
734+
else
735+
fileindex = location.fileIndex;
736+
737+
lineDirective(fileindex, line, &location);
736738
}
737739

738740
continue;

test.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2089,7 +2089,8 @@ static void location8()
20892089
"# 3\n"
20902090
"__LINE__ __FILE__\n";
20912091
ASSERT_EQUALS("\n"
2092-
"2 \"\"", // TODO: should say 3
2092+
"\n"
2093+
"3 \"\"",
20932094
preprocess(code));
20942095
}
20952096

@@ -2130,6 +2131,17 @@ static void location11()
21302131
preprocess(code));
21312132
}
21322133

2134+
static void location12()
2135+
{
2136+
const char code[] =
2137+
"/**//**/#/**//**/line/**//**/3/**//**/\"file.c\"/**/\n"
2138+
"__LINE__ __FILE__\n";
2139+
ASSERT_EQUALS("\n"
2140+
"#line 3 \"file.c\"\n"
2141+
"3 \"file.c\"",
2142+
preprocess(code));
2143+
}
2144+
21332145
static void missingHeader1()
21342146
{
21352147
const char code[] = "#include \"notexist.h\"\n";
@@ -3564,6 +3576,7 @@ int main(int argc, char **argv)
35643576
TEST_CASE(location9);
35653577
TEST_CASE(location10);
35663578
TEST_CASE(location11);
3579+
TEST_CASE(location12);
35673580

35683581
TEST_CASE(missingHeader1);
35693582
TEST_CASE(missingHeader2);

0 commit comments

Comments
 (0)