Skip to content

Commit 318a37b

Browse files
authored
optimized handling of some preprocessor directives (#502)
1 parent cb9a9a2 commit 318a37b

File tree

2 files changed

+53
-58
lines changed

2 files changed

+53
-58
lines changed

simplecpp.cpp

Lines changed: 52 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -697,33 +697,55 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename,
697697

698698
if (oldLastToken != cback()) {
699699
oldLastToken = cback();
700-
if (!isLastLinePreprocessor())
700+
const Token * const llTok = isLastLinePreprocessor();
701+
if (!llTok)
701702
continue;
702-
const std::string lastline(lastLine());
703-
if (lastline == "# file %str%") {
704-
const Token *strtok = cback();
705-
while (strtok->comment)
706-
strtok = strtok->previous;
707-
loc.push(location);
708-
location.fileIndex = fileIndex(strtok->str().substr(1U, strtok->str().size() - 2U));
709-
location.line = 1U;
710-
} else if (lastline == "# line %num%") {
711-
const Token *numtok = cback();
712-
while (numtok->comment)
713-
numtok = numtok->previous;
714-
lineDirective(location.fileIndex, std::atol(numtok->str().c_str()), &location);
715-
} else if (lastline == "# %num% %str%" || lastline == "# line %num% %str%") {
716-
const Token *strtok = cback();
717-
while (strtok->comment)
718-
strtok = strtok->previous;
719-
const Token *numtok = strtok->previous;
720-
while (numtok->comment)
721-
numtok = numtok->previous;
722-
lineDirective(fileIndex(replaceAll(strtok->str().substr(1U, strtok->str().size() - 2U),"\\\\","\\")),
723-
std::atol(numtok->str().c_str()), &location);
703+
const Token * const llNextToken = llTok->next;
704+
if (!llTok->next)
705+
continue;
706+
if (llNextToken->next) {
707+
// #file "file.c"
708+
if (llNextToken->str() == "file" &&
709+
llNextToken->next->str()[0] == '\"')
710+
{
711+
const Token *strtok = cback();
712+
while (strtok->comment)
713+
strtok = strtok->previous;
714+
loc.push(location);
715+
location.fileIndex = fileIndex(strtok->str().substr(1U, strtok->str().size() - 2U));
716+
location.line = 1U;
717+
}
718+
// #3 "file.c"
719+
// #line 3 "file.c"
720+
else if ((llNextToken->number &&
721+
llNextToken->next->str()[0] == '\"') ||
722+
(llNextToken->str() == "line" &&
723+
llNextToken->next->number &&
724+
llNextToken->next->next &&
725+
llNextToken->next->next->str()[0] == '\"'))
726+
{
727+
const Token *strtok = cback();
728+
while (strtok->comment)
729+
strtok = strtok->previous;
730+
const Token *numtok = strtok->previous;
731+
while (numtok->comment)
732+
numtok = numtok->previous;
733+
lineDirective(fileIndex(replaceAll(strtok->str().substr(1U, strtok->str().size() - 2U),"\\\\","\\")),
734+
std::atol(numtok->str().c_str()), &location);
735+
}
736+
// #line 3
737+
else if (llNextToken->str() == "line" &&
738+
llNextToken->next->number)
739+
{
740+
const Token *numtok = cback();
741+
while (numtok->comment)
742+
numtok = numtok->previous;
743+
lineDirective(location.fileIndex, std::atol(numtok->str().c_str()), &location);
744+
}
724745
}
725746
// #endfile
726-
else if (lastline == "# endfile" && !loc.empty()) {
747+
else if (llNextToken->str() == "endfile" && !loc.empty())
748+
{
727749
location = loc.top();
728750
loc.pop();
729751
}
@@ -740,8 +762,8 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename,
740762
TokenString currentToken;
741763

742764
if (cback() && cback()->location.line == location.line && cback()->previous && cback()->previous->op == '#') {
743-
const Token* const llTok = lastLineTok();
744-
if (llTok && llTok->op == '#' && llTok->next && (llTok->next->str() == "error" || llTok->next->str() == "warning")) {
765+
const Token* const ppTok = cback()->previous;
766+
if (ppTok->next && (ppTok->next->str() == "error" || ppTok->next->str() == "warning")) {
745767
char prev = ' ';
746768
while (stream.good() && (prev == '\\' || (ch != '\r' && ch != '\n'))) {
747769
currentToken += ch;
@@ -1418,34 +1440,6 @@ std::string simplecpp::TokenList::readUntil(Stream &stream, const Location &loca
14181440
return ret;
14191441
}
14201442

1421-
std::string simplecpp::TokenList::lastLine(int maxsize) const
1422-
{
1423-
std::string ret;
1424-
int count = 0;
1425-
for (const Token *tok = cback(); ; tok = tok->previous) {
1426-
if (!sameline(tok, cback())) {
1427-
break;
1428-
}
1429-
if (tok->comment)
1430-
continue;
1431-
if (++count > maxsize)
1432-
return "";
1433-
if (!ret.empty())
1434-
ret += ' ';
1435-
// add tokens in reverse for performance reasons
1436-
if (tok->str()[0] == '\"')
1437-
ret += "%rts%"; // %str%
1438-
else if (tok->number)
1439-
ret += "%mun%"; // %num%
1440-
else {
1441-
ret += tok->str();
1442-
std::reverse(ret.end() - tok->str().length(), ret.end());
1443-
}
1444-
}
1445-
std::reverse(ret.begin(), ret.end());
1446-
return ret;
1447-
}
1448-
14491443
const simplecpp::Token* simplecpp::TokenList::lastLineTok(int maxsize) const
14501444
{
14511445
const Token* prevTok = nullptr;
@@ -1462,10 +1456,12 @@ const simplecpp::Token* simplecpp::TokenList::lastLineTok(int maxsize) const
14621456
return prevTok;
14631457
}
14641458

1465-
bool simplecpp::TokenList::isLastLinePreprocessor(int maxsize) const
1459+
const simplecpp::Token* simplecpp::TokenList::isLastLinePreprocessor(int maxsize) const
14661460
{
14671461
const Token * const prevTok = lastLineTok(maxsize);
1468-
return prevTok && prevTok->op == '#';
1462+
if (prevTok && prevTok->op == '#')
1463+
return prevTok;
1464+
return nullptr;
14691465
}
14701466

14711467
unsigned int simplecpp::TokenList::fileIndex(const std::string &filename)

simplecpp.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,9 +359,8 @@ namespace simplecpp {
359359
std::string readUntil(Stream &stream, const Location &location, char start, char end, OutputList *outputList);
360360
void lineDirective(unsigned int fileIndex, unsigned int line, Location *location);
361361

362-
std::string lastLine(int maxsize=1000) const;
363362
const Token* lastLineTok(int maxsize=1000) const;
364-
bool isLastLinePreprocessor(int maxsize=1000) const;
363+
const Token* isLastLinePreprocessor(int maxsize=1000) const;
365364

366365
unsigned int fileIndex(const std::string &filename);
367366

0 commit comments

Comments
 (0)