* Expand macro. This will recursively expand inner macros. * @param output destination tokenlist * @param rawtok macro token * @param macros list of macros * @param inputFiles the input files * @return token after macro * @throws Error thrown on missing or invalid preprocessor directives * @throws wrongNumberOfParameters th
| 1591 | * @throws invalidHashHash thrown on invalid ## usage |
| 1592 | */ |
| 1593 | const Token * expand(TokenList & output, |
| 1594 | const Token * rawtok, |
| 1595 | const MacroMap ¯os, |
| 1596 | std::vector<std::string> &inputFiles) const { |
| 1597 | std::set<TokenString> expandedmacros; |
| 1598 | |
| 1599 | #ifdef SIMPLECPP_DEBUG_MACRO_EXPANSION |
| 1600 | std::cout << "expand " << name() << " " << locstring(rawtok->location) << std::endl; |
| 1601 | #endif |
| 1602 | |
| 1603 | TokenList output2(inputFiles); |
| 1604 | |
| 1605 | if (functionLike() && rawtok->next && rawtok->next->op == '(') { |
| 1606 | // Copy macro call to a new tokenlist with no linebreaks |
| 1607 | const Token * const rawtok1 = rawtok; |
| 1608 | TokenList rawtokens2(inputFiles); |
| 1609 | rawtokens2.push_back(new Token(rawtok->str(), rawtok1->location, rawtok->whitespaceahead)); |
| 1610 | rawtok = rawtok->next; |
| 1611 | rawtokens2.push_back(new Token(rawtok->str(), rawtok1->location, rawtok->whitespaceahead)); |
| 1612 | rawtok = rawtok->next; |
| 1613 | int par = 1; |
| 1614 | while (rawtok && par > 0) { |
| 1615 | if (rawtok->op == '(') |
| 1616 | ++par; |
| 1617 | else if (rawtok->op == ')') |
| 1618 | --par; |
| 1619 | else if (rawtok->op == '#' && !sameline(rawtok->previous, rawtok)) |
| 1620 | throw Error(rawtok->location, "it is invalid to use a preprocessor directive as macro parameter"); |
| 1621 | rawtokens2.push_back(new Token(rawtok->str(), rawtok1->location, rawtok->whitespaceahead)); |
| 1622 | rawtok = rawtok->next; |
| 1623 | } |
| 1624 | if (expand(output2, rawtok1->location, rawtokens2.cfront(), macros, expandedmacros)) |
| 1625 | rawtok = rawtok1->next; |
| 1626 | } else { |
| 1627 | rawtok = expand(output2, rawtok->location, rawtok, macros, expandedmacros); |
| 1628 | } |
| 1629 | while (output2.cback() && rawtok) { |
| 1630 | unsigned int par = 0; |
| 1631 | Token* macro2tok = output2.back(); |
| 1632 | while (macro2tok) { |
| 1633 | if (macro2tok->op == '(') { |
| 1634 | if (par==0) |
| 1635 | break; |
| 1636 | --par; |
| 1637 | } else if (macro2tok->op == ')') { |
| 1638 | ++par; |
| 1639 | } |
| 1640 | macro2tok = macro2tok->previous; |
| 1641 | } |
| 1642 | if (macro2tok) { // macro2tok->op == '(' |
| 1643 | macro2tok = macro2tok->previous; |
| 1644 | expandedmacros.insert(name()); |
| 1645 | } else if (rawtok->op == '(') { |
| 1646 | macro2tok = output2.back(); |
| 1647 | } |
| 1648 | if (!macro2tok || !macro2tok->name) |
| 1649 | break; |
| 1650 | if (output2.cfront() != output2.cback() && macro2tok->str() == this->name()) |
no test coverage detected