Skip to content

Commit e9fef00

Browse files
committed
Preprocessor: refactoring directives, they are now only set once for each file
1 parent 48fc19b commit e9fef00

4 files changed

Lines changed: 44 additions & 22 deletions

File tree

lib/cppcheck.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ unsigned int CppCheck::processFile(const std::string& filename, std::istream& fi
112112
tokens1.removeComments();
113113
preprocessor.removeComments();
114114

115+
// Get directives
116+
preprocessor.setDirectives(tokens1);
117+
115118
// Get configurations..
116119
if (_settings.userDefines.empty() || _settings.force) {
117120
Timer t("Preprocessor::getConfigs", _settings.showtime, &S_timerResults);

lib/preprocessor.cpp

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,39 @@ void Preprocessor::inlineSuppressions(const simplecpp::TokenList &tokens)
135135
}
136136
}
137137

138+
void Preprocessor::setDirectives(const simplecpp::TokenList &tokens1)
139+
{
140+
// directive list..
141+
directives.clear();
142+
143+
std::list<const simplecpp::TokenList *> list;
144+
list.push_back(&tokens1);
145+
for (std::map<std::string, simplecpp::TokenList *>::const_iterator it = tokenlists.begin(); it != tokenlists.end(); ++it) {
146+
list.push_back(it->second);
147+
}
148+
149+
for (std::list<const simplecpp::TokenList *>::const_iterator it = list.begin(); it != list.end(); ++it) {
150+
for (const simplecpp::Token *tok = (*it)->cbegin(); tok; tok = tok ? tok->next : nullptr) {
151+
if ((tok->op != '#') || (tok->previous && tok->previous->location.line == tok->location.line))
152+
continue;
153+
if (tok->next && tok->next->str == "endfile")
154+
continue;
155+
Directive directive(tok->location.file(), tok->location.line, "");
156+
for (const simplecpp::Token *tok2 = tok; tok2 && tok2->location.line == directive.linenr; tok2 = tok2->next) {
157+
if (tok2->comment)
158+
continue;
159+
if (!directive.str.empty() && (tok2->location.col > tok2->previous->location.col + tok2->previous->str.size()))
160+
directive.str += ' ';
161+
if (directive.str == "#" && tok2->str == "file")
162+
directive.str += "include";
163+
else
164+
directive.str += tok2->str;
165+
}
166+
directives.push_back(directive);
167+
}
168+
}
169+
}
170+
138171
static bool sameline(const simplecpp::Token *tok1, const simplecpp::Token *tok2)
139172
{
140173
return tok1 && tok2 && tok1->location.sameline(tok2->location);
@@ -465,27 +498,6 @@ std::string Preprocessor::getcode(const simplecpp::TokenList &tokens1, const std
465498
};
466499
}
467500

468-
// directive list..
469-
directives.clear();
470-
for (const simplecpp::Token *tok = tokens1.cbegin(); tok; tok = tok ? tok->next : nullptr) {
471-
if ((tok->op != '#') || (tok->previous && tok->previous->location.line == tok->location.line))
472-
continue;
473-
if (tok->next && tok->next->str == "endfile")
474-
continue;
475-
Directive directive(tok->location.file(), tok->location.line, "");
476-
for (const simplecpp::Token *tok2 = tok; tok2 && tok2->location.line == directive.linenr; tok2 = tok2->next) {
477-
if (tok2->comment)
478-
continue;
479-
if (!directive.str.empty() && (tok2->location.col > tok2->previous->location.col + tok2->previous->str.size()))
480-
directive.str += ' ';
481-
if (directive.str == "#" && tok2->str == "file")
482-
directive.str += "include";
483-
else
484-
directive.str += tok2->str;
485-
}
486-
directives.push_back(directive);
487-
}
488-
489501
// ensure that guessed define macros without value are not used in the code
490502
for (std::list<std::string>::const_iterator defineIt = dui.defines.begin(); defineIt != dui.defines.end(); ++defineIt) {
491503
if (defineIt->find("=") != std::string::npos)
@@ -591,8 +603,11 @@ std::string Preprocessor::getcode(const std::string &filedata, const std::string
591603
std::vector<std::string> files;
592604

593605
std::istringstream istr(filedata);
594-
const simplecpp::TokenList &tokens1 = simplecpp::TokenList(istr, files, Path::simplifyPath(filename), &outputList);
606+
simplecpp::TokenList tokens1(istr, files, Path::simplifyPath(filename), &outputList);
595607
inlineSuppressions(tokens1);
608+
tokens1.removeComments();
609+
removeComments();
610+
setDirectives(tokens1);
596611

597612
for (simplecpp::OutputList::const_iterator it = outputList.begin(); it != outputList.end(); ++it) {
598613
switch (it->type) {

lib/preprocessor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,15 @@ class CPPCHECKLIB Preprocessor {
8888

8989
void inlineSuppressions(const simplecpp::TokenList &tokens);
9090

91+
void setDirectives(const simplecpp::TokenList &tokens);
92+
9193
std::set<std::string> getConfigs(const simplecpp::TokenList &tokens) const;
9294

9395
void loadFiles(const simplecpp::TokenList &rawtokens, std::vector<std::string> &files);
9496

9597
void removeComments();
9698

99+
97100
/**
98101
* Extract the code for each configuration
99102
* @param istr The (file/string) stream to read from.

test/testpreprocessor.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ class TestPreprocessor : public TestFixture {
264264
simplecpp::TokenList tokens(istr, files, filename, &outputList);
265265
tokens.removeComments();
266266
const std::set<std::string> configs(preprocessor0.getConfigs(tokens));
267+
preprocessor0.setDirectives(tokens);
267268
for (std::set<std::string>::const_iterator it = configs.begin(); it != configs.end(); ++it) {
268269
try {
269270
const std::string &cfgcode = preprocessor0.getcode(tokens, *it, files, std::string(code).find("#file") != std::string::npos);

0 commit comments

Comments
 (0)