refs issue #9089: avoid usage of expensive std::stringstream (#2996)

This commit is contained in:
Oliver Stöneberg 2021-01-16 19:03:28 +01:00 committed by GitHub
parent 853c271f22
commit 9f9a652ae1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 92 additions and 93 deletions

View File

@ -1938,7 +1938,9 @@ void CheckIO::argumentType(std::ostream& os, const ArgumentInfo * argInfo)
os << type->str() << "::"; os << type->str() << "::";
type = type->tokAt(2); type = type->tokAt(2);
} }
type->stringify(os, false, true, false); std::string s;
type->stringify(s, false, true, false);
os << s;
if (type->strAt(1) == "*" && !argInfo->element) if (type->strAt(1) == "*" && !argInfo->element)
os << " *"; os << " *";
else if (argInfo->variableInfo && !argInfo->element && argInfo->variableInfo->isArray()) else if (argInfo->variableInfo && !argInfo->element && argInfo->variableInfo->isArray())
@ -1956,7 +1958,9 @@ void CheckIO::argumentType(std::ostream& os, const ArgumentInfo * argInfo)
if (type->strAt(1) == "*" || argInfo->address) if (type->strAt(1) == "*" || argInfo->address)
os << " *"; os << " *";
os << " {aka "; os << " {aka ";
type->stringify(os, false, true, false); std::string s;
type->stringify(s, false, true, false);
os << s;
if (type->strAt(1) == "*" || argInfo->address) if (type->strAt(1) == "*" || argInfo->address)
os << " *"; os << " *";
os << "}"; os << "}";

View File

@ -622,11 +622,12 @@ bool ErrorLogger::reportUnmatchedSuppressions(const std::list<Suppressions::Supp
std::string ErrorLogger::callStackToString(const std::list<ErrorMessage::FileLocation> &callStack) std::string ErrorLogger::callStackToString(const std::list<ErrorMessage::FileLocation> &callStack)
{ {
std::ostringstream ostr; std::string str;
for (std::list<ErrorMessage::FileLocation>::const_iterator tok = callStack.begin(); tok != callStack.end(); ++tok) { for (std::list<ErrorMessage::FileLocation>::const_iterator tok = callStack.begin(); tok != callStack.end(); ++tok) {
ostr << (tok == callStack.begin() ? "" : " -> ") << tok->stringify(); str += (tok == callStack.begin() ? "" : " -> ");
str += tok->stringify();
} }
return ostr.str(); return str;
} }
@ -663,12 +664,15 @@ void ErrorMessage::FileLocation::setfile(const std::string &file)
std::string ErrorMessage::FileLocation::stringify() const std::string ErrorMessage::FileLocation::stringify() const
{ {
std::ostringstream oss; std::string str;
oss << '[' << Path::toNativeSeparators(mFileName); str += '[';
if (line != Suppressions::Suppression::NO_LINE) str += Path::toNativeSeparators(mFileName);
oss << ':' << line; if (line != Suppressions::Suppression::NO_LINE) {
oss << ']'; str += ':';
return oss.str(); str += std::to_string(line);
}
str += ']';
return str;
} }
std::string ErrorLogger::toxml(const std::string &str) std::string ErrorLogger::toxml(const std::string &str)

View File

@ -294,24 +294,13 @@ MathLib::biguint MathLib::toULongNumber(const std::string & str)
{ {
// hexadecimal numbers: // hexadecimal numbers:
if (isIntHex(str)) { if (isIntHex(str)) {
if (str[0] == '-') { const biguint ret = std::stoull(str, nullptr, 16);
biguint ret = 0;
std::istringstream istr(str);
istr >> std::hex >> ret;
return ret; return ret;
} else {
unsigned long long ret = 0;
std::istringstream istr(str);
istr >> std::hex >> ret;
return (biguint)ret;
}
} }
// octal numbers: // octal numbers:
if (isOct(str)) { if (isOct(str)) {
biguint ret = 0; const biguint ret = std::stoull(str, nullptr, 8);
std::istringstream istr(str);
istr >> std::oct >> ret;
return ret; return ret;
} }
@ -340,9 +329,7 @@ MathLib::biguint MathLib::toULongNumber(const std::string & str)
return static_cast<biguint>(doubleval); return static_cast<biguint>(doubleval);
} }
biguint ret = 0; const biguint ret = std::stoull(str, nullptr, 10);
std::istringstream istr(str);
istr >> ret;
return ret; return ret;
} }
@ -488,23 +475,17 @@ MathLib::bigint MathLib::toLongNumber(const std::string & str)
// hexadecimal numbers: // hexadecimal numbers:
if (isIntHex(str)) { if (isIntHex(str)) {
if (str[0] == '-') { if (str[0] == '-') {
bigint ret = 0; const bigint ret = std::stoll(str, nullptr, 16);
std::istringstream istr(str);
istr >> std::hex >> ret;
return ret; return ret;
} else { } else {
unsigned long long ret = 0; const biguint ret = std::stoull(str, nullptr, 16);
std::istringstream istr(str);
istr >> std::hex >> ret;
return (bigint)ret; return (bigint)ret;
} }
} }
// octal numbers: // octal numbers:
if (isOct(str)) { if (isOct(str)) {
bigint ret = 0; const bigint ret = std::stoll(str, nullptr, 8);
std::istringstream istr(str);
istr >> std::oct >> ret;
return ret; return ret;
} }
@ -540,15 +521,11 @@ MathLib::bigint MathLib::toLongNumber(const std::string & str)
} }
if (str[0] == '-') { if (str[0] == '-') {
bigint ret = 0; const bigint ret = std::stoll(str, nullptr, 10);
std::istringstream istr(str);
istr >> ret;
return ret; return ret;
} }
biguint ret = 0; const biguint ret = std::stoull(str, nullptr, 10);
std::istringstream istr(str);
istr >> ret;
return ret; return ret;
} }

