Preprocessor: refactoring directives, they are now only set once for each file
This commit is contained in:
parent
48fc19b34c
commit
e9fef003ac
|
@ -112,6 +112,9 @@ unsigned int CppCheck::processFile(const std::string& filename, std::istream& fi
|
||||||
tokens1.removeComments();
|
tokens1.removeComments();
|
||||||
preprocessor.removeComments();
|
preprocessor.removeComments();
|
||||||
|
|
||||||
|
// Get directives
|
||||||
|
preprocessor.setDirectives(tokens1);
|
||||||
|
|
||||||
// Get configurations..
|
// Get configurations..
|
||||||
if (_settings.userDefines.empty() || _settings.force) {
|
if (_settings.userDefines.empty() || _settings.force) {
|
||||||
Timer t("Preprocessor::getConfigs", _settings.showtime, &S_timerResults);
|
Timer t("Preprocessor::getConfigs", _settings.showtime, &S_timerResults);
|
||||||
|
|
|
@ -135,6 +135,39 @@ void Preprocessor::inlineSuppressions(const simplecpp::TokenList &tokens)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Preprocessor::setDirectives(const simplecpp::TokenList &tokens1)
|
||||||
|
{
|
||||||
|
// directive list..
|
||||||
|
directives.clear();
|
||||||
|
|
||||||
|
std::list<const simplecpp::TokenList *> list;
|
||||||
|
list.push_back(&tokens1);
|
||||||
|
for (std::map<std::string, simplecpp::TokenList *>::const_iterator it = tokenlists.begin(); it != tokenlists.end(); ++it) {
|
||||||
|
list.push_back(it->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::list<const simplecpp::TokenList *>::const_iterator it = list.begin(); it != list.end(); ++it) {
|
||||||
|
for (const simplecpp::Token *tok = (*it)->cbegin(); tok; tok = tok ? tok->next : nullptr) {
|
||||||
|
if ((tok->op != '#') || (tok->previous && tok->previous->location.line == tok->location.line))
|
||||||
|
continue;
|
||||||
|
if (tok->next && tok->next->str == "endfile")
|
||||||
|
continue;
|
||||||
|
Directive directive(tok->location.file(), tok->location.line, "");
|
||||||
|
for (const simplecpp::Token *tok2 = tok; tok2 && tok2->location.line == directive.linenr; tok2 = tok2->next) {
|
||||||
|
if (tok2->comment)
|
||||||
|
continue;
|
||||||
|
if (!directive.str.empty() && (tok2->location.col > tok2->previous->location.col + tok2->previous->str.size()))
|
||||||
|
directive.str += ' ';
|
||||||
|
if (directive.str == "#" && tok2->str == "file")
|
||||||
|
directive.str += "include";
|
||||||
|
else
|
||||||
|
directive.str += tok2->str;
|
||||||
|
}
|
||||||
|
directives.push_back(directive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool sameline(const simplecpp::Token *tok1, const simplecpp::Token *tok2)
|
static bool sameline(const simplecpp::Token *tok1, const simplecpp::Token *tok2)
|
||||||
{
|
{
|
||||||
return tok1 && tok2 && tok1->location.sameline(tok2->location);
|
return tok1 && tok2 && tok1->location.sameline(tok2->location);
|
||||||
|
@ -465,27 +498,6 @@ std::string Preprocessor::getcode(const simplecpp::TokenList &tokens1, const std
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// directive list..
|
|
||||||
directives.clear();
|
|
||||||
for (const simplecpp::Token *tok = tokens1.cbegin(); tok; tok = tok ? tok->next : nullptr) {
|
|
||||||
if ((tok->op != '#') || (tok->previous && tok->previous->location.line == tok->location.line))
|
|
||||||
continue;
|
|
||||||
if (tok->next && tok->next->str == "endfile")
|
|
||||||
continue;
|
|
||||||
Directive directive(tok->location.file(), tok->location.line, "");
|
|
||||||
for (const simplecpp::Token *tok2 = tok; tok2 && tok2->location.line == directive.linenr; tok2 = tok2->next) {
|
|
||||||
if (tok2->comment)
|
|
||||||
continue;
|
|
||||||
if (!directive.str.empty() && (tok2->location.col > tok2->previous->location.col + tok2->previous->str.size()))
|
|
||||||
directive.str += ' ';
|
|
||||||
if (directive.str == "#" && tok2->str == "file")
|
|
||||||
directive.str += "include";
|
|
||||||
else
|
|
||||||
directive.str += tok2->str;
|
|
||||||
}
|
|
||||||
directives.push_back(directive);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure that guessed define macros without value are not used in the code
|
// ensure that guessed define macros without value are not used in the code
|
||||||
for (std::list<std::string>::const_iterator defineIt = dui.defines.begin(); defineIt != dui.defines.end(); ++defineIt) {
|
for (std::list<std::string>::const_iterator defineIt = dui.defines.begin(); defineIt != dui.defines.end(); ++defineIt) {
|
||||||
if (defineIt->find("=") != std::string::npos)
|
if (defineIt->find("=") != std::string::npos)
|
||||||
|
@ -591,8 +603,11 @@ std::string Preprocessor::getcode(const std::string &filedata, const std::string
|
||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
|
|
||||||
std::istringstream istr(filedata);
|
std::istringstream istr(filedata);
|
||||||
const simplecpp::TokenList &tokens1 = simplecpp::TokenList(istr, files, Path::simplifyPath(filename), &outputList);
|
simplecpp::TokenList tokens1(istr, files, Path::simplifyPath(filename), &outputList);
|
||||||
inlineSuppressions(tokens1);
|
inlineSuppressions(tokens1);
|
||||||
|
tokens1.removeComments();
|
||||||
|
removeComments();
|
||||||
|
setDirectives(tokens1);
|
||||||
|
|
||||||
for (simplecpp::OutputList::const_iterator it = outputList.begin(); it != outputList.end(); ++it) {
|
for (simplecpp::OutputList::const_iterator it = outputList.begin(); it != outputList.end(); ++it) {
|
||||||
switch (it->type) {
|
switch (it->type) {
|
||||||
|
|
|
@ -88,12 +88,15 @@ public:
|
||||||
|
|
||||||
void inlineSuppressions(const simplecpp::TokenList &tokens);
|
void inlineSuppressions(const simplecpp::TokenList &tokens);
|
||||||
|
|
||||||
|
void setDirectives(const simplecpp::TokenList &tokens);
|
||||||
|
|
||||||
std::set<std::string> getConfigs(const simplecpp::TokenList &tokens) const;
|
std::set<std::string> getConfigs(const simplecpp::TokenList &tokens) const;
|
||||||
|
|
||||||
void loadFiles(const simplecpp::TokenList &rawtokens, std::vector<std::string> &files);
|
void loadFiles(const simplecpp::TokenList &rawtokens, std::vector<std::string> &files);
|
||||||
|
|
||||||
void removeComments();
|
void removeComments();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract the code for each configuration
|
* Extract the code for each configuration
|
||||||
* @param istr The (file/string) stream to read from.
|
* @param istr The (file/string) stream to read from.
|
||||||
|
|
|
@ -264,6 +264,7 @@ private:
|
||||||
simplecpp::TokenList tokens(istr, files, filename, &outputList);
|
simplecpp::TokenList tokens(istr, files, filename, &outputList);
|
||||||
tokens.removeComments();
|
tokens.removeComments();
|
||||||
const std::set<std::string> configs(preprocessor0.getConfigs(tokens));
|
const std::set<std::string> configs(preprocessor0.getConfigs(tokens));
|
||||||
|
preprocessor0.setDirectives(tokens);
|
||||||
for (std::set<std::string>::const_iterator it = configs.begin(); it != configs.end(); ++it) {
|
for (std::set<std::string>::const_iterator it = configs.begin(); it != configs.end(); ++it) {
|
||||||
try {
|
try {
|
||||||
const std::string &cfgcode = preprocessor0.getcode(tokens, *it, files, std::string(code).find("#file") != std::string::npos);
|
const std::string &cfgcode = preprocessor0.getcode(tokens, *it, files, std::string(code).find("#file") != std::string::npos);
|
||||||
|
|
Loading…
Reference in New Issue