Skip to content

Commit 7dcdbda

Browse files
authored
fixed #504 / refs #507 - cleaned up and improved parsing of #line preprocessor directive (#586)
1 parent 5ac1f38 commit 7dcdbda

2 files changed

Lines changed: 50 additions & 35 deletions

File tree

simplecpp.cpp

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

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

740742
continue;

test.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2413,7 +2413,8 @@ static void location8()
24132413
"# 3\n"
24142414
"__LINE__ __FILE__\n";
24152415
ASSERT_EQUALS("\n"
2416-
"2 \"\"", // TODO: should say 3
2416+
"\n"
2417+
"3 \"\"",
24172418
preprocess(code));
24182419
}
24192420

@@ -2454,6 +2455,17 @@ static void location11()
24542455
preprocess(code));
24552456
}
24562457

2458+
static void location12()
2459+
{
2460+
const char code[] =
2461+
"/**//**/#/**//**/line/**//**/3/**//**/\"file.c\"/**/\n"
2462+
"__LINE__ __FILE__\n";
2463+
ASSERT_EQUALS("\n"
2464+
"#line 3 \"file.c\"\n"
2465+
"3 \"file.c\"",
2466+
preprocess(code));
2467+
}
2468+
24572469
static void missingHeader1()
24582470
{
24592471
const char code[] = "#include \"notexist.h\"\n";
@@ -4060,6 +4072,7 @@ static void runTests(int argc, char **argv, Input input)
40604072
TEST_CASE(location9);
40614073
TEST_CASE(location10);
40624074
TEST_CASE(location11);
4075+
TEST_CASE(location12);
40634076

40644077
TEST_CASE(missingHeader1);
40654078
TEST_CASE(missingHeader2);

0 commit comments

Comments
 (0)