View File

@ -3400,9 +3400,11 @@ void SymbolDatabase::printOut(const char *title) const
if (scope->type == Scope::eEnum) { if (scope->type == Scope::eEnum) {
std::cout << " enumType: "; std::cout << " enumType: ";
if (scope->enumType) if (scope->enumType) {
scope->enumType->stringify(std::cout, false, true, false); std::string s;
else scope->enumType->stringify(s, false, true, false);
std::cout << s;
} else
std::cout << "int"; std::cout << "int";
std::cout << std::endl; std::cout << std::endl;
std::cout << " enumClass: " << scope->enumClass << std::endl; std::cout << " enumClass: " << scope->enumClass << std::endl;

View File

@ -1174,44 +1174,49 @@ void Token::printLines(int lines) const
std::cout << stringifyList(stringifyOptions::forDebugExprId(), nullptr, end) << std::endl; std::cout << stringifyList(stringifyOptions::forDebugExprId(), nullptr, end) << std::endl;
} }
void Token::stringify(std::ostream& os, const stringifyOptions& options) const void Token::stringify(std::string& os, const stringifyOptions& options) const
{ {
if (options.attributes) { if (options.attributes) {
if (isUnsigned()) if (isUnsigned())
os << "unsigned "; os += "unsigned ";
else if (isSigned()) else if (isSigned())
os << "signed "; os += "signed ";
if (isComplex()) if (isComplex())
os << "_Complex "; os += "_Complex ";
if (isLong()) { if (isLong()) {
if (!(mTokType == eString || mTokType == eChar)) if (!(mTokType == eString || mTokType == eChar))
os << "long "; os += "long ";
} }
} }
if (options.macro && isExpandedMacro()) if (options.macro && isExpandedMacro())
os << "$"; os += '$';
if (isName() && mStr.find(' ') != std::string::npos) { if (isName() && mStr.find(' ') != std::string::npos) {
for (char i : mStr) { for (char i : mStr) {
if (i != ' ') if (i != ' ')
os << i; os += i;
} }
} else if (mStr[0] != '\"' || mStr.find('\0') == std::string::npos) } else if (mStr[0] != '\"' || mStr.find('\0') == std::string::npos)
os << mStr; os += mStr;
else { else {
for (char i : mStr) { for (char i : mStr) {
if (i == '\0') if (i == '\0')
os << "\\0"; os += "\\0";
else else
os << i; os += i;
} }
} }
if (options.varid && mImpl->mVarId != 0) if (options.varid && mImpl->mVarId != 0) {
os << "@" << (options.idtype ? "var" : "") << mImpl->mVarId; os += '@';
else if (options.exprid && mImpl->mExprId != 0) os += (options.idtype ? "var" : "");
os << "@" << (options.idtype ? "expr" : "") << mImpl->mExprId; os += std::to_string(mImpl->mVarId);
} else if (options.exprid && mImpl->mExprId != 0) {
os += '@';
os += (options.idtype ? "expr" : "");
os += std::to_string(mImpl->mExprId);
}
} }
void Token::stringify(std::ostream& os, bool varid, bool attributes, bool macro) const void Token::stringify(std::string& os, bool varid, bool attributes, bool macro) const
{ {
stringifyOptions options; stringifyOptions options;
options.varid = varid; options.varid = varid;
@ -1225,7 +1230,7 @@ std::string Token::stringifyList(const stringifyOptions& options, const std::vec
if (this == end) if (this == end)
return ""; return "";
std::ostringstream ret; std::string ret;
unsigned int lineNumber = mImpl->mLineNumber - (options.linenumbers ? 1U : 0U); unsigned int lineNumber = mImpl->mLineNumber - (options.linenumbers ? 1U : 0U);
unsigned int fileIndex = options.files ? ~0U : mImpl->mFileIndex; unsigned int fileIndex = options.files ? ~0U : mImpl->mFileIndex;
@ -1239,12 +1244,12 @@ std::string Token::stringifyList(const stringifyOptions& options, const std::vec
fileIndex = tok->mImpl->mFileIndex; fileIndex = tok->mImpl->mFileIndex;
if (options.files) { if (options.files) {
ret << "\n\n##file "; ret += "\n\n##file ";
if (fileNames && fileNames->size() > tok->mImpl->mFileIndex) if (fileNames && fileNames->size() > tok->mImpl->mFileIndex)
ret << fileNames->at(tok->mImpl->mFileIndex); ret += fileNames->at(tok->mImpl->mFileIndex);
else else
ret << fileIndex; ret += std::to_string(fileIndex);
ret << '\n'; ret += '\n';
} }
lineNumber = lineNumbers[fileIndex]; lineNumber = lineNumbers[fileIndex];
@ -1253,27 +1258,34 @@ std::string Token::stringifyList(const stringifyOptions& options, const std::vec
if (options.linebreaks && (lineNumber != tok->linenr() || fileChange)) { if (options.linebreaks && (lineNumber != tok->linenr() || fileChange)) {
if (lineNumber+4 < tok->linenr() && fileIndex == tok->mImpl->mFileIndex) { if (lineNumber+4 < tok->linenr() && fileIndex == tok->mImpl->mFileIndex) {
ret << '\n' << lineNumber+1 << ":\n|\n"; ret += '\n';
ret << tok->linenr()-1 << ":\n"; ret += std::to_string(lineNumber+1);
ret << tok->linenr() << ": "; ret += ":\n|\n";
ret += std::to_string(tok->linenr()-1);
ret += ":\n";
ret += std::to_string(tok->linenr());
ret += ": ";
} else if (this == tok && options.linenumbers) { } else if (this == tok && options.linenumbers) {
ret << tok->linenr() << ": "; ret += std::to_string(tok->linenr());
ret += ": ";
} else if (lineNumber > tok->linenr()) { } else if (lineNumber > tok->linenr()) {
lineNumber = tok->linenr(); lineNumber = tok->linenr();
ret << '\n'; ret += '\n';
if (options.linenumbers) { if (options.linenumbers) {
ret << lineNumber << ':'; ret += std::to_string(lineNumber);
ret += ':';
if (lineNumber == tok->linenr()) if (lineNumber == tok->linenr())
ret << ' '; ret += ' ';
} }
} else { } else {
while (lineNumber < tok->linenr()) { while (lineNumber < tok->linenr()) {
++lineNumber; ++lineNumber;
ret << '\n'; ret += '\n';
if (options.linenumbers) { if (options.linenumbers) {
ret << lineNumber << ':'; ret += std::to_string(lineNumber);
ret += ':';
if (lineNumber == tok->linenr()) if (lineNumber == tok->linenr())
ret << ' '; ret += ' ';
} }
} }
} }
@ -1282,11 +1294,11 @@ std::string Token::stringifyList(const stringifyOptions& options, const std::vec
tok->stringify(ret, options); // print token tok->stringify(ret, options); // print token
if (tok->next() != end && (!options.linebreaks || (tok->next()->linenr() == tok->linenr() && tok->next()->fileIndex() == tok->fileIndex()))) if (tok->next() != end && (!options.linebreaks || (tok->next()->linenr() == tok->linenr() && tok->next()->fileIndex() == tok->fileIndex())))
ret << ' '; ret += ' ';
} }
if (options.linebreaks && (options.files || options.linenumbers)) if (options.linebreaks && (options.files || options.linenumbers))
ret << '\n'; ret += '\n';
return ret.str(); return ret;
} }
std::string Token::stringifyList(bool varid, bool attributes, bool linenumbers, bool linebreaks, bool files, const std::vector<std::string>* fileNames, const Token* end) const std::string Token::stringifyList(bool varid, bool attributes, bool linenumbers, bool linebreaks, bool files, const std::vector<std::string>* fileNames, const Token* end) const
{ {
@ -1472,38 +1484,38 @@ bool Token::isUnaryPreOp() const
static std::string stringFromTokenRange(const Token* start, const Token* end) static std::string stringFromTokenRange(const Token* start, const Token* end)
{ {
std::ostringstream ret; std::string ret;
if (end) if (end)
end = end->next(); end = end->next();
for (const Token *tok = start; tok && tok != end; tok = tok->next()) { for (const Token *tok = start; tok && tok != end; tok = tok->next()) {
if (tok->isUnsigned()) if (tok->isUnsigned())
ret << "unsigned "; ret += "unsigned ";
if (tok->isLong() && !tok->isLiteral()) if (tok->isLong() && !tok->isLiteral())
ret << "long "; ret += "long ";
if (tok->tokType() == Token::eString) { if (tok->tokType() == Token::eString) {
for (unsigned char c: tok->str()) { for (unsigned char c: tok->str()) {
if (c == '\n') if (c == '\n')
ret << "\\n"; ret += "\\n";
else if (c == '\r') else if (c == '\r')
ret << "\\r"; ret += "\\r";
else if (c == '\t') else if (c == '\t')
ret << "\\t"; ret += "\\t";
else if (c >= ' ' && c <= 126) else if (c >= ' ' && c <= 126)
ret << c; ret += c;
else { else {
char str[10]; char str[10];
sprintf(str, "\\x%02x", c); sprintf(str, "\\x%02x", c);
ret << str; ret += str;
} }
} }
} else if (tok->originalName().empty() || tok->isUnsigned() || tok->isLong()) { } else if (tok->originalName().empty() || tok->isUnsigned() || tok->isLong()) {
ret << tok->str(); ret += tok->str();
} else } else
ret << tok->originalName(); ret += tok->originalName();
if (Token::Match(tok, "%name%|%num% %name%|%num%")) if (Token::Match(tok, "%name%|%num% %name%|%num%"))
ret << ' '; ret += ' ';
} }
return ret.str(); return ret;
} }
std::string Token::expressionString() const std::string Token::expressionString() const

View File

@ -887,7 +887,7 @@ public:
} }
}; };
void stringify(std::ostream& os, const stringifyOptions& options) const; void stringify(std::string& os, const stringifyOptions& options) const;
/** /**
* Stringify a token * Stringify a token
@ -896,7 +896,7 @@ public:
* @param attributes Print attributes of tokens like "unsigned" in front of it. * @param attributes Print attributes of tokens like "unsigned" in front of it.
* @param macro Prints $ in front of the token if it was expanded from a macro. * @param macro Prints $ in front of the token if it was expanded from a macro.
*/ */
void stringify(std::ostream& os, bool varid, bool attributes, bool macro) const; void stringify(std::string& os, bool varid, bool attributes, bool macro) const;
std::string stringifyList(const stringifyOptions& options, const std::vector<std::string>* fileNames = nullptr, const Token* end = nullptr) const; std::string stringifyList(const stringifyOptions& options, const std::vector<std::string>* fileNames = nullptr, const Token* end = nullptr) const;
std::string stringifyList(const Token* end, bool attributes = true) const; std::string stringifyList(const Token* end, bool attributes = true) const;