Skip to content

Commit 8a4737e

Browse files
committed
refs #507 - cleaned up and improved parsing of line preprocessor directive [skip ci]
1 parent 341e485 commit 8a4737e

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

734734
void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, OutputList *outputList)
735735
{
736-
std::stack<simplecpp::Location> loc;
737-
738736
unsigned int multiline = 0U;
739737

740738
const Token *oldLastToken = nullptr;
@@ -776,42 +774,44 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename,
776774

777775
if (oldLastToken != cback()) {
778776
oldLastToken = cback();
779-
const Token * const llTok = isLastLinePreprocessor();
780-
if (!llTok)
777+
778+
// #line 3
779+
// #line 3 "file.c"
780+
// #3
781+
// #3 "file.c"
782+
const Token * ppTok = isLastLinePreprocessor();
783+
if (!ppTok)
781784
continue;
782-
const Token * const llNextToken = llTok->next;
783-
if (!llTok->next)
785+
786+
const auto advanceAndSkipComments = [](const Token* tok) {
787+
do {
788+
tok = tok->next;
789+
} while (tok && tok->comment);
790+
return tok;
791+
};
792+
793+
// skip #
794+
ppTok = advanceAndSkipComments(ppTok);
795+
if (!ppTok)
784796
continue;
785-
if (llNextToken->next) {
786-
// TODO: add support for "# 3"
787-
// #3 "file.c"
788-
// #line 3 "file.c"
789-
if ((llNextToken->number &&
790-
llNextToken->next->str()[0] == '\"') ||
791-
(llNextToken->str() == "line" &&
792-
llNextToken->next->number &&
793-
llNextToken->next->next &&
794-
llNextToken->next->next->str()[0] == '\"'))
795-
{
796-
const Token *strtok = cback();
797-
while (strtok->comment)
798-
strtok = strtok->previous;
799-
const Token *numtok = strtok->previous;
800-
while (numtok->comment)
801-
numtok = numtok->previous;
802-
lineDirective(fileIndex(replaceAll(strtok->str().substr(1U, strtok->str().size() - 2U),"\\\\","\\")),
803-
std::atol(numtok->str().c_str()), &location);
804-
}
805-
// #line 3
806-
else if (llNextToken->str() == "line" &&
807-
llNextToken->next->number)
808-
{
809-
const Token *numtok = cback();
810-
while (numtok->comment)
811-
numtok = numtok->previous;
812-
lineDirective(location.fileIndex, std::atol(numtok->str().c_str()), &location);
813-
}
814-
}
797+
798+
if (ppTok->str() == "line")
799+
ppTok = advanceAndSkipComments(ppTok);
800+
801+
if (!ppTok || !ppTok->number)
802+
continue;
803+
804+
const unsigned int line = std::atol(ppTok->str().c_str());
805+
ppTok = advanceAndSkipComments(ppTok);
806+
807+
unsigned int fileindex;
808+
809+
if (ppTok && ppTok->str()[0] == '\"')
810+
fileindex = fileIndex(replaceAll(ppTok->str().substr(1U, ppTok->str().size() - 2U),"\\\\","\\"));
811+
else
812+
fileindex = location.fileIndex;
813+
814+
lineDirective(fileindex, line, &location);
815815
}
816816

817817
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";
@@ -3622,6 +3634,7 @@ int main(int argc, char **argv)
36223634
TEST_CASE(location9);
36233635
TEST_CASE(location10);
36243636
TEST_CASE(location11);
3637+
TEST_CASE(location12);
36253638

36263639
TEST_CASE(missingHeader1);
36273640
TEST_CASE(missingHeader2);

0 commit comments

Comments
 (0)