diff --git a/lib/token.cpp b/lib/token.cpp index a13d00926..8c2d18e51 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -1365,7 +1365,7 @@ void Token::printAst(bool verbose, bool xml, std::ostream &out) const astStringXml(tok, 2U, out); out << "" << std::endl; } else if (verbose) - out << tok->astStringVerbose(0,0) << std::endl; + out << tok->astStringVerbose() << std::endl; else out << tok->astString(" ") << std::endl; if (tok->str() == "(") @@ -1374,18 +1374,16 @@ void Token::printAst(bool verbose, bool xml, std::ostream &out) const } } -static std::string indent(const unsigned int indent1, const unsigned int indent2) +static void indent(std::string &str, const unsigned int indent1, const unsigned int indent2) { - std::string ret(indent1,' '); + for (unsigned int i = 0; i < indent1; ++i) + str += ' '; for (unsigned int i = indent1; i < indent2; i += 2) - ret += "| "; - return ret; + str += "| "; } -std::string Token::astStringVerbose(const unsigned int indent1, const unsigned int indent2) const +void Token::astStringVerboseRecursive(std::string& ret, const unsigned int indent1, const unsigned int indent2) const { - std::string ret; - if (isExpandedMacro()) ret += '$'; ret += mStr; @@ -1395,16 +1393,26 @@ std::string Token::astStringVerbose(const unsigned int indent1, const unsigned i if (mImpl->mAstOperand1) { unsigned int i1 = indent1, i2 = indent2 + 2; - if (indent1==indent2 && !mImpl->mAstOperand2) + if (indent1 == indent2 && !mImpl->mAstOperand2) i1 += 2; - ret += indent(indent1,indent2) + (mImpl->mAstOperand2 ? "|-" : "`-") + mImpl->mAstOperand1->astStringVerbose(i1,i2); + indent(ret, indent1, indent2); + ret += mImpl->mAstOperand2 ? "|-" : "`-"; + mImpl->mAstOperand1->astStringVerboseRecursive(ret, i1, i2); } if (mImpl->mAstOperand2) { unsigned int i1 = indent1, i2 = indent2 + 2; - if (indent1==indent2) + if (indent1 == indent2) i1 += 2; - ret += indent(indent1,indent2) + "`-" + mImpl->mAstOperand2->astStringVerbose(i1,i2); + indent(ret, indent1, indent2); + ret += "`-"; + mImpl->mAstOperand2->astStringVerboseRecursive(ret, i1, i2); } +} + +std::string Token::astStringVerbose() const +{ + std::string ret; + astStringVerboseRecursive(ret); return ret; } diff --git a/lib/token.h b/lib/token.h index fc2972dcb..8cc82b987 100644 --- a/lib/token.h +++ b/lib/token.h @@ -1069,6 +1069,9 @@ private: /** Update internal property cache about string and char literals */ void update_property_char_string_literal(); + /** Internal helper function to avoid excessive string allocations */ + void astStringVerboseRecursive(std::string& ret, const unsigned int indent1 = 0U, const unsigned int indent2 = 0U) const; + public: void astOperand1(Token *tok); void astOperand2(Token *tok); @@ -1118,7 +1121,7 @@ public: return ret + sep + mStr; } - std::string astStringVerbose(const unsigned int indent1, const unsigned int indent2) const; + std::string astStringVerbose() const; std::string expressionString() const; diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 65ad338d4..61b1d8641 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -6983,7 +6983,7 @@ private: // Return stringified AST if (verbose) - return tokenList.list.front()->astTop()->astStringVerbose(0, 0); + return tokenList.list.front()->astTop()->astStringVerbose(); std::string ret; std::set astTop;