Refactoring: Use std::string instead of const char *

This commit is contained in:
Daniel Marjamäki 2010-02-14 19:58:17 +01:00
parent 2ad812d2de
commit 9394816fcf
18 changed files with 126 additions and 126 deletions

View File

@ -141,21 +141,13 @@ void CheckBufferOverrun::terminateStrncpyError(const Token *tok)
// Check array usage.. // Check array usage..
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], const int size, const int total_size, unsigned int varid) void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::string> &varname, const int size, const int total_size, unsigned int varid)
{ {
unsigned int varc = 0;
std::string varnames; std::string varnames;
while (varname && varname[varc]) for (unsigned int i = 0; i < varname.size(); ++i)
{ varnames += (i==0?"":" . ") + varname[i];
if (varc > 0)
varnames += " . ";
varnames += varname[varc];
++varc;
}
unsigned int varc = varname.size();
if (varc == 0) if (varc == 0)
varc = 1; varc = 1;
@ -172,7 +164,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
{ {
if (Token::Match(tok, "%varid% [ %num% ]", varid)) if (Token::Match(tok, "%varid% [ %num% ]", varid))
{ {
int index = std::strtol(tok->strAt(2), NULL, 10); int index = MathLib::toLongNumber(tok->strAt(2));
if (index < 0 || index >= size) if (index < 0 || index >= size)
{ {
arrayIndexOutOfBounds(tok, size, index); arrayIndexOutOfBounds(tok, size, index);
@ -181,7 +173,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
} }
else if (Token::Match(tok, std::string(varnames + " [ %num% ]").c_str())) else if (Token::Match(tok, std::string(varnames + " [ %num% ]").c_str()))
{ {
int index = std::strtol(tok->strAt(2 + varc), NULL, 10); int index = MathLib::toLongNumber(tok->strAt(2 + varc));
if (index < 0 || index >= size) if (index < 0 || index >= size)
{ {
arrayIndexOutOfBounds(tok->tokAt(varc), size, index); arrayIndexOutOfBounds(tok->tokAt(varc), size, index);
@ -214,7 +206,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
{ {
if (!tok->isName() && !Token::Match(tok, "[.&]") && Token::Match(tok->next(), "%varid% [ %num% ]", varid)) if (!tok->isName() && !Token::Match(tok, "[.&]") && Token::Match(tok->next(), "%varid% [ %num% ]", varid))
{ {
int index = std::strtol(tok->strAt(3), NULL, 10); int index = MathLib::toLongNumber(tok->strAt(3));
if (index < 0 || index >= size) if (index < 0 || index >= size)
{ {
if (index > size || !Token::Match(tok->previous(), "& (")) if (index > size || !Token::Match(tok->previous(), "& ("))
@ -226,7 +218,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
} }
else if (!tok->isName() && !Token::Match(tok, "[.&]") && Token::Match(tok->next(), std::string(varnames + " [ %num% ]").c_str())) else if (!tok->isName() && !Token::Match(tok, "[.&]") && Token::Match(tok->next(), std::string(varnames + " [ %num% ]").c_str()))
{ {
int index = std::strtol(tok->strAt(3 + varc), NULL, 10); int index = MathLib::toLongNumber(tok->strAt(3 + varc));
if (index < 0 || index >= size) if (index < 0 || index >= size)
{ {
arrayIndexOutOfBounds(tok->tokAt(1 + varc), size, index); arrayIndexOutOfBounds(tok->tokAt(1 + varc), size, index);
@ -248,8 +240,8 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
if (tokSz->isNumber()) if (tokSz->isNumber())
{ {
// strncpy takes entire variable length as input size // strncpy takes entire variable length as input size
const char *num = tok->strAt(6); const std::string num = tok->strAt(6);
if (std::atoi(num) == total_size) if (MathLib::toLongNumber(num) == total_size)
{ {
const Token *tok2 = tok->next()->link()->next()->next(); const Token *tok2 = tok->next()->link()->next()->next();
for (; tok2; tok2 = tok2->next()) for (; tok2; tok2 = tok2->next())
@ -278,8 +270,8 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
sizeArgumentAsChar(tok); sizeArgumentAsChar(tok);
else if (tokSz->isNumber()) else if (tokSz->isNumber())
{ {
const char *num = tok->strAt(6); const std::string num = tok->strAt(6);
if (std::atoi(num) < 0 || std::atoi(num) > total_size) if (MathLib::toLongNumber(num) < 0 || MathLib::toLongNumber(num) > total_size)
{ {
bufferOverrun(tok); bufferOverrun(tok);
} }
@ -291,8 +283,8 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
if (Token::Match(tok->next(), std::string("( " + varnames + " , %num% , %num% )").c_str()) || if (Token::Match(tok->next(), std::string("( " + varnames + " , %num% , %num% )").c_str()) ||
Token::Match(tok->next(), std::string("( %var% , " + varnames + " , %num% )").c_str())) Token::Match(tok->next(), std::string("( %var% , " + varnames + " , %num% )").c_str()))
{ {
const char *num = tok->strAt(varc + 6); const std::string num = tok->strAt(varc + 6);
if (std::atoi(num) < 0 || std::atoi(num) > total_size) if (MathLib::toLongNumber(num) < 0 || MathLib::toLongNumber(num) > total_size)
{ {
bufferOverrun(tok); bufferOverrun(tok);
} }
@ -350,12 +342,12 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
if (Token::Match(tok2, "%varid% < %num% ;", counter_varid)) if (Token::Match(tok2, "%varid% < %num% ;", counter_varid))
{ {
value = std::atoi(tok2->strAt(2)); value = MathLib::toLongNumber(tok2->strAt(2));
max_counter_value = MathLib::toString<long>(value - 1); max_counter_value = MathLib::toString<long>(value - 1);
} }
else if (Token::Match(tok2, "%varid% <= %num% ;", counter_varid)) else if (Token::Match(tok2, "%varid% <= %num% ;", counter_varid))
{ {
value = std::atoi(tok2->strAt(2)) + 1; value = MathLib::toLongNumber(tok2->strAt(2)) + 1;
max_counter_value = tok2->strAt(2); max_counter_value = tok2->strAt(2);
} }
@ -373,7 +365,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
if (!MathLib::isInt(tok3->strAt(2))) if (!MathLib::isInt(tok3->strAt(2)))
continue; continue;
const int num = std::atoi(tok3->strAt(2)); const int num = MathLib::toLongNumber(tok3->strAt(2));
// We have for example code: "for(i=2;i<22;i+=6) // We have for example code: "for(i=2;i<22;i+=6)
// We can calculate that max value for i is 20, not 21 // We can calculate that max value for i is 20, not 21
@ -392,7 +384,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
if (!MathLib::isInt(tok3->strAt(4))) if (!MathLib::isInt(tok3->strAt(4)))
continue; continue;
const int num = std::atoi(tok3->strAt(4)); const int num = MathLib::toLongNumber(tok3->strAt(4));
long max = MathLib::toLongNumber(max_counter_value); long max = MathLib::toLongNumber(max_counter_value);
long min = MathLib::toLongNumber(min_counter_value); long min = MathLib::toLongNumber(min_counter_value);
max = ((max - min) / num) * num + min; max = ((max - min) / num) * num + min;
@ -474,7 +466,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
if (Token::Match(tok2, "%varid% [ %var% +|-|*|/ %num% ]", varid) && if (Token::Match(tok2, "%varid% [ %var% +|-|*|/ %num% ]", varid) &&
tok2->tokAt(2)->varId() == counter_varid) tok2->tokAt(2)->varId() == counter_varid)
{ {
char action = *(tok2->strAt(3)); const char action = tok2->strAt(3)[0];
const std::string &second(tok2->tokAt(4)->str()); const std::string &second(tok2->tokAt(4)->str());
//printf("min_index: %s %c %s\n", min_counter_value.c_str(), action, second.c_str()); //printf("min_index: %s %c %s\n", min_counter_value.c_str(), action, second.c_str());
@ -486,7 +478,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
else if (Token::Match(tok2, "%varid% [ %num% +|-|*|/ %var% ]", varid) && else if (Token::Match(tok2, "%varid% [ %num% +|-|*|/ %var% ]", varid) &&
tok2->tokAt(4)->varId() == counter_varid) tok2->tokAt(4)->varId() == counter_varid)
{ {
char action = *(tok2->strAt(3)); const char action = tok2->strAt(3)[0];
const std::string &first(tok2->tokAt(2)->str()); const std::string &first(tok2->tokAt(2)->str());
//printf("min_index: %s %c %s\n", first.c_str(), action, min_counter_value.c_str()); //printf("min_index: %s %c %s\n", first.c_str(), action, min_counter_value.c_str());
@ -549,7 +541,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
// Dangerous usage of strncat.. // Dangerous usage of strncat..
if (varid > 0 && Token::Match(tok, "strncat ( %varid% , %any% , %num% )", varid)) if (varid > 0 && Token::Match(tok, "strncat ( %varid% , %any% , %num% )", varid))
{ {
int n = std::atoi(tok->strAt(6)); int n = MathLib::toLongNumber(tok->strAt(6));
if (n >= total_size) if (n >= total_size)
strncatUsage(tok); strncatUsage(tok);
} }
@ -558,7 +550,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
// Dangerous usage of strncpy + strncat.. // Dangerous usage of strncpy + strncat..
if (varid > 0 && Token::Match(tok, "strncpy|strncat ( %varid% , %any% , %num% ) ; strncat ( %varid% , %any% , %num% )", varid)) if (varid > 0 && Token::Match(tok, "strncpy|strncat ( %varid% , %any% , %num% ) ; strncat ( %varid% , %any% , %num% )", varid))
{ {
int n = std::atoi(tok->strAt(6)) + std::atoi(tok->strAt(15)); int n = MathLib::toLongNumber(tok->strAt(6)) + MathLib::toLongNumber(tok->strAt(15));
if (n > total_size) if (n > total_size)
strncatUsage(tok->tokAt(9)); strncatUsage(tok->tokAt(9));
} }
@ -590,7 +582,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
// snprintf.. // snprintf..
if (varid > 0 && Token::Match(tok, "snprintf ( %varid% , %num% ,", varid)) if (varid > 0 && Token::Match(tok, "snprintf ( %varid% , %num% ,", varid))
{ {
int n = std::atoi(tok->strAt(4)); int n = MathLib::toLongNumber(tok->strAt(4));
if (n > total_size) if (n > total_size)
outOfBounds(tok->tokAt(4), "snprintf size"); outOfBounds(tok->tokAt(4), "snprintf size");
} }
@ -676,9 +668,10 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
else if (par == 1 && parlevel == 1 && Token::Match(ftok, "%var% [,)]")) else if (par == 1 && parlevel == 1 && Token::Match(ftok, "%var% [,)]"))
{ {
// Parameter name.. // Parameter name..
const char *parname[2]; std::vector<std::string> parname;
parname[0] = ftok->str().c_str(); parname.push_back(ftok->str());
parname[1] = 0;
const unsigned int parId = ftok->varId();
// Goto function body.. // Goto function body..
while (ftok && (ftok->str() != "{")) while (ftok && (ftok->str() != "{"))
@ -691,7 +684,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
// Check variable usage in the function.. // Check variable usage in the function..
_callStack.push_back(tok1); _callStack.push_back(tok1);
checkScope(ftok, parname, size, total_size, 0); checkScope(ftok, parname, size, total_size, parId);
_callStack.pop_back(); _callStack.pop_back();
// break out.. // break out..
@ -721,7 +714,7 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
--indentlevel; --indentlevel;
unsigned int size = 0; unsigned int size = 0;
const char *type = 0; std::string type;
unsigned int varid = 0; unsigned int varid = 0;
int nextTok = 0; int nextTok = 0;
@ -734,14 +727,14 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
unsigned int varpos = 1; unsigned int varpos = 1;
if (tok->next()->str() == "*") if (tok->next()->str() == "*")
++varpos; ++varpos;
size = std::strtoul(tok->strAt(varpos + 2), NULL, 10); size = MathLib::toLongNumber(tok->strAt(varpos + 2));
type = tok->strAt(varpos - 1); type = tok->strAt(varpos - 1);
varid = tok->tokAt(varpos)->varId(); varid = tok->tokAt(varpos)->varId();
nextTok = varpos + 5; nextTok = varpos + 5;
} }
else if (indentlevel > 0 && Token::Match(tok, "[*;{}] %var% = new %type% [ %num% ]")) else if (indentlevel > 0 && Token::Match(tok, "[*;{}] %var% = new %type% [ %num% ]"))
{ {
size = std::strtoul(tok->strAt(6), NULL, 10); size = MathLib::toLongNumber(tok->strAt(6));
type = tok->strAt(4); type = tok->strAt(4);
varid = tok->tokAt(1)->varId(); varid = tok->tokAt(1)->varId();
nextTok = 8; nextTok = 8;
@ -755,7 +748,7 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
} }
else if (indentlevel > 0 && Token::Match(tok, "[*;{}] %var% = malloc ( %num% ) ;")) else if (indentlevel > 0 && Token::Match(tok, "[*;{}] %var% = malloc ( %num% ) ;"))
{ {
size = std::strtoul(tok->strAt(5), NULL, 10); size = MathLib::toLongNumber(tok->strAt(5));
type = "char"; type = "char";
varid = tok->tokAt(1)->varId(); varid = tok->tokAt(1)->varId();
nextTok = 7; nextTok = 7;
@ -789,7 +782,8 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
// The callstack is empty // The callstack is empty
_callStack.clear(); _callStack.clear();
checkScope(tok->tokAt(nextTok), 0, size, total_size, varid); std::vector<std::string> v;
checkScope(tok->tokAt(nextTok), v, size, total_size, varid);
} }
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -825,10 +819,10 @@ void CheckBufferOverrun::checkStructVariable()
else else
continue; continue;
const char *varname[3] = {0, 0, 0}; std::vector<std::string> varname(2, "");
const unsigned int varId = tok2->tokAt(ivar)->varId(); const unsigned int varId = tok2->tokAt(ivar)->varId();
varname[1] = tok2->strAt(ivar); varname[1] = tok2->strAt(ivar);
int arrsize = std::atoi(tok2->strAt(ivar + 2)); int arrsize = MathLib::toLongNumber(tok2->strAt(ivar + 2));
int total_size = arrsize * _tokenizer->sizeOfType(tok2->tokAt(1)); int total_size = arrsize * _tokenizer->sizeOfType(tok2->tokAt(1));
if (tok2->tokAt(2)->str() == "*") if (tok2->tokAt(2)->str() == "*")
total_size = arrsize * _tokenizer->sizeOfType(tok2->tokAt(2)); total_size = arrsize * _tokenizer->sizeOfType(tok2->tokAt(2));
@ -850,7 +844,8 @@ void CheckBufferOverrun::checkStructVariable()
if (Token::simpleMatch(tok4, ") {")) if (Token::simpleMatch(tok4, ") {"))
{ {
checkScope(tok4->tokAt(2), 0, arrsize, total_size, varId); std::vector<std::string> v;
checkScope(tok4->tokAt(2), v, arrsize, total_size, varId);
break; break;
} }
} }

View File

@ -25,6 +25,8 @@
#include "check.h" #include "check.h"
#include "settings.h" #include "settings.h"
#include <list> #include <list>
#include <vector>
#include <string>
class ErrorLogger; class ErrorLogger;
class Token; class Token;
@ -74,7 +76,7 @@ private:
void checkGlobalAndLocalVariable(); void checkGlobalAndLocalVariable();
/** Check for buffer overruns - this is the function that performs the actual checking */ /** Check for buffer overruns - this is the function that performs the actual checking */
void checkScope(const Token *tok, const char *varname[], const int size, const int total_size, unsigned int varid); void checkScope(const Token *tok, const std::vector<std::string> &varname, const int size, const int total_size, unsigned int varid);
/** callstack - used during intra-function checking */ /** callstack - used during intra-function checking */
std::list<const Token *> _callStack; std::list<const Token *> _callStack;

View File

@ -87,7 +87,7 @@ CheckClass::Var *CheckClass::getVarList(const Token *tok1, bool withClasses, boo
} }
// "private:" "public:" "protected:" etc // "private:" "public:" "protected:" etc
const bool b((*tok->strAt(0) != ':') && strchr(tok->strAt(0), ':') != 0); const bool b((tok->str()[0] != ':') && tok->str().find(":") != std::string::npos);
if (b) if (b)
priv = bool(tok->str() == "private:"); priv = bool(tok->str() == "private:");
@ -98,7 +98,7 @@ CheckClass::Var *CheckClass::getVarList(const Token *tok1, bool withClasses, boo
// This is the start of a statement // This is the start of a statement
const Token *next = tok->next(); const Token *next = tok->next();
const char *varname = 0; std::string varname;
// If next token contains a ":".. it is not part of a variable declaration // If next token contains a ":".. it is not part of a variable declaration
if (next->str().find(":") != std::string::npos) if (next->str().find(":") != std::string::npos)
@ -165,7 +165,7 @@ CheckClass::Var *CheckClass::getVarList(const Token *tok1, bool withClasses, boo
} }
// If the varname was set in one of the two if-block above, create a entry for this variable.. // If the varname was set in one of the two if-block above, create a entry for this variable..
if (varname && strcmp(varname, "operator")) if (!varname.empty() && varname != "operator")
{ {
Var *var = new Var(varname, false, priv, varlist); Var *var = new Var(varname, false, priv, varlist);
varlist = var; varlist = var;
@ -176,11 +176,11 @@ CheckClass::Var *CheckClass::getVarList(const Token *tok1, bool withClasses, boo
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckClass::initVar(Var *varlist, const char varname[]) void CheckClass::initVar(Var *varlist, const std::string &varname)
{ {
for (Var *var = varlist; var; var = var->next) for (Var *var = varlist; var; var = var->next)
{ {
if (strcmp(var->name, varname) == 0) if (var->name == varname)
{ {
var->init = true; var->init = true;
return; return;
@ -189,7 +189,7 @@ void CheckClass::initVar(Var *varlist, const char varname[])
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckClass::initializeVarList(const Token *tok1, const Token *ftok, Var *varlist, const char classname[], std::list<std::string> &callstack, bool isStruct) void CheckClass::initializeVarList(const Token *tok1, const Token *ftok, Var *varlist, const std::string &classname, std::list<std::string> &callstack, bool isStruct)
{ {
bool Assign = false; bool Assign = false;
unsigned int indentlevel = 0; unsigned int indentlevel = 0;
@ -401,8 +401,7 @@ void CheckClass::constructors()
const Token *tok1 = Token::findmatch(_tokenizer->tokens(), pattern_class); const Token *tok1 = Token::findmatch(_tokenizer->tokens(), pattern_class);
while (tok1) while (tok1)
{ {
const char *className; const std::string className = tok1->strAt(1);
className = tok1->strAt(1);
const Token *classNameToken = tok1->tokAt(1); const Token *classNameToken = tok1->tokAt(1);
bool isStruct = tok1->str() == "struct"; bool isStruct = tok1->str() == "struct";
@ -499,12 +498,12 @@ void CheckClass::constructors()
} }
} }
void CheckClass::checkConstructors(const Token *tok1, const char funcname[], bool hasPrivateConstructor, bool isStruct) void CheckClass::checkConstructors(const Token *tok1, const std::string &funcname, bool hasPrivateConstructor, bool isStruct)
{ {
const char * const className = tok1->strAt(1); const std::string className = tok1->strAt(1);
// Check that all member variables are initialized.. // Check that all member variables are initialized..
bool withClasses = bool(_settings->_showAll && std::string(funcname) == "operator ="); bool withClasses = bool(_settings->_showAll && funcname == "operator =");
Var *varlist = getVarList(tok1, withClasses, isStruct); Var *varlist = getVarList(tok1, withClasses, isStruct);
int indentlevel = 0; int indentlevel = 0;
@ -737,7 +736,7 @@ void CheckClass::noMemset()
if (!Token::Match(tok, "memset|memcpy|memmove")) if (!Token::Match(tok, "memset|memcpy|memmove"))
continue; continue;
const char *type = NULL; std::string type;
if (Token::Match(tok, "memset ( %var% , %num% , sizeof ( %type% ) )")) if (Token::Match(tok, "memset ( %var% , %num% , sizeof ( %type% ) )"))
type = tok->strAt(8); type = tok->strAt(8);
else if (Token::Match(tok, "memset ( & %var% , %num% , sizeof ( %type% ) )")) else if (Token::Match(tok, "memset ( & %var% , %num% , sizeof ( %type% ) )"))
@ -750,7 +749,7 @@ void CheckClass::noMemset()
type = tok->strAt(8); type = tok->strAt(8);
// No type defined => The tokens didn't match // No type defined => The tokens didn't match
if (!(type && type[0])) if (type.empty())
continue; continue;
// Warn if type is a class or struct that contains any std::* variables // Warn if type is a class or struct that contains any std::* variables
@ -1319,9 +1318,7 @@ void CheckClass::virtualDestructor()
derived = derived->next(); derived = derived->next();
// Name of base class.. // Name of base class..
const char *baseName[2]; const std::string baseName = derived->strAt(0);
baseName[0] = derived->strAt(0);
baseName[1] = 0;
// Update derived so it's ready for the next loop. // Update derived so it's ready for the next loop.
do do
@ -1344,9 +1341,9 @@ void CheckClass::virtualDestructor()
continue; continue;
// Find the destructor declaration for the base class. // Find the destructor declaration for the base class.
const Token *base = Token::findmatch(_tokenizer->tokens(), (std::string("%any% ~ ") + baseName[0] + " (").c_str()); const Token *base = Token::findmatch(_tokenizer->tokens(), (std::string("%any% ~ ") + baseName + " (").c_str());
while (base && base->str() == "::") while (base && base->str() == "::")
base = Token::findmatch(base->next(), (std::string("%any% ~ ") + baseName[0] + " (").c_str()); base = Token::findmatch(base->next(), (std::string("%any% ~ ") + baseName + " (").c_str());
const Token *reverseTok = base; const Token *reverseTok = base;
while (Token::Match(base, "%var%") && base->str() != "virtual") while (Token::Match(base, "%var%") && base->str() != "virtual")
@ -1356,10 +1353,10 @@ void CheckClass::virtualDestructor()
if (! base) if (! base)
{ {
// Is the class declaration available? // Is the class declaration available?
base = Token::findmatch(_tokenizer->tokens(), (std::string("class ") + baseName[0] + " {").c_str()); base = Token::findmatch(_tokenizer->tokens(), (std::string("class ") + baseName + " {").c_str());
if (base) if (base)
{ {
virtualDestructorError(base, baseName[0], derivedClass->str()); virtualDestructorError(base, baseName, derivedClass->str());
} }
continue; continue;
@ -1375,7 +1372,7 @@ void CheckClass::virtualDestructor()
// Proper solution is to check all of the base classes. If base class is not // Proper solution is to check all of the base classes. If base class is not
// found or if one of the base classes has virtual destructor, error should not // found or if one of the base classes has virtual destructor, error should not
// be printed. See TODO test case "virtualDestructorInherited" // be printed. See TODO test case "virtualDestructorInherited"
if (!Token::findmatch(_tokenizer->tokens(), (std::string("class ") + baseName[0] + " {").c_str())) if (!Token::findmatch(_tokenizer->tokens(), (std::string("class ") + baseName + " {").c_str()))
continue; continue;
// Make sure that the destructor is public (protected or private // Make sure that the destructor is public (protected or private
@ -1386,7 +1383,7 @@ void CheckClass::virtualDestructor()
{ {
if (reverseTok->str() == "public:") if (reverseTok->str() == "public:")
{ {
virtualDestructorError(base, baseName[0], derivedClass->str()); virtualDestructorError(base, baseName, derivedClass->str());
break; break;
} }
else if (reverseTok->str() == "protected:" || else if (reverseTok->str() == "protected:" ||

View File

@ -106,16 +106,16 @@ private:
class Var class Var
{ {
public: public:
Var(const char *name = 0, bool init = false, bool priv = false, Var *next = 0) Var(const std::string &name_, bool init = false, bool priv = false, Var *next = 0)
: name(name_)
{ {
this->name = name;
this->init = init; this->init = init;
this->priv = priv; this->priv = priv;
this->next = next; this->next = next;
} }
/** @brief name of variable */ /** @brief name of variable */
const char *name; const std::string name;
/** @brief has this variable been initialized? */ /** @brief has this variable been initialized? */
bool init; bool init;
@ -136,10 +136,10 @@ private:
* @param callstack the function doesn't look into recursive function calls. * @param callstack the function doesn't look into recursive function calls.
* @param isStruct if this is a struct instead of a class * @param isStruct if this is a struct instead of a class
*/ */
void initializeVarList(const Token *tok1, const Token *ftok, Var *varlist, const char classname[], std::list<std::string> &callstack, bool isStruct); void initializeVarList(const Token *tok1, const Token *ftok, Var *varlist, const std::string &classname, std::list<std::string> &callstack, bool isStruct);
/** @brief initialize a variable in the varlist */ /** @brief initialize a variable in the varlist */
void initVar(Var *varlist, const char varname[]); void initVar(Var *varlist, const std::string &varname);
/** /**
* @brief get varlist from a class definition * @brief get varlist from a class definition
@ -150,7 +150,7 @@ private:
Var *getVarList(const Token *tok1, bool withClasses, bool isStruct); Var *getVarList(const Token *tok1, bool withClasses, bool isStruct);
// Check constructors for a specified class // Check constructors for a specified class
void checkConstructors(const Token *tok1, const char funcname[], bool hasPrivateConstructor, bool isStruct); void checkConstructors(const Token *tok1, const std::string &funcname, bool hasPrivateConstructor, bool isStruct);
// Reporting errors.. // Reporting errors..
void noConstructorError(const Token *tok, const std::string &classname, bool isStruct); void noConstructorError(const Token *tok, const std::string &classname, bool isStruct);

View File

@ -97,10 +97,10 @@ void CheckHeaders::warningIncludeHeader()
// Get fileindex of included file.. // Get fileindex of included file..
unsigned int hfile = 0; unsigned int hfile = 0;
const char *includefile = includetok->strAt(1); const std::string includefile = includetok->strAt(1);
while (hfile < _tokenizer->getFiles()->size()) while (hfile < _tokenizer->getFiles()->size())
{ {
if (FileLister::sameFileName(_tokenizer->getFiles()->at(hfile).c_str(), includefile)) if (FileLister::sameFileName(_tokenizer->getFiles()->at(hfile), includefile))
break; break;
++hfile; ++hfile;
} }
@ -184,7 +184,7 @@ void CheckHeaders::warningIncludeHeader()
// -------------------------------------- // --------------------------------------
else if (tok1->str() == "typedef") else if (tok1->str() == "typedef")
{ {
if (strcmp(tok1->strAt(1), "enum") == 0) if (tok1->strAt(1) == "enum")
continue; continue;
int parlevel = 0; int parlevel = 0;
while (tok1->next()) while (tok1->next())
@ -220,7 +220,7 @@ void CheckHeaders::warningIncludeHeader()
if (Token::Match(tok1, ": %var% {") || Token::Match(tok1, ": %type% %var% {")) if (Token::Match(tok1, ": %var% {") || Token::Match(tok1, ": %type% %var% {"))
{ {
std::string classname = tok1->strAt((strcmp(tok1->strAt(2), "{")) ? 2 : 1); const std::string classname = tok1->strAt(((tok1->strAt(2) != "{")) ? 2 : 1);
if (std::find(classlist.begin(), classlist.end(), classname) != classlist.end()) if (std::find(classlist.begin(), classlist.end(), classname) != classlist.end())
{ {
Needed = true; Needed = true;

View File

@ -527,16 +527,16 @@ static int countParameters(const Token *tok)
return -1; return -1;
} }
bool CheckMemoryLeakInFunction::test_white_list(const char funcname[]) bool CheckMemoryLeakInFunction::test_white_list(const std::string &funcname)
{ {
return std::bsearch(funcname, call_func_white_list, return std::bsearch(funcname.c_str(), call_func_white_list,
sizeof(call_func_white_list) / sizeof(call_func_white_list[0]), sizeof(call_func_white_list) / sizeof(call_func_white_list[0]),
sizeof(call_func_white_list[0]), call_func_white_list_compare); sizeof(call_func_white_list[0]), call_func_white_list_compare);
} }
const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<const Token *> callstack, const unsigned int varid, AllocType &alloctype, AllocType &dealloctype, bool &all, unsigned int sz) const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<const Token *> callstack, const unsigned int varid, AllocType &alloctype, AllocType &dealloctype, bool &all, unsigned int sz)
{ {
if (test_white_list(tok->strAt(0))) if (test_white_list(tok->str()))
return 0; return 0;
if (noreturn.find(tok->str()) != noreturn.end()) if (noreturn.find(tok->str()) != noreturn.end())
@ -2408,7 +2408,7 @@ void CheckMemoryLeakInClass::variable(const std::string &classname, const Token
// Function call in destructor .. possible deallocation // Function call in destructor .. possible deallocation
else if (destructor && Token::Match(tok->previous(), "[{};] %var% (")) else if (destructor && Token::Match(tok->previous(), "[{};] %var% ("))
{ {
if (!std::bsearch(tok->strAt(0), call_func_white_list, if (!std::bsearch(tok->str().c_str(), call_func_white_list,
sizeof(call_func_white_list) / sizeof(call_func_white_list[0]), sizeof(call_func_white_list) / sizeof(call_func_white_list[0]),
sizeof(call_func_white_list[0]), call_func_white_list_compare)) sizeof(call_func_white_list[0]), call_func_white_list_compare))
{ {

View File

@ -160,7 +160,7 @@ public:
} }
/** For unit testing the white list */ /** For unit testing the white list */
static bool test_white_list(const char funcname[]); static bool test_white_list(const std::string &funcname);
void check(); void check();

View File

@ -315,8 +315,8 @@ void CheckOther::checkUnsignedDivision()
{ {
if (Token::Match(tok, "[{};(,] %type% %var% [;=,)]")) if (Token::Match(tok, "[{};(,] %type% %var% [;=,)]"))
{ {
const char *type = tok->strAt(1); const std::string type = tok->strAt(1);
if (strcmp(type, "char") == 0 || strcmp(type, "short") == 0 || strcmp(type, "int") == 0) if (type == "char" || type == "short" || type == "int")
varsign[tok->tokAt(2)->varId()] = 's'; varsign[tok->tokAt(2)->varId()] = 's';
} }
@ -451,7 +451,7 @@ void CheckOther::checkVariableScope()
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckOther::lookupVar(const Token *tok1, const char varname[]) void CheckOther::lookupVar(const Token *tok1, const std::string &varname)
{ {
const Token *tok = tok1; const Token *tok = tok1;
@ -607,7 +607,7 @@ void CheckOther::checkConstantFunctionParameter()
void CheckOther::checkStructMemberUsage() void CheckOther::checkStructMemberUsage()
{ {
const char *structname = 0; std::string structname;
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{ {
if (tok->fileIndex() != 0) if (tok->fileIndex() != 0)
@ -622,7 +622,7 @@ void CheckOther::checkStructMemberUsage()
{ {
if (tok2->str() == "(") if (tok2->str() == "(")
{ {
structname = 0; structname = "";
break; break;
} }
@ -633,15 +633,15 @@ void CheckOther::checkStructMemberUsage()
// Bail out if some data is casted to struct.. // Bail out if some data is casted to struct..
const std::string s("( struct| " + tok->next()->str() + " * ) & %var% ["); const std::string s("( struct| " + tok->next()->str() + " * ) & %var% [");
if (Token::findmatch(tok, s.c_str())) if (Token::findmatch(tok, s.c_str()))
structname = 0; structname = "";
} }
if (tok->str() == "}") if (tok->str() == "}")
structname = 0; structname = "";
if (structname && Token::Match(tok, "[{;]")) if (!structname.empty() && Token::Match(tok, "[{;]"))
{ {
const char *varname = 0; std::string varname;
if (Token::Match(tok->next(), "%type% %var% [;[]")) if (Token::Match(tok->next(), "%type% %var% [;[]"))
varname = tok->strAt(2); varname = tok->strAt(2);
else if (Token::Match(tok->next(), "%type% %type% %var% [;[]")) else if (Token::Match(tok->next(), "%type% %type% %var% [;[]"))
@ -653,7 +653,7 @@ void CheckOther::checkStructMemberUsage()
else else
continue; continue;
const std::string usagePattern(". " + std::string(varname)); const std::string usagePattern(". " + varname);
bool used = false; bool used = false;
for (const Token *tok2 = _tokenizer->tokens(); tok2; tok2 = tok2->next()) for (const Token *tok2 = _tokenizer->tokens(); tok2; tok2 = tok2->next())
{ {
@ -834,8 +834,8 @@ void CheckOther::strPlusChar()
else if (Token::Match(tok, "[=(] %str% + %any%")) else if (Token::Match(tok, "[=(] %str% + %any%"))
{ {
// char constant.. // char constant..
const char *s = tok->strAt(3); const std::string s = tok->strAt(3);
if (*s == '\'') if (s[0] == '\'')
strPlusChar(tok->next()); strPlusChar(tok->next());
// char variable.. // char variable..

View File

@ -128,7 +128,7 @@ public:
/** Check for post increment/decrement in for loop*/ /** Check for post increment/decrement in for loop*/
void postIncrement(); void postIncrement();
void lookupVar(const Token *tok1, const char varname[]); void lookupVar(const Token *tok1, const std::string &varname);
// Redundant condition // Redundant condition
// if (haystack.find(needle) != haystack.end()) // if (haystack.find(needle) != haystack.end())

View File

@ -73,7 +73,7 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer)
funcname = tok->tokAt(1); funcname = tok->tokAt(1);
else if (Token::Match(tok, "%type% * %var% (")) else if (Token::Match(tok, "%type% * %var% ("))
funcname = tok->tokAt(2); funcname = tok->tokAt(2);
else if (Token::Match(tok, "%type% :: %var% (") && !Token::Match(tok, tok->strAt(2))) else if (Token::Match(tok, "%type% :: %var% (") && !Token::Match(tok, tok->strAt(2).c_str()))
funcname = tok->tokAt(2); funcname = tok->tokAt(2);
// Don't assume throw as a function name: void foo() throw () {} // Don't assume throw as a function name: void foo() throw () {}

View File

@ -310,18 +310,18 @@ void FileLister::recursiveAddFiles(std::vector<std::string> &filenames, const st
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool FileLister::sameFileName(const char fname1[], const char fname2[]) bool FileLister::sameFileName(const std::string &fname1, const std::string &fname2)
{ {
#if defined(__linux__) || defined(__sun) #if defined(__linux__) || defined(__sun)
return bool(strcmp(fname1, fname2) == 0); return bool(fname1 == fname2);
#endif #endif
#ifdef __GNUC__ #ifdef __GNUC__
return bool(strcasecmp(fname1, fname2) == 0); return bool(strcasecmp(fname1.c_str(), fname2.c_str()) == 0);
#endif #endif
#ifdef __BORLANDC__ #ifdef __BORLANDC__
return bool(stricmp(fname1, fname2) == 0); return bool(stricmp(fname1.c_str(), fname2.c_str()) == 0);
#endif #endif
#ifdef _MSC_VER #ifdef _MSC_VER
return bool(_stricmp(fname1, fname2) == 0); return bool(_stricmp(fname1.c_str(), fname2.c_str()) == 0);
#endif #endif
} }

View File

@ -31,7 +31,7 @@ class FileLister
public: public:
static void recursiveAddFiles(std::vector<std::string> &filenames, const std::string &path, bool recursive); static void recursiveAddFiles(std::vector<std::string> &filenames, const std::string &path, bool recursive);
static std::string simplifyPath(const char *originalPath); static std::string simplifyPath(const char *originalPath);
static bool sameFileName(const char fname1[], const char fname2[]); static bool sameFileName(const std::string &fname1, const std::string &fname2);
static bool acceptFile(const std::string &filename); static bool acceptFile(const std::string &filename);
private: private:

View File

@ -180,7 +180,7 @@ void Settings::addAutoAllocClass(const std::string &name)
_autoDealloc.insert(name); _autoDealloc.insert(name);
} }
bool Settings::isAutoDealloc(const char classname[]) const bool Settings::isAutoDealloc(const std::string &classname) const
{ {
return (_autoDealloc.find(classname) != _autoDealloc.end()); return (_autoDealloc.find(classname) != _autoDealloc.end());
} }

View File

@ -103,7 +103,7 @@ public:
void addAutoAllocClass(const std::string &name); void addAutoAllocClass(const std::string &name);
/** is a class automaticly deallocated? */ /** is a class automaticly deallocated? */
bool isAutoDealloc(const char classname[]) const; bool isAutoDealloc(const std::string &classname) const;
/** assign append code */ /** assign append code */
void append(const std::string &filename); void append(const std::string &filename);

View File

@ -183,7 +183,7 @@ Token *Token::tokAt(int index)
return tok; return tok;
} }
const char *Token::strAt(int index) const std::string Token::strAt(int index) const
{ {
const Token *tok = this->tokAt(index); const Token *tok = this->tokAt(index);
return tok ? tok->_str.c_str() : ""; return tok ? tok->_str.c_str() : "";
@ -592,7 +592,7 @@ const Token *Token::findmatch(const Token *tok, const char pattern[], unsigned i
return 0; return 0;
} }
void Token::insertToken(const char str[]) void Token::insertToken(const std::string &str)
{ {
Token *newToken = new Token(tokensBack); Token *newToken = new Token(tokensBack);
newToken->str(str); newToken->str(str);

View File

@ -69,7 +69,7 @@ public:
const Token *tokAt(int index) const; const Token *tokAt(int index) const;
Token *tokAt(int index); Token *tokAt(int index);
const char *strAt(int index) const; std::string strAt(int index) const;
/** /**
* Match given token (or list of tokens) to a pattern list. * Match given token (or list of tokens) to a pattern list.
@ -202,7 +202,7 @@ public:
* relations between next and previous token also. * relations between next and previous token also.
* @param str String for the new token. * @param str String for the new token.
*/ */
void insertToken(const char str[]); void insertToken(const std::string &str);
Token *previous() const Token *previous() const
{ {

View File

@ -125,7 +125,7 @@ void Tokenizer::addtoken(const char str[], const unsigned int lineno, const unsi
unsigned int Tokenizer::sizeOfType(const Token *type) const unsigned int Tokenizer::sizeOfType(const Token *type) const
{ {
if (!type || !type->strAt(0)) if (!type || type->str().empty())
return 0; return 0;
if (type->str()[0] == '"') if (type->str()[0] == '"')
@ -479,7 +479,7 @@ void Tokenizer::simplifyTypedef()
tok = tok3; tok = tok3;
} }
const char *typeName = 0; std::string typeName;
std::list<std::string> pointers; std::list<std::string> pointers;
Token *typeStart = 0; Token *typeStart = 0;
Token *typeEnd = 0; Token *typeEnd = 0;
@ -1733,7 +1733,7 @@ void Tokenizer::updateClassList()
if (tok1->str() == "struct") if (tok1->str() == "struct")
memberType = ClassInfo::PUBLIC; memberType = ClassInfo::PUBLIC;
const char *className = tok1->strAt(1); const std::string className = tok1->strAt(1);
tok1 = tok1->next(); tok1 = tok1->next();
int indentlevel = 0; int indentlevel = 0;
for (const Token *tok = tok1; tok; tok = tok->next()) for (const Token *tok = tok1; tok; tok = tok->next())
@ -2703,7 +2703,7 @@ bool Tokenizer::simplifyTokenList()
continue; continue;
} }
const char *num = tok->strAt(4); const std::string num = tok->strAt(4);
int indent = 1; int indent = 1;
for (Token *tok2 = tok->tokAt(6); tok2; tok2 = tok2->next()) for (Token *tok2 = tok->tokAt(6); tok2; tok2 = tok2->next())
{ {
@ -2746,15 +2746,21 @@ bool Tokenizer::simplifyTokenList()
if (Token::Match(next, "* ( %var% + %num% )")) if (Token::Match(next, "* ( %var% + %num% )"))
{ {
const char *str[4] = {"var", "[", "num", "]"}; // var
str[0] = tok->strAt(3);
str[2] = tok->strAt(5);
for (int i = 0; i < 4; i++)
{
tok = tok->next(); tok = tok->next();
tok->str(str[i]); tok->str(tok->strAt(2));
}
// [
tok = tok->next();
tok->str("[");
// num
tok = tok->next();
tok->str(tok->strAt(2));
// ]
tok = tok->next();
tok->str("]");
tok->deleteNext(); tok->deleteNext();
tok->deleteNext(); tok->deleteNext();
@ -3311,8 +3317,8 @@ bool Tokenizer::simplifyConditions()
if (Token::Match(tok->tokAt(1), "%num%")) if (Token::Match(tok->tokAt(1), "%num%"))
{ {
// Compare numbers // Compare numbers
double op1 = (strstr(tok->strAt(1), "0x")) ? std::strtol(tok->strAt(1), 0, 16) : std::atof(tok->strAt(1)); double op1 = MathLib::toDoubleNumber(tok->strAt(1));
double op2 = (strstr(tok->strAt(3), "0x")) ? std::strtol(tok->strAt(3), 0, 16) : std::atof(tok->strAt(3)); double op2 = MathLib::toDoubleNumber(tok->strAt(3));
if (cmp == "==") if (cmp == "==")
result = (op1 == op2); result = (op1 == op2);
@ -4743,7 +4749,7 @@ bool Tokenizer::simplifyCalculations()
else if (Token::Match(tok->previous(), "- %num% + %num%")) else if (Token::Match(tok->previous(), "- %num% + %num%"))
tok->str(MathLib::calculate(tok->str(), tok->tokAt(2)->str(), '-')); tok->str(MathLib::calculate(tok->str(), tok->tokAt(2)->str(), '-'));
else else
tok->str(MathLib::calculate(tok->str(), tok->tokAt(2)->str(), *(tok->strAt(1)))); tok->str(MathLib::calculate(tok->str(), tok->tokAt(2)->str(), tok->strAt(1)[0]));
Token::eraseTokens(tok, tok->tokAt(3)); Token::eraseTokens(tok, tok->tokAt(3));
@ -5130,14 +5136,14 @@ void Tokenizer::simplifyEnum()
} }
else else
{ {
tok1->insertToken(MathLib::toString<long>(lastValue).c_str()); tok1->insertToken(MathLib::toString<long>(lastValue));
enumValue = tok1->next(); enumValue = tok1->next();
} }
} }
else if (Token::Match(tok1->previous(), ",|{ %type% = %num% ,|}")) else if (Token::Match(tok1->previous(), ",|{ %type% = %num% ,|}"))
{ {
enumName = tok1; enumName = tok1;
lastValue = std::atoi(tok1->strAt(2)); lastValue = MathLib::toLongNumber(tok1->strAt(2));
enumValue = tok1->tokAt(2); enumValue = tok1->tokAt(2);
lastEnumValueStart = 0; lastEnumValueStart = 0;
lastEnumValueEnd = 0; lastEnumValueEnd = 0;
@ -5506,7 +5512,7 @@ std::string Tokenizer::file(const Token *tok) const
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
const Token * Tokenizer::findClassFunction(const Token *tok, const char classname[], const char funcname[], int &indentlevel, bool isStruct) const const Token * Tokenizer::findClassFunction(const Token *tok, const std::string &classname, const std::string &funcname, int &indentlevel, bool isStruct) const
{ {
if (indentlevel < 0 || tok == NULL) if (indentlevel < 0 || tok == NULL)
return NULL; return NULL;

View File

@ -115,7 +115,7 @@ public:
* @param isStruct is it a struct * @param isStruct is it a struct
* @return First matching token or NULL. * @return First matching token or NULL.
*/ */
const Token *findClassFunction(const Token *tok, const char classname[], const char funcname[], int &indentlevel, bool isStruct = false) const; const Token *findClassFunction(const Token *tok, const std::string &classname, const std::string &funcname, int &indentlevel, bool isStruct = false) const;
/** /**
* get error messages * get error messages