| 619 | } |
| 620 | |
| 621 | static bool evalCondition(const std::string& condition, const ProjectConfiguration &p) { |
| 622 | std::string c = '(' + condition + ")"; |
| 623 | replaceAll(c, "$(Configuration)", p.configuration); |
| 624 | replaceAll(c, "$(Platform)", p.platformStr); |
| 625 | |
| 626 | const Settings s; |
| 627 | TokenList tokenlist(s, Standards::Language::C); |
| 628 | if (!tokenlist.createTokensFromBuffer(c.data(), c.size())) { |
| 629 | throw std::runtime_error("Can not tokenize condition"); |
| 630 | } |
| 631 | |
| 632 | // generate links |
| 633 | { |
| 634 | std::stack<Token*> lpar; |
| 635 | for (Token* tok2 = tokenlist.front(); tok2; tok2 = tok2->next()) { |
| 636 | if (tok2->str() == "(") |
| 637 | lpar.push(tok2); |
| 638 | else if (tok2->str() == ")") { |
| 639 | if (lpar.empty()) |
| 640 | throw std::runtime_error("unmatched ')' in condition " + condition); |
| 641 | Token::createMutualLinks(lpar.top(), tok2); |
| 642 | lpar.pop(); |
| 643 | } |
| 644 | } |
| 645 | if (!lpar.empty()) |
| 646 | throw std::runtime_error("'(' without closing ')'!"); |
| 647 | } |
| 648 | |
| 649 | // Replace "And" and "Or" with "&&" and "||" |
| 650 | for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { |
| 651 | if (tok->str() == "And") |
| 652 | tok->str("&&"); |
| 653 | else if (tok->str() == "Or") |
| 654 | tok->str("||"); |
| 655 | } |
| 656 | |
| 657 | tokenlist.createAst(); |
| 658 | |
| 659 | // Locate ast top and execute the condition |
| 660 | for (const Token *tok = tokenlist.front(); tok; tok = tok->next()) { |
| 661 | if (tok->astParent()) { |
| 662 | return execute(tok->astTop(), p) == "True"; |
| 663 | } |
| 664 | } |
| 665 | throw std::runtime_error("Invalid condition: '" + condition + "'"); |
| 666 | } |
| 667 | |
| 668 | |
| 669 | private: |
nothing calls this directly
no test coverage detected