Refactorizations optimizing std::string usage:

1) Added global static const std::string emptyString; object:
-> Replaces some static variables in functions which might be not threadsafe
-> Avoids constructor call (std::string::string(""))
-> Even functions that return an empty string in some branches can return by reference now.
Added to config.h to ensure that it is available everywhere

2) Added overloads for TestFixture::assertEquals for the most common use cases:
-> Moves conversion from const char[] to std::string into a function, reducing code duplication in binary.
This commit is contained in:
PKEuS 2014-06-26 11:44:19 +02:00
parent feefa4c626
commit ec1bd420a7
15 changed files with 43 additions and 31 deletions

View File

@ -1069,7 +1069,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::str
(declarationId == 0 && Token::Match(tok, ("strcpy|strcat ( " + varnames + " , %str% )").c_str()))) { (declarationId == 0 && Token::Match(tok, ("strcpy|strcat ( " + varnames + " , %str% )").c_str()))) {
const std::size_t len = Token::getStrLength(tok->tokAt(varcount + 4)); const std::size_t len = Token::getStrLength(tok->tokAt(varcount + 4));
if (total_size > 0 && len >= (unsigned int)total_size) { if (total_size > 0 && len >= (unsigned int)total_size) {
bufferOverrunError(tok, declarationId > 0 ? std::string() : varnames); bufferOverrunError(tok, declarationId > 0 ? emptyString : varnames);
continue; continue;
} }
} else if ((declarationId > 0 && Token::Match(tok, "strcpy|strcat ( %varid% , %var% )", declarationId)) || } else if ((declarationId > 0 && Token::Match(tok, "strcpy|strcat ( %varid% , %var% )", declarationId)) ||

View File

@ -210,8 +210,8 @@ private:
static bool isArrayOfStruct(const Token* tok, int &position); static bool isArrayOfStruct(const Token* tok, int &position);
void arrayIndexOutOfBoundsError(const std::list<const Token *> &callstack, const ArrayInfo &arrayInfo, const std::vector<MathLib::bigint> &index); void arrayIndexOutOfBoundsError(const std::list<const Token *> &callstack, const ArrayInfo &arrayInfo, const std::vector<MathLib::bigint> &index);
void bufferOverrunError(const Token *tok, const std::string &varnames = ""); void bufferOverrunError(const Token *tok, const std::string &varnames = emptyString);
void bufferOverrunError(const std::list<const Token *> &callstack, const std::string &varnames = ""); void bufferOverrunError(const std::list<const Token *> &callstack, const std::string &varnames = emptyString);
void strncatUsageError(const Token *tok); void strncatUsageError(const Token *tok);
void negativeMemoryAllocationSizeError(const Token *tok); // provide a negative value to memory allocation function void negativeMemoryAllocationSizeError(const Token *tok); // provide a negative value to memory allocation function
void outOfBoundsError(const Token *tok, const std::string &what, const bool show_size_info, const MathLib::bigint &supplied_size, const MathLib::bigint &actual_size); void outOfBoundsError(const Token *tok, const std::string &what, const bool show_size_info, const MathLib::bigint &supplied_size, const MathLib::bigint &actual_size);

View File

@ -19,4 +19,7 @@
# include <crtdbg.h> # include <crtdbg.h>
#endif #endif
#include <string>
static const std::string emptyString;
#endif // configH #endif // configH

View File

@ -217,8 +217,8 @@ public:
* @param outputFormat Empty string to use default output format * @param outputFormat Empty string to use default output format
* or template to be used. E.g. "{file}:{line},{severity},{id},{message}" * or template to be used. E.g. "{file}:{line},{severity},{id},{message}"
* @return formatted string * @return formatted string
*/ */
std::string toString(bool verbose, const std::string &outputFormat = "") const; std::string toString(bool verbose, const std::string &outputFormat = emptyString) const;
std::string serialize() const; std::string serialize() const;
bool deserialize(const std::string &data); bool deserialize(const std::string &data);

View File

@ -184,9 +184,9 @@ public:
bool isargvalid(const std::string &functionName, int argnr, const MathLib::bigint argvalue) const; bool isargvalid(const std::string &functionName, int argnr, const MathLib::bigint argvalue) const;
std::string validarg(const std::string &functionName, int argnr) const { const std::string& validarg(const std::string &functionName, int argnr) const {
const ArgumentChecks *arg = getarg(functionName, argnr); const ArgumentChecks *arg = getarg(functionName, argnr);
return arg ? arg->valid : std::string(""); return arg ? arg->valid : emptyString;
} }
bool markupFile(const std::string &path) const { bool markupFile(const std::string &path) const {
@ -227,24 +227,24 @@ public:
return offset; return offset;
} }
std::string blockstart(const std::string &file) const { const std::string& blockstart(const std::string &file) const {
const std::map<std::string, CodeBlock>::const_iterator map_it const std::map<std::string, CodeBlock>::const_iterator map_it
= _executableblocks.find(Path::getFilenameExtensionInLowerCase(file)); = _executableblocks.find(Path::getFilenameExtensionInLowerCase(file));
if (map_it != _executableblocks.end()) { if (map_it != _executableblocks.end()) {
return map_it->second.start(); return map_it->second.start();
} }
return std::string(); return emptyString;
} }
std::string blockend(const std::string &file) const { const std::string& blockend(const std::string &file) const {
const std::map<std::string, CodeBlock>::const_iterator map_it const std::map<std::string, CodeBlock>::const_iterator map_it
= _executableblocks.find(Path::getFilenameExtensionInLowerCase(file)); = _executableblocks.find(Path::getFilenameExtensionInLowerCase(file));
if (map_it != _executableblocks.end()) { if (map_it != _executableblocks.end()) {
return map_it->second.end(); return map_it->second.end();
} }
return std::string(); return emptyString;
} }
bool iskeyword(const std::string &file, const std::string &keyword) const { bool iskeyword(const std::string &file, const std::string &keyword) const {

View File

@ -1040,7 +1040,7 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
processedFile = ostr.str(); processedFile = ostr.str();
} }
std::map<std::string, std::string> defs(getcfgmap(_settings ? _settings->userDefines : std::string(""), _settings, filename)); std::map<std::string, std::string> defs(getcfgmap(_settings ? _settings->userDefines : emptyString, _settings, filename));
if (_settings && _settings->_maxConfigs == 1U) { if (_settings && _settings->_maxConfigs == 1U) {
std::set<std::string> pragmaOnce; std::set<std::string> pragmaOnce;

View File

@ -99,7 +99,7 @@ public:
* @param line number, e.g. "123" * @param line number, e.g. "123"
* @return error message. empty upon success * @return error message. empty upon success
*/ */
std::string addSuppression(const std::string &errorId, const std::string &file = "", unsigned int line = 0); std::string addSuppression(const std::string &errorId, const std::string &file = emptyString, unsigned int line = 0);
/** /**
* @brief Returns true if this message should not be shown to the user. * @brief Returns true if this message should not be shown to the user.

View File

@ -104,8 +104,7 @@ public:
} }
const std::string& name() const { const std::string& name() const {
static const std::string empty; return classDef->next()->isName() ? classDef->strAt(1) : emptyString;
return classDef->next()->isName() ? classDef->strAt(1) : empty;
} }
const Token *initBaseInfo(const Token *tok, const Token *tok1); const Token *initBaseInfo(const Token *tok, const Token *tok1);
@ -215,13 +214,11 @@ public:
* @return name string * @return name string
*/ */
const std::string &name() const { const std::string &name() const {
static const std::string noname;
// name may not exist for function arguments // name may not exist for function arguments
if (_name) if (_name)
return _name->str(); return _name->str();
return noname; return emptyString;
} }
/** /**

View File

@ -266,10 +266,8 @@ const Token *Token::linkAt(int index) const
const std::string &Token::strAt(int index) const const std::string &Token::strAt(int index) const
{ {
static const std::string empty_str;
const Token *tok = this->tokAt(index); const Token *tok = this->tokAt(index);
return tok ? tok->_str : empty_str; return tok ? tok->_str : emptyString;
} }
static int multiComparePercent(const Token *tok, const char ** haystack_p, static int multiComparePercent(const Token *tok, const char ** haystack_p,

View File

@ -90,7 +90,7 @@ public:
*/ */
bool tokenize(std::istream &code, bool tokenize(std::istream &code,
const char FileName[], const char FileName[],
const std::string &configuration = "", const std::string &configuration = emptyString,
bool noSymbolDB_AST = false); bool noSymbolDB_AST = false);
/** /**
* tokenize condition and run simple simplifications on it * tokenize condition and run simple simplifications on it

View File

@ -56,8 +56,7 @@ TokenList::~TokenList()
const std::string& TokenList::getSourceFilePath() const const std::string& TokenList::getSourceFilePath() const
{ {
if (getFiles().empty()) { if (getFiles().empty()) {
static const std::string empty; return emptyString;
return empty;
} }
return getFiles()[0]; return getFiles()[0];
} }

View File

@ -73,7 +73,7 @@ public:
* @param code input stream for code * @param code input stream for code
* @param file0 source file name * @param file0 source file name
*/ */
bool createTokens(std::istream &code, const std::string& file0 = ""); bool createTokens(std::istream &code, const std::string& file0 = emptyString);
/** Deallocate list */ /** Deallocate list */
void deallocateTokens(); void deallocateTokens();

View File

@ -149,6 +149,18 @@ void TestFixture::assertEquals(const char *filename, unsigned int linenr, const
} }
} }
} }
void TestFixture::assertEquals(const char *filename, unsigned int linenr, const char expected[], const std::string& actual, const std::string &msg) const
{
assertEquals(filename, linenr, std::string(expected), actual, msg);
}
void TestFixture::assertEquals(const char *filename, unsigned int linenr, const char expected[], const char actual[], const std::string &msg) const
{
assertEquals(filename, linenr, std::string(expected), std::string(actual), msg);
}
void TestFixture::assertEquals(const char *filename, unsigned int linenr, const std::string& expected, const char actual[], const std::string &msg) const
{
assertEquals(filename, linenr, expected, std::string(actual), msg);
}
void TestFixture::assertEquals(const char *filename, unsigned int linenr, long long expected, long long actual, const std::string &msg) const void TestFixture::assertEquals(const char *filename, unsigned int linenr, long long expected, long long actual, const std::string &msg) const
{ {

View File

@ -52,9 +52,12 @@ protected:
void assert_(const char *filename, unsigned int linenr, bool condition) const; void assert_(const char *filename, unsigned int linenr, bool condition) const;
void todoAssert(const char *filename, unsigned int linenr, bool condition) const; void todoAssert(const char *filename, unsigned int linenr, bool condition) const;
void assertEquals(const char *filename, unsigned int linenr, const std::string &expected, const std::string &actual, const std::string &msg = "") const; void assertEquals(const char *filename, unsigned int linenr, const std::string &expected, const std::string &actual, const std::string &msg = emptyString) const;
void assertEquals(const char *filename, unsigned int linenr, long long expected, long long actual, const std::string &msg="") const; void assertEquals(const char *filename, unsigned int linenr, const char expected[], const std::string& actual, const std::string &msg = emptyString) const;
void assertEqualsDouble(const char *filename, unsigned int linenr, double expected, double actual, const std::string &msg="") const; void assertEquals(const char *filename, unsigned int linenr, const char expected[], const char actual[], const std::string &msg = emptyString) const;
void assertEquals(const char *filename, unsigned int linenr, const std::string& expected, const char actual[], const std::string &msg = emptyString) const;
void assertEquals(const char *filename, unsigned int linenr, long long expected, long long actual, const std::string &msg = emptyString) const;
void assertEqualsDouble(const char *filename, unsigned int linenr, double expected, double actual, const std::string &msg = emptyString) const;
void todoAssertEquals(const char *filename, unsigned int linenr, const std::string &wanted, void todoAssertEquals(const char *filename, unsigned int linenr, const std::string &wanted,
const std::string &current, const std::string &actual) const; const std::string &current, const std::string &actual) const;

View File

@ -115,7 +115,7 @@ private:
} }
// Check the suppression // Check the suppression
void checkSuppression(const char code[], const std::string &suppression = "") { void checkSuppression(const char code[], const std::string &suppression = emptyString) {
// Clear the error log // Clear the error log
errout.str(""); errout.str("");
@ -133,7 +133,7 @@ private:
reportUnmatchedSuppressions(settings.nomsg.getUnmatchedGlobalSuppressions()); reportUnmatchedSuppressions(settings.nomsg.getUnmatchedGlobalSuppressions());
} }
void checkSuppressionThreads(const char code[], const std::string &suppression = "") { void checkSuppressionThreads(const char code[], const std::string &suppression = emptyString) {
errout.str(""); errout.str("");
output.str(""); output.str("");
@ -157,7 +157,7 @@ private:
} }
// Check the suppression for multiple files // Check the suppression for multiple files
void checkSuppression(const char *names[], const char *codes[], const std::string &suppression = "") { void checkSuppression(const char *names[], const char *codes[], const std::string &suppression = emptyString) {
// Clear the error log // Clear the error log
errout.str(""); errout.str("");