Skip to content

Commit efa845d

Browse files
committed
refs #507 - cleaned up and improved parsing of line preprocessor directive [skip ci]
1 parent 57f9a3b commit efa845d

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
@@ -656,8 +656,6 @@ static const std::string COMMENT_END("*/");
656656

657657
void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, OutputList *outputList)
658658
{
659-
std::stack<simplecpp::Location> loc;
660-
661659
unsigned int multiline = 0U;
662660

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

700698
if (oldLastToken != cback()) {
701699
oldLastToken = cback();
702-
const Token * const llTok = isLastLinePreprocessor();
703-
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)
704707
continue;
705-
const Token * const llNextToken = llTok->next;
706-
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)
707719
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-
}
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);
738738
}
739739

740740
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";
@@ -3620,6 +3632,7 @@ int main(int argc, char **argv)
36203632
TEST_CASE(location9);
36213633
TEST_CASE(location10);
36223634
TEST_CASE(location11);
3635+
TEST_CASE(location12);
36233636

36243637
TEST_CASE(missingHeader1);
36253638
TEST_CASE(missingHeader2);

0 commit comments

Comments
 (0)