MCPcopy Create free account
hub / github.com/cppcheck-opensource/cppcheck / expand

Method expand

externals/simplecpp/simplecpp.cpp:1593–1684  ·  view source on GitHub ↗

* 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

Source from the content-addressed store, hash-verified

1591 * @throws invalidHashHash thrown on invalid ## usage
1592 */
1593 const Token * expand(TokenList & output,
1594 const Token * rawtok,
1595 const MacroMap &macros,
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())

Callers 4

recursiveExpandTokenMethod · 0.80
expandTokenMethod · 0.80
expandArgMethod · 0.80
preprocessTokenFunction · 0.80

Calls 15

locstringFunction · 0.85
functionLikeMethod · 0.80
deleteTokenMethod · 0.80
frontMethod · 0.80
samelineFunction · 0.70
ErrorClass · 0.70
toStringFunction · 0.70
push_backMethod · 0.45
strMethod · 0.45
nameMethod · 0.45
findMethod · 0.45

Tested by

no test coverage detected