Skip to content

Commit 4c9bcb4

Browse files
committed
refs #507 - cleaned up and improved parsing of line preprocessor directive
1 parent dde31b9 commit 4c9bcb4

File tree

2 files changed

+50
-37
lines changed

2 files changed

+50
-37
lines changed

simplecpp.cpp

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -654,8 +654,6 @@ static const std::string COMMENT_END("*/");
654654

655655
void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, OutputList *outputList)
656656
{
657-
std::stack<simplecpp::Location> loc;
658-
659657
unsigned int multiline = 0U;
660658

661659
const Token *oldLastToken = nullptr;
@@ -697,42 +695,44 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename,
697695

698696
if (oldLastToken != cback()) {
699697
oldLastToken = cback();
700-
const Token * const llTok = isLastLinePreprocessor();
701-
if (!llTok)
698+
699+
// #line 3
700+
// #line 3 "file.c"
701+
// #3
702+
// #3 "file.c"
703+
const Token * ppTok = isLastLinePreprocessor();
704+
if (!ppTok)
702705
continue;
703-
const Token * const llNextToken = llTok->next;
704-
if (!llTok->next)
706+
707+
const auto advanceAndSkipComments = [](const Token* tok) {
708+
do {
709+
tok = tok->next;
710+
} while (tok && tok->comment);
711+
return tok;
712+
};
713+
714+
// skip #
715+
ppTok = advanceAndSkipComments(ppTok);
716+
if (!ppTok)
705717
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-
}
718+
719+
if (ppTok->str() == "line")
720+
ppTok = advanceAndSkipComments(ppTok);
721+
722+
if (!ppTok || !ppTok->number)
723+
continue;
724+
725+
const unsigned int line = std::atol(ppTok->str().c_str());
726+
ppTok = advanceAndSkipComments(ppTok);
727+
728+
unsigned int fileindex;
729+
730+
if (ppTok && ppTok->str()[0] == '\"')
731+
fileindex = fileIndex(replaceAll(ppTok->str().substr(1U, ppTok->str().size() - 2U),"\\\\","\\"));
732+
else
733+
fileindex = location.fileIndex;
734+
735+
lineDirective(fileindex, line, &location);
736736
}
737737

738738
continue;

test.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2097,7 +2097,8 @@ static void location8()
20972097
"# 3\n"
20982098
"__LINE__ __FILE__\n";
20992099
ASSERT_EQUALS("\n"
2100-
"2 \"\"", // TODO: should say 3
2100+
"\n"
2101+
"3 \"\"",
21012102
preprocess(code));
21022103
}
21032104

@@ -2138,6 +2139,17 @@ static void location11()
21382139
preprocess(code));
21392140
}
21402141

2142+
static void location12()
2143+
{
2144+
const char code[] =
2145+
"/**//**/#/**//**/line/**//**/3/**//**/\"file.c\"/**/\n"
2146+
"__LINE__ __FILE__\n";
2147+
ASSERT_EQUALS("\n"
2148+
"#line 3 \"file.c\"\n"
2149+
"3 \"file.c\"",
2150+
preprocess(code));
2151+
}
2152+
21412153
static void missingHeader1()
21422154
{
21432155
const char code[] = "#include \"notexist.h\"\n";
@@ -3574,6 +3586,7 @@ int main(int argc, char **argv)
35743586
TEST_CASE(location9);
35753587
TEST_CASE(location10);
35763588
TEST_CASE(location11);
3589+
TEST_CASE(location12);
35773590

35783591
TEST_CASE(missingHeader1);
35793592
TEST_CASE(missingHeader2);

0 commit comments

Comments
 (0)