| 597 | } |
| 598 | |
| 599 | static void getConfigs(const simplecpp::TokenList &tokens, std::set<std::string> &defined, const std::string &userDefines, const std::set<std::string> &undefined, std::set<std::string> &ret) |
| 600 | { |
| 601 | std::vector<std::string> configs_if; |
| 602 | std::vector<std::string> configs_ifndef; |
| 603 | std::string elseError; |
| 604 | |
| 605 | for (const simplecpp::Token *tok = tokens.cfront(); tok; tok = tok->next) { |
| 606 | if (tok->op != '#' || sameline(tok->previous, tok)) |
| 607 | continue; |
| 608 | const simplecpp::Token *cmdtok = tok->next; |
| 609 | if (!sameline(tok, cmdtok)) |
| 610 | continue; |
| 611 | if (cmdtok->str() == "ifdef" || cmdtok->str() == "ifndef" || cmdtok->str() == "if") { |
| 612 | std::string config; |
| 613 | if (cmdtok->str() == "ifdef" || cmdtok->str() == "ifndef") { |
| 614 | const simplecpp::Token *expr1 = cmdtok->next; |
| 615 | if (sameline(tok,expr1) && expr1->name && !sameline(tok,expr1->next)) |
| 616 | config = expr1->str(); |
| 617 | if (defined.find(config) != defined.end()) { |
| 618 | config.clear(); |
| 619 | } else if ((cmdtok->str() == "ifdef") && sameline(cmdtok,expr1) && !config.empty()) { |
| 620 | config.append("=" + expr1->str()); //Set equal to itself if ifdef. |
| 621 | } |
| 622 | } else if (cmdtok->str() == "if") { |
| 623 | config = readcondition(cmdtok, defined, undefined); |
| 624 | } |
| 625 | |
| 626 | // skip undefined configurations.. |
| 627 | if (isUndefined(config, undefined)) |
| 628 | config.clear(); |
| 629 | |
| 630 | bool ifndef = false; |
| 631 | if (cmdtok->str() == "ifndef") |
| 632 | ifndef = true; |
| 633 | else { |
| 634 | const std::array<std::string, 6> match{"if", "!", "defined", "(", config, ")"}; |
| 635 | std::size_t i = 0; |
| 636 | ifndef = true; |
| 637 | for (const simplecpp::Token *t = cmdtok; i < match.size(); t = t->next) { |
| 638 | if (!t || t->str() != match[i++]) { |
| 639 | ifndef = false; |
| 640 | break; |
| 641 | } |
| 642 | } |
| 643 | } |
| 644 | |
| 645 | // include guard.. |
| 646 | if (ifndef && tok->location.fileIndex > 0) { |
| 647 | bool includeGuard = true; |
| 648 | for (const simplecpp::Token *t = tok->previous; t; t = t->previous) { |
| 649 | if (t->location.fileIndex == tok->location.fileIndex) { |
| 650 | includeGuard = false; |
| 651 | break; |
| 652 | } |
| 653 | } |
| 654 | if (includeGuard) { |
| 655 | configs_if.emplace_back(/*std::string()*/); |
| 656 | configs_ifndef.emplace_back(/*std::string()*/); |
no test coverage detected