Style: Updated the coding style with "astyle"

This commit is contained in:
Daniel Marjamäki 2009-01-05 15:49:57 +00:00
parent 7495190312
commit ea1f3f4e85
48 changed files with 3411 additions and 3392 deletions

View File

@ -36,7 +36,7 @@
CheckBufferOverrunClass::CheckBufferOverrunClass(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger)
: _settings(settings)
: _settings(settings)
{
_tokenizer = tokenizer;
_errorLogger = errorLogger;
@ -52,8 +52,8 @@ void CheckBufferOverrunClass::ReportError(const Token *tok, const char errmsg[])
{
std::ostringstream ostr;
std::list<const Token *>::const_iterator it;
for ( it = _callStack.begin(); it != _callStack.end(); it++ )
ostr << _tokenizer->fileLine(*it ) << " -> ";
for (it = _callStack.begin(); it != _callStack.end(); it++)
ostr << _tokenizer->fileLine(*it) << " -> ";
ostr << _tokenizer->fileLine(tok) << ": " << errmsg;
_errorLogger->reportErr(ostr.str());
}
@ -69,9 +69,9 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
unsigned int varc = 0;
std::string varnames;
while ( varname[varc] )
while (varname[varc])
{
if( varc > 0 )
if (varc > 0)
varnames += " . ";
varnames += varname[varc];
@ -79,15 +79,15 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
++varc;
}
if( varc == 0 )
if (varc == 0)
varc = 1;
varc = 2 * (varc - 1);
// Array index..
if ( varid > 0 )
if (varid > 0)
{
if ( Token::Match(tok, "%varid% [ %num% ]", varid) )
if (Token::Match(tok, "%varid% [ %num% ]", varid))
{
const char *num = tok->strAt(2);
if (strtol(num, NULL, 10) >= size)
@ -96,7 +96,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
}
}
}
else if ( Token::Match(tok, std::string( varnames + " [ %num% ]" ).c_str() ) )
else if (Token::Match(tok, std::string(varnames + " [ %num% ]").c_str()))
{
const char *num = tok->strAt(2 + varc);
if (strtol(num, NULL, 10) >= size)
@ -107,7 +107,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
int indentlevel = 0;
for ( ; tok; tok = tok->next() )
for (; tok; tok = tok->next())
{
if (tok->str() == "{")
{
@ -117,14 +117,14 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
else if (tok->str() == "}")
{
--indentlevel;
if ( indentlevel < 0 )
if (indentlevel < 0)
return;
}
// Array index..
if ( varid > 0 )
if (varid > 0)
{
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))
{
const char *num = tok->strAt(3);
if (strtol(num, NULL, 10) >= size)
@ -133,7 +133,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
}
}
}
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()))
{
const char *num = tok->next()->strAt(2 + varc);
if (strtol(num, NULL, 10) >= size)
@ -146,15 +146,15 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
// memset, memcmp, memcpy, strncpy, fgets..
if ( varid > 0 )
if (varid > 0)
{
if ( Token::Match(tok, "memset|memcpy|memmove|memcmp|strncpy|fgets") )
if (Token::Match(tok, "memset|memcpy|memmove|memcmp|strncpy|fgets"))
{
if ( Token::Match(tok->next(), "( %varid% , %num% , %num% )", varid) ||
Token::Match(tok->next(), "( %var% , %varid% , %num% )", varid) )
if (Token::Match(tok->next(), "( %varid% , %num% , %num% )", varid) ||
Token::Match(tok->next(), "( %var% , %varid% , %num% )", varid))
{
const char *num = tok->strAt(6);
if ( atoi(num) > total_size )
if (atoi(num) > total_size)
{
ReportError(tok, "Buffer overrun");
}
@ -162,13 +162,13 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
continue;
}
}
else if (Token::Match(tok,"memset|memcpy|memmove|memcmp|strncpy|fgets") )
else if (Token::Match(tok, "memset|memcpy|memmove|memcmp|strncpy|fgets"))
{
if ( Token::Match(tok->next(), std::string( "( "+varnames+" , %num% , %num% )" ).c_str()) ||
Token::Match(tok->next(), std::string( "( %var% , "+varnames+" , %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()))
{
const char *num = tok->strAt(varc + 6);
if ( atoi(num) > total_size )
if (atoi(num) > total_size)
{
ReportError(tok, "Buffer overrun");
}
@ -178,56 +178,56 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
// Loop..
if ( Token::simpleMatch(tok, "for (") )
if (Token::simpleMatch(tok, "for ("))
{
const Token *tok2 = tok->tokAt(2);
// for - setup..
if ( Token::Match(tok2, "%var% = 0 ;") )
if (Token::Match(tok2, "%var% = 0 ;"))
tok2 = tok2->tokAt(4);
else if ( Token::Match(tok2, "%type% %var% = 0 ;") )
else if (Token::Match(tok2, "%type% %var% = 0 ;"))
tok2 = tok2->tokAt(5);
else if ( Token::Match(tok2, "%type% %type% %var% = 0 ;") )
else if (Token::Match(tok2, "%type% %type% %var% = 0 ;"))
tok2 = tok2->tokAt(6);
else
continue;
// for - condition..
if ( !Token::Match(tok2, "%var% < %num% ;") && !Token::Match(tok2, "%var% <= %num% ;"))
if (!Token::Match(tok2, "%var% < %num% ;") && !Token::Match(tok2, "%var% <= %num% ;"))
continue;
// Get index variable and stopsize.
const char *strindex = tok2->aaaa();
int value = ((tok2->next()->aaaa1() == '=') ? 1 : 0) + atoi(tok2->strAt(2));
if ( value <= size )
if (value <= size)
continue;
// Goto the end of the for loop..
while ( tok2 && tok2->str() != ")" )
while (tok2 && tok2->str() != ")")
tok2 = tok2->next();
if ( !tok2 || !tok2->tokAt(5) )
if (!tok2 || !tok2->tokAt(5))
break;
std::ostringstream pattern;
pattern << varnames << " [ " << strindex << " ]";
int indentlevel2 = 0;
while ( (tok2 = tok2->next()) )
while ((tok2 = tok2->next()))
{
if ( tok2->str() == ";" && indentlevel2 == 0 )
if (tok2->str() == ";" && indentlevel2 == 0)
break;
if ( tok2->str() == "{" )
if (tok2->str() == "{")
++indentlevel2;
if ( tok2->str() == "}" )
if (tok2->str() == "}")
{
--indentlevel2;
if ( indentlevel2 <= 0 )
if (indentlevel2 <= 0)
break;
}
if ( Token::Match(tok2, pattern.str().c_str()) )
if (Token::Match(tok2, pattern.str().c_str()))
{
ReportError(tok2, "Buffer overrun");
break;
@ -239,20 +239,20 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
// Writing data into array..
if ( Token::Match(tok, std::string( "strcpy ( "+varnames+" , %str% )" ).c_str()) )
if (Token::Match(tok, std::string("strcpy ( " + varnames + " , %str% )").c_str()))
{
int len = 0;
const char *str = tok->strAt(varc + 4 );
while ( *str )
const char *str = tok->strAt(varc + 4);
while (*str)
{
if (*str=='\\')
if (*str == '\\')
++str;
++str;
++len;
}
if (len > 2 && len >= (int)size + 2)
{
ReportError(tok, "Buffer overrun");
ReportError(tok, "Buffer overrun");
}
continue;
}
@ -261,69 +261,69 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
// Function call..
// It's not interesting to check what happens when the whole struct is
// sent as the parameter, that is checked separately anyway.
if ( Token::Match(tok, "%var% (") )
if (Token::Match(tok, "%var% ("))
{
// Don't make recursive checking..
if (std::find(_callStack.begin(), _callStack.end(), tok) != _callStack.end())
continue;
// Only perform this checking if showAll setting is enabled..
if ( !_settings._showAll )
if (!_settings._showAll)
continue;
unsigned int parlevel = 0, par = 0;
for ( const Token *tok2 = tok; tok2; tok2 = tok2->next() )
for (const Token *tok2 = tok; tok2; tok2 = tok2->next())
{
if ( tok2->str() == "(" )
if (tok2->str() == "(")
{
++parlevel;
}
else if ( tok2->str() == ")" )
else if (tok2->str() == ")")
{
--parlevel;
if ( parlevel < 1 )
if (parlevel < 1)
{
par = 0;
break;
}
}
else if ( parlevel == 1 && (tok2->str() == ",") )
else if (parlevel == 1 && (tok2->str() == ","))
{
++par;
}
if ( parlevel == 1 && Token::Match(tok2, std::string( "[(,] "+varnames+" [,)]" ).c_str()) )
if (parlevel == 1 && Token::Match(tok2, std::string("[(,] " + varnames + " [,)]").c_str()))
{
++par;
break;
}
}
if ( par == 0 )
if (par == 0)
continue;
// Find function..
const Token *ftok = _tokenizer->GetFunctionTokenByName(tok->aaaa());
if ( !ftok )
if (!ftok)
continue;
// Parse head of function..
ftok = ftok->tokAt(2);
parlevel = 1;
while ( ftok && parlevel == 1 && par >= 1 )
while (ftok && parlevel == 1 && par >= 1)
{
if ( ftok->str() == "(" )
if (ftok->str() == "(")
++parlevel;
else if ( ftok->str() == ")" )
else if (ftok->str() == ")")
--parlevel;
else if ( ftok->str() == "," )
else if (ftok->str() == ",")
--par;
else if ( par==1 && parlevel==1 && Token::Match(ftok, "%var% [,)]") )
else if (par == 1 && parlevel == 1 && Token::Match(ftok, "%var% [,)]"))
{
// Parameter name..
const char *parname[2];
@ -331,7 +331,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
parname[1] = 0;
// Goto function body..
while ( ftok && (ftok->str() != "{") )
while (ftok && (ftok->str() != "{"))
ftok = ftok->next();
ftok = ftok ? ftok->next() : 0;
@ -415,50 +415,50 @@ void CheckBufferOverrunClass::CheckBufferOverrun_LocalVariable()
void CheckBufferOverrunClass::CheckBufferOverrun_StructVariable()
{
const char declstruct[] = "struct|class %var% {";
for ( const Token *tok = Token::findmatch(_tokenizer->tokens(), declstruct);
tok; tok = Token::findmatch(tok->next(), declstruct) )
for (const Token *tok = Token::findmatch(_tokenizer->tokens(), declstruct);
tok; tok = Token::findmatch(tok->next(), declstruct))
{
const std::string &structname = tok->next()->str();
// Found a struct declaration. Search for arrays..
for ( const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next() )
for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next())
{
if ( tok2->str() == "}" )
if (tok2->str() == "}")
break;
int ivar = 0;
if ( Token::Match(tok2->next(), "%type% %var% [ %num% ] ;") )
if (Token::Match(tok2->next(), "%type% %var% [ %num% ] ;"))
ivar = 2;
else if ( Token::Match(tok2->next(), "%type% %type% %var% [ %num% ] ;") )
else if (Token::Match(tok2->next(), "%type% %type% %var% [ %num% ] ;"))
ivar = 3;
else if ( Token::Match(tok2->next(), "%type% * %var% [ %num% ] ;") )
else if (Token::Match(tok2->next(), "%type% * %var% [ %num% ] ;"))
ivar = 3;
else if ( Token::Match(tok2->next(), "%type% %type% * %var% [ %num% ] ;") )
else if (Token::Match(tok2->next(), "%type% %type% * %var% [ %num% ] ;"))
ivar = 4;
else
continue;
const char *varname[3] = {0,0,0};
const char *varname[3] = {0, 0, 0};
varname[1] = tok2->strAt(ivar);
int arrsize = atoi(tok2->strAt(ivar+2));
int arrsize = atoi(tok2->strAt(ivar + 2));
int total_size = arrsize * _tokenizer->SizeOfType(tok2->next()->aaaa());
if (total_size == 0)
continue;
// Class member variable => Check functions
if ( tok->str() == "class" )
if (tok->str() == "class")
{
std::string func_pattern(structname + " :: %var% (");
const Token *tok3 = Token::findmatch(_tokenizer->tokens(), func_pattern.c_str());
while ( tok3 )
while (tok3)
{
for ( const Token *tok4 = tok3; tok4; tok4 = tok4->next() )
for (const Token *tok4 = tok3; tok4; tok4 = tok4->next())
{
if ( Token::Match(tok4, "[;{}]") )
if (Token::Match(tok4, "[;{}]"))
break;
if ( Token::simpleMatch(tok4, ") {") )
if (Token::simpleMatch(tok4, ") {"))
{
const char *names[2] = {varname[1], 0};
CheckBufferOverrun_CheckScope(tok4->tokAt(2), names, arrsize, total_size, 0);
@ -469,17 +469,17 @@ void CheckBufferOverrunClass::CheckBufferOverrun_StructVariable()
}
}
for ( const Token *tok3 = _tokenizer->tokens(); tok3; tok3 = tok3->next() )
for (const Token *tok3 = _tokenizer->tokens(); tok3; tok3 = tok3->next())
{
if ( tok3->str() != structname )
if (tok3->str() != structname)
continue;
// Declare variable: Fred fred1;
if ( Token::Match( tok3->next(), "%var% ;" ) )
if (Token::Match(tok3->next(), "%var% ;"))
varname[0] = tok3->strAt(1);
// Declare pointer: Fred *fred1
else if ( Token::Match(tok3->next(), "* %var% [,);=]") )
else if (Token::Match(tok3->next(), "* %var% [,);=]"))
varname[0] = tok3->strAt(2);
else
@ -488,21 +488,21 @@ void CheckBufferOverrunClass::CheckBufferOverrun_StructVariable()
// Goto end of statement.
const Token *CheckTok = NULL;
while ( tok3 )
while (tok3)
{
// End of statement.
if ( tok3->str() == ";" )
if (tok3->str() == ";")
{
CheckTok = tok3;
break;
}
// End of function declaration..
if ( Token::simpleMatch(tok3, ") ;") )
if (Token::simpleMatch(tok3, ") ;"))
break;
// Function implementation..
if ( Token::simpleMatch(tok3, ") {") )
if (Token::simpleMatch(tok3, ") {"))
{
CheckTok = tok3->tokAt(2);
break;
@ -511,10 +511,10 @@ void CheckBufferOverrunClass::CheckBufferOverrun_StructVariable()
tok3 = tok3->next();
}
if ( !tok3 )
if (!tok3)
break;
if ( !CheckTok )
if (!CheckTok)
continue;
// Check variable usage..

View File

@ -28,7 +28,7 @@
class CheckBufferOverrunClass
{
public:
CheckBufferOverrunClass( const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger );
CheckBufferOverrunClass(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger);
~CheckBufferOverrunClass();
// Buffer overrun..
@ -40,7 +40,7 @@ public:
private:
void CheckBufferOverrun_StructVariable();
void CheckBufferOverrun_LocalVariable();
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 char *varname[], const int size, const int total_size, unsigned int varid);
void ReportError(const Token *tok, const char errmsg[]);
const Tokenizer *_tokenizer;

View File

@ -33,7 +33,7 @@
#endif
//---------------------------------------------------------------------------
CheckClass::CheckClass( const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger )
CheckClass::CheckClass(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger)
{
_tokenizer = tokenizer;
_settings = settings;
@ -66,14 +66,14 @@ struct CheckClass::VAR *CheckClass::ClassChecking_GetVarList(const Token *tok1)
--indentlevel;
}
if ( indentlevel != 1 )
if (indentlevel != 1)
continue;
// "private:" "public:" "protected:" etc
bool b = bool((*tok->strAt(0) != ':') && strchr(tok->strAt(0), ':') != 0);
// Search for start of statement..
if ( ! Token::Match(tok, "[;{}]") && ! b )
if (! Token::Match(tok, "[;{}]") && ! b)
continue;
// This is the start of a statement
@ -81,14 +81,14 @@ struct CheckClass::VAR *CheckClass::ClassChecking_GetVarList(const Token *tok1)
const char *varname = 0;
// Is it a variable declaration?
if ( Token::Match(next,"%type% %var% ;") )
if (Token::Match(next, "%type% %var% ;"))
{
if ( next->isStandardType() )
if (next->isStandardType())
varname = next->strAt(1);
}
// Pointer?
else if ( Token::Match(next, "%type% * %var% ;") )
else if (Token::Match(next, "%type% * %var% ;"))
{
varname = next->strAt(2);
}
@ -109,9 +109,9 @@ struct CheckClass::VAR *CheckClass::ClassChecking_GetVarList(const Token *tok1)
}
//---------------------------------------------------------------------------
const Token * CheckClass::FindClassFunction( const Token *tok, const char classname[], const char funcname[], int &indentlevel )
const Token * CheckClass::FindClassFunction(const Token *tok, const char classname[], const char funcname[], int &indentlevel)
{
if ( indentlevel < 0 || tok == NULL )
if (indentlevel < 0 || tok == NULL)
return NULL;
std::ostringstream classPattern;
@ -123,66 +123,66 @@ const Token * CheckClass::FindClassFunction( const Token *tok, const char classn
std::ostringstream externalPattern;
externalPattern << classname << " :: " << funcname << " (";
for ( ;tok; tok = tok->next() )
for (;tok; tok = tok->next())
{
if ( indentlevel == 0 && Token::Match(tok, classPattern.str().c_str()) )
if (indentlevel == 0 && Token::Match(tok, classPattern.str().c_str()))
{
while ( tok && tok->str() != "{" )
while (tok && tok->str() != "{")
tok = tok->next();
if ( tok )
if (tok)
tok = tok->next();
if ( ! tok )
if (! tok)
break;
indentlevel = 1;
}
if ( tok->str() == "{" )
if (tok->str() == "{")
{
// If indentlevel==0 don't go to indentlevel 1. Skip the block.
if ( indentlevel > 0 )
if (indentlevel > 0)
++indentlevel;
else
{
for ( ; tok; tok = tok->next() )
for (; tok; tok = tok->next())
{
if ( tok->str() == "{" )
if (tok->str() == "{")
++indentlevel;
else if ( tok->str() == "}" )
else if (tok->str() == "}")
{
--indentlevel;
if ( indentlevel <= 0 )
if (indentlevel <= 0)
break;
}
}
if ( tok == NULL )
if (tok == NULL)
return NULL;
continue;
}
}
if ( tok->str() == "}" )
if (tok->str() == "}")
{
--indentlevel;
if ( indentlevel < 0 )
if (indentlevel < 0)
return NULL;
}
if ( indentlevel == 1 )
if (indentlevel == 1)
{
// Member function implemented in the class declaration?
if (tok->str()!="~" && Token::Match(tok->next(), internalPattern.str().c_str()))
if (tok->str() != "~" && Token::Match(tok->next(), internalPattern.str().c_str()))
{
const Token *tok2 = tok;
while ( tok2 && tok2->str() != "{" && tok2->str() != ";" )
while (tok2 && tok2->str() != "{" && tok2->str() != ";")
tok2 = tok2->next();
if ( tok2 && tok2->str() == "{" )
if (tok2 && tok2->str() == "{")
return tok->next();
}
}
else if ( indentlevel == 0 && Token::Match(tok, externalPattern.str().c_str()) )
else if (indentlevel == 0 && Token::Match(tok, externalPattern.str().c_str()))
{
return tok;
}
@ -197,7 +197,7 @@ void CheckClass::InitVar(struct VAR *varlist, const char varname[])
{
for (struct VAR *var = varlist; var; var = var->next)
{
if ( strcmp(var->name, varname) == 0 )
if (strcmp(var->name, varname) == 0)
{
var->init = true;
break;
@ -218,11 +218,11 @@ void CheckClass::ClassChecking_VarList_Initialize(const Token *tok1, const Token
// Class constructor.. initializing variables like this
// clKalle::clKalle() : var(value) { }
if (indentlevel==0)
if (indentlevel == 0)
{
if (Assign && Token::Match(ftok, "%var% ("))
{
InitVar( varlist, ftok->aaaa() );
InitVar(varlist, ftok->aaaa());
}
Assign |= (ftok->str() == ":");
@ -242,15 +242,15 @@ void CheckClass::ClassChecking_VarList_Initialize(const Token *tok1, const Token
--indentlevel;
}
if ( indentlevel < 1 )
if (indentlevel < 1)
continue;
// Before a new statement there is "[{};)=]" or "else"
if ( ! Token::Match(ftok, "[{};)=]") && ftok->str() != "else" )
if (! Token::Match(ftok, "[{};)=]") && ftok->str() != "else")
continue;
// Using the operator= function to initialize all variables..
if ( Token::simpleMatch(ftok->next(), "* this = ") )
if (Token::simpleMatch(ftok->next(), "* this = "))
{
for (struct VAR *var = varlist; var; var = var->next)
var->init = true;
@ -264,11 +264,11 @@ void CheckClass::ClassChecking_VarList_Initialize(const Token *tok1, const Token
ftok = ftok->next();
// Skip "this->"
if ( Token::simpleMatch(ftok, "this .") )
if (Token::simpleMatch(ftok, "this ."))
ftok = ftok->tokAt(2);
// Clearing all variables..
if (Token::simpleMatch(ftok,"memset ( this ,"))
if (Token::simpleMatch(ftok, "memset ( this ,"))
{
for (struct VAR *var = varlist; var; var = var->next)
var->init = true;
@ -279,11 +279,11 @@ void CheckClass::ClassChecking_VarList_Initialize(const Token *tok1, const Token
else if (Token::Match(ftok, "%var% ("))
{
// No recursive calls!
if ( std::find(callstack.begin(),callstack.end(),ftok->str()) == callstack.end() )
if (std::find(callstack.begin(), callstack.end(), ftok->str()) == callstack.end())
{
callstack.push_back( ftok->str() );
callstack.push_back(ftok->str());
int i = 0;
const Token *ftok2 = FindClassFunction( tok1, classname, ftok->aaaa(), i );
const Token *ftok2 = FindClassFunction(tok1, classname, ftok->aaaa(), i);
ClassChecking_VarList_Initialize(tok1, ftok2, varlist, classname, callstack);
}
}
@ -291,13 +291,13 @@ void CheckClass::ClassChecking_VarList_Initialize(const Token *tok1, const Token
// Assignment of member variable?
else if (Token::Match(ftok, "%var% ="))
{
InitVar( varlist, ftok->aaaa() );
InitVar(varlist, ftok->aaaa());
}
// The functions 'clear' and 'Clear' are supposed to initialize variable.
if (Token::Match(ftok,"%var% . clear|Clear ("))
if (Token::Match(ftok, "%var% . clear|Clear ("))
{
InitVar( varlist, ftok->aaaa() );
InitVar(varlist, ftok->aaaa());
}
}
}
@ -316,26 +316,26 @@ void CheckClass::constructors()
const char pattern_class[] = "class %var% {";
// Locate class
const Token *tok1 = Token::findmatch( _tokenizer->tokens(), pattern_class );
const Token *tok1 = Token::findmatch(_tokenizer->tokens(), pattern_class);
while (tok1)
{
const char *className[2];
className[0] = tok1->strAt( 1 );
className[0] = tok1->strAt(1);
className[1] = 0;
const Token *classNameToken = tok1->tokAt( 1 );
const Token *classNameToken = tok1->tokAt(1);
// TODO: handling of private constructors should be improved.
bool hasPrivateConstructor = false;
{
int indentlevel = 0;
bool isPrivate = true;
for ( const Token *tok = tok1; tok; tok = tok->next() )
for (const Token *tok = tok1; tok; tok = tok->next())
{
// Indentation
if ( tok->str() == "{" )
if (tok->str() == "{")
++indentlevel;
else if ( tok->str() == "}" )
else if (tok->str() == "}")
{
--indentlevel;
if (indentlevel <= 0)
@ -343,16 +343,16 @@ void CheckClass::constructors()
}
// Parse class contents (indentlevel == 1)..
if ( indentlevel == 1 )
if (indentlevel == 1)
{
// What section are we in.. private/non-private
if ( tok->str() == "private:" )
if (tok->str() == "private:")
isPrivate = true;
else if ( tok->str() == "protected:" || tok->str() == "public:" )
else if (tok->str() == "protected:" || tok->str() == "public:")
isPrivate = false;
// Is there a private constructor?
else if ( isPrivate && Token::simpleMatch(tok, classNameToken->str() + " (") )
else if (isPrivate && Token::simpleMatch(tok, (classNameToken->str() + " (").c_str()))
{
hasPrivateConstructor = true;
break;
@ -361,29 +361,29 @@ void CheckClass::constructors()
}
}
if ( hasPrivateConstructor )
if (hasPrivateConstructor)
{
// TODO: Handle private constructors.
// Right now to avoid false positives I just bail out
tok1 = Token::findmatch( tok1->next(), pattern_class );
tok1 = Token::findmatch(tok1->next(), pattern_class);
continue;
}
// Are there a class constructor?
std::string tempPattern = "%any% " + classNameToken->str() + " (";
const Token *constructor_token = Token::findmatch( tok1, tempPattern.c_str() );
while ( Token::Match( constructor_token, "~" ) )
constructor_token = Token::findmatch( constructor_token->next(), tempPattern.c_str() );
const Token *constructor_token = Token::findmatch(tok1, tempPattern.c_str());
while (Token::Match(constructor_token, "~"))
constructor_token = Token::findmatch(constructor_token->next(), tempPattern.c_str());
// There are no constructor.
if ( ! constructor_token )
if (! constructor_token)
{
// If "--style" has been given, give a warning
if ( _settings._checkCodingStyle )
if (_settings._checkCodingStyle)
{
// If the class has member variables there should be an constructor
struct VAR *varlist = ClassChecking_GetVarList(tok1);
if ( varlist )
if (varlist)
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok1);
@ -399,7 +399,7 @@ void CheckClass::constructors()
}
}
tok1 = Token::findmatch( tok1->next(), pattern_class );
tok1 = Token::findmatch(tok1->next(), pattern_class);
continue;
}
@ -407,10 +407,10 @@ void CheckClass::constructors()
struct VAR *varlist = ClassChecking_GetVarList(tok1);
// Check constructors
CheckConstructors( tok1, varlist, className[0] );
CheckConstructors(tok1, varlist, className[0]);
// Check assignment operators
CheckConstructors( tok1, varlist, "operator =" );
CheckConstructors(tok1, varlist, "operator =");
// Delete the varlist..
while (varlist)
@ -420,7 +420,7 @@ void CheckClass::constructors()
varlist = nextvar;
}
tok1 = Token::findmatch( tok1->next(), pattern_class );
tok1 = Token::findmatch(tok1->next(), pattern_class);
}
}
@ -429,15 +429,15 @@ void CheckClass::CheckConstructors(const Token *tok1, struct VAR *varlist, const
const char * const className = tok1->strAt(1);
int indentlevel = 0;
const Token *constructor_token = FindClassFunction( tok1, className, funcname, indentlevel );
const Token *constructor_token = FindClassFunction(tok1, className, funcname, indentlevel);
std::list<std::string> callstack;
ClassChecking_VarList_Initialize(tok1, constructor_token, varlist, className, callstack);
while ( constructor_token )
while (constructor_token)
{
// Check if any variables are uninitialized
for (struct VAR *var = varlist; var; var = var->next)
{
if ( var->init )
if (var->init)
continue;
// Is it a static member variable?
@ -453,10 +453,10 @@ void CheckClass::CheckConstructors(const Token *tok1, struct VAR *varlist, const
_errorLogger->reportErr(ostr.str());
}
for ( struct VAR *var = varlist; var; var = var->next )
for (struct VAR *var = varlist; var; var = var->next)
var->init = false;
constructor_token = FindClassFunction( constructor_token->next(), className, funcname, indentlevel );
constructor_token = FindClassFunction(constructor_token->next(), className, funcname, indentlevel);
callstack.clear();
ClassChecking_VarList_Initialize(tok1, constructor_token, varlist, className, callstack);
}
@ -486,7 +486,7 @@ void CheckClass::privateFunctions()
unsigned int indent_level = 0;
for (const Token *tok = tok1; tok; tok = tok->next())
{
if (Token::Match(tok,"friend %var%"))
if (Token::Match(tok, "friend %var%"))
{
// Todo: Handle friend classes
FuncList.clear();
@ -509,11 +509,11 @@ void CheckClass::privateFunctions()
priv = false;
else if (priv && indent_level == 1)
{
if ( Token::Match(tok, "typedef %type% (") )
if (Token::Match(tok, "typedef %type% ("))
tok = tok->tokAt(2);
if (Token::Match(tok, "%var% (") &&
!Token::Match(tok,classname.c_str()))
!Token::Match(tok, classname.c_str()))
{
FuncList.push_back(tok->str());
}
@ -526,7 +526,7 @@ void CheckClass::privateFunctions()
const Token *ftok = _tokenizer->tokens();
while (ftok)
{
ftok = Token::findmatch(ftok,pattern_function.c_str());
ftok = Token::findmatch(ftok, pattern_function.c_str());
int numpar = 0;
while (ftok && !Token::Match(ftok, "[;{]"))
{
@ -551,11 +551,11 @@ void CheckClass::privateFunctions()
++indent_level;
if (ftok->str() == "}")
{
if (indent_level<=1)
if (indent_level <= 1)
break;
--indent_level;
}
if (Token::Match( ftok->next(), "(") )
if (Token::Match(ftok->next(), "("))
FuncList.remove(ftok->str());
ftok = ftok->next();
}
@ -589,7 +589,7 @@ void CheckClass::noMemset()
// Locate all 'memset' tokens..
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
if (!Token::Match(tok,"memset|memcpy|memmove"))
if (!Token::Match(tok, "memset|memcpy|memmove"))
continue;
// Todo: Handle memcpy and memmove
@ -611,7 +611,7 @@ void CheckClass::noMemset()
// Warn if type is a class..
const std::string pattern1(std::string("class ") + type);
if (Token::findmatch(_tokenizer->tokens(),pattern1.c_str()))
if (Token::findmatch(_tokenizer->tokens(), pattern1.c_str()))
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok) << ": Using '" << tok->str() << "' on class.";
@ -674,17 +674,17 @@ void CheckClass::virtualDestructor()
{
std::ostringstream destructorPattern;
destructorPattern << "~ " << derived->strAt(1) << " ( ) {";
const Token *derived_destructor = Token::findmatch( _tokenizer->tokens(), destructorPattern.str().c_str() );
const Token *derived_destructor = Token::findmatch(_tokenizer->tokens(), destructorPattern.str().c_str());
// No destructor..
if ( ! derived_destructor )
if (! derived_destructor)
{
derived = derived->next();
continue;
}
// Empty destructor..
if ( Token::Match(derived_destructor, "~ %var% ( ) { }") )
if (Token::Match(derived_destructor, "~ %var% ( ) { }"))
{
derived = derived->next();
continue;
@ -695,12 +695,12 @@ void CheckClass::virtualDestructor()
// Iterate through each base class...
derived = derived->tokAt(3);
while ( Token::Match(derived, "%var%") )
while (Token::Match(derived, "%var%"))
{
bool isPublic = Token::Match(derived, "public");
// What kind of inheritance is it.. public|protected|private
if ( Token::Match( derived, "public|protected|private" ) )
if (Token::Match(derived, "public|protected|private"))
derived = derived->next();
// Name of base class..
@ -710,27 +710,27 @@ void CheckClass::virtualDestructor()
// Update derived so it's ready for the next loop.
derived = derived->next();
if ( Token::Match(derived, ",") )
if (Token::Match(derived, ","))
derived = derived->next();
// If not public inheritance, skip checking of this base class..
if ( ! isPublic )
if (! isPublic)
continue;
// 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[0] + " (").c_str());
while (Token::Match(base, "::"))
base = Token::findmatch(base->next(), (std::string( "%any% ~ " ) + baseName[0] + +" (").c_str());
base = Token::findmatch(base->next(), (std::string("%any% ~ ") + baseName[0] + + " (").c_str());
while (Token::Match(base, "%var%") && !Token::Match(base, "virtual"))
base = base->previous();
// Check that there is a destructor..
if ( ! base )
if (! base)
{
// Is the class declaration available?
base = Token::findmatch(_tokenizer->tokens(), (std::string( "class ")+baseName[0]+" :|{").c_str());
if ( base )
base = Token::findmatch(_tokenizer->tokens(), (std::string("class ") + baseName[0] + " :|{").c_str());
if (base)
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(base) << ": Class " << baseName[0] << " which is inherited by class " << derivedClass->str() << " does not have a virtual destructor";
@ -739,7 +739,7 @@ void CheckClass::virtualDestructor()
}
// There is a destructor. Check that it's virtual..
else if ( base->str() != "virtual" )
else if (base->str() != "virtual")
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(base) << ": Class " << baseName[0] << " which is inherited by class " << derivedClass->str() << " does not have a virtual destructor";

View File

@ -28,7 +28,7 @@
class CheckClass
{
public:
CheckClass( const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger );
CheckClass(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger);
~CheckClass();
void constructors();
@ -52,7 +52,7 @@ private:
void ClassChecking_VarList_Initialize(const Token *tok1, const Token *ftok, struct VAR *varlist, const char classname[], std::list<std::string> &callstack);
void InitVar(struct VAR *varlist, const char varname[]);
const Token *FindClassFunction( const Token *tok, const char classname[], const char funcname[], int &indentlevel );
const Token *FindClassFunction(const Token *tok, const char classname[], const char funcname[], int &indentlevel);
struct VAR *ClassChecking_GetVarList(const Token *tok1);
// Check constructors for a specified class

View File

@ -30,7 +30,7 @@
// FUNCTION USAGE - Check for unused functions etc
//---------------------------------------------------------------------------
CheckFunctionUsage::CheckFunctionUsage( ErrorLogger *errorLogger )
CheckFunctionUsage::CheckFunctionUsage(ErrorLogger *errorLogger)
{
_errorLogger = errorLogger;
}
@ -40,42 +40,42 @@ CheckFunctionUsage::~CheckFunctionUsage()
}
void CheckFunctionUsage::setErrorLogger( ErrorLogger *errorLogger )
void CheckFunctionUsage::setErrorLogger(ErrorLogger *errorLogger)
{
_errorLogger = errorLogger;
}
void CheckFunctionUsage::parseTokens( const Tokenizer &tokenizer )
void CheckFunctionUsage::parseTokens(const Tokenizer &tokenizer)
{
// Function declarations..
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)
continue;
const Token *funcname = 0;
if ( Token::Match( tok, "%type% %var% (" ) )
if (Token::Match(tok, "%type% %var% ("))
funcname = tok->tokAt(1);
else if ( Token::Match(tok, "%type% * %var% (") )
else if (Token::Match(tok, "%type% * %var% ("))
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)))
funcname = tok->tokAt(2);
// Check that ") {" is found..
for (const Token *tok2 = funcname; tok2; tok2 = tok2->next())
{
if ( Token::Match(tok2, ")") )
if (Token::Match(tok2, ")"))
{
if ( ! Token::Match(tok2, ") {") && ! Token::Match(tok2, ") const {") )
if (! Token::Match(tok2, ") {") && ! Token::Match(tok2, ") const {"))
funcname = NULL;
break;
}
}
if ( funcname )
if (funcname)
{
FunctionUsage &func = _functions[ funcname->str() ];
FunctionUsage &func = _functions[ funcname->str()];
// No filename set yet..
if (func.filename.empty())
@ -91,25 +91,25 @@ void CheckFunctionUsage::parseTokens( const Tokenizer &tokenizer )
}
// Function usage..
for ( const Token *tok = tokenizer.tokens(); tok; tok = tok->next() )
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
{
const Token *funcname = 0;
if ( Token::Match( tok, "[;{}.,()[=+-/&|!?:] %var% [(),;:}]" ) ||
Token::Match(tok, ":: %var% (") ||
Token::Match(tok, "|= %var% (") ||
Token::Match(tok, "&= %var% (") ||
Token::Match(tok, "&& %var% (") ||
Token::Match(tok, "|| %var% (") ||
Token::Match(tok, "else %var% (") ||
Token::Match(tok, "return %var% (") )
if (Token::Match(tok, "[;{}.,()[=+-/&|!?:] %var% [(),;:}]") ||
Token::Match(tok, ":: %var% (") ||
Token::Match(tok, "|= %var% (") ||
Token::Match(tok, "&= %var% (") ||
Token::Match(tok, "&& %var% (") ||
Token::Match(tok, "|| %var% (") ||
Token::Match(tok, "else %var% (") ||
Token::Match(tok, "return %var% ("))
funcname = tok->next();
// funcname ( => Assert that the end paranthesis isn't followed by {
if ( Token::Match(funcname, "%var% (") )
if (Token::Match(funcname, "%var% ("))
{
int parlevel = 0;
for ( const Token *tok2 = funcname; tok2; tok2 = tok2->next() )
for (const Token *tok2 = funcname; tok2; tok2 = tok2->next())
{
if (tok2->str() == "(")
++parlevel;
@ -119,17 +119,17 @@ void CheckFunctionUsage::parseTokens( const Tokenizer &tokenizer )
--parlevel;
if (parlevel == 0 && (Token::Match(tok2, ") {") || Token::Match(tok2, ") const")))
funcname = NULL;
if ( parlevel <= 0 )
if (parlevel <= 0)
break;
}
}
}
if ( funcname )
if (funcname)
{
FunctionUsage &func = _functions[ funcname->str() ];
FunctionUsage &func = _functions[ funcname->str()];
if ( func.filename.empty() || func.filename == "+" )
if (func.filename.empty() || func.filename == "+")
func.usedOtherFile = true;
else
@ -143,20 +143,20 @@ void CheckFunctionUsage::parseTokens( const Tokenizer &tokenizer )
void CheckFunctionUsage::check()
{
for ( std::map<std::string, FunctionUsage>::const_iterator it = _functions.begin(); it != _functions.end(); ++it )
for (std::map<std::string, FunctionUsage>::const_iterator it = _functions.begin(); it != _functions.end(); ++it)
{
const FunctionUsage &func = it->second;
if ( func.usedOtherFile || func.filename.empty() )
if (func.usedOtherFile || func.filename.empty())
continue;
if ( ! func.usedSameFile )
if (! func.usedSameFile)
{
std::ostringstream errmsg;
if ( func.filename != "+" )
if (func.filename != "+")
errmsg << "[" << func.filename << "] ";
errmsg << "The function '" << it->first << "' is never used.";
_errorLogger->reportErr( errmsg.str() );
_errorLogger->reportErr(errmsg.str());
}
else if ( ! func.usedOtherFile )
else if (! func.usedOtherFile)
{
/* TODO - add error message "function is only used in <file> it can be static"
std::ostringstream errmsg;

View File

@ -28,7 +28,7 @@
class CheckFunctionUsage
{
public:
CheckFunctionUsage( ErrorLogger *errorLogger = 0 );
CheckFunctionUsage(ErrorLogger *errorLogger = 0);
~CheckFunctionUsage();
/**
@ -36,12 +36,12 @@ public:
* errorlogger.
* @param errorLogger The errorlogger to be used.
*/
void setErrorLogger( ErrorLogger *errorLogger );
void setErrorLogger(ErrorLogger *errorLogger);
// Parse current tokens and determine..
// * Check what functions are used
// * What functions are declared
void parseTokens( const Tokenizer &tokenizer );
void parseTokens(const Tokenizer &tokenizer);
void check();

View File

@ -35,7 +35,7 @@
// HEADERS - No implementation in a header
//---------------------------------------------------------------------------
CheckHeaders::CheckHeaders( const Tokenizer *tokenizer, ErrorLogger *errorLogger )
CheckHeaders::CheckHeaders(const Tokenizer *tokenizer, ErrorLogger *errorLogger)
{
_tokenizer = tokenizer;
_errorLogger = errorLogger;
@ -48,7 +48,7 @@ CheckHeaders::~CheckHeaders()
void CheckHeaders::WarningHeaderWithImplementation()
{
for ( const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
// Only interested in included file
if (tok->fileIndex() == 0)
@ -62,7 +62,7 @@ void CheckHeaders::WarningHeaderWithImplementation()
// Goto next file..
unsigned int fileindex = tok->fileIndex();
while ( tok->next() && tok->fileIndex() == fileindex )
while (tok->next() && tok->fileIndex() == fileindex)
tok = tok->next();
}
}
@ -83,7 +83,7 @@ void CheckHeaders::WarningHeaderWithImplementation()
void CheckHeaders::WarningIncludeHeader()
{
// Including..
for ( const Token *includetok = _tokenizer->tokens(); includetok; includetok = includetok->next())
for (const Token *includetok = _tokenizer->tokens(); includetok; includetok = includetok->next())
{
if (includetok->str() != "#include")
continue;
@ -93,7 +93,7 @@ void CheckHeaders::WarningIncludeHeader()
const char *includefile = includetok->next()->aaaa();
while (hfile < _tokenizer->getFiles()->size())
{
if ( Tokenizer::SameFileName( _tokenizer->getFiles()->at(hfile).c_str(), includefile ) )
if (Tokenizer::SameFileName(_tokenizer->getFiles()->at(hfile).c_str(), includefile))
break;
++hfile;
}
@ -112,9 +112,9 @@ void CheckHeaders::WarningIncludeHeader()
// Extract classes and names in the header..
int indentlevel = 0;
for ( const Token *tok1 = _tokenizer->tokens(); tok1; tok1 = tok1->next() )
for (const Token *tok1 = _tokenizer->tokens(); tok1; tok1 = tok1->next())
{
if ( tok1->fileIndex() != hfile )
if (tok1->fileIndex() != hfile)
continue;
// I'm only interested in stuff that is declared at indentlevel 0
@ -129,7 +129,7 @@ void CheckHeaders::WarningIncludeHeader()
// Class or namespace declaration..
// --------------------------------------
if (Token::Match(tok1,"class %var% {") || Token::Match(tok1,"class %var% :") || Token::Match(tok1,"namespace %var% {"))
if (Token::Match(tok1, "class %var% {") || Token::Match(tok1, "class %var% :") || Token::Match(tok1, "namespace %var% {"))
classlist.push_back(tok1->strAt(1));
// Variable declaration..
@ -151,9 +151,9 @@ void CheckHeaders::WarningIncludeHeader()
else if (tok1->str() == "enum")
{
tok1 = tok1->next();
while ( ! Token::Match( tok1, "; %any%" ) )
while (! Token::Match(tok1, "; %any%"))
{
if ( tok1->isName() )
if (tok1->isName())
namelist.push_back(tok1->str());
tok1 = tok1->next();
}
@ -161,39 +161,39 @@ void CheckHeaders::WarningIncludeHeader()
// function..
// --------------------------------------
else if (Token::Match(tok1,"%type% %var% ("))
else if (Token::Match(tok1, "%type% %var% ("))
namelist.push_back(tok1->strAt(1));
else if (Token::Match(tok1,"%type% * %var% ("))
else if (Token::Match(tok1, "%type% * %var% ("))
namelist.push_back(tok1->strAt(2));
else if (Token::Match(tok1,"const %type% %var% ("))
else if (Token::Match(tok1, "const %type% %var% ("))
namelist.push_back(tok1->strAt(2));
else if (Token::Match(tok1,"const %type% * %var% ("))
else if (Token::Match(tok1, "const %type% * %var% ("))
namelist.push_back(tok1->strAt(3));
// typedef..
// --------------------------------------
else if (tok1->str() == "typedef")
{
if (strcmp(tok1->strAt(1),"enum")==0)
if (strcmp(tok1->strAt(1), "enum") == 0)
continue;
int parlevel = 0;
while (tok1->next())
{
if ( Token::Match(tok1, "[({]") )
if (Token::Match(tok1, "[({]"))
++parlevel;
else if ( Token::Match(tok1, "[)}]") )
else if (Token::Match(tok1, "[)}]"))
--parlevel;
else if (parlevel == 0)
{
if ( tok1->str() == ";" )
if (tok1->str() == ";")
break;
if ( Token::Match(tok1, "%var% ;") )
if (Token::Match(tok1, "%var% ;"))
namelist.push_back(tok1->str());
}
@ -206,32 +206,32 @@ void CheckHeaders::WarningIncludeHeader()
// Check if the extracted names are used...
bool Needed = false;
bool NeedDeclaration = false;
for ( const Token *tok1 = _tokenizer->tokens(); tok1; tok1 = tok1->next())
for (const Token *tok1 = _tokenizer->tokens(); tok1; tok1 = tok1->next())
{
if (tok1->fileIndex() != includetok->fileIndex())
continue;
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);
if (std::find(classlist.begin(),classlist.end(),classname)!=classlist.end())
std::string classname = tok1->strAt((strcmp(tok1->strAt(2), "{")) ? 2 : 1);
if (std::find(classlist.begin(), classlist.end(), classname) != classlist.end())
{
Needed = true;
break;
}
}
if ( ! tok1->isName() )
if (! tok1->isName())
continue;
if (std::find(namelist.begin(),namelist.end(),tok1->aaaa() ) != namelist.end())
if (std::find(namelist.begin(), namelist.end(), tok1->aaaa()) != namelist.end())
{
Needed = true;
break;
}
if ( ! NeedDeclaration )
NeedDeclaration = (std::find(classlist.begin(),classlist.end(),tok1->aaaa() ) != classlist.end());
if (! NeedDeclaration)
NeedDeclaration = (std::find(classlist.begin(), classlist.end(), tok1->aaaa()) != classlist.end());
}

View File

@ -28,7 +28,7 @@
class CheckHeaders
{
public:
CheckHeaders( const Tokenizer *tokenizer, ErrorLogger *errorLogger );
CheckHeaders(const Tokenizer *tokenizer, ErrorLogger *errorLogger);
~CheckHeaders();
void WarningHeaderWithImplementation();
void WarningIncludeHeader();

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@
class CheckMemoryLeakClass
{
public:
CheckMemoryLeakClass( const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger );
CheckMemoryLeakClass(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger);
~CheckMemoryLeakClass();
void CheckMemoryLeak();
@ -45,22 +45,22 @@ private:
// Extra allocation..
class AllocFunc
{
public:
const char *funcname;
AllocType alloctype;
public:
const char *funcname;
AllocType alloctype;
AllocFunc(const char f[], AllocType a)
{
funcname = f;
alloctype = a;
}
AllocFunc(const char f[], AllocType a)
{
funcname = f;
alloctype = a;
}
};
void CheckMemoryLeak_ClassMembers_Variable( const std::vector<const char *> &classname, const char varname[] );
void CheckMemoryLeak_ClassMembers_ParseClass( const Token *tok1, std::vector<const char *> &classname );
void CheckMemoryLeak_ClassMembers_Variable(const std::vector<const char *> &classname, const char varname[]);
void CheckMemoryLeak_ClassMembers_ParseClass(const Token *tok1, std::vector<const char *> &classname);
void CheckMemoryLeak_ClassMembers();
void CheckMemoryLeak_InFunction();
void CheckMemoryLeak_CheckScope( const Token *Tok1, const char varname[] );
void CheckMemoryLeak_CheckScope(const Token *Tok1, const char varname[]);
/**
* Simplify code e.g. by replacing empty "{ }" with ";"
@ -90,13 +90,13 @@ private:
Token *getcode(const Token *tok, std::list<const Token *> callstack, const char varname[], AllocType &alloctype, AllocType &dealloctype);
bool notvar(const Token *tok, const char *varnames[]);
void instoken(Token *tok, const char str[]);
void MemoryLeak( const Token *tok, const char varname[], AllocType alloctype );
void MismatchError( const Token *Tok1, const std::list<const Token *> &callstack, const char varname[] );
const char * call_func( const Token *tok, std::list<const Token *> callstack, const char *varnames[], AllocType &alloctype, AllocType &dealloctype );
AllocType GetDeallocationType( const Token *tok, const char *varnames[]);
AllocType GetAllocationType( const Token *tok2 );
AllocType GetReallocationType( const Token *tok2 );
bool isclass( const Token *typestr );
void MemoryLeak(const Token *tok, const char varname[], AllocType alloctype);
void MismatchError(const Token *Tok1, const std::list<const Token *> &callstack, const char varname[]);
const char * call_func(const Token *tok, std::list<const Token *> callstack, const char *varnames[], AllocType &alloctype, AllocType &dealloctype);
AllocType GetDeallocationType(const Token *tok, const char *varnames[]);
AllocType GetAllocationType(const Token *tok2);
AllocType GetReallocationType(const Token *tok2);
bool isclass(const Token *typestr);
const Tokenizer *_tokenizer;
ErrorLogger *_errorLogger;

View File

@ -35,7 +35,7 @@
// Warning on C-Style casts.. p = (kalle *)foo;
//---------------------------------------------------------------------------
CheckOther::CheckOther( const Tokenizer *tokenizer, ErrorLogger *errorLogger )
CheckOther::CheckOther(const Tokenizer *tokenizer, ErrorLogger *errorLogger)
{
_tokenizer = tokenizer;
_errorLogger = errorLogger;
@ -78,65 +78,65 @@ void CheckOther::WarningRedundantCode()
// if (p) delete p
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
if ( tok->str() != "if" )
if (tok->str() != "if")
continue;
const char *varname1 = NULL;
const Token *tok2 = NULL;
if (Token::Match(tok,"if ( %var% )"))
if (Token::Match(tok, "if ( %var% )"))
{
varname1 = tok->strAt( 2);
varname1 = tok->strAt(2);
tok2 = tok->tokAt(4);
}
else if (Token::Match(tok,"if ( %var% != NULL )"))
else if (Token::Match(tok, "if ( %var% != NULL )"))
{
varname1 = tok->strAt( 2);
varname1 = tok->strAt(2);
tok2 = tok->tokAt(6);
}
if (varname1==NULL || tok2==NULL)
if (varname1 == NULL || tok2 == NULL)
continue;
bool err = false;
if ( tok2->str() == "{" )
if (tok2->str() == "{")
{
tok2 = tok2->next();
if (Token::Match(tok2,"delete %var% ; }"))
if (Token::Match(tok2, "delete %var% ; }"))
{
err = (strcmp(tok2->strAt(1),varname1)==0);
err = (strcmp(tok2->strAt(1), varname1) == 0);
}
else if (Token::Match(tok2,"delete [ ] %var% ; }"))
else if (Token::Match(tok2, "delete [ ] %var% ; }"))
{
err = (strcmp(tok2->strAt(1),varname1)==0);
err = (strcmp(tok2->strAt(1), varname1) == 0);
}
else if (Token::Match(tok2,"free ( %var% ) ; }"))
else if (Token::Match(tok2, "free ( %var% ) ; }"))
{
err = (strcmp(tok2->strAt(2),varname1)==0);
err = (strcmp(tok2->strAt(2), varname1) == 0);
}
else if (Token::Match(tok2,"kfree ( %var% ) ; }"))
else if (Token::Match(tok2, "kfree ( %var% ) ; }"))
{
err = (strcmp(tok2->strAt(2),varname1)==0);
err = (strcmp(tok2->strAt(2), varname1) == 0);
}
}
else
{
if (Token::Match(tok2,"delete %var% ;"))
if (Token::Match(tok2, "delete %var% ;"))
{
err = (strcmp(tok2->strAt(1),varname1)==0);
err = (strcmp(tok2->strAt(1), varname1) == 0);
}
else if (Token::Match(tok2,"delete [ ] %var% ;"))
else if (Token::Match(tok2, "delete [ ] %var% ;"))
{
err = (strcmp(tok2->strAt(1),varname1)==0);
err = (strcmp(tok2->strAt(1), varname1) == 0);
}
else if (Token::Match(tok2,"free ( %var% ) ;"))
else if (Token::Match(tok2, "free ( %var% ) ;"))
{
err = (strcmp(tok2->strAt(2),varname1)==0);
err = (strcmp(tok2->strAt(2), varname1) == 0);
}
else if (Token::Match(tok2,"kfree ( %var% ) ;"))
else if (Token::Match(tok2, "kfree ( %var% ) ;"))
{
err = (strcmp(tok2->strAt(2),varname1)==0);
err = (strcmp(tok2->strAt(2), varname1) == 0);
}
}
@ -163,10 +163,10 @@ void CheckOther::redundantCondition2()
"{|{|"
" %var% . remove ( %any% ) ; "
"}|}|";
const Token *tok = Token::findmatch( _tokenizer->tokens(), pattern );
while ( tok )
const Token *tok = Token::findmatch(_tokenizer->tokens(), pattern);
while (tok)
{
bool b = Token::Match( tok->tokAt(15), "{" );
bool b = Token::Match(tok->tokAt(15), "{");
// Get tokens for the fields %var% and %any%
const Token *var1 = tok->tokAt(2);
@ -178,15 +178,15 @@ void CheckOther::redundantCondition2()
// Check if all the "%var%" fields are the same and if all the "%any%" are the same..
if (var1->str() == var2->str() &&
var2->str() == var3->str() &&
any1->str() == any2->str() )
any1->str() == any2->str())
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok)
<< ": Redundant condition found. The remove function in the STL will not do anything if element doesn't exist";
<< ": Redundant condition found. The remove function in the STL will not do anything if element doesn't exist";
_errorLogger->reportErr(errmsg.str());
}
tok = Token::findmatch( tok->next(), pattern );
tok = Token::findmatch(tok->next(), pattern);
}
}
//---------------------------------------------------------------------------
@ -215,9 +215,9 @@ void CheckOther::WarningIf()
else if (tok2->str() == ")")
{
--parlevel;
if ( parlevel <= 0 )
if (parlevel <= 0)
{
if ( Token::Match(tok2, ") ; !!else") )
if (Token::Match(tok2, ") ; !!else"))
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok) << ": Found \"if (condition);\"";
@ -233,35 +233,35 @@ void CheckOther::WarningIf()
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
// Begin statement?
if ( ! Token::Match(tok, "[;{}]") )
if (! Token::Match(tok, "[;{}]"))
continue;
tok = tok->next();
if ( ! tok )
if (! tok)
break;
if (!Token::Match(tok,"%var% = %var% ; if ( %var%"))
if (!Token::Match(tok, "%var% = %var% ; if ( %var%"))
continue;
if ( strcmp(tok->strAt( 9), ")") != 0 )
if (strcmp(tok->strAt(9), ")") != 0)
continue;
// var1 = var2 ; if ( var3 cond var4 )
const char *var1 = tok->strAt( 0);
const char *var2 = tok->strAt( 2);
const char *var3 = tok->strAt( 6);
const char *cond = tok->strAt( 7);
const char *var4 = tok->strAt( 8);
const char *var1 = tok->strAt(0);
const char *var2 = tok->strAt(2);
const char *var3 = tok->strAt(6);
const char *cond = tok->strAt(7);
const char *var4 = tok->strAt(8);
// Check that var3 is equal with either var1 or var2
if (strcmp(var1,var3) && strcmp(var2,var3))
if (strcmp(var1, var3) && strcmp(var2, var3))
continue;
// Check that var4 is equal with either var1 or var2
if (strcmp(var1,var4) && strcmp(var2,var4))
if (strcmp(var1, var4) && strcmp(var2, var4))
continue;
// Check that there is a condition..
const char *p[6] = {"==","<=",">=","!=","<",">"};
const char *p[6] = {"==", "<=", ">=", "!=", "<", ">"};
bool iscond = false;
for (int i = 0; i < 6; i++)
{
@ -296,7 +296,7 @@ void CheckOther::WarningIf()
void CheckOther::InvalidFunctionUsage()
{
for ( const Token *tok = _tokenizer->tokens(); tok; tok = tok->next() )
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
if ((tok->str() != "strtol") && (tok->str() != "strtoul"))
continue;
@ -304,21 +304,21 @@ void CheckOther::InvalidFunctionUsage()
// Locate the third parameter of the function call..
int parlevel = 0;
int param = 1;
for ( const Token *tok2 = tok->next(); tok2; tok2 = tok2->next() )
for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next())
{
if ( Token::Match(tok2, "(") )
if (Token::Match(tok2, "("))
++parlevel;
else if (Token::Match(tok2, ")"))
--parlevel;
else if (parlevel == 1 && Token::Match(tok2, ","))
{
++param;
if (param==3)
if (param == 3)
{
if ( Token::Match(tok2, ", %num% )") )
if (Token::Match(tok2, ", %num% )"))
{
int radix = atoi(tok2->strAt( 1));
if (!(radix==0 || (radix>=2 && radix<=36)))
int radix = atoi(tok2->strAt(1));
if (!(radix == 0 || (radix >= 2 && radix <= 36)))
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok2) << ": Invalid radix in call to strtol or strtoul. Must be 0 or 2-36";
@ -344,7 +344,7 @@ void CheckOther::CheckIfAssignment()
{
if (Token::Match(tok, "if ( %var% = %num% )") ||
Token::Match(tok, "if ( %var% = %str% )") ||
Token::Match(tok, "if ( %var% = %var% )") )
Token::Match(tok, "if ( %var% = %var% )"))
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok) << ": Possible bug. Should it be '==' instead of '='?";
@ -363,26 +363,26 @@ void CheckOther::CheckUnsignedDivision()
{
// Check for "ivar / uvar" and "uvar / ivar"
std::map<std::string, char> varsign;
for ( const Token *tok = _tokenizer->tokens(); tok; tok = tok->next() )
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
if ( Token::Match(tok, "[{};(,] %type% %var% [;=,)]") )
if (Token::Match(tok, "[{};(,] %type% %var% [;=,)]"))
{
const char *type = tok->strAt( 1);
if (strcmp(type,"char")==0 || strcmp(type,"short")==0 || strcmp(type,"int")==0)
const char *type = tok->strAt(1);
if (strcmp(type, "char") == 0 || strcmp(type, "short") == 0 || strcmp(type, "int") == 0)
varsign[tok->strAt(2)] = 's';
}
else if ( Token::Match(tok, "[{};(,] unsigned %type% %var% [;=,)]") )
else if (Token::Match(tok, "[{};(,] unsigned %type% %var% [;=,)]"))
varsign[tok->strAt(3)] = 'u';
else if (!Token::Match(tok,"[).]") && Token::Match(tok->next(), "%var% / %var%"))
else if (!Token::Match(tok, "[).]") && Token::Match(tok->next(), "%var% / %var%"))
{
const char *varname1 = tok->strAt(1);
const char *varname2 = tok->strAt(3);
char sign1 = varsign[varname1];
char sign2 = varsign[varname2];
if ( sign1 && sign2 && sign1 != sign2 )
if (sign1 && sign2 && sign1 != sign2)
{
// One of the operands are signed, the other is unsigned..
std::ostringstream ostr;
@ -391,11 +391,11 @@ void CheckOther::CheckUnsignedDivision()
}
}
else if (!Token::Match(tok,"[).]") && Token::Match(tok->next(), "%var% / - %num%"))
else if (!Token::Match(tok, "[).]") && Token::Match(tok->next(), "%var% / - %num%"))
{
const char *varname1 = tok->strAt(1);
char sign1 = varsign[varname1];
if ( sign1 == 'u' )
if (sign1 == 'u')
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok->next()) << ": Unsigned division. The result will be wrong.";
@ -407,7 +407,7 @@ void CheckOther::CheckUnsignedDivision()
{
const char *varname2 = tok->strAt(4);
char sign2 = varsign[varname2];
if ( sign2 == 'u' )
if (sign2 == 'u')
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok->next()) << ": Unsigned division. The result will be wrong.";
@ -430,26 +430,26 @@ void CheckOther::CheckVariableScope()
// Walk through all tokens..
bool func = false;
int indentlevel = 0;
for ( const Token *tok = _tokenizer->tokens(); tok; tok = tok->next() )
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
// Skip class and struct declarations..
if ( (tok->str() == "class") || (tok->str() == "struct") )
if ((tok->str() == "class") || (tok->str() == "struct"))
{
for (const Token *tok2 = tok; tok2; tok2 = tok2->next())
{
if ( tok2->str() == "{" )
if (tok2->str() == "{")
{
int indentlevel2 = 0;
for (tok = tok2; tok; tok = tok->next())
{
if ( tok->str() == "{" )
if (tok->str() == "{")
{
++indentlevel2;
}
if ( tok->str() == "}" )
if (tok->str() == "}")
{
--indentlevel2;
if ( indentlevel2 <= 0 )
if (indentlevel2 <= 0)
{
tok = tok->next();
break;
@ -463,29 +463,29 @@ void CheckOther::CheckVariableScope()
break;
}
}
if ( ! tok )
if (! tok)
break;
}
if ( tok->str() == "{" )
if (tok->str() == "{")
{
++indentlevel;
}
if ( tok->str() == "}" )
if (tok->str() == "}")
{
--indentlevel;
if ( indentlevel == 0 )
if (indentlevel == 0)
func = false;
}
if ( indentlevel == 0 && Token::Match(tok, ") {") )
if (indentlevel == 0 && Token::Match(tok, ") {"))
{
func = true;
}
if ( indentlevel > 0 && func && Token::Match(tok, "[{};]") )
if (indentlevel > 0 && func && Token::Match(tok, "[{};]"))
{
// First token of statement..
const Token *tok1 = tok->next();
if ( ! tok1 )
if (! tok1)
continue;
if ((tok1->str() == "return") ||
@ -496,9 +496,9 @@ void CheckOther::CheckVariableScope()
// Variable declaration?
if (Token::Match(tok1, "%var% %var% ;") ||
Token::Match(tok1, "%var% %var% =") )
Token::Match(tok1, "%var% %var% ="))
{
CheckVariableScope_LookupVar( tok1, tok1->strAt( 1) );
CheckVariableScope_LookupVar(tok1, tok1->strAt(1));
}
}
}
@ -506,12 +506,12 @@ void CheckOther::CheckVariableScope()
}
//---------------------------------------------------------------------------
void CheckOther::CheckVariableScope_LookupVar( const Token *tok1, const char varname[] )
void CheckOther::CheckVariableScope_LookupVar(const Token *tok1, const char varname[])
{
const Token *tok = tok1;
// Skip the variable declaration..
while (tok && !Token::Match(tok,";"))
while (tok && !Token::Match(tok, ";"))
tok = tok->next();
// Check if the variable is used in this indentlevel..
@ -519,48 +519,48 @@ void CheckOther::CheckVariableScope_LookupVar( const Token *tok1, const char var
int indentlevel = 0;
int parlevel = 0;
bool for_or_while = false;
while ( indentlevel >= 0 && tok )
while (indentlevel >= 0 && tok)
{
if ( tok->str() == "{" )
if (tok->str() == "{")
{
++indentlevel;
}
else if ( tok->str() == "}" )
else if (tok->str() == "}")
{
--indentlevel;
if ( indentlevel == 0 )
if (indentlevel == 0)
{
if ( for_or_while && used )
if (for_or_while && used)
return;
used1 = used;
used = false;
}
}
else if ( tok->str() == "(" )
else if (tok->str() == "(")
{
++parlevel;
}
else if ( tok->str() == ")" )
else if (tok->str() == ")")
{
--parlevel;
}
else if ( tok->str() == varname )
else if (tok->str() == varname)
{
if ( indentlevel == 0 || used1 )
if (indentlevel == 0 || used1)
return;
used = true;
}
else if ( indentlevel==0 )
else if (indentlevel == 0)
{
if ( (tok->str() == "for") || (tok->str() == "while") )
if ((tok->str() == "for") || (tok->str() == "while"))
for_or_while = true;
if ( parlevel == 0 && (tok->str() == ";") )
if (parlevel == 0 && (tok->str() == ";"))
for_or_while = false;
}
@ -570,7 +570,7 @@ void CheckOther::CheckVariableScope_LookupVar( const Token *tok1, const char var
// Warning if "used" is true
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok1) << " The scope of the variable '" << varname << "' can be limited";
_errorLogger->reportErr( errmsg.str() );
_errorLogger->reportErr(errmsg.str());
}
//---------------------------------------------------------------------------
@ -583,22 +583,22 @@ void CheckOther::CheckConstantFunctionParameter()
{
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
if ( Token::Match(tok,"[,(] const std :: %type% %var% [,)]") )
if (Token::Match(tok, "[,(] const std :: %type% %var% [,)]"))
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok) << " " << tok->strAt(5) << " is passed by value, it could be passed by reference/pointer instead";
_errorLogger->reportErr( errmsg.str() );
_errorLogger->reportErr(errmsg.str());
}
else if ( Token::Match(tok,"[,(] const %type% %var% [,)]") )
else if (Token::Match(tok, "[,(] const %type% %var% [,)]"))
{
// Check if type is a struct or class.
const std::string pattern(std::string("class|struct ") + tok->strAt(2));
if ( Token::findmatch(_tokenizer->tokens(), pattern.c_str()) )
if (Token::findmatch(_tokenizer->tokens(), pattern.c_str()))
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok) << " " << tok->strAt(3) << " is passed by value, it could be passed by reference/pointer instead";
_errorLogger->reportErr( errmsg.str() );
_errorLogger->reportErr(errmsg.str());
}
}
}
@ -614,41 +614,41 @@ void CheckOther::CheckStructMemberUsage()
{
const char *structname = 0;
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)
continue;
if ( tok->str() == "}" )
if (tok->str() == "}")
structname = 0;
if ( Token::Match(tok, "struct|union %type% {") )
structname = tok->strAt( 1);
if (Token::Match(tok, "struct|union %type% {"))
structname = tok->strAt(1);
if (structname && Token::Match(tok, "[{;]"))
{
const char *varname = 0;
if (Token::Match(tok->next(), "%type% %var% [;[]"))
varname = tok->strAt( 2 );
varname = tok->strAt(2);
else if (Token::Match(tok->next(), "%type% %type% %var% [;[]"))
varname = tok->strAt( 2 );
varname = tok->strAt(2);
else if (Token::Match(tok->next(), "%type% * %var% [;[]"))
varname = tok->strAt( 3 );
varname = tok->strAt(3);
else if (Token::Match(tok->next(), "%type% %type% * %var% [;[]"))
varname = tok->strAt( 4 );
varname = tok->strAt(4);
else
continue;
const std::string usagePattern( ". " + std::string(varname) );
const std::string usagePattern(". " + std::string(varname));
bool used = false;
for ( const Token *tok2 = _tokenizer->tokens(); tok2; tok2 = tok2->next() )
for (const Token *tok2 = _tokenizer->tokens(); tok2; tok2 = tok2->next())
{
if (Token::simpleMatch(tok2, usagePattern.c_str() ))
if (Token::simpleMatch(tok2, usagePattern.c_str()))
{
used = true;
break;
}
}
if ( ! used )
if (! used)
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok->next()) << ": struct or union member '" << structname << "::" << varname << "' is never used";
@ -671,22 +671,22 @@ void CheckOther::CheckCharVariable()
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
// Declaring the variable..
if ( Token::Match(tok, "[{};(,] char %var% [;=,)]") )
if (Token::Match(tok, "[{};(,] char %var% [;=,)]"))
{
// Set tok to point to the variable name
tok = tok->tokAt( 2 );
tok = tok->tokAt(2);
// Check usage of char variable..
int indentlevel = 0;
for ( const Token *tok2 = tok->next(); tok2; tok2 = tok2->next() )
for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next())
{
if ( tok2->str() == "{" )
if (tok2->str() == "{")
++indentlevel;
else if ( tok2->str() == "}" )
else if (tok2->str() == "}")
{
--indentlevel;
if ( indentlevel <= 0 )
if (indentlevel <= 0)
break;
}
@ -701,7 +701,7 @@ void CheckOther::CheckCharVariable()
std::string tempFirst = "%var% [&|] " + tok->str();
std::string tempSecond = tok->str() + " [&|]";
if ( Token::Match(tok2, tempFirst.c_str()) || Token::Match(tok2, tempSecond.c_str()) )
if (Token::Match(tok2, tempFirst.c_str()) || Token::Match(tok2, tempSecond.c_str()))
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok2) << ": Warning - using char variable in bit operation";
@ -727,24 +727,24 @@ void CheckOther::CheckIncompleteStatement()
{
int parlevel = 0;
for ( const Token *tok = _tokenizer->tokens(); tok; tok = tok->next() )
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
if ( tok->str() == "(" )
if (tok->str() == "(")
++parlevel;
else if ( tok->str() == ")" )
else if (tok->str() == ")")
--parlevel;
if ( parlevel != 0 )
if (parlevel != 0)
continue;
if ( (tok->str() != "#") && Token::Match(tok->next(),"; %str%") && !Token::Match(tok->tokAt(3), ",") )
if ((tok->str() != "#") && Token::Match(tok->next(), "; %str%") && !Token::Match(tok->tokAt(3), ","))
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok->next()) << ": Redundant code: Found a statement that begins with string constant";
_errorLogger->reportErr(errmsg.str());
}
if ( !Token::Match(tok,"#") && Token::Match(tok->next(),"; %num%") && !Token::Match(tok->tokAt(3), ",") )
if (!Token::Match(tok, "#") && Token::Match(tok->next(), "; %num%") && !Token::Match(tok->tokAt(3), ","))
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok->next()) << ": Redundant code: Found a statement that begins with numeric constant";
@ -765,16 +765,16 @@ void CheckOther::CheckIncompleteStatement()
void CheckOther::unreachableCode()
{
const Token *tok = Token::findmatch( _tokenizer->tokens(), "[;{}] return" );
while ( tok )
const Token *tok = Token::findmatch(_tokenizer->tokens(), "[;{}] return");
while (tok)
{
// Goto the 'return' token
tok = tok->next();
// Locate the end of the 'return' statement
while ( tok && ! Token::Match(tok, ";") )
while (tok && ! Token::Match(tok, ";"))
tok = tok->next();
while ( tok && Token::Match(tok->next(), ";") )
while (tok && Token::Match(tok->next(), ";"))
tok = tok->next();
// If there is a statement below the return it is unreachable
@ -786,7 +786,7 @@ void CheckOther::unreachableCode()
}
// Find the next 'return' statement
tok = Token::findmatch( tok, "[;{}] return" );
tok = Token::findmatch(tok, "[;{}] return");
}
}
//---------------------------------------------------------------------------
@ -822,7 +822,7 @@ void CheckOther::functionVariableUsage()
if (!tok1)
return;
while ((tok1 = Token::findmatch( tok1->next(), ") const| {" )) != NULL)
while ((tok1 = Token::findmatch(tok1->next(), ") const| {")) != NULL)
{
// Varname, usage {1=declare, 2=read, 4=write}
std::map<std::string, unsigned int> varUsage;
@ -831,59 +831,59 @@ void CheckOther::functionVariableUsage()
static const unsigned int USAGE_WRITE = 4;
int indentlevel = 0;
for ( const Token *tok = tok1; tok; tok = tok->next() )
for (const Token *tok = tok1; tok; tok = tok->next())
{
if ( tok->str() == "{" )
if (tok->str() == "{")
++indentlevel;
else if ( tok->str() == "}" )
else if (tok->str() == "}")
{
--indentlevel;
if ( indentlevel <= 0 )
if (indentlevel <= 0)
break;
}
else if ( Token::Match(tok, "struct|union|class {") ||
Token::Match(tok, "struct|union|class %type% {") )
else if (Token::Match(tok, "struct|union|class {") ||
Token::Match(tok, "struct|union|class %type% {"))
{
while ( tok && tok->str() != "}" )
while (tok && tok->str() != "}")
tok = tok->next();
if ( tok )
if (tok)
continue;
break;
}
if ( Token::Match(tok, "[;{}] bool|char|short|int|long|float|double %var% ;|=") )
varUsage[ tok->strAt(2) ] = USAGE_DECLARE;
if (Token::Match(tok, "[;{}] bool|char|short|int|long|float|double %var% ;|="))
varUsage[ tok->strAt(2)] = USAGE_DECLARE;
if ( Token::Match(tok, "[;{}] bool|char|short|int|long|float|double * %var% ;|=") )
varUsage[ tok->strAt(3) ] = USAGE_DECLARE;
if (Token::Match(tok, "[;{}] bool|char|short|int|long|float|double * %var% ;|="))
varUsage[ tok->strAt(3)] = USAGE_DECLARE;
if ( Token::Match(tok, "delete|return %var%") )
varUsage[ tok->strAt(1) ] |= USAGE_READ;
if (Token::Match(tok, "delete|return %var%"))
varUsage[ tok->strAt(1)] |= USAGE_READ;
if ( Token::Match(tok, "%var% =") )
varUsage[ tok->str() ] |= USAGE_WRITE;
if (Token::Match(tok, "%var% ="))
varUsage[ tok->str()] |= USAGE_WRITE;
if ( Token::Match(tok, "else %var% =") )
varUsage[ tok->strAt(1) ] |= USAGE_WRITE;
if (Token::Match(tok, "else %var% ="))
varUsage[ tok->strAt(1)] |= USAGE_WRITE;
if ( Token::Match(tok, ">>|& %var%") )
varUsage[ tok->strAt(1) ] |= USAGE_WRITE;
if (Token::Match(tok, ">>|& %var%"))
varUsage[ tok->strAt(1)] |= USAGE_WRITE;
if ((Token::Match(tok,"[(=&!]") || isOp(tok)) && Token::Match(tok->next(), "%var%"))
varUsage[ tok->strAt(1) ] |= USAGE_READ;
if ((Token::Match(tok, "[(=&!]") || isOp(tok)) && Token::Match(tok->next(), "%var%"))
varUsage[ tok->strAt(1)] |= USAGE_READ;
if (Token::Match(tok, "-=|+=|*=|/=|&=|^= %var%") || Token::Match(tok, "|= %var%"))
varUsage[ tok->strAt(1) ] |= USAGE_READ;
varUsage[ tok->strAt(1)] |= USAGE_READ;
if (Token::Match(tok, "%var%") && (tok->next()->str()==")" || isOp(tok->next())))
varUsage[ tok->str() ] |= USAGE_READ;
if (Token::Match(tok, "%var%") && (tok->next()->str() == ")" || isOp(tok->next())))
varUsage[ tok->str()] |= USAGE_READ;
if ( Token::Match(tok, "[(,] %var% [,)]") )
varUsage[ tok->strAt(1) ] |= USAGE_WRITE;
if (Token::Match(tok, "[(,] %var% [,)]"))
varUsage[ tok->strAt(1)] |= USAGE_WRITE;
}
// Check usage of all variables in the current scope..
for ( std::map<std::string, unsigned int>::const_iterator it = varUsage.begin(); it != varUsage.end(); ++it )
for (std::map<std::string, unsigned int>::const_iterator it = varUsage.begin(); it != varUsage.end(); ++it)
{
std::string varname = it->first;
unsigned int usage = it->second;
@ -891,24 +891,24 @@ void CheckOther::functionVariableUsage()
if (!std::isalpha(varname[0]))
continue;
if ( ! ( usage & USAGE_DECLARE ) )
if (!(usage & USAGE_DECLARE))
continue;
if ( usage == USAGE_DECLARE )
if (usage == USAGE_DECLARE)
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok1->next()) << ": Unused variable '" << varname << "'";
_errorLogger->reportErr(errmsg.str());
}
else if ( ! (usage & USAGE_READ) )
else if (!(usage & USAGE_READ))
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok1->next()) << ": Variable '" << varname << "' is assigned a value that is never used";
_errorLogger->reportErr(errmsg.str());
}
else if ( ! (usage & USAGE_WRITE) )
else if (!(usage & USAGE_WRITE))
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok1->next()) << ": Variable '" << varname << "' is not assigned a value";

View File

@ -29,7 +29,7 @@
class CheckOther
{
public:
CheckOther( const Tokenizer *tokenizer, ErrorLogger *errorLogger );
CheckOther(const Tokenizer *tokenizer, ErrorLogger *errorLogger);
~CheckOther();
// Casting
@ -74,7 +74,7 @@ public:
#ifndef UNIT_TESTING
private:
#endif
void CheckVariableScope_LookupVar( const Token *tok1, const char varname[] );
void CheckVariableScope_LookupVar(const Token *tok1, const char varname[]);
// Redundant condition
// if (haystack.find(needle) != haystack.end())

View File

@ -36,7 +36,7 @@
//---------------------------------------------------------------------------
CppCheck::CppCheck( ErrorLogger &errorLogger )
CppCheck::CppCheck(ErrorLogger &errorLogger)
{
_errorLogger = &errorLogger;
}
@ -46,97 +46,97 @@ CppCheck::~CppCheck()
}
void CppCheck::settings( const Settings &settings )
void CppCheck::settings(const Settings &settings)
{
_settings = settings;
}
void CppCheck::addFile( const std::string &path )
void CppCheck::addFile(const std::string &path)
{
_filenames.push_back( path );
_filenames.push_back(path);
}
void CppCheck::addFile( const std::string &path, const std::string &content )
void CppCheck::addFile(const std::string &path, const std::string &content)
{
_filenames.push_back( path );
_filenames.push_back(path);
_fileContents[ path ] = content;
}
std::string CppCheck::parseFromArgs( int argc, const char* const argv[] )
std::string CppCheck::parseFromArgs(int argc, const char* const argv[])
{
std::vector<std::string> pathnames;
for (int i = 1; i < argc; i++)
{
// Flag used for various purposes during debugging
if (strcmp(argv[i],"--debug") == 0)
if (strcmp(argv[i], "--debug") == 0)
_settings._debug = true;
// Show all messages
else if (strcmp(argv[i],"-a") == 0 || strcmp(argv[i],"--all") == 0)
else if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "--all") == 0)
_settings._showAll = true;
// Only print something when there are errors
else if (strcmp(argv[i],"-q")==0 || strcmp(argv[i],"--quiet")==0)
else if (strcmp(argv[i], "-q") == 0 || strcmp(argv[i], "--quiet") == 0)
_settings._errorsOnly = true;
// Checking coding style
else if (strcmp(argv[i],"-s")==0 || strcmp(argv[i],"--style")==0)
else if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--style") == 0)
_settings._checkCodingStyle = true;
// Verbose error messages (configuration info)
else if (strcmp(argv[i],"-v")==0 || strcmp(argv[i],"--verbose")==0)
else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0)
_settings._verbose = true;
// Force checking of files that have "too many" configurations
else if (strcmp(argv[i],"-f")==0 || strcmp(argv[i],"--force")==0)
else if (strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "--force") == 0)
_settings._force = true;
else
pathnames.push_back( argv[i] );
pathnames.push_back(argv[i]);
}
if( pathnames.size() > 0 )
if (pathnames.size() > 0)
{
// Execute RecursiveAddFiles() to each given file parameter
std::vector<std::string>::const_iterator iter;
for(iter=pathnames.begin(); iter!=pathnames.end(); iter++)
FileLister::RecursiveAddFiles( _filenames, iter->c_str(), true );
for (iter = pathnames.begin(); iter != pathnames.end(); iter++)
FileLister::RecursiveAddFiles(_filenames, iter->c_str(), true);
}
if (_filenames.empty())
{
std::ostringstream oss;
oss << "cppcheck 1.27\n"
"\n"
"C/C++ code checking\n"
"\n"
"Syntax:\n"
" cppcheck [--all] [--force] [--quiet] [--style] [--verbose] [file or path1] [file or path]\n"
"\n"
"If path is given instead of filename, *.cpp, *.cxx, *.cc and *.c files are \n"
"checked recursively from given directory.\n\n"
"Options:\n"
" -a, --all Make the checking more sensitive. More bugs are detected,\n"
" but there are also more false positives\n"
" -f, --force Force checking on files that have \"too many\" configurations\n"
" -q, --quiet Only print error messages\n"
" -s, --style Check coding style\n"
" -v, --verbose More detailed error reports\n"
"\n"
"Example usage:\n"
" # Recursively check the current folder. Print the progress on the screen and write errors in a file:\n"
" cppcheck . 2> err.txt\n"
" # Recursively check ../myproject/ and print only most fatal errors:\n"
" cppcheck --quiet ../myproject/\n"
" # Check only files one.cpp and two.cpp and give all information there is:\n"
" cppcheck -v -a -s one.cpp two.cpp\n";
"\n"
"C/C++ code checking\n"
"\n"
"Syntax:\n"
" cppcheck [--all] [--force] [--quiet] [--style] [--verbose] [file or path1] [file or path]\n"
"\n"
"If path is given instead of filename, *.cpp, *.cxx, *.cc and *.c files are \n"
"checked recursively from given directory.\n\n"
"Options:\n"
" -a, --all Make the checking more sensitive. More bugs are detected,\n"
" but there are also more false positives\n"
" -f, --force Force checking on files that have \"too many\" configurations\n"
" -q, --quiet Only print error messages\n"
" -s, --style Check coding style\n"
" -v, --verbose More detailed error reports\n"
"\n"
"Example usage:\n"
" # Recursively check the current folder. Print the progress on the screen and write errors in a file:\n"
" cppcheck . 2> err.txt\n"
" # Recursively check ../myproject/ and print only most fatal errors:\n"
" cppcheck --quiet ../myproject/\n"
" # Check only files one.cpp and two.cpp and give all information there is:\n"
" cppcheck -v -a -s one.cpp two.cpp\n";
return oss.str();
}
// Check function usage if "--style" and "--all" was given.
// There will be false positives for exported library functions
if ( _settings._showAll && _settings._checkCodingStyle )
if (_settings._showAll && _settings._checkCodingStyle)
_settings._checkFunctionUsage = true;
return "";
@ -144,8 +144,8 @@ std::string CppCheck::parseFromArgs( int argc, const char* const argv[] )
void CppCheck::check()
{
_checkFunctionUsage.setErrorLogger( this );
std::sort( _filenames.begin(), _filenames.end() );
_checkFunctionUsage.setErrorLogger(this);
std::sort(_filenames.begin(), _filenames.end());
for (unsigned int c = 0; c < _filenames.size(); c++)
{
_errout.str("");
@ -155,54 +155,54 @@ void CppCheck::check()
Preprocessor preprocessor;
std::list<std::string> configurations;
std::string filedata = "";
if( _fileContents.size() > 0 && _fileContents.find( _filenames[c] ) != _fileContents.end() )
if (_fileContents.size() > 0 && _fileContents.find(_filenames[c]) != _fileContents.end())
{
// File content was given as a string
std::istringstream iss( _fileContents[ _filenames[c] ] );
preprocessor.preprocess(iss, filedata, configurations );
std::istringstream iss(_fileContents[ _filenames[c] ]);
preprocessor.preprocess(iss, filedata, configurations);
}
else
{
// Only file name was given, read the content from file
std::ifstream fin( fname.c_str() );
preprocessor.preprocess(fin, filedata, configurations );
std::ifstream fin(fname.c_str());
preprocessor.preprocess(fin, filedata, configurations);
}
int checkCount = 0;
for ( std::list<std::string>::const_iterator it = configurations.begin(); it != configurations.end(); ++it )
for (std::list<std::string>::const_iterator it = configurations.begin(); it != configurations.end(); ++it)
{
// Check only 12 first configurations, after that bail out, unless --force
// was used.
if( !_settings._force && checkCount > 11 )
if (!_settings._force && checkCount > 11)
{
if( _settings._errorsOnly == false )
_errorLogger->reportOut( std::string( "Bailing out from checking " ) + fname + ": Too many configurations. Recheck this file with --force if you want to check them all." );
if (_settings._errorsOnly == false)
_errorLogger->reportOut(std::string("Bailing out from checking ") + fname + ": Too many configurations. Recheck this file with --force if you want to check them all.");
break;
}
cfg = *it;
std::string codeWithoutCfg = Preprocessor::getcode( filedata, *it );
std::string codeWithoutCfg = Preprocessor::getcode(filedata, *it);
// If only errors are printed, print filename after the check
if ( _settings._errorsOnly == false )
_errorLogger->reportOut( std::string( "Checking " ) + fname + ": "+cfg+std::string( "..." ) );
if (_settings._errorsOnly == false)
_errorLogger->reportOut(std::string("Checking ") + fname + ": " + cfg + std::string("..."));
checkFile( codeWithoutCfg, _filenames[c].c_str());
checkFile(codeWithoutCfg, _filenames[c].c_str());
++checkCount;
}
if ( _settings._errorsOnly == false && _errout.str().empty() )
_errorLogger->reportOut( "No errors found" );
if (_settings._errorsOnly == false && _errout.str().empty())
_errorLogger->reportOut("No errors found");
}
// This generates false positives - especially for libraries
_settings._verbose = false;
if ( _settings._checkFunctionUsage )
if (_settings._checkFunctionUsage)
{
_errout.str("");
if( _settings._errorsOnly == false )
_errorLogger->reportOut( "Checking usage of global functions (this may take several minutes).." );
if (_settings._errorsOnly == false)
_errorLogger->reportOut("Checking usage of global functions (this may take several minutes)..");
_checkFunctionUsage.check();
}
@ -221,8 +221,8 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
// Tokenize the file
{
std::istringstream istr(code);
_tokenizer.tokenize(istr, FileName);
std::istringstream istr(code);
_tokenizer.tokenize(istr, FileName);
}
// Set variable id
@ -233,13 +233,13 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
// Check that the memsets are valid.
// The 'memset' function can do dangerous things if used wrong.
// Important: The checking doesn't work on simplified tokens list.
CheckClass checkClass( &_tokenizer, _settings, this );
CheckClass checkClass(&_tokenizer, _settings, this);
checkClass.noMemset();
// Coding style checks that must be run before the simplifyTokenList
CheckOther checkOther( &_tokenizer, this );
if ( _settings._checkCodingStyle )
CheckOther checkOther(&_tokenizer, this);
if (_settings._checkCodingStyle)
{
// Check for unsigned divisions where one operand is signed
checkOther.CheckUnsignedDivision();
@ -263,14 +263,14 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
_tokenizer.simplifyTokenList();
if ( _settings._checkFunctionUsage )
if (_settings._checkFunctionUsage)
_checkFunctionUsage.parseTokens(_tokenizer);
// Class for detecting buffer overruns and related problems
CheckBufferOverrunClass checkBufferOverrun( &_tokenizer, _settings, this );
CheckBufferOverrunClass checkBufferOverrun(&_tokenizer, _settings, this);
// Memory leak
CheckMemoryLeakClass checkMemoryLeak( &_tokenizer, _settings, this );
CheckMemoryLeakClass checkMemoryLeak(&_tokenizer, _settings, this);
checkMemoryLeak.CheckMemoryLeak();
// Check that all class constructors are ok.
@ -313,7 +313,7 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
// Warning upon c-style pointer casts
const char *ext = strrchr(FileName, '.');
if (ext && strcmp(ext,".cpp")==0)
if (ext && strcmp(ext, ".cpp") == 0)
checkOther.WarningOldStylePointerCast();
checkClass.operatorEq();
@ -343,28 +343,28 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
}
//---------------------------------------------------------------------------
void CppCheck::reportErr( const std::string &errmsg)
void CppCheck::reportErr(const std::string &errmsg)
{
if ( /*OnlyReportUniqueErrors*/ true )
if (/*OnlyReportUniqueErrors*/ true)
{
if ( std::find( _errorList.begin(), _errorList.end(), errmsg ) != _errorList.end() )
if (std::find(_errorList.begin(), _errorList.end(), errmsg) != _errorList.end())
return;
_errorList.push_back( errmsg );
_errorList.push_back(errmsg);
}
std::string errmsg2( errmsg );
if ( _settings._verbose )
std::string errmsg2(errmsg);
if (_settings._verbose)
{
errmsg2 += "\n Defines=\'" + cfg + "\'\n";
}
_errorLogger->reportErr( errmsg2 );
_errorLogger->reportErr(errmsg2);
_errout << errmsg2 << std::endl;
}
void CppCheck::reportOut( const std::string &outmsg)
void CppCheck::reportOut(const std::string &outmsg)
{
// This is currently never called. It is here just to comply with
// the interface.

View File

@ -36,91 +36,91 @@
*/
class CppCheck : public ErrorLogger
{
public:
/**
* Constructor.
*/
CppCheck( ErrorLogger &errorLogger );
public:
/**
* Constructor.
*/
CppCheck(ErrorLogger &errorLogger);
/**
* Destructor.
*/
virtual ~CppCheck();
/**
* Destructor.
*/
virtual ~CppCheck();
/**
* This starts the actual checking. Note that you must call
* parseFromArgs() or settings() and addFile() before calling this.
*/
void check();
/**
* This starts the actual checking. Note that you must call
* parseFromArgs() or settings() and addFile() before calling this.
*/
void check();
/**
* Adjust the settings before doing the check. E.g. show only
* actual bugs or also coding style issues.
*
* @param settings New settings which will overwrite the old.
*/
void settings( const Settings &settings );
/**
* Adjust the settings before doing the check. E.g. show only
* actual bugs or also coding style issues.
*
* @param settings New settings which will overwrite the old.
*/
void settings(const Settings &settings);
/**
* Add new file to be checked.
*
* @param path Relative or absolute path to the file to be checked,
* e.g. "cppcheck.cpp". Note that only source files (.c, .cc or .cpp)
* should be added to the list. Include filese are gathered automatically.
*/
void addFile( const std::string &path );
/**
* Add new file to be checked.
*
* @param path Relative or absolute path to the file to be checked,
* e.g. "cppcheck.cpp". Note that only source files (.c, .cc or .cpp)
* should be added to the list. Include filese are gathered automatically.
*/
void addFile(const std::string &path);
/**
* Add new unreal file to be checked.
*
* @param path File name (used for error reporting).
* @param content If the file would be a real file, this should be
* the content of the file.
*/
void addFile( const std::string &path, const std::string &content );
/**
* Add new unreal file to be checked.
*
* @param path File name (used for error reporting).
* @param content If the file would be a real file, this should be
* the content of the file.
*/
void addFile(const std::string &path, const std::string &content);
/**
* Parse command line args and get settings and file lists
* from there.
*
* @param argc argc from main()
* @param argv argv from main()
* @return Empty string if parameters were accepted, or
* string containing "help" text if no files were found to be
* checked.
*/
std::string parseFromArgs( int argc, const char* const argv[] );
/**
* Parse command line args and get settings and file lists
* from there.
*
* @param argc argc from main()
* @param argv argv from main()
* @return Empty string if parameters were accepted, or
* string containing "help" text if no files were found to be
* checked.
*/
std::string parseFromArgs(int argc, const char* const argv[]);
private:
void checkFile(const std::string &code, const char FileName[]);
private:
void checkFile(const std::string &code, const char FileName[]);
/**
* Errors and warnings are directed here.
*
* @param errmsg Errors messages are normally in format
* "[filepath:line number] Message", e.g.
* "[main.cpp:4] Uninitialized member variable"
*/
virtual void reportErr( const std::string &errmsg);
/**
* Errors and warnings are directed here.
*
* @param errmsg Errors messages are normally in format
* "[filepath:line number] Message", e.g.
* "[main.cpp:4] Uninitialized member variable"
*/
virtual void reportErr(const std::string &errmsg);
/**
* Information about progress is directed here.
*
* @param outmsg, E.g. "Checking main.cpp..."
*/
virtual void reportOut( const std::string &outmsg);
/**
* Information about progress is directed here.
*
* @param outmsg, E.g. "Checking main.cpp..."
*/
virtual void reportOut(const std::string &outmsg);
std::list<std::string> _errorList;
std::ostringstream _errout;
Settings _settings;
std::vector<std::string> _filenames;
/** Key is file name, and value is the content of the file */
std::map<std::string,std::string> _fileContents;
CheckFunctionUsage _checkFunctionUsage;
ErrorLogger *_errorLogger;
std::list<std::string> _errorList;
std::ostringstream _errout;
Settings _settings;
std::vector<std::string> _filenames;
/** Key is file name, and value is the content of the file */
std::map<std::string, std::string> _fileContents;
CheckFunctionUsage _checkFunctionUsage;
ErrorLogger *_errorLogger;
/** Current configuration */
std::string cfg;
/** Current configuration */
std::string cfg;
};
#endif // CPPCHECK_H

View File

@ -30,22 +30,22 @@ CppCheckExecutor::~CppCheckExecutor()
//dtor
}
void CppCheckExecutor::check( int argc, const char* const argv[] )
void CppCheckExecutor::check(int argc, const char* const argv[])
{
CppCheck cppCheck( *this );
std::string result = cppCheck.parseFromArgs( argc, argv );
if( result.length() == 0 )
CppCheck cppCheck(*this);
std::string result = cppCheck.parseFromArgs(argc, argv);
if (result.length() == 0)
cppCheck.check();
else
std::cout << result;
}
void CppCheckExecutor::reportErr( const std::string &errmsg)
void CppCheckExecutor::reportErr(const std::string &errmsg)
{
std::cerr << errmsg << std::endl;
}
void CppCheckExecutor::reportOut( const std::string &outmsg)
void CppCheckExecutor::reportOut(const std::string &outmsg)
{
std::cout << outmsg << std::endl;
}

View File

@ -47,7 +47,7 @@ public:
* @param argc from main()
* @param argv from main()
*/
void check( int argc, const char* const argv[] );
void check(int argc, const char* const argv[]);
/**
* Errors and warnings are directed here. This should be
@ -57,7 +57,7 @@ public:
* "[filepath:line number] Message", e.g.
* "[main.cpp:4] Uninitialized member variable"
*/
virtual void reportErr( const std::string &errmsg);
virtual void reportErr(const std::string &errmsg);
/**
* Information about progress is directed here. This should be
@ -65,7 +65,7 @@ public:
*
* @param outmsg, E.g. "Checking main.cpp..."
*/
virtual void reportOut( const std::string &outmsg);
virtual void reportOut(const std::string &outmsg);
};
#endif // CPPCHECKEXECUTOR_H

View File

@ -37,14 +37,14 @@ public:
* "[filepath:line number] Message", e.g.
* "[main.cpp:4] Uninitialized member variable"
*/
virtual void reportErr( const std::string &errmsg) = 0;
virtual void reportErr(const std::string &errmsg) = 0;
/**
* Information about progress is directed here.
*
* @param outmsg, E.g. "Checking main.cpp..."
*/
virtual void reportOut( const std::string &outmsg) = 0;
virtual void reportOut(const std::string &outmsg) = 0;
};
#endif // #ifndef ERRORLOGGER_H

View File

@ -9,11 +9,11 @@
*/
class ErrorMessage
{
public:
ErrorMessage();
virtual ~ErrorMessage();
protected:
private:
public:
ErrorMessage();
virtual ~ErrorMessage();
protected:
private:
};
#endif // ErrorMessageH

View File

@ -31,52 +31,52 @@
#include <windows.h>
#endif
std::string FileLister::simplifyPath( const char *originalPath )
std::string FileLister::simplifyPath(const char *originalPath)
{
std::string subPath = "";
std::vector<std::string> pathParts;
for( ; *originalPath; ++originalPath )
for (; *originalPath; ++originalPath)
{
if( *originalPath == '/' )
if (*originalPath == '/')
{
if( subPath.length() > 0 )
if (subPath.length() > 0)
{
pathParts.push_back( subPath );
pathParts.push_back(subPath);
subPath = "";
}
pathParts.push_back( "/" );
pathParts.push_back("/");
}
else
subPath.append( 1, *originalPath );
subPath.append(1, *originalPath);
}
if( subPath.length() > 0 )
pathParts.push_back( subPath );
if (subPath.length() > 0)
pathParts.push_back(subPath);
for( std::vector<std::string>::size_type i = 0; i < pathParts.size(); ++i )
for (std::vector<std::string>::size_type i = 0; i < pathParts.size(); ++i)
{
if( pathParts[i] == ".." && i > 1 )
if (pathParts[i] == ".." && i > 1)
{
pathParts.erase( pathParts.begin() + i );
pathParts.erase( pathParts.begin()+i-1 );
pathParts.erase( pathParts.begin()+i-2 );
pathParts.erase(pathParts.begin() + i);
pathParts.erase(pathParts.begin() + i - 1);
pathParts.erase(pathParts.begin() + i - 2);
i = 0;
}
else if( i > 0 && pathParts[i] == "." )
else if (i > 0 && pathParts[i] == ".")
{
pathParts.erase( pathParts.begin()+i );
pathParts.erase(pathParts.begin() + i);
i = 0;
}
else if( pathParts[i] == "/" && i > 0 && pathParts[i-1] == "/" )
else if (pathParts[i] == "/" && i > 0 && pathParts[i-1] == "/")
{
pathParts.erase( pathParts.begin()+i-1 );
pathParts.erase(pathParts.begin() + i - 1);
i = 0;
}
}
std::ostringstream oss;
for( std::vector<std::string>::size_type i = 0; i < pathParts.size(); ++i )
for (std::vector<std::string>::size_type i = 0; i < pathParts.size(); ++i)
{
oss << pathParts[i];
}
@ -86,19 +86,19 @@ std::string FileLister::simplifyPath( const char *originalPath )
bool FileLister::AcceptFile( const std::string &filename )
bool FileLister::AcceptFile(const std::string &filename)
{
std::string::size_type dotLocation = filename.find_last_of ( '.' );
if ( dotLocation == std::string::npos )
std::string::size_type dotLocation = filename.find_last_of('.');
if (dotLocation == std::string::npos)
return false;
std::string extension = filename.substr( dotLocation );
std::transform( extension.begin(), extension.end(), extension.begin(), static_cast<int(*)(int)> (std::tolower) );
std::string extension = filename.substr(dotLocation);
std::transform(extension.begin(), extension.end(), extension.begin(), static_cast < int(*)(int) > (std::tolower));
if( extension == ".cpp" ||
if (extension == ".cpp" ||
extension == ".cxx" ||
extension == ".cc" ||
extension == ".c" )
extension == ".c")
{
return true;
}
@ -112,33 +112,33 @@ bool FileLister::AcceptFile( const std::string &filename )
#if defined(__GNUC__) && !defined(__MINGW32__)
// gcc / cygwin..
void FileLister::RecursiveAddFiles( std::vector<std::string> &filenames, const std::string &path, bool recursive )
void FileLister::RecursiveAddFiles(std::vector<std::string> &filenames, const std::string &path, bool recursive)
{
std::ostringstream oss;
oss << path;
if ( path.length() > 0 && path[path.length()-1] == '/' )
if (path.length() > 0 && path[path.length()-1] == '/')
oss << "*";
glob_t glob_results;
glob( oss.str().c_str(), GLOB_MARK, 0, &glob_results);
for ( unsigned int i = 0; i < glob_results.gl_pathc; i++ )
glob(oss.str().c_str(), GLOB_MARK, 0, &glob_results);
for (unsigned int i = 0; i < glob_results.gl_pathc; i++)
{
std::string filename = glob_results.gl_pathv[i];
if ( filename == "." || filename == ".." || filename.length() == 0 )
if (filename == "." || filename == ".." || filename.length() == 0)
continue;
if ( filename[filename.length()-1] != '/' )
if (filename[filename.length()-1] != '/')
{
// File
// If recursive is not used, accept all files given by user
if( !recursive || FileLister::AcceptFile( filename ) )
filenames.push_back( filename );
if (!recursive || FileLister::AcceptFile(filename))
filenames.push_back(filename);
}
else if( recursive )
else if (recursive)
{
// Directory
FileLister::RecursiveAddFiles( filenames, filename, recursive );
FileLister::RecursiveAddFiles(filenames, filename, recursive);
}
}
globfree(&glob_results);
@ -152,11 +152,11 @@ void FileLister::RecursiveAddFiles( std::vector<std::string> &filenames, const s
#if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
void FileLister::RecursiveAddFiles( std::vector<std::string> &filenames, const std::string &path, bool recursive )
void FileLister::RecursiveAddFiles(std::vector<std::string> &filenames, const std::string &path, bool recursive)
{
std::ostringstream bdir, oss;
oss << path;
if ( path.length() > 0 && path[path.length()-1] == '/' )
if (path.length() > 0 && path[path.length()-1] == '/')
{
bdir << path;
oss << "*";
@ -164,7 +164,7 @@ void FileLister::RecursiveAddFiles( std::vector<std::string> &filenames, const s
WIN32_FIND_DATA ffd;
HANDLE hFind = FindFirstFile(oss.str().c_str(), &ffd);
if ( INVALID_HANDLE_VALUE == hFind )
if (INVALID_HANDLE_VALUE == hFind)
return;
do
@ -172,22 +172,22 @@ void FileLister::RecursiveAddFiles( std::vector<std::string> &filenames, const s
std::ostringstream fname;
fname << bdir.str().c_str() << ffd.cFileName;
if ( ffd.cFileName[0] == '.' || ffd.cFileName[0] == '\0' )
if (ffd.cFileName[0] == '.' || ffd.cFileName[0] == '\0')
continue;
if ( ( ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) == 0 )
if ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
{
// File
// If recursive is not used, accept all files given by user
if ( !recursive || FileLister::AcceptFile( ffd.cFileName ) )
filenames.push_back( fname.str() );
if (!recursive || FileLister::AcceptFile(ffd.cFileName))
filenames.push_back(fname.str());
}
else if ( recursive )
else if (recursive)
{
// Directory
fname << "/";
FileLister::RecursiveAddFiles( filenames, fname.str().c_str(), recursive );
FileLister::RecursiveAddFiles(filenames, fname.str().c_str(), recursive);
}
}
while (FindNextFile(hFind, &ffd) != FALSE);

View File

@ -38,10 +38,10 @@
class FileLister
{
public:
static void RecursiveAddFiles( std::vector<std::string> &filenames, const std::string &path, bool recursive );
static std::string simplifyPath( const char *originalPath );
static void RecursiveAddFiles(std::vector<std::string> &filenames, const std::string &path, bool recursive);
static std::string simplifyPath(const char *originalPath);
private:
static bool AcceptFile( const std::string &filename );
static bool AcceptFile(const std::string &filename);
};
#endif // #ifndef FILELISTER_H

View File

@ -28,6 +28,6 @@
int main(int argc, char* argv[])
{
CppCheckExecutor exec;
exec.check( argc, argv );
exec.check(argc, argv);
return 0;
}

View File

@ -45,38 +45,38 @@ std::string Preprocessor::read(std::istream &istr)
std::ostringstream code;
for (char ch = (char)istr.get(); istr.good(); ch = (char)istr.get())
{
if ( ch < 0 )
if (ch < 0)
continue;
if ( ch == '\n' )
if (ch == '\n')
++lineno;
// Replace assorted special chars with spaces..
if ( (ch != '\n') && (isspace(ch) || iscntrl(ch)) )
if ((ch != '\n') && (isspace(ch) || iscntrl(ch)))
ch = ' ';
// Skip spaces after ' ' and after '#'
if ( ch == ' ' && ignoreSpace )
if (ch == ' ' && ignoreSpace)
continue;
ignoreSpace = bool(ch == ' ' || ch == '#' || ch == '/');
// Remove comments..
if ( ch == '/' )
if (ch == '/')
{
char chNext = (char)istr.get();
if ( chNext == '/' )
if (chNext == '/')
{
while (istr.good() && ch!='\n')
while (istr.good() && ch != '\n')
ch = (char)istr.get();
code << "\n";
++lineno;
}
else if ( chNext == '*' )
else if (chNext == '*')
{
char chPrev = 0;
while (istr.good() && (chPrev!='*' || ch!='/'))
while (istr.good() && (chPrev != '*' || ch != '/'))
{
chPrev = ch;
ch = (char)istr.get();
@ -90,41 +90,42 @@ std::string Preprocessor::read(std::istream &istr)
else
{
if ( chNext == '\n' )
if (chNext == '\n')
++lineno;
code << std::string(1,ch) << std::string(1,chNext);
code << std::string(1, ch) << std::string(1, chNext);
}
}
// String constants..
else if ( ch == '\"' )
else if (ch == '\"')
{
code << "\"";
do
{
ch = (char)istr.get();
code << std::string(1,ch);
if ( ch == '\\' )
code << std::string(1, ch);
if (ch == '\\')
{
ch = (char)istr.get();
code << std::string(1,ch);
code << std::string(1, ch);
// Avoid exiting loop if string contains "-characters
ch = 0;
}
} while ( istr.good() && ch != '\"' );
}
while (istr.good() && ch != '\"');
}
// char constants..
else if ( ch == '\'' )
else if (ch == '\'')
{
code << "\'";
ch = (char)istr.get();
code << std::string(1,ch);
if ( ch == '\\' )
code << std::string(1, ch);
if (ch == '\\')
{
ch = (char)istr.get();
code << std::string(1,ch);
code << std::string(1, ch);
}
ch = (char)istr.get();
code << "\'";
@ -142,30 +143,30 @@ std::string Preprocessor::read(std::istream &istr)
void Preprocessor::preprocess(std::istream &istr, std::map<std::string, std::string> &result)
{
std::list<std::string> configs;
std::string data;
preprocess( istr, data, configs );
for ( std::list<std::string>::const_iterator it = configs.begin(); it != configs.end(); ++it )
result[ *it ] = Preprocessor::getcode( data, *it );
std::list<std::string> configs;
std::string data;
preprocess(istr, data, configs);
for (std::list<std::string>::const_iterator it = configs.begin(); it != configs.end(); ++it)
result[ *it ] = Preprocessor::getcode(data, *it);
}
std::string Preprocessor::removeSpaceNearNL( const std::string &str )
std::string Preprocessor::removeSpaceNearNL(const std::string &str)
{
std::string tmp;
int prev = -1;
for( unsigned int i = 0; i < str.size(); i++ )
for (unsigned int i = 0; i < str.size(); i++)
{
if( str[i] == ' ' &&
( ( i > 0 && tmp[prev] == '\n' ) ||
( i+1 < str.size() && str[i+1] == '\n' )
if (str[i] == ' ' &&
((i > 0 && tmp[prev] == '\n') ||
(i + 1 < str.size() && str[i+1] == '\n')
)
)
)
{
// Ignore space that has new line in either side of it
}
else
{
tmp.append( 1,str[i] );
tmp.append(1, str[i]);
++prev;
}
}
@ -173,20 +174,20 @@ std::string Preprocessor::removeSpaceNearNL( const std::string &str )
return tmp;
}
std::string Preprocessor::replaceIfDefined( const std::string &str )
std::string Preprocessor::replaceIfDefined(const std::string &str)
{
std::string ret(str);
std::string::size_type pos = 0;
while ((pos = ret.find("#if defined(", pos)) != std::string::npos)
{
std::string::size_type pos2 = ret.find(")", pos+9);
std::string::size_type pos2 = ret.find(")", pos + 9);
if (pos2 > ret.length() - 1)
break;
if (ret[pos2+1] == '\n')
{
ret.erase( pos2, 1 );
ret.erase( pos + 3, 9 );
ret.insert( pos + 3, "def " );
ret.erase(pos2, 1);
ret.erase(pos + 3, 9);
ret.insert(pos + 3, "def ");
}
++pos;
}
@ -199,30 +200,30 @@ void Preprocessor::preprocess(std::istream &istr, std::string &processedFile, st
processedFile = read(istr);
// Replace all tabs with spaces..
std::replace( processedFile.begin(), processedFile.end(), '\t', ' ' );
std::replace(processedFile.begin(), processedFile.end(), '\t', ' ');
// Remove all indentation..
if ( !processedFile.empty() && processedFile[0] == ' ' )
processedFile.erase( 0, processedFile.find_first_not_of(" ") );
if (!processedFile.empty() && processedFile[0] == ' ')
processedFile.erase(0, processedFile.find_first_not_of(" "));
// Remove space characters that are after or before new line character
processedFile = removeSpaceNearNL( processedFile );
processedFile = removeSpaceNearNL(processedFile);
// Using the backslash at the end of a line..
std::string::size_type loc = 0;
while ( (loc = processedFile.rfind("\\\n")) != std::string::npos )
while ((loc = processedFile.rfind("\\\n")) != std::string::npos)
{
processedFile.erase(loc, 2);
if (loc > 0 && processedFile[loc-1] != ' ')
processedFile.insert(loc, " ");
if ( (loc = processedFile.find("\n", loc)) != std::string::npos)
processedFile.insert( loc, "\n" );
if ((loc = processedFile.find("\n", loc)) != std::string::npos)
processedFile.insert(loc, "\n");
}
processedFile = replaceIfDefined(processedFile);
// Get all possible configurations..
resultConfigurations = getcfgs( processedFile );
resultConfigurations = getcfgs(processedFile);
}
@ -231,23 +232,23 @@ void Preprocessor::preprocess(std::istream &istr, std::string &processedFile, st
std::string Preprocessor::getdef(std::string line, bool def)
{
// If def is true, the line must start with "#ifdef"
if ( def && line.find("#ifdef ") != 0 && line.find("#if ") != 0 && line.find("#elif ") != 0 )
if (def && line.find("#ifdef ") != 0 && line.find("#if ") != 0 && line.find("#elif ") != 0)
{
return "";
}
// If def is false, the line must start with "#ifndef"
if ( !def && line.find("#ifndef ") != 0 )
if (!def && line.find("#ifndef ") != 0)
{
return "";
}
// Remove the "#ifdef" or "#ifndef"
line.erase( 0, line.find(" ") );
line.erase(0, line.find(" "));
// Remove all spaces.
while ( line.find(" ") != std::string::npos )
line.erase( line.find(" "), 1 );
while (line.find(" ") != std::string::npos)
line.erase(line.find(" "), 1);
// The remaining string is our result.
return line;
@ -255,7 +256,7 @@ std::string Preprocessor::getdef(std::string line, bool def)
std::list<std::string> Preprocessor::getcfgs( const std::string &filedata )
std::list<std::string> Preprocessor::getcfgs(const std::string &filedata)
{
std::list<std::string> ret;
ret.push_back("");
@ -264,38 +265,38 @@ std::list<std::string> Preprocessor::getcfgs( const std::string &filedata )
std::istringstream istr(filedata);
std::string line;
while ( getline(istr, line) )
while (getline(istr, line))
{
std::string def = getdef(line, true) + getdef(line, false);
if (!def.empty())
{
if ( ! deflist.empty() && line.find("#elif ") == 0 )
if (! deflist.empty() && line.find("#elif ") == 0)
deflist.pop_back();
deflist.push_back(def);
def = "";
for ( std::list<std::string>::const_iterator it = deflist.begin(); it != deflist.end(); ++it)
for (std::list<std::string>::const_iterator it = deflist.begin(); it != deflist.end(); ++it)
{
if ( *it == "0" )
if (*it == "0")
break;
if ( *it == "1" )
if (*it == "1")
continue;
if ( ! def.empty() )
if (! def.empty())
def += ";";
def += *it;
}
if (std::find(ret.begin(), ret.end(), def) == ret.end())
ret.push_back( def );
ret.push_back(def);
}
if ( line.find("#else") == 0 && ! deflist.empty() )
if (line.find("#else") == 0 && ! deflist.empty())
{
std::string def( ( deflist.back() == "1" ) ? "0" : "1" );
std::string def((deflist.back() == "1") ? "0" : "1");
deflist.pop_back();
deflist.push_back( def );
deflist.push_back(def);
}
if ( line.find("#endif") == 0 && ! deflist.empty() )
if (line.find("#endif") == 0 && ! deflist.empty())
deflist.pop_back();
}
@ -304,25 +305,25 @@ std::list<std::string> Preprocessor::getcfgs( const std::string &filedata )
bool Preprocessor::match_cfg_def( std::string cfg, const std::string &def )
bool Preprocessor::match_cfg_def(std::string cfg, const std::string &def)
{
if ( def == "0" )
if (def == "0")
return false;
if ( def == "1" )
if (def == "1")
return true;
if ( cfg.empty() )
if (cfg.empty())
return false;
while ( ! cfg.empty() )
while (! cfg.empty())
{
if ( cfg.find(";") == std::string::npos )
if (cfg.find(";") == std::string::npos)
return bool(cfg == def);
std::string _cfg = cfg.substr( 0, cfg.find(";") );
if ( _cfg == def )
std::string _cfg = cfg.substr(0, cfg.find(";"));
if (_cfg == def)
return true;
cfg.erase( 0, cfg.find(";") + 1 );
cfg.erase(0, cfg.find(";") + 1);
}
return false;
@ -339,20 +340,20 @@ std::string Preprocessor::getcode(const std::string &filedata, std::string cfg)
std::istringstream istr(filedata);
std::string line;
while ( getline(istr, line) )
while (getline(istr, line))
{
std::string def = getdef( line, true );
std::string ndef = getdef( line, false );
std::string def = getdef(line, true);
std::string ndef = getdef(line, false);
if ( line.find("#elif ") == 0 )
if (line.find("#elif ") == 0)
{
if ( matched_ifdef.back() )
if (matched_ifdef.back())
{
matching_ifdef.back() = false;
}
else
{
if ( match_cfg_def(cfg, def) )
if (match_cfg_def(cfg, def))
{
matching_ifdef.back() = true;
matched_ifdef.back() = true;
@ -360,45 +361,45 @@ std::string Preprocessor::getcode(const std::string &filedata, std::string cfg)
}
}
else if ( ! def.empty() )
else if (! def.empty())
{
matching_ifdef.push_back( match_cfg_def(cfg, def) );
matched_ifdef.push_back( matching_ifdef.back() );
matching_ifdef.push_back(match_cfg_def(cfg, def));
matched_ifdef.push_back(matching_ifdef.back());
}
else if ( ! ndef.empty() )
else if (! ndef.empty())
{
matching_ifdef.push_back( ! match_cfg_def(cfg, ndef) );
matched_ifdef.push_back( matching_ifdef.back() );
matching_ifdef.push_back(! match_cfg_def(cfg, ndef));
matched_ifdef.push_back(matching_ifdef.back());
}
else if ( line == "#else" )
else if (line == "#else")
{
if ( ! matched_ifdef.empty() )
if (! matched_ifdef.empty())
matching_ifdef.back() = ! matched_ifdef.back();
}
else if ( line == "#endif" )
else if (line == "#endif")
{
if ( ! matched_ifdef.empty() )
if (! matched_ifdef.empty())
matched_ifdef.pop_back();
if ( ! matching_ifdef.empty() )
if (! matching_ifdef.empty())
matching_ifdef.pop_back();
}
if ( !line.empty() && line[0] == '#' )
if (!line.empty() && line[0] == '#')
{
match = true;
for ( std::list<bool>::const_iterator it = matching_ifdef.begin(); it != matching_ifdef.end(); ++it )
for (std::list<bool>::const_iterator it = matching_ifdef.begin(); it != matching_ifdef.end(); ++it)
match &= bool(*it);
}
if ( ! match )
if (! match)
line = "";
if ( line.find("#if") == 0 ||
line.find("#else") == 0 ||
line.find("#elif") == 0 ||
line.find("#endif") == 0 )
if (line.find("#if") == 0 ||
line.find("#else") == 0 ||
line.find("#elif") == 0 ||
line.find("#endif") == 0)
line = "";
ret << line << "\n";
@ -409,7 +410,7 @@ std::string Preprocessor::getcode(const std::string &filedata, std::string cfg)
static std::string Preprocessor::expandMacros( std::string code )
std::string Preprocessor::expandMacros(std::string code)
{
std::list<std::string> macros;
@ -423,12 +424,12 @@ static std::string Preprocessor::expandMacros( std::string code )
endpos = code.find("\n", endpos + 1);
if (endpos == std::string::npos)
{
code.erase( defpos );
code.erase(defpos);
break;
}
macros.push_back( code.substr( defpos, endpos - defpos ) );
code.erase( defpos, endpos + 1 - defpos );
macros.push_back(code.substr(defpos, endpos - defpos));
code.erase(defpos, endpos + 1 - defpos);
}
// Expand macros..

View File

@ -50,7 +50,7 @@ public:
* @param resultConfigurations List of configurations. Pass these one by one
* to getcode() with processedFile.
*/
void preprocess(std::istream &istr, std::string &processedFile, std::list<std::string> &resultConfigurations );
void preprocess(std::istream &istr, std::string &processedFile, std::list<std::string> &resultConfigurations);
/** Just read the code into a string. Perform simple cleanup of the code */
std::string read(std::istream &istr);
@ -70,7 +70,7 @@ private:
* @param str The string to be converted
* @return The string where space characters have been removed.
*/
static std::string removeSpaceNearNL( const std::string &str );
static std::string removeSpaceNearNL(const std::string &str);
/**
* Replace "#if defined" with "#ifdef" where possible
@ -78,18 +78,18 @@ private:
* @param str The string to be converted
* @return The replaced string
*/
static std::string replaceIfDefined( const std::string &str );
static std::string replaceIfDefined(const std::string &str);
/**
* Get all possible configurations. By looking at the ifdefs and ifndefs in filedata
*/
std::list<std::string> getcfgs( const std::string &filedata );
std::list<std::string> getcfgs(const std::string &filedata);
static std::string getdef(std::string line, bool def);
static bool match_cfg_def( std::string cfg, const std::string &def );
static bool match_cfg_def(std::string cfg, const std::string &def);
static std::string expandMacros( const std::string &code );
static std::string expandMacros(std::string code);
};
//---------------------------------------------------------------------------

View File

@ -36,12 +36,12 @@ private:
void check( const char code[] )
void check(const char code[])
{
// Tokenize..
Tokenizer tokenizer;
std::istringstream istr(code);
tokenizer.tokenize( istr, "test.cpp" );
tokenizer.tokenize(istr, "test.cpp");
tokenizer.simplifyTokenList();
// Assign variable ids
@ -56,342 +56,342 @@ private:
// Check for buffer overruns..
Settings settings;
settings._showAll = true;
CheckBufferOverrunClass checkBufferOverrun( &tokenizer, settings, this );
CheckBufferOverrunClass checkBufferOverrun(&tokenizer, settings, this);
checkBufferOverrun.bufferOverrun();
}
void run()
{
TEST_CASE( noerr1 );
TEST_CASE( noerr2 );
TEST_CASE( noerr3 );
TEST_CASE( noerr4 );
TEST_CASE(noerr1);
TEST_CASE(noerr2);
TEST_CASE(noerr3);
TEST_CASE(noerr4);
TEST_CASE( array_index_1 );
TEST_CASE( array_index_2 );
TEST_CASE( array_index_3 );
TEST_CASE( array_index_4 );
TEST_CASE( array_index_5 );
TEST_CASE( array_index_6 );
TEST_CASE( array_index_7 );
TEST_CASE( array_index_8 );
TEST_CASE( array_index_9 );
TEST_CASE( array_index_10 );
TEST_CASE( array_index_11 );
TEST_CASE( array_index_12 );
TEST_CASE(array_index_1);
TEST_CASE(array_index_2);
TEST_CASE(array_index_3);
TEST_CASE(array_index_4);
TEST_CASE(array_index_5);
TEST_CASE(array_index_6);
TEST_CASE(array_index_7);
TEST_CASE(array_index_8);
TEST_CASE(array_index_9);
TEST_CASE(array_index_10);
TEST_CASE(array_index_11);
TEST_CASE(array_index_12);
TEST_CASE( buffer_overrun_1 );
TEST_CASE( buffer_overrun_2 );
TEST_CASE(buffer_overrun_1);
TEST_CASE(buffer_overrun_2);
TEST_CASE( varid1 );
TEST_CASE( varid2 );
TEST_CASE(varid1);
TEST_CASE(varid2);
}
void noerr1()
{
check( "void f()\n"
"{\n"
" if (ab)\n"
" {\n"
" char str[50];\n"
" }\n"
" if (ab)\n"
" {\n"
" char str[50];\n"
" }\n"
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
check("void f()\n"
"{\n"
" if (ab)\n"
" {\n"
" char str[50];\n"
" }\n"
" if (ab)\n"
" {\n"
" char str[50];\n"
" }\n"
"}\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
void noerr2()
{
check( "void f1(char *str)\n"
"{\n"
" strcpy(buf,str);\n"
"}\n"
"void f2(char *str)\n"
"{\n"
" strcat(buf,str);\n"
"}\n"
"void f3(char *str)\n"
"{\n"
" sprintf(buf,\"%s\",str);\n"
"}\n"
"void f4(const char str[])\n"
"{\n"
" strcpy(buf, str);\n"
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
check("void f1(char *str)\n"
"{\n"
" strcpy(buf,str);\n"
"}\n"
"void f2(char *str)\n"
"{\n"
" strcat(buf,str);\n"
"}\n"
"void f3(char *str)\n"
"{\n"
" sprintf(buf,\"%s\",str);\n"
"}\n"
"void f4(const char str[])\n"
"{\n"
" strcpy(buf, str);\n"
"}\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
void noerr3()
{
check( "static void f()\n"
"{\n"
" char data[1];\n"
" return abc.data[1];\n"
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
check("static void f()\n"
"{\n"
" char data[1];\n"
" return abc.data[1];\n"
"}\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
void noerr4()
{
// The memory isn't read or written and therefore there is no error.
check( "static void f()\n"
"{\n"
" char data[100];\n"
" const char *p = &data[100];\n"
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
check("static void f()\n"
"{\n"
" char data[100];\n"
" const char *p = &data[100];\n"
"}\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
void array_index_1()
{
check("void f()\n"
"{\n"
" char str[0x10];\n"
" str[15] = 0;\n"
" str[16] = 0;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:5]: Array index out of bounds\n"), errout.str() );
"{\n"
" char str[0x10];\n"
" str[15] = 0;\n"
" str[16] = 0;\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:5]: Array index out of bounds\n"), errout.str());
}
void array_index_2()
{
check("void f()\n"
"{\n"
" char *str = new char[0x10];\n"
" str[15] = 0;\n"
" str[16] = 0;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:5]: Array index out of bounds\n"), errout.str() );
"{\n"
" char *str = new char[0x10];\n"
" str[15] = 0;\n"
" str[16] = 0;\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:5]: Array index out of bounds\n"), errout.str());
}
void array_index_3()
{
check( "void f()\n"
"{\n"
" int val[50];\n"
" for (i = 0; i < 100; i++)\n"
" sum += val[i];\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:5]: Buffer overrun\n"), errout.str() );
check("void f()\n"
"{\n"
" int val[50];\n"
" for (i = 0; i < 100; i++)\n"
" sum += val[i];\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:5]: Buffer overrun\n"), errout.str());
}
void array_index_4()
{
check( "const int SIZE = 10;\n"
"void f()\n"
"{\n"
" int i[SIZE];\n"
" i[SIZE] = 0;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:5]: Array index out of bounds\n"), errout.str() );
check("const int SIZE = 10;\n"
"void f()\n"
"{\n"
" int i[SIZE];\n"
" i[SIZE] = 0;\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:5]: Array index out of bounds\n"), errout.str());
}
void array_index_5()
{
check( "void f()\n"
"{\n"
" int i[10];\n"
" i[ sizeof(i) - 1 ] = 0;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:4]: Array index out of bounds\n"), errout.str() );
check("void f()\n"
"{\n"
" int i[10];\n"
" i[ sizeof(i) - 1 ] = 0;\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:4]: Array index out of bounds\n"), errout.str());
}
void array_index_6()
{
check( "struct ABC\n"
"{\n"
" char str[10];\n"
"};\n"
"\n"
"static void f()\n"
"{\n"
" struct ABC abc;\n"
" abc.str[10] = 0;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:9]: Array index out of bounds\n"), errout.str() );
check("struct ABC\n"
"{\n"
" char str[10];\n"
"};\n"
"\n"
"static void f()\n"
"{\n"
" struct ABC abc;\n"
" abc.str[10] = 0;\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:9]: Array index out of bounds\n"), errout.str());
}
void array_index_7()
{
check( "struct ABC\n"
"{\n"
" char str[10];\n"
"};\n"
"\n"
"static void f(ABC *abc)\n"
"{\n"
" abc->str[10] = 0;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:8]: Array index out of bounds\n"), errout.str() );
check("struct ABC\n"
"{\n"
" char str[10];\n"
"};\n"
"\n"
"static void f(ABC *abc)\n"
"{\n"
" abc->str[10] = 0;\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:8]: Array index out of bounds\n"), errout.str());
}
void array_index_8()
{
check( "const int SIZE = 10;\n"
"\n"
"struct ABC\n"
"{\n"
" char str[SIZE];\n"
"};\n"
"\n"
"static void f()\n"
"{\n"
" struct ABC abc;\n"
" abc.str[SIZE] = 0;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:11]: Array index out of bounds\n"), errout.str() );
check("const int SIZE = 10;\n"
"\n"
"struct ABC\n"
"{\n"
" char str[SIZE];\n"
"};\n"
"\n"
"static void f()\n"
"{\n"
" struct ABC abc;\n"
" abc.str[SIZE] = 0;\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:11]: Array index out of bounds\n"), errout.str());
}
void array_index_9()
{
check( "static void memclr( char *data )\n"
"{\n"
" data[10] = 0;\n"
"}\n"
"\n"
"static void f()\n"
"{\n"
" char str[5];\n"
" memclr( str ); // ERROR\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:9] -> [test.cpp:3]: Array index out of bounds\n"), errout.str() );
check("static void memclr( char *data )\n"
"{\n"
" data[10] = 0;\n"
"}\n"
"\n"
"static void f()\n"
"{\n"
" char str[5];\n"
" memclr( str ); // ERROR\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:9] -> [test.cpp:3]: Array index out of bounds\n"), errout.str());
}
void array_index_10()
{
check( "struct ABC\n"
"{\n"
" char str[10];\n"
"};\n"
"\n"
"static void memclr( char *data )\n"
"{\n"
" data[10] = 0;\n"
"}\n"
"\n"
"static void f(ABC *abc)\n"
"{\n"
" memclr(abc->str);\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:13] -> [test.cpp:8]: Array index out of bounds\n"), errout.str() );
check("struct ABC\n"
"{\n"
" char str[10];\n"
"};\n"
"\n"
"static void memclr( char *data )\n"
"{\n"
" data[10] = 0;\n"
"}\n"
"\n"
"static void f(ABC *abc)\n"
"{\n"
" memclr(abc->str);\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:13] -> [test.cpp:8]: Array index out of bounds\n"), errout.str());
}
void array_index_11()
{
check( "class ABC\n"
"{\n"
"public:\n"
" ABC();\n"
" char *str[10];\n"
" struct ABC *next;"
"};\n"
"\n"
"static void f()\n"
"{\n"
" for ( ABC *abc = abc1; abc; abc = abc->next() )\n"
" {\n"
" abc->str[10] = 0;\n"
" }\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:12]: Array index out of bounds\n"), errout.str() );
check("class ABC\n"
"{\n"
"public:\n"
" ABC();\n"
" char *str[10];\n"
" struct ABC *next;"
"};\n"
"\n"
"static void f()\n"
"{\n"
" for ( ABC *abc = abc1; abc; abc = abc->next() )\n"
" {\n"
" abc->str[10] = 0;\n"
" }\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:12]: Array index out of bounds\n"), errout.str());
}
void array_index_12()
{
check( "class Fred\n"
"{\n"
"private:\n"
" char str[10];\n"
"public:\n"
" Fred();\n"
"};\n"
"Fred::Fred()\n"
"{\n"
" str[10] = 0;\n"
"}\n" );
std::string err( errout.str() );
ASSERT_EQUALS( std::string("[test.cpp:10]: Array index out of bounds\n"), err );
check("class Fred\n"
"{\n"
"private:\n"
" char str[10];\n"
"public:\n"
" Fred();\n"
"};\n"
"Fred::Fred()\n"
"{\n"
" str[10] = 0;\n"
"}\n");
std::string err(errout.str());
ASSERT_EQUALS(std::string("[test.cpp:10]: Array index out of bounds\n"), err);
}
void buffer_overrun_1()
{
check( "void f()\n"
"{\n"
" char str[3];\n"
" strcpy(str, \"abc\");\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:4]: Buffer overrun\n"), errout.str() );
check("void f()\n"
"{\n"
" char str[3];\n"
" strcpy(str, \"abc\");\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:4]: Buffer overrun\n"), errout.str());
}
void buffer_overrun_2()
{
check( "struct ABC\n"
"{\n"
" char str[5];\n"
"};\n"
"\n"
"static void f(ABC *abc)\n"
"{\n"
" strcpy( abc->str, \"abcdef\" );\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:8]: Buffer overrun\n"), errout.str() );
check("struct ABC\n"
"{\n"
" char str[5];\n"
"};\n"
"\n"
"static void f(ABC *abc)\n"
"{\n"
" strcpy( abc->str, \"abcdef\" );\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:8]: Buffer overrun\n"), errout.str());
}
void varid1()
{
check( "void foo()\n"
"{\n"
" char str[10];\n"
" if (str[0])\n"
" {\n"
" char str[50];\n"
" str[30] = 0;\n"
" }\n"
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
check("void foo()\n"
"{\n"
" char str[10];\n"
" if (str[0])\n"
" {\n"
" char str[50];\n"
" str[30] = 0;\n"
" }\n"
"}\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
void varid2()
{
check( "void foo()\n"
"{\n"
" char str[10];\n"
" if (str[0])\n"
" {\n"
" char str[50];\n"
" memset(str,0,50);\n"
" }\n"
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
check("void foo()\n"
"{\n"
" char str[10];\n"
" if (str[0])\n"
" {\n"
" char str[50];\n"
" memset(str,0,50);\n"
" }\n"
"}\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
};
REGISTER_TEST( TestBufferOverrun )
REGISTER_TEST(TestBufferOverrun)

View File

@ -36,71 +36,71 @@ private:
void run()
{
TEST_CASE( array_index );
TEST_CASE( bitop1 );
TEST_CASE( bitop2 );
TEST_CASE(array_index);
TEST_CASE(bitop1);
TEST_CASE(bitop2);
}
void check( const char code[] )
void check(const char code[])
{
// Tokenize..
Tokenizer tokenizer;
std::istringstream istr(code);
tokenizer.tokenize( istr, "test.cpp" );
tokenizer.tokenize(istr, "test.cpp");
tokenizer.setVarId();
// Clear the error buffer..
errout.str("");
// Check char variable usage..
CheckOther checkOther( &tokenizer, this );
CheckOther checkOther(&tokenizer, this);
checkOther.CheckCharVariable();
}
void array_index()
{
check( "void foo()\n"
"{\n"
" unsigned char ch = 0x80;\n"
" buf[ch] = 0;\n"
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
check("void foo()\n"
"{\n"
" unsigned char ch = 0x80;\n"
" buf[ch] = 0;\n"
"}\n");
ASSERT_EQUALS(std::string(""), errout.str());
check( "void foo()\n"
"{\n"
" char ch = 0x80;\n"
" buf[ch] = 0;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:4]: Warning - using char variable as array index\n"), errout.str() );
check("void foo()\n"
"{\n"
" char ch = 0x80;\n"
" buf[ch] = 0;\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:4]: Warning - using char variable as array index\n"), errout.str());
check( "void foo(char ch)\n"
"{\n"
" buf[ch] = 0;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:3]: Warning - using char variable as array index\n"), errout.str() );
check("void foo(char ch)\n"
"{\n"
" buf[ch] = 0;\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:3]: Warning - using char variable as array index\n"), errout.str());
}
void bitop1()
{
check( "void foo()\n"
"{\n"
" char ch;\n"
" result = a | ch;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:4]: Warning - using char variable in bit operation\n"), errout.str() );
check("void foo()\n"
"{\n"
" char ch;\n"
" result = a | ch;\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:4]: Warning - using char variable in bit operation\n"), errout.str());
}
void bitop2()
{
check( "void foo()\n"
"{\n"
" char ch;\n"
" func(&ch);\n"
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
check("void foo()\n"
"{\n"
" char ch;\n"
" func(&ch);\n"
"}\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
};
REGISTER_TEST( TestCharVar )
REGISTER_TEST(TestCharVar)

View File

@ -36,11 +36,11 @@ private:
void run()
{
TEST_CASE( virtualDestructor1 ); // Base class not found => no error
TEST_CASE( virtualDestructor2 ); // Base class doesn't have a destructor
TEST_CASE( virtualDestructor3 ); // Base class has a destructor, but it's not virtual
TEST_CASE( virtualDestructor4 ); // Derived class doesn't have a destructor => no error
TEST_CASE( virtualDestructor5 ); // Derived class has empty destructor => no error
TEST_CASE(virtualDestructor1); // Base class not found => no error
TEST_CASE(virtualDestructor2); // Base class doesn't have a destructor
TEST_CASE(virtualDestructor3); // Base class has a destructor, but it's not virtual
TEST_CASE(virtualDestructor4); // Derived class doesn't have a destructor => no error
TEST_CASE(virtualDestructor5); // Derived class has empty destructor => no error
}
// Check that base classes have virtual destructors
@ -49,7 +49,7 @@ private:
// Tokenize..
Tokenizer tokenizer;
std::istringstream istr(code);
tokenizer.tokenize( istr, "test.cpp" );
tokenizer.tokenize(istr, "test.cpp");
tokenizer.simplifyTokenList();
// Clear the error log
@ -57,73 +57,73 @@ private:
// Check..
Settings settings;
CheckClass checkClass( &tokenizer, settings, this );
CheckClass checkClass(&tokenizer, settings, this);
checkClass.virtualDestructor();
}
void virtualDestructor1()
{
// Base class not found
// Base class not found
checkVirtualDestructor("class Derived : public Base { };");
ASSERT_EQUALS( std::string(""), errout.str() );
ASSERT_EQUALS(std::string(""), errout.str());
checkVirtualDestructor("class Derived : Base { };");
ASSERT_EQUALS( std::string(""), errout.str() );
ASSERT_EQUALS(std::string(""), errout.str());
}
void virtualDestructor2()
{
// Base class doesn't have a destructor
// Base class doesn't have a destructor
checkVirtualDestructor("class Base { };\n"
"class Derived : public Base { public: ~Derived() { (void)11; } };");
ASSERT_EQUALS( std::string("[test.cpp:1]: Class Base which is inherited by class Derived does not have a virtual destructor\n"), errout.str() );
ASSERT_EQUALS(std::string("[test.cpp:1]: Class Base which is inherited by class Derived does not have a virtual destructor\n"), errout.str());
checkVirtualDestructor("class Base { };\n"
"class Derived : Base { public: ~Derived() { (void)11; } };");
ASSERT_EQUALS( std::string(""), errout.str() );
ASSERT_EQUALS(std::string(""), errout.str());
}
void virtualDestructor3()
{
// Base class has a destructor, but it's not virtual
// Base class has a destructor, but it's not virtual
checkVirtualDestructor("class Base { public: ~Base(); };\n"
"class Derived : public Base { public: ~Derived() { (void)11; } };");
ASSERT_EQUALS( std::string("[test.cpp:1]: Class Base which is inherited by class Derived does not have a virtual destructor\n"), errout.str() );
ASSERT_EQUALS(std::string("[test.cpp:1]: Class Base which is inherited by class Derived does not have a virtual destructor\n"), errout.str());
checkVirtualDestructor("class Base { public: ~Base(); };\n"
"class Derived : private Fred, public Base { public: ~Derived() { (void)11; } };");
ASSERT_EQUALS( std::string("[test.cpp:1]: Class Base which is inherited by class Derived does not have a virtual destructor\n"), errout.str() );
ASSERT_EQUALS(std::string("[test.cpp:1]: Class Base which is inherited by class Derived does not have a virtual destructor\n"), errout.str());
}
void virtualDestructor4()
{
// Derived class doesn't have a destructor => no error
// Derived class doesn't have a destructor => no error
checkVirtualDestructor("class Base { public: ~Base(); };\n"
"class Derived : public Base { };");
ASSERT_EQUALS( std::string(""), errout.str() );
ASSERT_EQUALS(std::string(""), errout.str());
checkVirtualDestructor("class Base { public: ~Base(); };\n"
"class Derived : private Fred, public Base { };");
ASSERT_EQUALS( std::string(""), errout.str() );
ASSERT_EQUALS(std::string(""), errout.str());
}
void virtualDestructor5()
{
// Derived class has empty destructor => no error
// Derived class has empty destructor => no error
checkVirtualDestructor("class Base { public: ~Base(); };\n"
"class Derived : public Base { public: ~Derived() {} };");
ASSERT_EQUALS( std::string(""), errout.str() );
ASSERT_EQUALS(std::string(""), errout.str());
checkVirtualDestructor("class Base { public: ~Base(); };\n"
"class Derived : public Base { public: ~Derived(); }; Derived::~Derived() {}");
ASSERT_EQUALS( std::string(""), errout.str() );
ASSERT_EQUALS(std::string(""), errout.str());
}
};
REGISTER_TEST( TestClass )
REGISTER_TEST(TestClass)

View File

@ -35,12 +35,12 @@ public:
private:
void check( const char code[] )
void check(const char code[])
{
// Tokenize..
Tokenizer tokenizer;
std::istringstream istr(code);
tokenizer.tokenize( istr, "test.cpp" );
tokenizer.tokenize(istr, "test.cpp");
tokenizer.simplifyTokenList();
// Clear the error buffer..
@ -49,278 +49,278 @@ private:
// Check class constructors..
Settings settings;
settings._checkCodingStyle = true;
CheckClass checkClass( &tokenizer, settings, this );
CheckClass checkClass(&tokenizer, settings, this);
checkClass.constructors();
}
void run()
{
TEST_CASE( simple1 );
TEST_CASE( simple2 );
TEST_CASE( simple3 );
TEST_CASE( simple4 );
TEST_CASE(simple1);
TEST_CASE(simple2);
TEST_CASE(simple3);
TEST_CASE(simple4);
TEST_CASE( initvar_with_this ); // BUG 2190300
TEST_CASE( initvar_if ); // BUG 2190290
TEST_CASE( initvar_operator_eq1 ); // BUG 2190376
TEST_CASE( initvar_operator_eq2 ); // BUG 2190376
TEST_CASE( initvar_operator_eq3 );
TEST_CASE( initvar_same_classname ); // BUG 2208157
TEST_CASE( initvar_chained_assign ); // BUG 2270433
TEST_CASE( initvar_2constructors ); // BUG 2270353
TEST_CASE(initvar_with_this); // BUG 2190300
TEST_CASE(initvar_if); // BUG 2190290
TEST_CASE(initvar_operator_eq1); // BUG 2190376
TEST_CASE(initvar_operator_eq2); // BUG 2190376
TEST_CASE(initvar_operator_eq3);
TEST_CASE(initvar_same_classname); // BUG 2208157
TEST_CASE(initvar_chained_assign); // BUG 2270433
TEST_CASE(initvar_2constructors); // BUG 2270353
TEST_CASE( initvar_private_constructor ); // BUG 2354171 - private constructor
TEST_CASE(initvar_private_constructor); // BUG 2354171 - private constructor
TEST_CASE( initvar_destructor ); // No variables need to be initialized in a destructor
TEST_CASE(initvar_destructor); // No variables need to be initialized in a destructor
}
void simple1()
{
check( "class Fred\n"
"{\n"
"public:\n"
" int i;\n"
"};\n" );
std::string actual( errout.str() );
std::string expected( "[test.cpp:1] The class 'Fred' has no constructor\n" );
ASSERT_EQUALS( expected, actual );
check("class Fred\n"
"{\n"
"public:\n"
" int i;\n"
"};\n");
std::string actual(errout.str());
std::string expected("[test.cpp:1] The class 'Fred' has no constructor\n");
ASSERT_EQUALS(expected, actual);
}
void simple2()
{
check( "class Fred\n"
"{\n"
"public:\n"
" Fred() { }\n"
" int i;\n"
"};\n" );
ASSERT_EQUALS( std::string("[test.cpp:4] Uninitialized member variable 'Fred::i'\n"), errout.str() );
check("class Fred\n"
"{\n"
"public:\n"
" Fred() { }\n"
" int i;\n"
"};\n");
ASSERT_EQUALS(std::string("[test.cpp:4] Uninitialized member variable 'Fred::i'\n"), errout.str());
}
void simple3()
{
check( "class Fred\n"
"{\n"
"public:\n"
" Fred();\n"
" int i;\n"
"};\n"
"Fred::Fred()\n"
"{ }\n" );
ASSERT_EQUALS( std::string("[test.cpp:7] Uninitialized member variable 'Fred::i'\n"), errout.str() );
check("class Fred\n"
"{\n"
"public:\n"
" Fred();\n"
" int i;\n"
"};\n"
"Fred::Fred()\n"
"{ }\n");
ASSERT_EQUALS(std::string("[test.cpp:7] Uninitialized member variable 'Fred::i'\n"), errout.str());
}
void simple4()
{
check( "class Fred\n"
"{\n"
"public:\n"
" Fred();\n"
" Fred(int _i);\n"
" int i;\n"
"};\n"
"Fred::Fred()\n"
"{ }\n"
"Fred::Fred(int _i)\n"
"{\n"
" i = _i;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:8] Uninitialized member variable 'Fred::i'\n"), errout.str() );
check("class Fred\n"
"{\n"
"public:\n"
" Fred();\n"
" Fred(int _i);\n"
" int i;\n"
"};\n"
"Fred::Fred()\n"
"{ }\n"
"Fred::Fred(int _i)\n"
"{\n"
" i = _i;\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:8] Uninitialized member variable 'Fred::i'\n"), errout.str());
}
void initvar_with_this()
{
check( "class Fred\n"
"{\n"
"public:\n"
" Fred()\n"
" { this->i = 0; }\n"
" int i;\n"
"};\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
check("class Fred\n"
"{\n"
"public:\n"
" Fred()\n"
" { this->i = 0; }\n"
" int i;\n"
"};\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
void initvar_if()
{
check( "class Fred\n"
"{\n"
"public:\n"
" Fred()\n"
" {\n"
" if (true)\n"
" i = 0;\n"
" else\n"
" i = 1;\n"
" }\n"
" int i;\n"
"};\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
check("class Fred\n"
"{\n"
"public:\n"
" Fred()\n"
" {\n"
" if (true)\n"
" i = 0;\n"
" else\n"
" i = 1;\n"
" }\n"
" int i;\n"
"};\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
void initvar_operator_eq1()
{
// Bug 2190376 - False positive, Uninitialized member variable with operator=
check( "class Fred\n"
"{\n"
"private:\n"
" int i;\n"
"\n"
"public:\n"
" Fred()\n"
" { i = 0; }\n"
"\n"
" Fred(const Fred &fred)\n"
" { *this = fred; }\n"
"\n"
" const Fred & operator=(const Fred &fred)\n"
" { i = fred.i; return *this; }\n"
"};\n" );
check("class Fred\n"
"{\n"
"private:\n"
" int i;\n"
"\n"
"public:\n"
" Fred()\n"
" { i = 0; }\n"
"\n"
" Fred(const Fred &fred)\n"
" { *this = fred; }\n"
"\n"
" const Fred & operator=(const Fred &fred)\n"
" { i = fred.i; return *this; }\n"
"};\n");
std::string err( errout.str() );
ASSERT_EQUALS( std::string(""), err );
std::string err(errout.str());
ASSERT_EQUALS(std::string(""), err);
}
void initvar_operator_eq2()
{
check( "class Fred\n"
"{\n"
"public:\n"
" Fred() { i = 0; }\n"
" void operator=() { }\n"
" int i;\n"
"};\n" );
ASSERT_EQUALS( std::string("[test.cpp:5] Uninitialized member variable 'Fred::i'\n"), errout.str() );
check("class Fred\n"
"{\n"
"public:\n"
" Fred() { i = 0; }\n"
" void operator=() { }\n"
" int i;\n"
"};\n");
ASSERT_EQUALS(std::string("[test.cpp:5] Uninitialized member variable 'Fred::i'\n"), errout.str());
}
void initvar_operator_eq3()
{
check( "class Fred\n"
"{\n"
"public:\n"
" Fred() { Init(); }\n"
" void operator=() { Init(); }\n"
"private:\n"
" Init() { i = 0; }\n"
" int i;\n"
"};\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
check("class Fred\n"
"{\n"
"public:\n"
" Fred() { Init(); }\n"
" void operator=() { Init(); }\n"
"private:\n"
" Init() { i = 0; }\n"
" int i;\n"
"};\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
void initvar_same_classname()
{
// Bug 2208157 - False positive: Uninitialized variable, same class name
check( "void func1()\n"
"{\n"
" class Fred\n"
" {\n"
" int a;\n"
" Fred() { a = 0; }\n"
" };\n"
"}\n"
"\n"
"void func2()\n"
"{\n"
" class Fred\n"
" {\n"
" int b;\n"
" Fred() { b = 0; }\n"
" };\n"
"}\n" );
check("void func1()\n"
"{\n"
" class Fred\n"
" {\n"
" int a;\n"
" Fred() { a = 0; }\n"
" };\n"
"}\n"
"\n"
"void func2()\n"
"{\n"
" class Fred\n"
" {\n"
" int b;\n"
" Fred() { b = 0; }\n"
" };\n"
"}\n");
std::string err( errout.str() );
ASSERT_EQUALS( std::string(""), err );
std::string err(errout.str());
ASSERT_EQUALS(std::string(""), err);
}
void initvar_chained_assign()
{
// Bug 2270433 - Uninitialized variable false positive on chained assigns
check( "class c\n"
"{\n"
" c();\n"
"\n"
" int m_iMyInt1;\n"
" int m_iMyInt2;\n"
"}\n"
"\n"
"c::c()\n"
"{\n"
" m_iMyInt1 = m_iMyInt2 = 0;\n"
"}\n" );
check("class c\n"
"{\n"
" c();\n"
"\n"
" int m_iMyInt1;\n"
" int m_iMyInt2;\n"
"}\n"
"\n"
"c::c()\n"
"{\n"
" m_iMyInt1 = m_iMyInt2 = 0;\n"
"}\n");
std::string err( errout.str() );
ASSERT_EQUALS( std::string(""), err );
std::string err(errout.str());
ASSERT_EQUALS(std::string(""), err);
}
void initvar_2constructors()
{
check( "class c\n"
"{\n"
" c();\n"
" c(bool b);"
"\n"
" void InitInt();\n"
"\n"
" int m_iMyInt;\n"
" int m_bMyBool;\n"
"}\n"
"\n"
"c::c()\n"
"{\n"
" m_bMyBool = false;\n"
" InitInt();"
"}\n"
"\n"
"c::c(bool b)\n"
"{\n"
" m_bMyBool = b;\n"
" InitInt();\n"
"}\n"
"\n"
"void c::InitInt()\n"
"{\n"
" m_iMyInt = 0;\n"
"}\n" );
check("class c\n"
"{\n"
" c();\n"
" c(bool b);"
"\n"
" void InitInt();\n"
"\n"
" int m_iMyInt;\n"
" int m_bMyBool;\n"
"}\n"
"\n"
"c::c()\n"
"{\n"
" m_bMyBool = false;\n"
" InitInt();"
"}\n"
"\n"
"c::c(bool b)\n"
"{\n"
" m_bMyBool = b;\n"
" InitInt();\n"
"}\n"
"\n"
"void c::InitInt()\n"
"{\n"
" m_iMyInt = 0;\n"
"}\n");
std::string err( errout.str() );
ASSERT_EQUALS( std::string(""), err );
std::string err(errout.str());
ASSERT_EQUALS(std::string(""), err);
}
void initvar_private_constructor()
{
check( "class Fred\n"
"{\n"
"private:\n"
" int var;\n"
" Fred();\n"
"};\n"
"Fred::Fred()\n"
"{ }" );
ASSERT_EQUALS( std::string(""), errout.str() );
check("class Fred\n"
"{\n"
"private:\n"
" int var;\n"
" Fred();\n"
"};\n"
"Fred::Fred()\n"
"{ }");
ASSERT_EQUALS(std::string(""), errout.str());
}
void initvar_destructor()
{
check( "class Fred\n"
"{\n"
"private:\n"
" int var;\n"
"public:\n"
" Fred() : var(0) {}\n"
" ~Fred() {}\n"
"};\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
}
void initvar_destructor()
{
check("class Fred\n"
"{\n"
"private:\n"
" int var;\n"
"public:\n"
" Fred() : var(0) {}\n"
" ~Fred() {}\n"
"};\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
};
REGISTER_TEST( TestConstructors )
REGISTER_TEST(TestConstructors)

View File

@ -37,114 +37,114 @@ public:
{ }
private:
void check( const char code[] )
void check(const char code[])
{
// Tokenize..
Tokenizer tokenizer;
std::istringstream istr(code);
tokenizer.tokenize( istr, "test.cpp" );
tokenizer.tokenize(istr, "test.cpp");
// Clear the error buffer..
errout.str("");
// Check for unsigned divisions..
CheckOther checkOther( &tokenizer, this );
CheckOther checkOther(&tokenizer, this);
checkOther.CheckUnsignedDivision();
}
void run()
{
TEST_CASE( division1 );
TEST_CASE( division2 );
TEST_CASE( division3 );
TEST_CASE( division4 );
TEST_CASE( division5 );
TEST_CASE( division6 );
TEST_CASE( division7 );
TEST_CASE(division1);
TEST_CASE(division2);
TEST_CASE(division3);
TEST_CASE(division4);
TEST_CASE(division5);
TEST_CASE(division6);
TEST_CASE(division7);
}
void division1()
{
check( "void f()\n"
"{\n"
" int ivar = -2;\n"
" unsigned int uvar = 2;\n"
" return ivar / uvar;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:5]: Warning: Division with signed and unsigned operators\n"), errout.str() );
check("void f()\n"
"{\n"
" int ivar = -2;\n"
" unsigned int uvar = 2;\n"
" return ivar / uvar;\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:5]: Warning: Division with signed and unsigned operators\n"), errout.str());
}
void division2()
{
check( "void f()\n"
"{\n"
" int ivar = -2;\n"
" unsigned int uvar = 2;\n"
" return uvar / ivar;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:5]: Warning: Division with signed and unsigned operators\n"), errout.str() );
check("void f()\n"
"{\n"
" int ivar = -2;\n"
" unsigned int uvar = 2;\n"
" return uvar / ivar;\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:5]: Warning: Division with signed and unsigned operators\n"), errout.str());
}
void division3()
{
check( "typedef int s32;\n"
"typedef unsigned int u32;\n"
"void f()\n"
"{\n"
" s32 ivar = -2;\n"
" u32 uvar = 2;\n"
" return uvar / ivar;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:7]: Warning: Division with signed and unsigned operators\n"), errout.str() );
check("typedef int s32;\n"
"typedef unsigned int u32;\n"
"void f()\n"
"{\n"
" s32 ivar = -2;\n"
" u32 uvar = 2;\n"
" return uvar / ivar;\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:7]: Warning: Division with signed and unsigned operators\n"), errout.str());
}
void division4()
{
check( "void f1()\n"
"{\n"
" int i1;\n"
"}\n"
"\n"
"void f2(unsigned int i1)\n"
"{\n"
" unsigned int i2;\n"
" result = i2 / i1;\n"
);
ASSERT_EQUALS( std::string(""), errout.str() );
check("void f1()\n"
"{\n"
" int i1;\n"
"}\n"
"\n"
"void f2(unsigned int i1)\n"
"{\n"
" unsigned int i2;\n"
" result = i2 / i1;\n"
);
ASSERT_EQUALS(std::string(""), errout.str());
}
void division5()
{
check( "#define USER_HASH (16)\n"
"void foo()\n"
"{\n"
" unsigned int val = 32;\n"
" val = val / USER_HASH;\n"
);
ASSERT_EQUALS( std::string(""), errout.str() );
check("#define USER_HASH (16)\n"
"void foo()\n"
"{\n"
" unsigned int val = 32;\n"
" val = val / USER_HASH;\n"
);
ASSERT_EQUALS(std::string(""), errout.str());
}
void division6()
{
check( "void foo()\n"
"{\n"
" unsigned int val = 32;\n"
" int i = val / -2;\n"
);
ASSERT_EQUALS( std::string("[test.cpp:4]: Unsigned division. The result will be wrong.\n"), errout.str() );
check("void foo()\n"
"{\n"
" unsigned int val = 32;\n"
" int i = val / -2;\n"
);
ASSERT_EQUALS(std::string("[test.cpp:4]: Unsigned division. The result will be wrong.\n"), errout.str());
}
void division7()
{
check( "void foo()\n"
"{\n"
" unsigned int val = 32;\n"
" int i = -96 / val;\n"
);
ASSERT_EQUALS( std::string("[test.cpp:4]: Unsigned division. The result will be wrong.\n"), errout.str() );
check("void foo()\n"
"{\n"
" unsigned int val = 32;\n"
" int i = -96 / val;\n"
);
ASSERT_EQUALS(std::string("[test.cpp:4]: Unsigned division. The result will be wrong.\n"), errout.str());
}
};
REGISTER_TEST( TestDivision )
REGISTER_TEST(TestDivision)

View File

@ -30,24 +30,24 @@ private:
void run()
{
TEST_CASE( simplify_path );
TEST_CASE(simplify_path);
}
void simplify_path()
{
ASSERT_EQUALS( std::string( "index.h" ), FileLister::simplifyPath( "index.h" ) );
ASSERT_EQUALS( std::string( "/index.h" ), FileLister::simplifyPath( "/index.h" ) );
ASSERT_EQUALS( std::string( "/path/" ), FileLister::simplifyPath( "/path/" ) );
ASSERT_EQUALS( std::string( "/" ), FileLister::simplifyPath( "/" ) );
ASSERT_EQUALS( std::string( "./index.h" ), FileLister::simplifyPath( "./index.h" ) );
ASSERT_EQUALS( std::string( "../index.h" ), FileLister::simplifyPath( "../index.h" ) );
ASSERT_EQUALS( std::string( "/index.h" ), FileLister::simplifyPath( "/path/../index.h" ) );
ASSERT_EQUALS( std::string( "/index.h" ), FileLister::simplifyPath( "/path/../other/../index.h" ) );
ASSERT_EQUALS( std::string( "/index.h" ), FileLister::simplifyPath( "/path/../other///././../index.h" ) );
ASSERT_EQUALS( std::string( "../path/index.h" ), FileLister::simplifyPath( "../path/other/../index.h" ) );
ASSERT_EQUALS(std::string("index.h"), FileLister::simplifyPath("index.h"));
ASSERT_EQUALS(std::string("/index.h"), FileLister::simplifyPath("/index.h"));
ASSERT_EQUALS(std::string("/path/"), FileLister::simplifyPath("/path/"));
ASSERT_EQUALS(std::string("/"), FileLister::simplifyPath("/"));
ASSERT_EQUALS(std::string("./index.h"), FileLister::simplifyPath("./index.h"));
ASSERT_EQUALS(std::string("../index.h"), FileLister::simplifyPath("../index.h"));
ASSERT_EQUALS(std::string("/index.h"), FileLister::simplifyPath("/path/../index.h"));
ASSERT_EQUALS(std::string("/index.h"), FileLister::simplifyPath("/path/../other/../index.h"));
ASSERT_EQUALS(std::string("/index.h"), FileLister::simplifyPath("/path/../other///././../index.h"));
ASSERT_EQUALS(std::string("../path/index.h"), FileLister::simplifyPath("../path/other/../index.h"));
}
};
REGISTER_TEST( TestFileLister )
REGISTER_TEST(TestFileLister)

View File

@ -36,70 +36,70 @@ private:
void run()
{
TEST_CASE( incondition );
TEST_CASE( return1 );
TEST_CASE( callback1 );
TEST_CASE( else1 );
TEST_CASE(incondition);
TEST_CASE(return1);
TEST_CASE(callback1);
TEST_CASE(else1);
}
void check( const char code[] )
void check(const char code[])
{
// Tokenize..
Tokenizer tokenizer;
std::istringstream istr(code);
tokenizer.tokenize( istr, "test.cpp" );
tokenizer.tokenize(istr, "test.cpp");
// Clear the error buffer..
errout.str("");
// Check for unused functions..
CheckFunctionUsage checkFunctionUsage(this);
checkFunctionUsage.parseTokens( tokenizer );
checkFunctionUsage.parseTokens(tokenizer);
checkFunctionUsage.check();
}
void incondition()
{
check( "int f1()\n"
"{\n"
" if (f1())\n"
" { }\n"
"}\n" );
std::string err( errout.str() );
ASSERT_EQUALS( std::string(""), errout.str() );
check("int f1()\n"
"{\n"
" if (f1())\n"
" { }\n"
"}\n");
std::string err(errout.str());
ASSERT_EQUALS(std::string(""), errout.str());
}
void return1()
{
check( "int f1()\n"
"{\n"
" return f1();\n"
"}\n" );
std::string err( errout.str() );
ASSERT_EQUALS( std::string(""), errout.str() );
check("int f1()\n"
"{\n"
" return f1();\n"
"}\n");
std::string err(errout.str());
ASSERT_EQUALS(std::string(""), errout.str());
}
void callback1()
{
check( "void f1()\n"
"{\n"
" void (*f)() = cond ? f1 : NULL;\n"
"}\n" );
std::string err( errout.str() );
ASSERT_EQUALS( std::string(""), errout.str() );
check("void f1()\n"
"{\n"
" void (*f)() = cond ? f1 : NULL;\n"
"}\n");
std::string err(errout.str());
ASSERT_EQUALS(std::string(""), errout.str());
}
void else1()
{
check( "void f1()\n"
"{\n"
" if (cond) ;\n"
" else f1();\n"
"}\n" );
std::string err( errout.str() );
ASSERT_EQUALS( std::string(""), errout.str() );
check("void f1()\n"
"{\n"
" if (cond) ;\n"
" else f1();\n"
"}\n");
std::string err(errout.str());
ASSERT_EQUALS(std::string(""), errout.str());
}
};
REGISTER_TEST( TestFunctionUsage )
REGISTER_TEST(TestFunctionUsage)

View File

@ -36,56 +36,56 @@ public:
{ }
private:
void check( const char code[] )
void check(const char code[])
{
// Tokenize..
Tokenizer tokenizer;
std::istringstream istr(code);
tokenizer.tokenize( istr, "test.cpp" );
tokenizer.tokenize(istr, "test.cpp");
tokenizer.simplifyTokenList();
// Clear the error buffer..
errout.str("");
// Check for unused variables..
CheckOther checkOther( &tokenizer, this );
CheckOther checkOther(&tokenizer, this);
checkOther.CheckIncompleteStatement();
}
void run()
{
TEST_CASE( test1 );
TEST_CASE( test2 );
TEST_CASE(test1);
TEST_CASE(test2);
}
void test1()
{
check( "void foo()\n"
"{\n"
" const char def[] =\n"
"#ifdef ABC\n"
" \"abc\";\n"
"#else\n"
" \"not abc\";\n"
"#endif\n"
"}\n" );
check("void foo()\n"
"{\n"
" const char def[] =\n"
"#ifdef ABC\n"
" \"abc\";\n"
"#else\n"
" \"not abc\";\n"
"#endif\n"
"}\n");
ASSERT_EQUALS( std::string(""), errout.str() );
ASSERT_EQUALS(std::string(""), errout.str());
}
void test2()
{
// Todo: remove the ';' before the string
check( "void foo()\n"
"{\n"
" ;\"abc\";\n"
"}\n" );
check("void foo()\n"
"{\n"
" ;\"abc\";\n"
"}\n");
ASSERT_EQUALS( std::string("[test.cpp:3]: Redundant code: Found a statement that begins with string constant\n"), errout.str() );
ASSERT_EQUALS(std::string("[test.cpp:3]: Redundant code: Found a statement that begins with string constant\n"), errout.str());
}
};
REGISTER_TEST( TestIncompleteStatement )
REGISTER_TEST(TestIncompleteStatement)

File diff suppressed because it is too large Load Diff

View File

@ -36,7 +36,7 @@ private:
void run()
{
TEST_CASE( param1 );
TEST_CASE(param1);
}
void param1()
@ -49,7 +49,7 @@ private:
// Tokenize..
Tokenizer tokenizer;
std::istringstream istr(code);
tokenizer.tokenize( istr, "test.cpp" );
tokenizer.tokenize(istr, "test.cpp");
tokenizer.simplifyTokenList();
// Clear the error log
@ -57,16 +57,16 @@ private:
// Check..
Settings settings;
CheckMemoryLeakClass checkMemoryLeak( &tokenizer, settings, this );
CheckMemoryLeakClass checkMemoryLeak(&tokenizer, settings, this);
Token *tok = checkMemoryLeak.functionParameterCode(tokenizer.tokens(), 1);
// Compare tokens..
std::string s;
for ( const Token *tok2 = tok; tok2; tok2 = tok2->next() )
for (const Token *tok2 = tok; tok2; tok2 = tok2->next())
s += tok2->str() + " ";
ASSERT_EQUALS( "; } ", s );
ASSERT_EQUALS("; } ", s);
}
};
REGISTER_TEST( TestMemleakMultiPass )
REGISTER_TEST(TestMemleakMultiPass)

View File

@ -34,58 +34,58 @@ private:
void run()
{
TEST_CASE( delete1 );
TEST_CASE(delete1);
TEST_CASE( delete2 );
TEST_CASE(delete2);
}
void check( const char code[] )
void check(const char code[])
{
// Tokenize..
Tokenizer tokenizer;
std::istringstream istr(code);
tokenizer.tokenize( istr, "test.cpp" );
tokenizer.tokenize(istr, "test.cpp");
// Clear the error buffer..
errout.str("");
// Check for redundant code..
CheckOther checkOther( &tokenizer, this );
CheckOther checkOther(&tokenizer, this);
checkOther.WarningRedundantCode();
}
void delete1()
{
check( "void foo()\n"
"{\n"
" if (p)\n"
" {\n"
" delete p;\n"
" p = 0;\n"
" }\n"
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
check("void foo()\n"
"{\n"
" if (p)\n"
" {\n"
" delete p;\n"
" p = 0;\n"
" }\n"
"}\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
void delete2()
{
check( "void foo()\n"
"{\n"
" if (p)\n"
" {\n"
" delete p;\n"
" }\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:3]: Redundant condition. It is safe to deallocate a NULL pointer\n"), errout.str() );
check("void foo()\n"
"{\n"
" if (p)\n"
" {\n"
" delete p;\n"
" }\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:3]: Redundant condition. It is safe to deallocate a NULL pointer\n"), errout.str());
check( "void foo()\n"
"{\n"
" if (p)\n"
" delete p;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:3]: Redundant condition. It is safe to deallocate a NULL pointer\n"), errout.str() );
check("void foo()\n"
"{\n"
" if (p)\n"
" delete p;\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:3]: Redundant condition. It is safe to deallocate a NULL pointer\n"), errout.str());
}
};
REGISTER_TEST( TestOther )
REGISTER_TEST(TestOther)

View File

@ -42,31 +42,31 @@ private:
TEST_CASE(readCode);
// The bug that started the whole work with the new preprocessor
TEST_CASE( Bug2190219 );
TEST_CASE(Bug2190219);
TEST_CASE( test1 );
TEST_CASE( test2 );
TEST_CASE( test3 );
TEST_CASE( test4 );
TEST_CASE( test5 );
TEST_CASE(test1);
TEST_CASE(test2);
TEST_CASE(test3);
TEST_CASE(test4);
TEST_CASE(test5);
TEST_CASE( comments1 );
TEST_CASE(comments1);
TEST_CASE( if0 );
TEST_CASE( if1 );
TEST_CASE(if0);
TEST_CASE(if1);
TEST_CASE( elif );
TEST_CASE(elif);
TEST_CASE( include1 );
TEST_CASE(include1);
TEST_CASE( if_cond1 );
TEST_CASE(if_cond1);
TEST_CASE( multiline );
TEST_CASE(multiline);
TEST_CASE( if_defined ); // "#if defined(AAA)" => "#ifdef AAA"
TEST_CASE(if_defined); // "#if defined(AAA)" => "#ifdef AAA"
// Macros..
TEST_CASE( macro1 );
TEST_CASE(macro1);
}
@ -76,29 +76,29 @@ private:
" #aa\t /* remove this */\tb \r\n";
Preprocessor p;
std::istringstream istr(code);
std::string codestr( p.read(istr) );
ASSERT_EQUALS( "a \n#aa b \n", codestr );
std::string codestr(p.read(istr));
ASSERT_EQUALS("a \n#aa b \n", codestr);
}
bool cmpmaps(const std::map<std::string, std::string> &m1, const std::map<std::string, std::string> &m2)
{
// Begin by checking the sizes
if ( m1.size() != m2.size() )
if (m1.size() != m2.size())
return false;
// Check each item in the maps..
for ( std::map<std::string,std::string>::const_iterator it1 = m1.begin(); it1 != m1.end(); ++it1 )
for (std::map<std::string, std::string>::const_iterator it1 = m1.begin(); it1 != m1.end(); ++it1)
{
std::string s1 = it1->first;
std::map<std::string,std::string>::const_iterator it2 = m2.find(s1);
if ( it2 == m2.end() )
std::map<std::string, std::string>::const_iterator it2 = m2.find(s1);
if (it2 == m2.end())
return false;
else
{
std::string s1 = it1->second;
std::string s2 = it2->second;
if ( s1 != s2 )
if (s1 != s2)
return false;
}
}
@ -143,28 +143,28 @@ private:
"}\n";
expected["__cplusplus"] = "int main()\n"
"{\n"
"\n"
"int* flags = new int[10];\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"delete [] flags;\n"
"\n"
"\n"
"\n"
"}\n";
"{\n"
"\n"
"int* flags = new int[10];\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"delete [] flags;\n"
"\n"
"\n"
"\n"
"}\n";
// Preprocess => actual result..
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
preprocessor.preprocess( istr, actual );
preprocessor.preprocess(istr, actual);
// Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected));
ASSERT_EQUALS(true, cmpmaps(actual, expected));
}
@ -185,10 +185,10 @@ private:
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
preprocessor.preprocess( istr, actual );
preprocessor.preprocess(istr, actual);
// Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected));
ASSERT_EQUALS(true, cmpmaps(actual, expected));
}
void test2()
@ -208,10 +208,10 @@ private:
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
preprocessor.preprocess( istr, actual );
preprocessor.preprocess(istr, actual);
// Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected));
ASSERT_EQUALS(true, cmpmaps(actual, expected));
}
void test3()
@ -234,10 +234,10 @@ private:
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
preprocessor.preprocess( istr, actual );
preprocessor.preprocess(istr, actual);
// Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected));
ASSERT_EQUALS(true, cmpmaps(actual, expected));
}
void test4()
@ -258,10 +258,10 @@ private:
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
preprocessor.preprocess( istr, actual );
preprocessor.preprocess(istr, actual);
// Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected));
ASSERT_EQUALS(true, cmpmaps(actual, expected));
}
void test5()
@ -285,10 +285,10 @@ private:
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
preprocessor.preprocess( istr, actual );
preprocessor.preprocess(istr, actual);
// Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected));
ASSERT_EQUALS(true, cmpmaps(actual, expected));
}
@ -308,10 +308,10 @@ private:
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
preprocessor.preprocess( istr, actual );
preprocessor.preprocess(istr, actual);
// Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected));
ASSERT_EQUALS(true, cmpmaps(actual, expected));
}
@ -331,10 +331,10 @@ private:
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
preprocessor.preprocess( istr, actual );
preprocessor.preprocess(istr, actual);
// Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected));
ASSERT_EQUALS(true, cmpmaps(actual, expected));
}
void if1()
@ -351,10 +351,10 @@ private:
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
preprocessor.preprocess( istr, actual );
preprocessor.preprocess(istr, actual);
// Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected));
ASSERT_EQUALS(true, cmpmaps(actual, expected));
}
@ -376,10 +376,10 @@ private:
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
preprocessor.preprocess( istr, actual );
preprocessor.preprocess(istr, actual);
// Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected));
ASSERT_EQUALS(true, cmpmaps(actual, expected));
}
@ -396,10 +396,10 @@ private:
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
preprocessor.preprocess( istr, actual );
preprocessor.preprocess(istr, actual);
// Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected));
ASSERT_EQUALS(true, cmpmaps(actual, expected));
}
@ -421,10 +421,10 @@ private:
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
preprocessor.preprocess( istr, actual );
preprocessor.preprocess(istr, actual);
// Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected));
ASSERT_EQUALS(true, cmpmaps(actual, expected));
}
@ -441,10 +441,10 @@ private:
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
preprocessor.preprocess( istr, actual );
preprocessor.preprocess(istr, actual);
// Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected));
ASSERT_EQUALS(true, cmpmaps(actual, expected));
}
@ -454,10 +454,10 @@ private:
"#endif\n";
// Expected result..
std::string expected( "#ifdef AAA\n#endif\n" );
std::string expected("#ifdef AAA\n#endif\n");
// Compare result..
ASSERT_EQUALS( expected, Preprocessor::replaceIfDefined(filedata) );
ASSERT_EQUALS(expected, Preprocessor::replaceIfDefined(filedata));
}
@ -467,7 +467,7 @@ private:
"AAA(5);\n";
// Expected result..
std::string expected( "\nf(5);\n" );
std::string expected("\nf(5);\n");
// Compare result..
//ASSERT_EQUALS( expected, Preprocessor::expandMacros(filedata) );
@ -476,4 +476,4 @@ private:
};
REGISTER_TEST( TestPreprocessor )
REGISTER_TEST(TestPreprocessor)

View File

@ -37,51 +37,51 @@ public:
{ }
private:
void check( const char code[] )
void check(const char code[])
{
// Tokenize..
Tokenizer tokenizer;
std::istringstream istr(code);
tokenizer.tokenize( istr, "test.cpp" );
tokenizer.tokenize(istr, "test.cpp");
// Clear the error buffer..
errout.str("");
// Check for redundant condition..
CheckOther checkOther( &tokenizer, this );
CheckOther checkOther(&tokenizer, this);
checkOther.redundantCondition2();
}
void run()
{
TEST_CASE( remove1 );
TEST_CASE( remove2 );
TEST_CASE(remove1);
TEST_CASE(remove2);
}
void remove1()
{
check( "void f()\n"
"{\n"
" if (haystack.find(needle) != haystack.end())\n"
" haystack.remove(needle);"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:3]: Redundant condition found. The remove function in the STL will not do anything if element doesn't exist\n"), errout.str() );
check("void f()\n"
"{\n"
" if (haystack.find(needle) != haystack.end())\n"
" haystack.remove(needle);"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:3]: Redundant condition found. The remove function in the STL will not do anything if element doesn't exist\n"), errout.str());
}
void remove2()
{
check( "void f()\n"
"{\n"
" if (haystack.find(needle) != haystack.end())\n"
" {\n"
" haystack.remove(needle);\n"
" }\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:3]: Redundant condition found. The remove function in the STL will not do anything if element doesn't exist\n"), errout.str() );
check("void f()\n"
"{\n"
" if (haystack.find(needle) != haystack.end())\n"
" {\n"
" haystack.remove(needle);\n"
" }\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:3]: Redundant condition found. The remove function in the STL will not do anything if element doesn't exist\n"), errout.str());
}
};
REGISTER_TEST( TestRedundantIf )
REGISTER_TEST(TestRedundantIf)

View File

@ -22,7 +22,7 @@
int main(int argc, const char *argv[])
{
TestFixture::runTests( (argc==2) ? argv[1] : NULL );
TestFixture::runTests((argc == 2) ? argv[1] : NULL);
return 0;
}

View File

@ -35,20 +35,20 @@ private:
void run()
{
TEST_CASE( cast0 );
TEST_CASE( sizeof1 );
TEST_CASE( iftruefalse );
TEST_CASE(cast0);
TEST_CASE(sizeof1);
TEST_CASE(iftruefalse);
}
std::string tok(const char code[])
{
std::istringstream istr(code);
Tokenizer tokenizer;
tokenizer.tokenize( istr, "test.cpp" );
tokenizer.tokenize(istr, "test.cpp");
tokenizer.setVarId();
tokenizer.simplifyTokenList();
std::string ret;
for ( const Token *tok = tokenizer.tokens(); tok; tok = tok->next() )
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
{
ret += tok->str() + " ";
}
@ -60,14 +60,14 @@ private:
{
const char code1[] = " if ( p == (char *)0 ) ";
const char code2[] = " if ( p == 0 ) ";
ASSERT_EQUALS( tok(code1), tok(code2) );
ASSERT_EQUALS(tok(code1), tok(code2));
}
void sizeof1()
{
const char code1[] = " struct ABC *abc = malloc(sizeof(*abc)); ";
const char code2[] = " struct ABC *abc = malloc(100); ";
ASSERT_EQUALS( tok(code1), tok(code2) );
ASSERT_EQUALS(tok(code1), tok(code2));
}
void iftruefalse()
@ -75,69 +75,69 @@ private:
{
const char code1[] = " void f() { int a; bool use = false; if( use ) { a=0; } else {a=1;} } ";
const char code2[] = " void f() { int a; bool use = false; {a=1;} } ";
ASSERT_EQUALS( tok(code2), tok(code1) );
ASSERT_EQUALS(tok(code2), tok(code1));
}
{
const char code1[] = " void f() { int a; bool use = true; if( use ) { a=0; } else {a=1;} } ";
const char code2[] = " void f() { int a; bool use = true; { a=0; } } ";
ASSERT_EQUALS( tok(code2), tok(code1) );
ASSERT_EQUALS(tok(code2), tok(code1));
}
{
const char code1[] = " void f() { int a; int use = 5; if( use ) { a=0; } else {a=1;} } ";
const char code2[] = " void f() { int a; int use = 5; { a=0; } } ";
ASSERT_EQUALS( tok(code2), tok(code1) );
ASSERT_EQUALS(tok(code2), tok(code1));
}
{
const char code1[] = " void f() { int a; int use = 0; if( use ) { a=0; } else {a=1;} } ";
const char code2[] = " void f() { int a; int use = 0; {a=1;} } ";
ASSERT_EQUALS( tok(code2), tok(code1) );
ASSERT_EQUALS(tok(code2), tok(code1));
}
{
const char code1[] = " void f() { int a; bool use = false; if( use ) a=0; else a=1; int c=1; } ";
const char code2[] = " void f() { int a; bool use = false; { a=1; } int c=1; } ";
ASSERT_EQUALS( tok(code2), tok(code1) );
ASSERT_EQUALS(tok(code2), tok(code1));
}
{
const char code1[] = " void f() { int a; bool use = true; if( use ) a=0; else a=1; int c=1; } ";
const char code2[] = " void f() { int a; bool use = true; { a=0; } int c=1; } ";
ASSERT_EQUALS( tok(code2), tok(code1) );
ASSERT_EQUALS(tok(code2), tok(code1));
}
{
const char code1[] = " void f() { int a; bool use = false; if( use ) a=0; else if( bb ) a=1; int c=1; } ";
const char code2[] = " void f() { int a; bool use = false; if( bb ) a=1; int c=1; } ";
ASSERT_EQUALS( tok(code2), tok(code1) );
ASSERT_EQUALS(tok(code2), tok(code1));
}
{
const char code1[] = " void f() { int a; bool use = true; if( use ) a=0; else if( bb ) a=1; int c=1; } ";
const char code2[] = " void f() { int a; bool use = true; { a=0;} int c=1; } ";
ASSERT_EQUALS( tok(code2), tok(code1) );
ASSERT_EQUALS(tok(code2), tok(code1));
}
{
const char code1[] = " void f() { int a; bool use = true; if( use ) a=0; else if( bb ) a=1; else if( cc ) a=33; else { gg = 0; } int c=1; } ";
const char code2[] = " void f() { int a; bool use = true; { a=0; }int c=1; } ";
ASSERT_EQUALS( tok(code2), tok(code1) );
ASSERT_EQUALS(tok(code2), tok(code1));
}
{
const char code1[] = " void f() { if( aa ) { a=0; } else if( true ) a=1; else { a=2; } } ";
const char code2[] = " void f() { if( aa ) { a=0; } else { a=1; } } ";
ASSERT_EQUALS( tok(code2), tok(code1) );
ASSERT_EQUALS(tok(code2), tok(code1));
}
{
const char code1[] = " void f() { if( aa ) { a=0; } else if( false ) a=1; else { a=2; } } ";
const char code2[] = " void f() { if( aa ) { a=0; } else { a=2; } } ";
ASSERT_EQUALS( tok(code2), tok(code1) );
ASSERT_EQUALS(tok(code2), tok(code1));
}
}
};
REGISTER_TEST( TestSimplifyTokens )
REGISTER_TEST(TestSimplifyTokens)

View File

@ -43,9 +43,9 @@ public:
return testreg;
}
void addTest( TestFixture *t )
void addTest(TestFixture *t)
{
_tests.push_back( t );
_tests.push_back(t);
}
const std::list<TestFixture *> &tests() const
@ -72,7 +72,7 @@ TestFixture::TestFixture(const std::string &_name) : classname(_name)
bool TestFixture::runTest(const char testname[])
{
if ( testToRun.empty() || testToRun == testname )
if (testToRun.empty() || testToRun == testname)
{
++countTests;
std::cout << classname << "::" << testname << "\n";
@ -81,18 +81,18 @@ bool TestFixture::runTest(const char testname[])
return false;
}
static std::string writestr( const std::string &str )
static std::string writestr(const std::string &str)
{
std::ostringstream ostr;
ostr << "\"";
for (unsigned int i = 0; i < str.length(); ++i)
{
char ch = str[i];
if ( ch == '\n' )
if (ch == '\n')
ostr << "\\n";
else if ( ch == '\t' )
else if (ch == '\t')
ostr << "\\t";
else if ( ch == '\"' )
else if (ch == '\"')
ostr << "\\\"";
else
ostr << std::string(1, ch);
@ -103,13 +103,13 @@ static std::string writestr( const std::string &str )
void TestFixture::assertEquals(const char *filename, int linenr, const std::string &expected, const std::string &actual)
{
if ( expected != actual )
if (expected != actual)
{
errmsg << "Assertion failed in " << filename << " at line " << linenr << std::endl
<< "Expected:" << std::endl
<< writestr(expected) << std::endl
<< "Actual:" << std::endl
<< writestr(actual) << std::endl;
<< "Expected:" << std::endl
<< writestr(expected) << std::endl
<< "Actual:" << std::endl
<< writestr(actual) << std::endl;
}
}
@ -119,14 +119,14 @@ void TestFixture::assertEquals(const char *filename, int linenr, unsigned int ex
ostr1 << expected;
std::ostringstream ostr2;
ostr2 << actual;
assertEquals( filename, linenr, ostr1.str(), ostr2.str() );
assertEquals(filename, linenr, ostr1.str(), ostr2.str());
}
void TestFixture::printTests()
{
const std::list<TestFixture *> &tests = TestRegistry::theInstance().tests();
for ( std::list<TestFixture *>::const_iterator it = tests.begin(); it != tests.end(); ++it )
for (std::list<TestFixture *>::const_iterator it = tests.begin(); it != tests.end(); ++it)
{
std::cout << (*it)->classname << std::endl;
}
@ -142,10 +142,10 @@ void TestFixture::runTests(const char cmd[])
{
std::string classname(cmd ? cmd : "");
std::string testname("");
if ( classname.find("::") != std::string::npos )
if (classname.find("::") != std::string::npos)
{
testname = classname.substr( classname.find("::") + 2 );
classname.erase( classname.find("::") );
testname = classname.substr(classname.find("::") + 2);
classname.erase(classname.find("::"));
}
countTests = 0;
@ -153,9 +153,9 @@ void TestFixture::runTests(const char cmd[])
const std::list<TestFixture *> &tests = TestRegistry::theInstance().tests();
for ( std::list<TestFixture *>::const_iterator it = tests.begin(); it != tests.end(); ++it )
for (std::list<TestFixture *>::const_iterator it = tests.begin(); it != tests.end(); ++it)
{
if ( classname.empty() || (*it)->classname == classname )
if (classname.empty() || (*it)->classname == classname)
{
(*it)->run(testname);
}
@ -167,12 +167,12 @@ void TestFixture::runTests(const char cmd[])
}
void TestFixture::reportErr( const std::string &errmsg)
void TestFixture::reportErr(const std::string &errmsg)
{
errout << errmsg << std::endl;
}
void TestFixture::reportOut( const std::string &outmsg)
void TestFixture::reportOut(const std::string &outmsg)
{
// These can probably be ignored
}

View File

@ -41,9 +41,9 @@ protected:
void assertEquals(const char *filename, int linenr, unsigned int expected, unsigned int actual);
public:
virtual void reportErr( const std::string &errmsg);
virtual void reportErr(const std::string &errmsg);
virtual void reportOut( const std::string &outmsg);
virtual void reportOut(const std::string &outmsg);
void run(const std::string &str);

View File

@ -31,31 +31,31 @@ private:
void run()
{
TEST_CASE( nextprevious );
TEST_CASE(nextprevious);
}
void nextprevious()
{
Token *token = new Token;
token->str( "1" );
token->insertToken( "2" );
token->next()->insertToken( "3" );
token->str("1");
token->insertToken("2");
token->next()->insertToken("3");
Token *last = token->next()->next();
ASSERT_EQUALS( token->str(), "1" );
ASSERT_EQUALS( token->next()->str(), "2" );
ASSERT_EQUALS( token->next()->next()->str(), "3" );
if( last->next() )
ASSERT_EQUALS( "Null was expected", "" );
ASSERT_EQUALS(token->str(), "1");
ASSERT_EQUALS(token->next()->str(), "2");
ASSERT_EQUALS(token->next()->next()->str(), "3");
if (last->next())
ASSERT_EQUALS("Null was expected", "");
ASSERT_EQUALS( last->str(), "3" );
ASSERT_EQUALS( last->previous()->str(), "2" );
ASSERT_EQUALS( last->previous()->previous()->str(), "1" );
if( token->previous() )
ASSERT_EQUALS( "Null was expected", "" );
ASSERT_EQUALS(last->str(), "3");
ASSERT_EQUALS(last->previous()->str(), "2");
ASSERT_EQUALS(last->previous()->previous()->str(), "1");
if (token->previous())
ASSERT_EQUALS("Null was expected", "");
}
};
REGISTER_TEST( TestTOKEN )
REGISTER_TEST(TestTOKEN)

View File

@ -37,36 +37,36 @@ private:
void run()
{
TEST_CASE( multiline );
TEST_CASE( longtok );
TEST_CASE(multiline);
TEST_CASE(longtok);
TEST_CASE( inlineasm );
TEST_CASE(inlineasm);
TEST_CASE( dupfuncname );
TEST_CASE(dupfuncname);
TEST_CASE( const_and_volatile_functions );
TEST_CASE(const_and_volatile_functions);
TEST_CASE( ifAddBraces1 );
TEST_CASE( ifAddBraces2 );
TEST_CASE( ifAddBraces3 );
TEST_CASE( ifAddBraces4 );
TEST_CASE(ifAddBraces1);
TEST_CASE(ifAddBraces2);
TEST_CASE(ifAddBraces3);
TEST_CASE(ifAddBraces4);
TEST_CASE( numeric_true_condition );
TEST_CASE(numeric_true_condition);
TEST_CASE( simplifyKnownVariables1 );
TEST_CASE( simplifyKnownVariables2 );
TEST_CASE( simplifyKnownVariables3 );
TEST_CASE( simplifyKnownVariables4 );
TEST_CASE( simplifyKnownVariables5 );
TEST_CASE(simplifyKnownVariables1);
TEST_CASE(simplifyKnownVariables2);
TEST_CASE(simplifyKnownVariables3);
TEST_CASE(simplifyKnownVariables4);
TEST_CASE(simplifyKnownVariables5);
TEST_CASE( multiCompare );
TEST_CASE(multiCompare);
TEST_CASE( match1 );
TEST_CASE(match1);
TEST_CASE( match2 );
TEST_CASE(match2);
TEST_CASE( varid1 );
TEST_CASE( varid2 );
TEST_CASE(varid1);
TEST_CASE(varid2);
}
@ -75,7 +75,7 @@ private:
unsigned int i = 0;
for (; expected[i] && actual; ++i, actual = actual->next())
{
if ( strcmp( expected[i], actual->aaaa() ) != 0)
if (strcmp(expected[i], actual->aaaa()) != 0)
return false;
}
return (expected[i] == NULL && actual == NULL);
@ -102,13 +102,13 @@ private:
};
// Compare..
ASSERT_EQUALS( true, cmptok(expected, tokenizer.tokens()) );
ASSERT_EQUALS(true, cmptok(expected, tokenizer.tokens()));
}
void longtok()
{
std::string filedata(10000,'a');
std::string filedata(10000, 'a');
// tokenize..
Tokenizer tokenizer;
@ -116,7 +116,7 @@ private:
tokenizer.tokenize(istr, "test.cpp");
// Expected result..
ASSERT_EQUALS( std::string(10000,'a'), std::string(tokenizer.tokens()->aaaa()) );
ASSERT_EQUALS(std::string(10000, 'a'), std::string(tokenizer.tokens()->aaaa()));
}
@ -149,7 +149,7 @@ private:
};
// Compare..
ASSERT_EQUALS( true, cmptok(expected, tokenizer.tokens()) );
ASSERT_EQUALS(true, cmptok(expected, tokenizer.tokens()));
}
@ -168,8 +168,8 @@ private:
tokenizer.fillFunctionList();
ASSERT_EQUALS( 1, static_cast<unsigned int>(tokenizer._functionList.size()) );
ASSERT_EQUALS( std::string("b"), tokenizer._functionList[0]->aaaa() );
ASSERT_EQUALS(1, static_cast<unsigned int>(tokenizer._functionList.size()));
ASSERT_EQUALS(std::string("b"), tokenizer._functionList[0]->aaaa());
}
void const_and_volatile_functions()
@ -199,12 +199,12 @@ private:
tokenizer.fillFunctionList();
ASSERT_EQUALS( 3, static_cast<unsigned int>(tokenizer._functionList.size()) );
if( tokenizer._functionList.size() == 3 )
ASSERT_EQUALS(3, static_cast<unsigned int>(tokenizer._functionList.size()));
if (tokenizer._functionList.size() == 3)
{
ASSERT_EQUALS( std::string("a"), tokenizer._functionList[0]->str() );
ASSERT_EQUALS( std::string("b"), tokenizer._functionList[1]->str() );
ASSERT_EQUALS( std::string("c"), tokenizer._functionList[2]->str() );
ASSERT_EQUALS(std::string("a"), tokenizer._functionList[0]->str());
ASSERT_EQUALS(std::string("b"), tokenizer._functionList[1]->str());
ASSERT_EQUALS(std::string("c"), tokenizer._functionList[2]->str());
}
}
@ -226,7 +226,7 @@ private:
std::ostringstream ostr;
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
ostr << " " << tok->str();
ASSERT_EQUALS( std::string(" void f ( ) { { ; } }"), ostr.str() );
ASSERT_EQUALS(std::string(" void f ( ) { { ; } }"), ostr.str());
}
void ifAddBraces1()
@ -242,12 +242,12 @@ private:
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
ASSERT_EQUALS( true, tokenizer.simplifyIfAddBraces() );
ASSERT_EQUALS(true, tokenizer.simplifyIfAddBraces());
std::ostringstream ostr;
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
ostr << " " << tok->str();
ASSERT_EQUALS( std::string(" void f ( ) { if ( a ) { ; } else { ; } }"), ostr.str() );
ASSERT_EQUALS(std::string(" void f ( ) { if ( a ) { ; } else { ; } }"), ostr.str());
}
void ifAddBraces2()
@ -262,12 +262,12 @@ private:
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
ASSERT_EQUALS( true, tokenizer.simplifyIfAddBraces() );
ASSERT_EQUALS(true, tokenizer.simplifyIfAddBraces());
std::ostringstream ostr;
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
ostr << " " << tok->str();
ASSERT_EQUALS( std::string(" void f ( ) { if ( a ) { if ( b ) { } } }"), ostr.str() );
ASSERT_EQUALS(std::string(" void f ( ) { if ( a ) { if ( b ) { } } }"), ostr.str());
}
void ifAddBraces3()
@ -282,12 +282,12 @@ private:
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
ASSERT_EQUALS( true, tokenizer.simplifyIfAddBraces() );
ASSERT_EQUALS(true, tokenizer.simplifyIfAddBraces());
std::ostringstream ostr;
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
ostr << " " << tok->str();
ASSERT_EQUALS( std::string(" void f ( ) { if ( a ) { for ( ; ; ) { } } }"), ostr.str() );
ASSERT_EQUALS(std::string(" void f ( ) { if ( a ) { for ( ; ; ) { } } }"), ostr.str());
}
void ifAddBraces4()
@ -307,12 +307,12 @@ private:
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
ASSERT_EQUALS( true, tokenizer.simplifyIfAddBraces() );
ASSERT_EQUALS(true, tokenizer.simplifyIfAddBraces());
std::ostringstream ostr;
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
ostr << " " << tok->str();
ASSERT_EQUALS( std::string(" char * foo ( ) { char * str = malloc ( 10 ) ; if ( somecondition ) { for ( ; ; ) { } } return str ; }"), ostr.str() );
ASSERT_EQUALS(std::string(" char * foo ( ) { char * str = malloc ( 10 ) ; if ( somecondition ) { for ( ; ; ) { } } return str ; }"), ostr.str());
}
void simplifyKnownVariables1()
@ -334,7 +334,7 @@ private:
std::ostringstream ostr;
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
ostr << " " << tok->str();
ASSERT_EQUALS( std::string(" void f ( ) { int a = 10 ; if ( 10 ) ; }"), ostr.str() );
ASSERT_EQUALS(std::string(" void f ( ) { int a = 10 ; if ( 10 ) ; }"), ostr.str());
}
void simplifyKnownVariables2()
@ -357,7 +357,7 @@ private:
std::ostringstream ostr;
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
ostr << " " << tok->str();
ASSERT_EQUALS( std::string(" void f ( ) { int a = 10 ; a = g ( ) ; if ( a ) ; }"), ostr.str() );
ASSERT_EQUALS(std::string(" void f ( ) { int a = 10 ; a = g ( ) ; if ( a ) ; }"), ostr.str());
}
void simplifyKnownVariables3()
@ -383,7 +383,7 @@ private:
std::ostringstream ostr;
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
ostr << " " << tok->str();
ASSERT_EQUALS( std::string(" void f ( ) { int a = 4 ; while ( true ) { break ; a = 10 ; } if ( a ) ; }"), ostr.str() );
ASSERT_EQUALS(std::string(" void f ( ) { int a = 4 ; while ( true ) { break ; a = 10 ; } if ( a ) ; }"), ostr.str());
}
void simplifyKnownVariables4()
@ -405,7 +405,7 @@ private:
std::ostringstream ostr;
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
ostr << " " << tok->str();
ASSERT_EQUALS( std::string(" void f ( ) { int a = 4 ; if ( g ( a ) ) ; }"), ostr.str() );
ASSERT_EQUALS(std::string(" void f ( ) { int a = 4 ; if ( g ( a ) ) ; }"), ostr.str());
}
void simplifyKnownVariables5()
@ -427,26 +427,26 @@ private:
std::ostringstream ostr;
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
ostr << " " << tok->str();
ASSERT_EQUALS( std::string(" void f ( ) { int a = 4 ; if ( a = 5 ) ; }"), ostr.str() );
ASSERT_EQUALS(std::string(" void f ( ) { int a = 4 ; if ( a = 5 ) ; }"), ostr.str());
}
void multiCompare()
{
// Test for found
ASSERT_EQUALS( 1, Token::multiCompare( "one|two", "one" ) );
ASSERT_EQUALS( 1, Token::multiCompare( "one|two", "two" ) );
ASSERT_EQUALS( 1, Token::multiCompare( "verybig|two|", "two" ) );
ASSERT_EQUALS(1, Token::multiCompare("one|two", "one"));
ASSERT_EQUALS(1, Token::multiCompare("one|two", "two"));
ASSERT_EQUALS(1, Token::multiCompare("verybig|two|", "two"));
// Test for empty string found
ASSERT_EQUALS( 0, Token::multiCompare( "|one|two", "notfound" ) );
ASSERT_EQUALS( 0, Token::multiCompare( "one||two", "notfound" ) );
ASSERT_EQUALS( 0, Token::multiCompare( "one|two|", "notfound" ) );
ASSERT_EQUALS(0, Token::multiCompare("|one|two", "notfound"));
ASSERT_EQUALS(0, Token::multiCompare("one||two", "notfound"));
ASSERT_EQUALS(0, Token::multiCompare("one|two|", "notfound"));
// Test for not found
ASSERT_EQUALS( -1, Token::multiCompare( "one|two", "notfound" ) );
ASSERT_EQUALS( -1, Token::multiCompare( "verybig|two", "s" ) );
ASSERT_EQUALS( -1, Token::multiCompare( "one|two", "ne" ) );
ASSERT_EQUALS( -1, Token::multiCompare( "abc|def", "a" ) );
ASSERT_EQUALS(-1, Token::multiCompare("one|two", "notfound"));
ASSERT_EQUALS(-1, Token::multiCompare("verybig|two", "s"));
ASSERT_EQUALS(-1, Token::multiCompare("one|two", "ne"));
ASSERT_EQUALS(-1, Token::multiCompare("abc|def", "a"));
}
void match1()
@ -461,7 +461,7 @@ private:
tokenizer.tokenize(istr, "test.cpp");
// Match..
ASSERT_EQUALS( true, Token::Match(tokenizer.tokens(), "%var% | %var%") );
ASSERT_EQUALS(true, Token::Match(tokenizer.tokens(), "%var% | %var%"));
}
// Match "%var% || %var%"
@ -474,7 +474,7 @@ private:
tokenizer.tokenize(istr, "test.cpp");
// Match..
ASSERT_EQUALS( true, Token::Match(tokenizer.tokens(), "%var% || %var%") );
ASSERT_EQUALS(true, Token::Match(tokenizer.tokens(), "%var% || %var%"));
}
}
@ -489,7 +489,7 @@ private:
tokenizer.tokenize(istr, "test.cpp");
// Match..
ASSERT_EQUALS( true, Token::Match(tokenizer.tokens(), "!!else") );
ASSERT_EQUALS(true, Token::Match(tokenizer.tokens(), "!!else"));
}
{
@ -501,7 +501,7 @@ private:
tokenizer.tokenize(istr, "test.cpp");
// Match..
ASSERT_EQUALS( true, Token::Match(tokenizer.tokens(), "if ; !!else") );
ASSERT_EQUALS(true, Token::Match(tokenizer.tokens(), "if ; !!else"));
}
{
@ -513,7 +513,7 @@ private:
tokenizer.tokenize(istr, "test.cpp");
// Match..
ASSERT_EQUALS( true, Token::Match(tokenizer.tokens(), "if ; !!else") );
ASSERT_EQUALS(true, Token::Match(tokenizer.tokens(), "if ; !!else"));
}
{
@ -525,7 +525,7 @@ private:
tokenizer.tokenize(istr, "test.cpp");
// Match..
ASSERT_EQUALS( false, Token::Match(tokenizer.tokens(), "!!else") );
ASSERT_EQUALS(false, Token::Match(tokenizer.tokens(), "!!else"));
}
{
@ -537,7 +537,7 @@ private:
tokenizer.tokenize(istr, "test.cpp");
// Match..
ASSERT_EQUALS( false, Token::Match(tokenizer.tokens(), "if ; !!else") );
ASSERT_EQUALS(false, Token::Match(tokenizer.tokens(), "if ; !!else"));
}
}
@ -550,7 +550,7 @@ private:
" for (int i = 0; i < 10; ++i)\n"
" i = 3;\n"
" i = 4;\n"
"}\n" );
"}\n");
// tokenize..
Tokenizer tokenizer;
@ -558,18 +558,18 @@ private:
tokenizer.tokenize(istr, "test.cpp");
tokenizer.setVarId();
for ( const Token *tok = tokenizer.tokens(); tok; tok = tok->next() )
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
{
if ( tok->str() != "i" )
ASSERT_EQUALS( 0, tok->varId() );
else if ( Token::Match(tok, "i = 1") )
ASSERT_EQUALS( 1, tok->varId() );
else if ( Token::Match(tok, "i = 2") )
ASSERT_EQUALS( 2, tok->varId() );
else if ( Token::Match(tok, "i = 3") )
ASSERT_EQUALS( 3, tok->varId() );
else if ( Token::Match(tok, "i = 4") )
ASSERT_EQUALS( 2, tok->varId() );
if (tok->str() != "i")
ASSERT_EQUALS(0, tok->varId());
else if (Token::Match(tok, "i = 1"))
ASSERT_EQUALS(1, tok->varId());
else if (Token::Match(tok, "i = 2"))
ASSERT_EQUALS(2, tok->varId());
else if (Token::Match(tok, "i = 3"))
ASSERT_EQUALS(3, tok->varId());
else if (Token::Match(tok, "i = 4"))
ASSERT_EQUALS(2, tok->varId());
}
}
@ -580,7 +580,7 @@ private:
" struct ABC abc;\n"
" abc.a = 3;\n"
" i = abc.a;\n"
"}\n" );
"}\n");
// tokenize..
Tokenizer tokenizer;
@ -588,16 +588,16 @@ private:
tokenizer.tokenize(istr, "test.cpp");
tokenizer.setVarId();
for ( const Token *tok = tokenizer.tokens(); tok; tok = tok->next() )
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
{
if ( tok->str() == "abc" )
ASSERT_EQUALS( 1, tok->varId() );
else if ( tok->str() == "a" )
ASSERT_EQUALS( 2, tok->varId() );
if (tok->str() == "abc")
ASSERT_EQUALS(1, tok->varId());
else if (tok->str() == "a")
ASSERT_EQUALS(2, tok->varId());
else
ASSERT_EQUALS( 0, tok->varId() );
ASSERT_EQUALS(0, tok->varId());
}
}
};
REGISTER_TEST( TestTokenizer )
REGISTER_TEST(TestTokenizer)

View File

@ -35,19 +35,19 @@ public:
private:
void run()
{
TEST_CASE( test1 );
TEST_CASE(test1);
// [ 2236547 ] False positive --style unused function, called via pointer
TEST_CASE( func_pointer );
TEST_CASE(func_pointer);
}
void check( const char code[] )
void check(const char code[])
{
// Tokenize..
Tokenizer tokenizer;
std::istringstream istr(code);
tokenizer.tokenize( istr, "test.cpp" );
tokenizer.tokenize(istr, "test.cpp");
// Clear the error buffer..
errout.str("");
@ -55,7 +55,7 @@ private:
// Check for unused private functions..
Settings settings;
settings._checkCodingStyle = true;
CheckClass checkClass( &tokenizer, settings, this );
CheckClass checkClass(&tokenizer, settings, this);
checkClass.privateFunctions();
}
@ -63,21 +63,21 @@ private:
void test1()
{
check( "class Fred\n"
"{\n"
"private:\n"
" unsigned int f();\n"
"public:\n"
" Fred();\n"
"};\n"
"\n"
"Fred::Fred()\n"
"{ }\n"
"\n"
"unsigned int Fred::f()\n"
"{ }\n" );
check("class Fred\n"
"{\n"
"private:\n"
" unsigned int f();\n"
"public:\n"
" Fred();\n"
"};\n"
"\n"
"Fred::Fred()\n"
"{ }\n"
"\n"
"unsigned int Fred::f()\n"
"{ }\n");
ASSERT_EQUALS( std::string("Class 'Fred', unused private function: 'f'\n"), errout.str() );
ASSERT_EQUALS(std::string("Class 'Fred', unused private function: 'f'\n"), errout.str());
}
@ -87,34 +87,34 @@ private:
void func_pointer()
{
check( "class Fred\n"
"{\n"
"private:\n"
" typedef void (*testfp)();\n"
"\n"
" testfp get()\n"
" {\n"
" return test;\n"
" }\n"
"\n"
" static void test()\n"
" { }\n"
"\n"
"public:\n"
" Fred();\n"
"};\n"
"\n"
"Fred::Fred()\n"
"{}\n" );
check("class Fred\n"
"{\n"
"private:\n"
" typedef void (*testfp)();\n"
"\n"
" testfp get()\n"
" {\n"
" return test;\n"
" }\n"
"\n"
" static void test()\n"
" { }\n"
"\n"
"public:\n"
" Fred();\n"
"};\n"
"\n"
"Fred::Fred()\n"
"{}\n");
std::string str( errout.str() );
std::string str(errout.str());
ASSERT_EQUALS( std::string("Class 'Fred', unused private function: 'get'\n"), str );
ASSERT_EQUALS(std::string("Class 'Fred', unused private function: 'get'\n"), str);
}
};
REGISTER_TEST( TestUnusedPrivateFunction )
REGISTER_TEST(TestUnusedPrivateFunction)

View File

@ -35,188 +35,188 @@ public:
{ }
private:
void check( const char code[] )
void check(const char code[])
{
// Tokenize..
Tokenizer tokenizer;
std::istringstream istr(code);
tokenizer.tokenize( istr, "test.cpp" );
tokenizer.tokenize(istr, "test.cpp");
tokenizer.simplifyTokenList();
// Clear the error buffer..
errout.str("");
// Check for unused variables..
CheckOther checkOther( &tokenizer, this );
CheckOther checkOther(&tokenizer, this);
checkOther.CheckStructMemberUsage();
}
void run()
{
TEST_CASE( structmember1 );
TEST_CASE( structmember2 );
TEST_CASE( structmember3 );
TEST_CASE(structmember1);
TEST_CASE(structmember2);
TEST_CASE(structmember3);
TEST_CASE( localvar1 );
TEST_CASE( localvar2 );
TEST_CASE( localvar3 );
TEST_CASE( localvar4 );
TEST_CASE( localvar5 );
TEST_CASE(localvar1);
TEST_CASE(localvar2);
TEST_CASE(localvar3);
TEST_CASE(localvar4);
TEST_CASE(localvar5);
// Don't give false positives for variables in structs/unions
TEST_CASE( localvarStruct1 );
TEST_CASE( localvarStruct2 );
TEST_CASE(localvarStruct1);
TEST_CASE(localvarStruct2);
TEST_CASE( localvarOp ); // Usage with arithmetic operators
TEST_CASE( localvarInvert ); // Usage with inverted variable
TEST_CASE( localvarIf ); // Usage in if
TEST_CASE( localvarIfElse ); // return tmp1 ? tmp2 : tmp3;
TEST_CASE( localvarOpAssign ); // a |= b;
TEST_CASE(localvarOp); // Usage with arithmetic operators
TEST_CASE(localvarInvert); // Usage with inverted variable
TEST_CASE(localvarIf); // Usage in if
TEST_CASE(localvarIfElse); // return tmp1 ? tmp2 : tmp3;
TEST_CASE(localvarOpAssign); // a |= b;
}
void structmember1()
{
check( "struct abc\n"
"{\n"
" int a;\n"
" int b;\n"
" int c;\n"
"};\n" );
ASSERT_EQUALS( std::string("[test.cpp:3]: struct or union member 'abc::a' is never used\n"
"[test.cpp:4]: struct or union member 'abc::b' is never used\n"
"[test.cpp:5]: struct or union member 'abc::c' is never used\n"), errout.str() );
check("struct abc\n"
"{\n"
" int a;\n"
" int b;\n"
" int c;\n"
"};\n");
ASSERT_EQUALS(std::string("[test.cpp:3]: struct or union member 'abc::a' is never used\n"
"[test.cpp:4]: struct or union member 'abc::b' is never used\n"
"[test.cpp:5]: struct or union member 'abc::c' is never used\n"), errout.str());
}
void structmember2()
{
check( "struct ABC\n"
"{\n"
" int a;\n"
" int b;\n"
" int c;\n"
"};\n"
"\n"
"void foo()\n"
"{\n"
" struct ABC abc;\n"
" int a = abc.a;\n"
" int b = abc.b;\n"
" int c = abc.c;\n"
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
check("struct ABC\n"
"{\n"
" int a;\n"
" int b;\n"
" int c;\n"
"};\n"
"\n"
"void foo()\n"
"{\n"
" struct ABC abc;\n"
" int a = abc.a;\n"
" int b = abc.b;\n"
" int c = abc.c;\n"
"}\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
void structmember3()
{
check( "struct ABC\n"
"{\n"
" int a;\n"
" int b;\n"
" int c;\n"
"};\n"
"\n"
"static struct ABC abc[] = { {1, 2, 3} };\n"
"\n"
"void foo()\n"
"{\n"
" int a = abc[0].a;\n"
" int b = abc[0].b;\n"
" int c = abc[0].c;\n"
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
check("struct ABC\n"
"{\n"
" int a;\n"
" int b;\n"
" int c;\n"
"};\n"
"\n"
"static struct ABC abc[] = { {1, 2, 3} };\n"
"\n"
"void foo()\n"
"{\n"
" int a = abc[0].a;\n"
" int b = abc[0].b;\n"
" int c = abc[0].c;\n"
"}\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
void functionVariableUsage( const char code[] )
void functionVariableUsage(const char code[])
{
// Tokenize..
Tokenizer tokenizer;
std::istringstream istr(code);
tokenizer.tokenize( istr, "test.cpp" );
tokenizer.tokenize(istr, "test.cpp");
tokenizer.simplifyTokenList();
// Clear the error buffer..
errout.str("");
// Check for unused variables..
CheckOther checkOther( &tokenizer, this );
CheckOther checkOther(&tokenizer, this);
checkOther.functionVariableUsage();
}
void localvar1()
{
functionVariableUsage( "void foo()\n"
"{\n"
" int i = 0;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:2]: Variable 'i' is assigned a value that is never used\n"), errout.str() );
functionVariableUsage("void foo()\n"
"{\n"
" int i = 0;\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:2]: Variable 'i' is assigned a value that is never used\n"), errout.str());
}
void localvar2()
{
functionVariableUsage( "void foo()\n"
"{\n"
" int i;\n"
" return i;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:2]: Variable 'i' is not assigned a value\n"), errout.str() );
functionVariableUsage("void foo()\n"
"{\n"
" int i;\n"
" return i;\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:2]: Variable 'i' is not assigned a value\n"), errout.str());
}
void localvar3()
{
functionVariableUsage( "void foo()\n"
"{\n"
" int i;\n"
" if ( abc )\n"
" ;\n"
" else i = 0;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:2]: Variable 'i' is assigned a value that is never used\n"), errout.str() );
functionVariableUsage("void foo()\n"
"{\n"
" int i;\n"
" if ( abc )\n"
" ;\n"
" else i = 0;\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:2]: Variable 'i' is assigned a value that is never used\n"), errout.str());
}
void localvar4()
{
functionVariableUsage( "void foo()\n"
"{\n"
" int i = 0;\n"
" f(i);\n"
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
functionVariableUsage("void foo()\n"
"{\n"
" int i = 0;\n"
" f(i);\n"
"}\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
void localvar5()
{
functionVariableUsage( "void foo()\n"
"{\n"
" int a = 0;\n"
" b = (char)a;\n"
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
functionVariableUsage("void foo()\n"
"{\n"
" int a = 0;\n"
" b = (char)a;\n"
"}\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
void localvarStruct1()
{
functionVariableUsage( "void foo()\n"
"{\n"
" static const struct{ int x, y, w, h; } bounds = {1,2,3,4};\n"
" return bounds.x + bounds.y + bounds.w + bounds.h;\n"
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
functionVariableUsage("void foo()\n"
"{\n"
" static const struct{ int x, y, w, h; } bounds = {1,2,3,4};\n"
" return bounds.x + bounds.y + bounds.w + bounds.h;\n"
"}\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
void localvarStruct2()
{
functionVariableUsage( "void foo()\n"
"{\n"
" struct ABC { int a, b, c; };\n"
" struct ABC abc = { 1, 2, 3 };\n"
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
functionVariableUsage("void foo()\n"
"{\n"
" struct ABC { int a, b, c; };\n"
" struct ABC abc = { 1, 2, 3 };\n"
"}\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
@ -226,64 +226,64 @@ private:
const char op[] = "+-*/%&|^";
for (const char *p = op; *p; ++p)
{
std::string code( "int main()\n"
"{\n"
" int tmp = 10;\n"
" return 123 " + std::string(1, *p) + " tmp;\n"
"}\n" );
functionVariableUsage( code.c_str() );
ASSERT_EQUALS( std::string(""), errout.str() );
std::string code("int main()\n"
"{\n"
" int tmp = 10;\n"
" return 123 " + std::string(1, *p) + " tmp;\n"
"}\n");
functionVariableUsage(code.c_str());
ASSERT_EQUALS(std::string(""), errout.str());
}
}
void localvarInvert()
{
functionVariableUsage( "int main()\n"
"{\n"
" int tmp = 10;\n"
" return ~tmp;\n"
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
functionVariableUsage("int main()\n"
"{\n"
" int tmp = 10;\n"
" return ~tmp;\n"
"}\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
void localvarIf()
{
functionVariableUsage( "int main()\n"
"{\n"
" int tmp = 10;\n"
" if ( tmp )\n"
" return 1;\n"
" return 0;\n"
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
functionVariableUsage("int main()\n"
"{\n"
" int tmp = 10;\n"
" if ( tmp )\n"
" return 1;\n"
" return 0;\n"
"}\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
void localvarIfElse()
{
functionVariableUsage( "int foo()\n"
"{\n"
" int tmp1 = 1;\n"
" int tmp2 = 2;\n"
" int tmp3 = 3;\n"
" return tmp1 ? tmp2 : tmp3;\n"
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
functionVariableUsage("int foo()\n"
"{\n"
" int tmp1 = 1;\n"
" int tmp2 = 2;\n"
" int tmp3 = 3;\n"
" return tmp1 ? tmp2 : tmp3;\n"
"}\n");
ASSERT_EQUALS(std::string(""), errout.str());
}
void localvarOpAssign()
{
functionVariableUsage( "void foo()\n"
"{\n"
" int a = 1;\n"
" int b = 2;\n"
" a |= b;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:2]: Variable 'a' is assigned a value that is never used\n"), errout.str() );
functionVariableUsage("void foo()\n"
"{\n"
" int a = 1;\n"
" int b = 2;\n"
" a |= b;\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:2]: Variable 'a' is assigned a value that is never used\n"), errout.str());
}
};
REGISTER_TEST( TestUnusedVar )
REGISTER_TEST(TestUnusedVar)

176
token.cpp
View File

@ -27,16 +27,16 @@
#endif
Token::Token() :
_str(""),
_cstr(0),
_isName(false),
_isNumber(false),
_isBoolean(false),
_varId(0),
_next(0),
_previous(0),
_fileIndex(0),
_linenr(0)
_str(""),
_cstr(0),
_isName(false),
_isNumber(false),
_isBoolean(false),
_varId(0),
_next(0),
_previous(0),
_fileIndex(0),
_linenr(0)
{
}
@ -45,14 +45,14 @@ Token::~Token()
std::free(_cstr);
}
void Token::str( const char s[] )
void Token::str(const char s[])
{
_str = s;
std::free(_cstr);
_cstr = strdup(s);
_isName = bool(_str[0]=='_' || isalpha(_str[0]));
_isName = bool(_str[0] == '_' || isalpha(_str[0]));
_isNumber = bool(isdigit(_str[0]) != 0);
if( _str == "true" || _str == "false" )
if (_str == "true" || _str == "false")
_isBoolean = true;
else
_isBoolean = false;
@ -72,7 +72,7 @@ void Token::deleteNext()
const Token *Token::tokAt(int index) const
{
const Token *tok = this;
while (index>0 && tok)
while (index > 0 && tok)
{
tok = tok->next();
--index;
@ -86,21 +86,21 @@ const char *Token::strAt(int index) const
return tok ? tok->_cstr : "";
}
int Token::multiCompare( const char *needle, const char *haystack )
int Token::multiCompare(const char *needle, const char *haystack)
{
bool emptyStringFound = false;
bool findNextOr = false;
const char *haystackPointer = haystack;
for( ; *needle; ++needle )
for (; *needle; ++needle)
{
if( *needle == '|' )
if (*needle == '|')
{
// If needle and haystack are both at the end, we have a match.
if( *haystackPointer == 0 )
if (*haystackPointer == 0)
return 1;
haystackPointer = haystack;
if( findNextOr )
if (findNextOr)
findNextOr = false;
else
emptyStringFound = true;
@ -108,12 +108,12 @@ int Token::multiCompare( const char *needle, const char *haystack )
continue;
}
if( findNextOr )
if (findNextOr)
continue;
// If haystack and needle don't share the same character, reset
// haystackpointer and find next '|' character.
if( *haystackPointer != *needle )
if (*haystackPointer != *needle)
{
haystackPointer = haystack;
findNextOr = true;
@ -125,11 +125,11 @@ int Token::multiCompare( const char *needle, const char *haystack )
}
// If both needle and haystack are at the end, then we have a match.
if( *haystackPointer == 0 )
if (*haystackPointer == 0)
return 1;
// If empty string was found or if last character in needle was '|'
if( emptyStringFound || findNextOr == false )
if (emptyStringFound || findNextOr == false)
return 0;
return -1;
@ -141,21 +141,21 @@ bool Token::simpleMatch(const Token *tok, const char pattern[])
current = pattern;
next = strchr(pattern, ' ');
if ( !next )
if (!next)
next = pattern + strlen(pattern);
while ( *current )
while (*current)
{
size_t length = static_cast<size_t>(next-current);
size_t length = static_cast<size_t>(next - current);
if ( !tok || length != tok->_str.length() || strncmp(current, tok->_cstr, length) )
if (!tok || length != tok->_str.length() || strncmp(current, tok->_cstr, length))
return false;
current = next;
if ( *next )
if (*next)
{
next = strchr(++current, ' ');
if ( !next )
if (!next)
next = current + strlen(current);
}
tok = tok->next();
@ -164,19 +164,19 @@ bool Token::simpleMatch(const Token *tok, const char pattern[])
return true;
}
bool Token::Match(const Token *tok, const char pattern[], unsigned int varid, const char *varname1[] )
bool Token::Match(const Token *tok, const char pattern[], unsigned int varid, const char *varname1[])
{
const char *p = pattern;
while ( *p )
while (*p)
{
// Skip spaces in pattern..
while ( *p == ' ' )
while (*p == ' ')
++p;
if (!tok)
{
// If we have no tokens, pattern "!!else" should return true
if( p[1] == '!' && p[0] == '!' && strlen(p) > 2 )
if (p[1] == '!' && p[0] == '!' && strlen(p) > 2)
return true;
else
return false;
@ -186,7 +186,7 @@ bool Token::Match(const Token *tok, const char pattern[], unsigned int varid, co
// TODO: Refactor this so there can't be buffer overflows
char str[500];
char *s = str;
while (*p && *p!=' ')
while (*p && *p != ' ')
{
*s = *p;
++s;
@ -198,13 +198,13 @@ bool Token::Match(const Token *tok, const char pattern[], unsigned int varid, co
if (str[0] == 0)
return true;
// Compare the first character of the string for optimization reasons
// before doing more detailed checks.
// Compare the first character of the string for optimization reasons
// before doing more detailed checks.
bool patternIdentified = false;
if( str[0] == '%' )
if (str[0] == '%')
{
// Any symbolname..
if (strcmp(str,"%var%")==0 || strcmp(str,"%type%")==0)
if (strcmp(str, "%var%") == 0 || strcmp(str, "%type%") == 0)
{
if (!tok->isName())
return false;
@ -213,7 +213,7 @@ bool Token::Match(const Token *tok, const char pattern[], unsigned int varid, co
}
// Accept any token
else if (strcmp(str,"%any%")==0 )
else if (strcmp(str, "%any%") == 0)
{
patternIdentified = true;
}
@ -221,21 +221,21 @@ bool Token::Match(const Token *tok, const char pattern[], unsigned int varid, co
// Variable name..
else if (strcmp(str, "%var1%") == 0)
{
if ( ! varname1 )
if (! varname1)
return false;
if (tok->_str != varname1[0])
return false;
for ( int i = 1; varname1[i]; i++ )
for (int i = 1; varname1[i]; i++)
{
if ( !(tok->tokAt(2)) )
if (!(tok->tokAt(2)))
return false;
if ( strcmp(tok->strAt(1), ".") )
if (strcmp(tok->strAt(1), "."))
return false;
if ( strcmp(tok->strAt(2), varname1[i]) )
if (strcmp(tok->strAt(2), varname1[i]))
return false;
tok = tok->tokAt(2);
@ -244,67 +244,67 @@ bool Token::Match(const Token *tok, const char pattern[], unsigned int varid, co
patternIdentified = true;
}
else if (strcmp(str,"%varid%")==0)
else if (strcmp(str, "%varid%") == 0)
{
if( varid == 0 )
if (varid == 0)
{
std::cout << "\n###### If you see this, there is a bug ###### Token::Match() - varid was 0" << std::endl;
}
if ( tok->varId() != varid )
if (tok->varId() != varid)
return false;
patternIdentified = true;
}
else if (strcmp(str,"%num%")==0)
else if (strcmp(str, "%num%") == 0)
{
if ( !tok->isNumber() )
if (!tok->isNumber())
return false;
patternIdentified = true;
}
else if (strcmp(str,"%bool%")==0)
else if (strcmp(str, "%bool%") == 0)
{
if ( !tok->isBoolean() )
if (!tok->isBoolean())
return false;
patternIdentified = true;
}
else if (strcmp(str,"%str%")==0)
else if (strcmp(str, "%str%") == 0)
{
if ( tok->_str[0] != '\"' )
if (tok->_str[0] != '\"')
return false;
patternIdentified = true;
}
}
if( patternIdentified )
if (patternIdentified)
{
// Pattern was identified already above.
}
// [.. => search for a one-character token..
else if (str[0]=='[' && strchr(str, ']') && tok->_str[1] == 0)
else if (str[0] == '[' && strchr(str, ']') && tok->_str[1] == 0)
{
*strrchr(str, ']') = 0;
if ( strchr( str + 1, tok->_str[0] ) == 0 )
if (strchr(str + 1, tok->_str[0]) == 0)
return false;
}
// Parse multi options, such as void|int|char (accept token which is one of these 3)
else if ( strchr(str, '|') && strlen( str ) > 2 )
else if (strchr(str, '|') && strlen(str) > 2)
{
int res = multiCompare( str, tok->_cstr );
if( res == 0 )
int res = multiCompare(str, tok->_cstr);
if (res == 0)
{
// Empty alternative matches, use the same token on next round
continue;
}
else if( res == -1 )
else if (res == -1)
{
// No match
return false;
@ -312,9 +312,9 @@ bool Token::Match(const Token *tok, const char pattern[], unsigned int varid, co
}
// Parse "not" options. Token can be anything except the given one
else if( str[1] == '!' && str[0] == '!' && strlen(str) > 2 )
else if (str[1] == '!' && str[0] == '!' && strlen(str) > 2)
{
if( strcmp( tok->aaaa(), &(str[2]) ) == 0 )
if (strcmp(tok->aaaa(), &(str[2])) == 0)
return false;
}
@ -346,7 +346,7 @@ bool Token::isBoolean() const
bool Token::isStandardType() const
{
bool ret = false;
const char *type[] = {"bool","char","short","int","long","float","double",0};
const char *type[] = {"bool", "char", "short", "int", "long", "float", "double", 0};
for (int i = 0; type[i]; i++)
ret |= (_str == type[i]);
return ret;
@ -356,19 +356,19 @@ bool Token::isStandardType() const
const Token *Token::findmatch(const Token *tok, const char pattern[], const char *varname1[])
{
for ( ; tok; tok = tok->next())
for (; tok; tok = tok->next())
{
if ( Token::Match(tok, pattern, 0, varname1) )
if (Token::Match(tok, pattern, 0, varname1))
return tok;
}
return 0;
}
const Token *Token::findmatch(const Token *tok, const char pattern[], unsigned int varId )
const Token *Token::findmatch(const Token *tok, const char pattern[], unsigned int varId)
{
for ( ; tok; tok = tok->next())
for (; tok; tok = tok->next())
{
if ( Token::Match(tok, pattern, varId) )
if (Token::Match(tok, pattern, varId))
return tok;
}
return 0;
@ -379,7 +379,7 @@ unsigned int Token::varId() const
return _varId;
}
void Token::varId( unsigned int id )
void Token::varId(unsigned int id)
{
_varId = id;
}
@ -389,7 +389,7 @@ Token *Token::next() const
return _next;
}
void Token::next( Token *next )
void Token::next(Token *next)
{
_next = next;
}
@ -399,33 +399,33 @@ Token *Token::previous() const
return _previous;
}
void Token::previous( Token *previous )
void Token::previous(Token *previous)
{
_previous = previous;
}
void Token::insertToken( const char str[] )
void Token::insertToken(const char str[])
{
Token *newToken = new Token;
newToken->str( str );
newToken->str(str);
newToken->_linenr = _linenr;
newToken->_fileIndex = _fileIndex;
if( this->next() )
if (this->next())
{
newToken->next( this->next() );
newToken->next()->previous( newToken );
newToken->next(this->next());
newToken->next()->previous(newToken);
}
this->next( newToken );
newToken->previous( this );
this->next(newToken);
newToken->previous(this);
}
void Token::eraseTokens( Token *begin, const Token *end )
void Token::eraseTokens(Token *begin, const Token *end)
{
if ( ! begin )
if (! begin)
return;
while ( begin->next() && begin->next() != end )
while (begin->next() && begin->next() != end)
{
begin->deleteNext();
}
@ -436,7 +436,7 @@ unsigned int Token::fileIndex() const
return _fileIndex;
}
void Token::fileIndex( unsigned int fileIndex )
void Token::fileIndex(unsigned int fileIndex)
{
_fileIndex = fileIndex;
}
@ -446,25 +446,25 @@ unsigned int Token::linenr() const
return _linenr;
}
void Token::linenr( unsigned int linenr )
void Token::linenr(unsigned int linenr)
{
_linenr = linenr;
}
void Token::printOut( const char *title ) const
void Token::printOut(const char *title) const
{
std::cout << std::endl << "###";
if ( title )
if (title)
std::cout << " " << title << " ";
else
std::cout << "########";
std::cout << "###" << std::endl;
for( const Token *t = this; t; t = t->next() )
for (const Token *t = this; t; t = t->next())
{
std::cout << t->linenr() << ": " << t->str();
if ( t->varId() )
std::cout << " ("<< t->varId() <<")";
if (t->varId())
std::cout << " (" << t->varId() << ")";
std::cout << std::endl;
}

42
token.h
View File

@ -26,19 +26,27 @@ class Token
public:
Token();
~Token();
void str( const char s[] );
void str(const char s[]);
const std::string &str() const
{ return _str; }
{
return _str;
}
const char *aaaa() const
{ return _cstr; }
{
return _cstr;
}
char aaaa0() const
{ return _cstr[0]; }
{
return _cstr[0];
}
char aaaa1() const
{ return _cstr[1]; }
{
return _cstr[1];
}
/**
* Unlink and delete next token.
@ -105,14 +113,14 @@ public:
* @return true if given token matches with given pattern
* false if given token does not match with given pattern
*/
static bool Match(const Token *tok, const char pattern[], unsigned int varid=0, const char *varname1[]=0 );
static bool Match(const Token *tok, const char pattern[], unsigned int varid = 0, const char *varname1[] = 0);
bool isName() const;
bool isNumber() const;
bool isBoolean() const;
bool isStandardType() const;
static const Token *findmatch(const Token *tok, const char pattern[], const char *varname1[]=0);
static const Token *findmatch(const Token *tok, const char pattern[], unsigned int varId );
static const Token *findmatch(const Token *tok, const char pattern[], const char *varname1[] = 0);
static const Token *findmatch(const Token *tok, const char pattern[], unsigned int varId);
/**
* Needle is build from multiple alternatives. If one of
@ -127,14 +135,14 @@ public:
* 0 if needle was empty string
* -1 if needle was not found
*/
static int multiCompare( const char *needle, const char *haystack );
static int multiCompare(const char *needle, const char *haystack);
unsigned int linenr() const;
void linenr( unsigned int linenr );
void linenr(unsigned int linenr);
unsigned int fileIndex() const;
void fileIndex( unsigned int fileIndex );
void fileIndex(unsigned int fileIndex);
Token *next() const;
@ -146,20 +154,20 @@ public:
* @param begin Tokens after this will be erased.
* @param end Tokens before this will be erased.
*/
static void eraseTokens( Token *begin, const Token *end );
static void eraseTokens(Token *begin, const Token *end);
/**
* Insert new token after this token. This function will handle
* relations between next and previous token also.
* @param str String for the new token.
*/
void insertToken( const char str[] );
void insertToken(const char str[]);
Token *previous() const;
unsigned int varId() const;
void varId( unsigned int id );
void varId(unsigned int id);
/**
* For debugging purposes, prints token and all tokens
@ -167,11 +175,11 @@ public:
* @param title Title for the printout or use default parameter or 0
* for no title.
*/
void printOut( const char *title = 0 ) const;
void printOut(const char *title = 0) const;
private:
void next( Token *next );
void previous( Token *previous );
void next(Token *next);
void previous(Token *previous);
std::string _str;
char * _cstr;

File diff suppressed because it is too large Load Diff

View File

@ -38,7 +38,7 @@ private:
/**
* Helper function for "tokenize". This recursively parses into included header files.
*/
void tokenizeCode(std::istream &code, const unsigned int FileIndex=0);
void tokenizeCode(std::istream &code, const unsigned int FileIndex = 0);
public:
Tokenizer();
@ -61,12 +61,12 @@ public:
// Helper functions for handling the tokens list..
static void deleteTokens(Token *tok);
static const char *getParameterName( const Token *ftok, int par );
static const char *getParameterName(const Token *ftok, int par);
static bool SameFileName( const char fname1[], const char fname2[] );
static bool SameFileName(const char fname1[], const char fname2[]);
std::string fileLine( const Token *tok ) const;
std::string fileLine(const Token *tok) const;
// Return size.
int SizeOfType(const char type[]) const;
@ -76,7 +76,7 @@ public:
const std::vector<std::string> *getFiles() const;
void fillFunctionList();
const Token *GetFunctionTokenByName( const char funcname[] ) const;
const Token *GetFunctionTokenByName(const char funcname[]) const;
const Token *tokens() const;
@ -98,7 +98,7 @@ private:
* @param end e.g. "}"
* @return The end tag that matches given parameter or 0 if not found.
*/
static const Token *findClosing( const Token *tok, const char *start, const char *end );
static const Token *findClosing(const Token *tok, const char *start, const char *end);
void Define(const char Name[], const char Value[]);