Refactoring: CommonCheck.* files are removed. Rest of the global functions from there were moved to Tokenizer class
This commit is contained in:
parent
66412ed4ae
commit
125692bc65
|
@ -21,7 +21,6 @@
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "CheckBufferOverrun.h"
|
||||
#include "CommonCheck.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
@ -73,7 +72,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
|
||||
|
||||
// Array index..
|
||||
if ( Match(tok, "%var1% [ %num% ]", varname) )
|
||||
if ( Tokenizer::Match(tok, "%var1% [ %num% ]", varname) )
|
||||
{
|
||||
const char *num = Tokenizer::getstr(tok, 2 + varc);
|
||||
if (strtol(num, NULL, 10) >= size)
|
||||
|
@ -86,12 +85,12 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
int indentlevel = 0;
|
||||
for ( ; tok; tok = tok->next )
|
||||
{
|
||||
if (Match(tok, "{"))
|
||||
if (Tokenizer::Match(tok, "{"))
|
||||
{
|
||||
indentlevel++;
|
||||
}
|
||||
|
||||
else if (Match(tok, "}"))
|
||||
else if (Tokenizer::Match(tok, "}"))
|
||||
{
|
||||
indentlevel--;
|
||||
if ( indentlevel < 0 )
|
||||
|
@ -99,7 +98,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
}
|
||||
|
||||
// Array index..
|
||||
if ( !Match(tok, "%var%") && !Match(tok,"[.&]") && Match(tok->next, "%var1% [ %num% ]", varname) )
|
||||
if ( !Tokenizer::Match(tok, "%var%") && !Tokenizer::Match(tok,"[.&]") && Tokenizer::Match(tok->next, "%var1% [ %num% ]", varname) )
|
||||
{
|
||||
const char *num = Tokenizer::getstr(tok->next, 2 + varc);
|
||||
if (strtol(num, NULL, 10) >= size)
|
||||
|
@ -112,15 +111,15 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
|
||||
|
||||
// memset, memcmp, memcpy, strncpy, fgets..
|
||||
if (Match(tok,"memset") ||
|
||||
Match(tok,"memcpy") ||
|
||||
Match(tok,"memmove") ||
|
||||
Match(tok,"memcmp") ||
|
||||
Match(tok,"strncpy") ||
|
||||
Match(tok,"fgets") )
|
||||
if (Tokenizer::Match(tok,"memset") ||
|
||||
Tokenizer::Match(tok,"memcpy") ||
|
||||
Tokenizer::Match(tok,"memmove") ||
|
||||
Tokenizer::Match(tok,"memcmp") ||
|
||||
Tokenizer::Match(tok,"strncpy") ||
|
||||
Tokenizer::Match(tok,"fgets") )
|
||||
{
|
||||
if ( Match( tok->next, "( %var1% , %num% , %num% )", varname ) ||
|
||||
Match( tok->next, "( %var% , %var1% , %num% )", varname ) )
|
||||
if ( Tokenizer::Match( tok->next, "( %var1% , %num% , %num% )", varname ) ||
|
||||
Tokenizer::Match( tok->next, "( %var% , %var1% , %num% )", varname ) )
|
||||
{
|
||||
const char *num = Tokenizer::getstr(tok, varc + 6);
|
||||
if ( atoi(num) > total_size )
|
||||
|
@ -133,22 +132,22 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
|
||||
|
||||
// Loop..
|
||||
if ( Match(tok, "for (") )
|
||||
if ( Tokenizer::Match(tok, "for (") )
|
||||
{
|
||||
const TOKEN *tok2 = Tokenizer::gettok( tok, 2 );
|
||||
|
||||
// for - setup..
|
||||
if ( Match(tok2, "%var% = 0 ;") )
|
||||
if ( Tokenizer::Match(tok2, "%var% = 0 ;") )
|
||||
tok2 = Tokenizer::gettok(tok2, 4);
|
||||
else if ( Match(tok2, "%type% %var% = 0 ;") )
|
||||
else if ( Tokenizer::Match(tok2, "%type% %var% = 0 ;") )
|
||||
tok2 = Tokenizer::gettok(tok2, 5);
|
||||
else if ( Match(tok2, "%type% %type% %var% = 0 ;") )
|
||||
else if ( Tokenizer::Match(tok2, "%type% %type% %var% = 0 ;") )
|
||||
tok2 = Tokenizer::gettok(tok2, 6);
|
||||
else
|
||||
continue;
|
||||
|
||||
// for - condition..
|
||||
if ( ! Match(tok2, "%var% < %num% ;") && ! Match(tok2, "%var% <= %num% ;"))
|
||||
if ( ! Tokenizer::Match(tok2, "%var% < %num% ;") && ! Tokenizer::Match(tok2, "%var% <= %num% ;"))
|
||||
continue;
|
||||
|
||||
// Get index variable and stopsize.
|
||||
|
@ -158,7 +157,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
continue;
|
||||
|
||||
// Goto the end of the for loop..
|
||||
while (tok2 && !Match(tok2,")"))
|
||||
while (tok2 && !Tokenizer::Match(tok2,")"))
|
||||
tok2 = tok2->next;
|
||||
if (!Tokenizer::gettok(tok2,5))
|
||||
break;
|
||||
|
@ -169,20 +168,20 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
int indentlevel2 = 0;
|
||||
while (tok2)
|
||||
{
|
||||
if ( Match(tok2, ";") && indentlevel2 == 0 )
|
||||
if ( Tokenizer::Match(tok2, ";") && indentlevel2 == 0 )
|
||||
break;
|
||||
|
||||
if ( Match(tok2, "{") )
|
||||
if ( Tokenizer::Match(tok2, "{") )
|
||||
indentlevel2++;
|
||||
|
||||
if ( Match(tok2, "}") )
|
||||
if ( Tokenizer::Match(tok2, "}") )
|
||||
{
|
||||
indentlevel2--;
|
||||
if ( indentlevel2 <= 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( Match( tok2, pattern.str().c_str(), varname ) )
|
||||
if ( Tokenizer::Match( tok2, pattern.str().c_str(), varname ) )
|
||||
{
|
||||
ReportError(tok2, "Buffer overrun");
|
||||
break;
|
||||
|
@ -195,7 +194,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
|
||||
|
||||
// Writing data into array..
|
||||
if ( Match(tok, "strcpy ( %var1% , %str% )", varname) )
|
||||
if ( Tokenizer::Match(tok, "strcpy ( %var1% , %str% )", varname) )
|
||||
{
|
||||
int len = 0;
|
||||
const char *str = Tokenizer::getstr(tok, varc + 4 );
|
||||
|
@ -217,7 +216,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
// 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 ( Match( tok, "%var% (" ) )
|
||||
if ( Tokenizer::Match( tok, "%var% (" ) )
|
||||
{
|
||||
// Don't make recursive checking..
|
||||
if (std::find(CallStack.begin(), CallStack.end(), tok) != CallStack.end())
|
||||
|
@ -226,12 +225,12 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
unsigned int parlevel = 0, par = 0;
|
||||
for ( const TOKEN *tok2 = tok; tok2; tok2 = tok2->next )
|
||||
{
|
||||
if ( Match(tok2, "(") )
|
||||
if ( Tokenizer::Match(tok2, "(") )
|
||||
{
|
||||
parlevel++;
|
||||
}
|
||||
|
||||
else if ( Match(tok2, ")") )
|
||||
else if ( Tokenizer::Match(tok2, ")") )
|
||||
{
|
||||
parlevel--;
|
||||
if ( parlevel < 1 )
|
||||
|
@ -241,12 +240,12 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
}
|
||||
}
|
||||
|
||||
else if ( parlevel == 1 && Match(tok2, ",") )
|
||||
else if ( parlevel == 1 && Tokenizer::Match(tok2, ",") )
|
||||
{
|
||||
par++;
|
||||
}
|
||||
|
||||
if ( parlevel == 1 && Match(tok2, "[(,] %var1% [,)]", varname) )
|
||||
if ( parlevel == 1 && Tokenizer::Match(tok2, "[(,] %var1% [,)]", varname) )
|
||||
{
|
||||
par++;
|
||||
break;
|
||||
|
@ -266,16 +265,16 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
parlevel = 1;
|
||||
while ( ftok && parlevel == 1 && par >= 1 )
|
||||
{
|
||||
if ( Match(ftok, "(") )
|
||||
if ( Tokenizer::Match(ftok, "(") )
|
||||
parlevel++;
|
||||
|
||||
else if ( Match(ftok, ")") )
|
||||
else if ( Tokenizer::Match(ftok, ")") )
|
||||
parlevel--;
|
||||
|
||||
else if ( Match(ftok, ",") )
|
||||
else if ( Tokenizer::Match(ftok, ",") )
|
||||
par--;
|
||||
|
||||
else if (par==1 && parlevel==1 && (Match(ftok, "%var% ,") || Match(ftok, "%var% )")))
|
||||
else if (par==1 && parlevel==1 && (Tokenizer::Match(ftok, "%var% ,") || Tokenizer::Match(ftok, "%var% )")))
|
||||
{
|
||||
// Parameter name..
|
||||
const char *parname[2];
|
||||
|
@ -283,7 +282,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
parname[1] = 0;
|
||||
|
||||
// Goto function body..
|
||||
while ( ftok && !Match(ftok,"{") )
|
||||
while ( ftok && !Tokenizer::Match(ftok,"{") )
|
||||
ftok = ftok->next;
|
||||
ftok = ftok ? ftok->next : 0;
|
||||
|
||||
|
@ -312,10 +311,10 @@ void CheckBufferOverrunClass::CheckBufferOverrun_LocalVariable()
|
|||
int indentlevel = 0;
|
||||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
if (Match(tok, "{"))
|
||||
if (Tokenizer::Match(tok, "{"))
|
||||
indentlevel++;
|
||||
|
||||
else if (Match(tok, "}"))
|
||||
else if (Tokenizer::Match(tok, "}"))
|
||||
indentlevel--;
|
||||
|
||||
else if (indentlevel > 0)
|
||||
|
@ -324,13 +323,13 @@ void CheckBufferOverrunClass::CheckBufferOverrun_LocalVariable()
|
|||
unsigned int size = 0;
|
||||
const char *type = 0;
|
||||
|
||||
if (Match(tok, "%type% %var% [ %num% ] ;"))
|
||||
if (Tokenizer::Match(tok, "%type% %var% [ %num% ] ;"))
|
||||
{
|
||||
varname[0] = Tokenizer::getstr(tok,1);
|
||||
size = strtoul(Tokenizer::getstr(tok,3), NULL, 10);
|
||||
type = tok->str;
|
||||
}
|
||||
else if (indentlevel > 0 && Match(tok, "[*;{}] %var% = new %type% [ %num% ]"))
|
||||
else if (indentlevel > 0 && Tokenizer::Match(tok, "[*;{}] %var% = new %type% [ %num% ]"))
|
||||
{
|
||||
varname[0] = Tokenizer::getstr(tok,1);
|
||||
size = strtoul(Tokenizer::getstr(tok,6), NULL, 10);
|
||||
|
@ -365,28 +364,28 @@ void CheckBufferOverrunClass::CheckBufferOverrun_StructVariable()
|
|||
tok;
|
||||
tok = Tokenizer::findtoken( tok->next, declstruct_pattern ) )
|
||||
{
|
||||
if (!Match(tok,"struct") && !Match(tok,"class"))
|
||||
if (!Tokenizer::Match(tok,"struct") && !Tokenizer::Match(tok,"class"))
|
||||
continue;
|
||||
|
||||
const char *structname = tok->next->str;
|
||||
|
||||
if ( ! IsName( structname ) )
|
||||
if ( ! Tokenizer::IsName( structname ) )
|
||||
continue;
|
||||
|
||||
// Found a struct declaration. Search for arrays..
|
||||
for ( TOKEN * tok2 = tok->next->next; tok2; tok2 = tok2->next )
|
||||
{
|
||||
if ( Match(tok2, "}") )
|
||||
if ( Tokenizer::Match(tok2, "}") )
|
||||
break;
|
||||
|
||||
int ivar = 0;
|
||||
if ( Match(tok2->next, "%type% %var% [ %num% ] ;") )
|
||||
if ( Tokenizer::Match(tok2->next, "%type% %var% [ %num% ] ;") )
|
||||
ivar = 2;
|
||||
else if ( Match(tok2->next, "%type% %type% %var% [ %num% ] ;") )
|
||||
else if ( Tokenizer::Match(tok2->next, "%type% %type% %var% [ %num% ] ;") )
|
||||
ivar = 3;
|
||||
else if ( Match(tok2->next, "%type% * %var% [ %num% ] ;") )
|
||||
else if ( Tokenizer::Match(tok2->next, "%type% * %var% [ %num% ] ;") )
|
||||
ivar = 3;
|
||||
else if ( Match(tok2->next, "%type% %type% * %var% [ %num% ] ;") )
|
||||
else if ( Tokenizer::Match(tok2->next, "%type% %type% * %var% [ %num% ] ;") )
|
||||
ivar = 4;
|
||||
else
|
||||
continue;
|
||||
|
@ -400,7 +399,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_StructVariable()
|
|||
|
||||
|
||||
// Class member variable => Check functions
|
||||
if ( Match(tok, "class") )
|
||||
if ( Tokenizer::Match(tok, "class") )
|
||||
{
|
||||
std::string func_pattern(structname + std::string(" :: %var% ("));
|
||||
const TOKEN *tok3 = Tokenizer::findmatch(_tokenizer->tokens(), func_pattern.c_str());
|
||||
|
@ -408,10 +407,10 @@ void CheckBufferOverrunClass::CheckBufferOverrun_StructVariable()
|
|||
{
|
||||
for ( const TOKEN *tok4 = tok3; tok4; tok4 = tok4->next )
|
||||
{
|
||||
if ( Match(tok4,"[;{}]") )
|
||||
if ( Tokenizer::Match(tok4,"[;{}]") )
|
||||
break;
|
||||
|
||||
if ( Match(tok4, ") {") )
|
||||
if ( Tokenizer::Match(tok4, ") {") )
|
||||
{
|
||||
const char *names[2] = {varname[1], 0};
|
||||
CheckBufferOverrun_CheckScope( Tokenizer::gettok(tok4, 2), names, arrsize, total_size );
|
||||
|
@ -428,11 +427,11 @@ void CheckBufferOverrunClass::CheckBufferOverrun_StructVariable()
|
|||
continue;
|
||||
|
||||
// Declare variable: Fred fred1;
|
||||
if ( Match( tok3->next, "%var% ;" ) )
|
||||
if ( Tokenizer::Match( tok3->next, "%var% ;" ) )
|
||||
varname[0] = Tokenizer::getstr(tok3, 1);
|
||||
|
||||
// Declare pointer: Fred *fred1
|
||||
else if ( Match(tok3->next, "* %var% [,);=]") )
|
||||
else if ( Tokenizer::Match(tok3->next, "* %var% [,);=]") )
|
||||
varname[0] = Tokenizer::getstr(tok3, 2);
|
||||
|
||||
else
|
||||
|
@ -444,18 +443,18 @@ void CheckBufferOverrunClass::CheckBufferOverrun_StructVariable()
|
|||
while ( tok3 )
|
||||
{
|
||||
// End of statement.
|
||||
if ( Match(tok3, ";") )
|
||||
if ( Tokenizer::Match(tok3, ";") )
|
||||
{
|
||||
CheckTok = tok3;
|
||||
break;
|
||||
}
|
||||
|
||||
// End of function declaration..
|
||||
if ( Match(tok3, ") ;") )
|
||||
if ( Tokenizer::Match(tok3, ") ;") )
|
||||
break;
|
||||
|
||||
// Function implementation..
|
||||
if ( Match(tok3, ") {") )
|
||||
if ( Tokenizer::Match(tok3, ") {") )
|
||||
{
|
||||
CheckTok = Tokenizer::gettok(tok3, 2);
|
||||
break;
|
||||
|
@ -502,14 +501,14 @@ void CheckBufferOverrunClass::WarningDangerousFunctions()
|
|||
{
|
||||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
if (Match(tok, "gets ("))
|
||||
if (Tokenizer::Match(tok, "gets ("))
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << _tokenizer->fileLine(tok) << ": Found 'gets'. You should use 'fgets' instead";
|
||||
_errorLogger->reportErr(ostr.str());
|
||||
}
|
||||
|
||||
else if (Match(tok, "scanf (") && strcmp(Tokenizer::getstr(tok,2),"\"%s\"") == 0)
|
||||
else if (Tokenizer::Match(tok, "scanf (") && strcmp(Tokenizer::getstr(tok,2),"\"%s\"") == 0)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << _tokenizer->fileLine(tok) << ": Found 'scanf'. You should use 'fgets' instead";
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
//---------------------------------------------------------------------------
|
||||
#include "CheckClass.h"
|
||||
|
||||
#include "CommonCheck.h"
|
||||
#include <locale>
|
||||
|
||||
#include <string>
|
||||
|
@ -75,7 +74,7 @@ struct VAR *CheckClass::ClassChecking_GetVarList(const TOKEN *tok1)
|
|||
const char *varname = 0;
|
||||
|
||||
// Is it a variable declaration?
|
||||
if ( Match(next,"%type% %var% ;") )
|
||||
if ( Tokenizer::Match(next,"%type% %var% ;") )
|
||||
{
|
||||
const char *types[] = {"bool", "char", "int", "short", "long", "float", "double", 0};
|
||||
for ( int type = 0; types[type]; type++ )
|
||||
|
@ -89,7 +88,7 @@ struct VAR *CheckClass::ClassChecking_GetVarList(const TOKEN *tok1)
|
|||
}
|
||||
|
||||
// Pointer?
|
||||
else if ( Match(next, "%type% * %var% ;") )
|
||||
else if ( Tokenizer::Match(next, "%type% * %var% ;") )
|
||||
{
|
||||
varname = Tokenizer::getstr(next, 2);
|
||||
}
|
||||
|
@ -123,10 +122,10 @@ const TOKEN * CheckClass::FindClassFunction( const TOKEN *tok, const char classn
|
|||
for ( ;tok; tok = tok->next )
|
||||
{
|
||||
if ( indentlevel == 0 &&
|
||||
( Match(tok, "class %var1% {", _classname) ||
|
||||
Match(tok, "class %var1% : %type% {", _classname) ) )
|
||||
( Tokenizer::Match(tok, "class %var1% {", _classname) ||
|
||||
Tokenizer::Match(tok, "class %var1% : %type% {", _classname) ) )
|
||||
{
|
||||
if ( Match(tok, "class %var% {") )
|
||||
if ( Tokenizer::Match(tok, "class %var% {") )
|
||||
tok = Tokenizer::gettok(tok, 3);
|
||||
else
|
||||
tok = Tokenizer::gettok(tok, 5);
|
||||
|
@ -169,7 +168,7 @@ const TOKEN * CheckClass::FindClassFunction( const TOKEN *tok, const char classn
|
|||
if ( indentlevel == 1 )
|
||||
{
|
||||
// Member function implemented in the class declaration?
|
||||
if ( Match( tok, "%var1% (", _funcname ) )
|
||||
if ( Tokenizer::Match( tok, "%var1% (", _funcname ) )
|
||||
{
|
||||
const TOKEN *tok2 = tok;
|
||||
while ( tok2 && tok2->str[0] != '{' && tok2->str[0] != ';' )
|
||||
|
@ -179,7 +178,7 @@ const TOKEN * CheckClass::FindClassFunction( const TOKEN *tok, const char classn
|
|||
}
|
||||
}
|
||||
|
||||
else if ( indentlevel == 0 && Match(tok, "%var1% :: %var2% (", _classname, _funcname) )
|
||||
else if ( indentlevel == 0 && Tokenizer::Match(tok, "%var1% :: %var2% (", _classname, _funcname) )
|
||||
{
|
||||
return tok;
|
||||
}
|
||||
|
@ -217,7 +216,7 @@ void CheckClass::ClassChecking_VarList_Initialize(const TOKEN *tok1, const TOKEN
|
|||
// clKalle::clKalle() : var(value) { }
|
||||
if (indentlevel==0)
|
||||
{
|
||||
if (Assign && Match(ftok, "%var% ("))
|
||||
if (Assign && Tokenizer::Match(ftok, "%var% ("))
|
||||
{
|
||||
InitVar( varlist, ftok->str );
|
||||
}
|
||||
|
@ -243,29 +242,29 @@ void CheckClass::ClassChecking_VarList_Initialize(const TOKEN *tok1, const TOKEN
|
|||
continue;
|
||||
|
||||
// Before a new statement there is "[{};)=]" or "else"
|
||||
if ( ! Match(ftok, "[{};)=]") && ! Match(ftok, "else") )
|
||||
if ( ! Tokenizer::Match(ftok, "[{};)=]") && ! Tokenizer::Match(ftok, "else") )
|
||||
continue;
|
||||
|
||||
// Using the operator= function to initialize all variables..
|
||||
if ( Match(ftok->next, "* this = ") )
|
||||
if ( Tokenizer::Match(ftok->next, "* this = ") )
|
||||
{
|
||||
for (struct VAR *var = varlist; var; var = var->next)
|
||||
var->init = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!Match(ftok->next, "%var%") && !Match(ftok->next, "this . %var%"))
|
||||
if (!Tokenizer::Match(ftok->next, "%var%") && !Tokenizer::Match(ftok->next, "this . %var%"))
|
||||
continue;
|
||||
|
||||
// Goto the first token in this statement..
|
||||
ftok = ftok->next;
|
||||
|
||||
// Skip "this->"
|
||||
if ( Match(ftok, "this .") )
|
||||
if ( Tokenizer::Match(ftok, "this .") )
|
||||
ftok = Tokenizer::gettok(ftok, 2);
|
||||
|
||||
// Clearing all variables..
|
||||
if (Match(ftok,"memset ( this ,"))
|
||||
if (Tokenizer::Match(ftok,"memset ( this ,"))
|
||||
{
|
||||
for (struct VAR *var = varlist; var; var = var->next)
|
||||
var->init = true;
|
||||
|
@ -273,7 +272,7 @@ void CheckClass::ClassChecking_VarList_Initialize(const TOKEN *tok1, const TOKEN
|
|||
}
|
||||
|
||||
// Calling member function?
|
||||
else if (Match(ftok, "%var% ("))
|
||||
else if (Tokenizer::Match(ftok, "%var% ("))
|
||||
{
|
||||
// No recursive calls!
|
||||
if ( std::find(callstack.begin(),callstack.end(),ftok->str) == callstack.end() )
|
||||
|
@ -286,13 +285,13 @@ void CheckClass::ClassChecking_VarList_Initialize(const TOKEN *tok1, const TOKEN
|
|||
}
|
||||
|
||||
// Assignment of member variable?
|
||||
else if (Match(ftok, "%var% ="))
|
||||
else if (Tokenizer::Match(ftok, "%var% ="))
|
||||
{
|
||||
InitVar( varlist, ftok->str );
|
||||
}
|
||||
|
||||
// The functions 'clear' and 'Clear' are supposed to initialize variable.
|
||||
if (Match(ftok,"%var% . clear (") || Match(ftok,"%var% . Clear ("))
|
||||
if (Tokenizer::Match(ftok,"%var% . clear (") || Tokenizer::Match(ftok,"%var% . Clear ("))
|
||||
{
|
||||
InitVar( varlist, ftok->str );
|
||||
}
|
||||
|
@ -316,7 +315,7 @@ void CheckClass::CheckConstructors()
|
|||
while (tok1)
|
||||
{
|
||||
const char *classname = tok1->next->str;
|
||||
if ( ! IsName(classname) )
|
||||
if ( ! Tokenizer::IsName(classname) )
|
||||
{
|
||||
tok1 = Tokenizer::findtoken( tok1->next, pattern_classname );
|
||||
continue;
|
||||
|
@ -431,7 +430,7 @@ void CheckClass::CheckUnusedPrivateFunctions()
|
|||
unsigned int indent_level = 0;
|
||||
for (const TOKEN *tok = tok1; tok; tok = tok->next)
|
||||
{
|
||||
if (Match(tok,"friend %var%"))
|
||||
if (Tokenizer::Match(tok,"friend %var%"))
|
||||
{
|
||||
// Todo: Handle friend classes
|
||||
FuncList.clear();
|
||||
|
@ -456,11 +455,11 @@ void CheckClass::CheckUnusedPrivateFunctions()
|
|||
priv = false;
|
||||
else if (priv && indent_level == 1)
|
||||
{
|
||||
if ( Match(tok, "typedef %type% (") )
|
||||
if ( Tokenizer::Match(tok, "typedef %type% (") )
|
||||
tok = Tokenizer::gettok(tok, 2);
|
||||
|
||||
if (Match(tok, "%var% (") &&
|
||||
!Match(tok,classname))
|
||||
if (Tokenizer::Match(tok, "%var% (") &&
|
||||
!Tokenizer::Match(tok,classname))
|
||||
{
|
||||
FuncList.push_back(tok->str);
|
||||
}
|
||||
|
@ -550,20 +549,20 @@ void CheckClass::CheckMemset()
|
|||
// Locate all 'memset' tokens..
|
||||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
if (!Match(tok,"memset") && !Match(tok,"memcpy") && !Match(tok,"memmove"))
|
||||
if (!Tokenizer::Match(tok,"memset") && !Tokenizer::Match(tok,"memcpy") && !Tokenizer::Match(tok,"memmove"))
|
||||
continue;
|
||||
|
||||
// Todo: Handle memcpy and memmove
|
||||
const char *type = NULL;
|
||||
if (Match(tok, "memset ( %var% , %num% , sizeof ( %type% ) )"))
|
||||
if (Tokenizer::Match(tok, "memset ( %var% , %num% , sizeof ( %type% ) )"))
|
||||
type = Tokenizer::getstr(tok, 8);
|
||||
else if (Match(tok, "memset ( & %var% , %num% , sizeof ( %type% ) )"))
|
||||
else if (Tokenizer::Match(tok, "memset ( & %var% , %num% , sizeof ( %type% ) )"))
|
||||
type = Tokenizer::getstr(tok, 9);
|
||||
else if (Match(tok, "memset ( %var% , %num% , sizeof ( struct %type% ) )"))
|
||||
else if (Tokenizer::Match(tok, "memset ( %var% , %num% , sizeof ( struct %type% ) )"))
|
||||
type = Tokenizer::getstr(tok, 9);
|
||||
else if (Match(tok, "memset ( & %var% , %num% , sizeof ( struct %type% ) )"))
|
||||
else if (Tokenizer::Match(tok, "memset ( & %var% , %num% , sizeof ( struct %type% ) )"))
|
||||
type = Tokenizer::getstr(tok, 10);
|
||||
else if (Match(tok, "%type% ( %var% , %var% , sizeof ( %type% ) )"))
|
||||
else if (Tokenizer::Match(tok, "%type% ( %var% , %var% , sizeof ( %type% ) )"))
|
||||
type = Tokenizer::getstr(tok, 8);
|
||||
|
||||
// No type defined => The tokens didn't match
|
||||
|
@ -589,7 +588,7 @@ void CheckClass::CheckMemset()
|
|||
if (tstruct->str[0] == '}')
|
||||
break;
|
||||
|
||||
if (Match(tstruct, "std :: %type% %var% ;"))
|
||||
if (Tokenizer::Match(tstruct, "std :: %type% %var% ;"))
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << _tokenizer->fileLine(tok) << ": Using '" << tok->str << "' on struct that contains a 'std::" << Tokenizer::getstr(tstruct,2) << "'";
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
//---------------------------------------------------------------------------
|
||||
#include "CheckHeaders.h"
|
||||
#include "tokenize.h"
|
||||
#include "CommonCheck.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <list>
|
||||
|
@ -55,7 +54,7 @@ void CheckHeaders::WarningHeaderWithImplementation()
|
|||
if (tok->FileIndex == 0)
|
||||
continue;
|
||||
|
||||
if (Match(tok, ") {"))
|
||||
if (Tokenizer::Match(tok, ") {"))
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << _tokenizer->fileLine(tok) << ": Found implementation in header";
|
||||
|
@ -94,7 +93,7 @@ void CheckHeaders::WarningIncludeHeader()
|
|||
const char *includefile = includetok->next->str;
|
||||
while (hfile < _tokenizer->getFiles()->size())
|
||||
{
|
||||
if ( SameFileName( _tokenizer->getFiles()->at(hfile).c_str(), includefile ) )
|
||||
if ( Tokenizer::SameFileName( _tokenizer->getFiles()->at(hfile).c_str(), includefile ) )
|
||||
break;
|
||||
hfile++;
|
||||
}
|
||||
|
@ -130,21 +129,21 @@ void CheckHeaders::WarningIncludeHeader()
|
|||
|
||||
// Class or namespace declaration..
|
||||
// --------------------------------------
|
||||
if (Match(tok1,"class %var% {") || Match(tok1,"class %var% :") || Match(tok1,"namespace %var% {"))
|
||||
if (Tokenizer::Match(tok1,"class %var% {") || Tokenizer::Match(tok1,"class %var% :") || Tokenizer::Match(tok1,"namespace %var% {"))
|
||||
classlist.push_back(Tokenizer::getstr(tok1, 1));
|
||||
|
||||
// Variable declaration..
|
||||
// --------------------------------------
|
||||
else if (Match(tok1, "%type% %var% ;") || Match(tok1, "%type% %var% ["))
|
||||
else if (Tokenizer::Match(tok1, "%type% %var% ;") || Tokenizer::Match(tok1, "%type% %var% ["))
|
||||
namelist.push_back(Tokenizer::getstr(tok1, 1));
|
||||
|
||||
else if (Match(tok1, "%type% * %var% ;") || Match(tok1, "%type% * %var% ["))
|
||||
else if (Tokenizer::Match(tok1, "%type% * %var% ;") || Tokenizer::Match(tok1, "%type% * %var% ["))
|
||||
namelist.push_back(Tokenizer::getstr(tok1, 2));
|
||||
|
||||
else if (Match(tok1, "const %type% %var% =") || Match(tok1, "const %type% %var% ["))
|
||||
else if (Tokenizer::Match(tok1, "const %type% %var% =") || Tokenizer::Match(tok1, "const %type% %var% ["))
|
||||
namelist.push_back(Tokenizer::getstr(tok1, 2));
|
||||
|
||||
else if (Match(tok1, "const %type% * %var% =") || Match(tok1, "const %type% * %var% ["))
|
||||
else if (Tokenizer::Match(tok1, "const %type% * %var% =") || Tokenizer::Match(tok1, "const %type% * %var% ["))
|
||||
namelist.push_back(Tokenizer::getstr(tok1, 3));
|
||||
|
||||
// enum..
|
||||
|
@ -154,7 +153,7 @@ void CheckHeaders::WarningIncludeHeader()
|
|||
tok1 = tok1->next;
|
||||
while (tok1->next && tok1->str[0]!=';')
|
||||
{
|
||||
if ( IsName(tok1->str) )
|
||||
if ( Tokenizer::IsName(tok1->str) )
|
||||
namelist.push_back(tok1->str);
|
||||
tok1 = tok1->next;
|
||||
}
|
||||
|
@ -162,16 +161,16 @@ void CheckHeaders::WarningIncludeHeader()
|
|||
|
||||
// function..
|
||||
// --------------------------------------
|
||||
else if (Match(tok1,"%type% %var% ("))
|
||||
else if (Tokenizer::Match(tok1,"%type% %var% ("))
|
||||
namelist.push_back(Tokenizer::getstr(tok1, 1));
|
||||
|
||||
else if (Match(tok1,"%type% * %var% ("))
|
||||
else if (Tokenizer::Match(tok1,"%type% * %var% ("))
|
||||
namelist.push_back(Tokenizer::getstr(tok1, 2));
|
||||
|
||||
else if (Match(tok1,"const %type% %var% ("))
|
||||
else if (Tokenizer::Match(tok1,"const %type% %var% ("))
|
||||
namelist.push_back(Tokenizer::getstr(tok1, 2));
|
||||
|
||||
else if (Match(tok1,"const %type% * %var% ("))
|
||||
else if (Tokenizer::Match(tok1,"const %type% * %var% ("))
|
||||
namelist.push_back(Tokenizer::getstr(tok1, 3));
|
||||
|
||||
// typedef..
|
||||
|
@ -194,7 +193,7 @@ void CheckHeaders::WarningIncludeHeader()
|
|||
if ( tok1->str[0] == ';' )
|
||||
break;
|
||||
|
||||
if ( Match(tok1, "%var% ;") )
|
||||
if ( Tokenizer::Match(tok1, "%var% ;") )
|
||||
namelist.push_back(tok1->str);
|
||||
}
|
||||
|
||||
|
@ -212,7 +211,7 @@ void CheckHeaders::WarningIncludeHeader()
|
|||
if (tok1->FileIndex != includetok->FileIndex)
|
||||
continue;
|
||||
|
||||
if ( Match(tok1, ": %var% {") || Match(tok1, ": %type% %var% {") )
|
||||
if ( Tokenizer::Match(tok1, ": %var% {") || Tokenizer::Match(tok1, ": %type% %var% {") )
|
||||
{
|
||||
std::string classname = Tokenizer::getstr(tok1, (strcmp(Tokenizer::getstr(tok1,2),"{")) ? 2 : 1);
|
||||
if (std::find(classlist.begin(),classlist.end(),classname)!=classlist.end())
|
||||
|
@ -222,7 +221,7 @@ void CheckHeaders::WarningIncludeHeader()
|
|||
}
|
||||
}
|
||||
|
||||
if ( ! IsName(tok1->str) )
|
||||
if ( ! Tokenizer::IsName(tok1->str) )
|
||||
continue;
|
||||
|
||||
if (std::find(namelist.begin(),namelist.end(),tok1->str ) != namelist.end())
|
||||
|
|
|
@ -19,11 +19,6 @@
|
|||
|
||||
#include "CheckMemoryLeak.h"
|
||||
|
||||
|
||||
|
||||
#include "CommonCheck.h"
|
||||
|
||||
|
||||
#include <stdlib.h> // free
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -124,16 +119,16 @@ CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetAllocationType( const T
|
|||
return gMalloc;
|
||||
}
|
||||
|
||||
if ( Match( tok2, "new %type% [;(]" ) )
|
||||
if ( Tokenizer::Match( tok2, "new %type% [;(]" ) )
|
||||
return New;
|
||||
|
||||
if ( Match( tok2, "new %type% [" ) )
|
||||
if ( Tokenizer::Match( tok2, "new %type% [" ) )
|
||||
return NewA;
|
||||
|
||||
if ( Match( tok2, "fopen (" ) )
|
||||
if ( Tokenizer::Match( tok2, "fopen (" ) )
|
||||
return FOPEN;
|
||||
|
||||
if ( Match( tok2, "popen (" ) )
|
||||
if ( Tokenizer::Match( tok2, "popen (" ) )
|
||||
return POPEN;
|
||||
|
||||
// Userdefined allocation function..
|
||||
|
@ -151,32 +146,32 @@ CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetAllocationType( const T
|
|||
CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetDeallocationType( const TOKEN *tok, const char *varnames[] )
|
||||
{
|
||||
// Redundant condition..
|
||||
if ( Match(tok, "if ( %var1% )", varnames) )
|
||||
if ( Tokenizer::Match(tok, "if ( %var1% )", varnames) )
|
||||
{
|
||||
tok = Tokenizer::gettok( tok, 4 );
|
||||
if ( Match(tok,"{") )
|
||||
if ( Tokenizer::Match(tok,"{") )
|
||||
tok = tok->next;
|
||||
}
|
||||
|
||||
if ( Match(tok, "delete %var1% ;", varnames) )
|
||||
if ( Tokenizer::Match(tok, "delete %var1% ;", varnames) )
|
||||
return New;
|
||||
|
||||
if ( Match(tok, "delete [ ] %var1% ;", varnames) )
|
||||
if ( Tokenizer::Match(tok, "delete [ ] %var1% ;", varnames) )
|
||||
return NewA;
|
||||
|
||||
if ( Match(tok, "free ( %var1% ) ;", varnames) ||
|
||||
Match(tok, "kfree ( %var1% ) ;", varnames) )
|
||||
if ( Tokenizer::Match(tok, "free ( %var1% ) ;", varnames) ||
|
||||
Tokenizer::Match(tok, "kfree ( %var1% ) ;", varnames) )
|
||||
{
|
||||
return Malloc;
|
||||
}
|
||||
|
||||
if ( Match(tok, "g_free ( %var1% ) ;", varnames) )
|
||||
if ( Tokenizer::Match(tok, "g_free ( %var1% ) ;", varnames) )
|
||||
return gMalloc;
|
||||
|
||||
if ( Match(tok, "fclose ( %var1% )", varnames) )
|
||||
if ( Tokenizer::Match(tok, "fclose ( %var1% )", varnames) )
|
||||
return FOPEN;
|
||||
|
||||
if ( Match(tok, "pclose ( %var1% )", varnames) )
|
||||
if ( Tokenizer::Match(tok, "pclose ( %var1% )", varnames) )
|
||||
return POPEN;
|
||||
|
||||
return No;
|
||||
|
@ -185,7 +180,7 @@ CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetDeallocationType( const
|
|||
|
||||
const char * CheckMemoryLeakClass::call_func( const TOKEN *tok, std::list<const TOKEN *> callstack, const char *varnames[], AllocType &alloctype, AllocType &dealloctype )
|
||||
{
|
||||
if (Match(tok,"if") || Match(tok,"for") || Match(tok,"while"))
|
||||
if (Tokenizer::Match(tok,"if") || Tokenizer::Match(tok,"for") || Tokenizer::Match(tok,"while"))
|
||||
return 0;
|
||||
|
||||
if (GetAllocationType(tok)!=No || GetDeallocationType(tok,varnames)!=No)
|
||||
|
@ -206,9 +201,9 @@ const char * CheckMemoryLeakClass::call_func( const TOKEN *tok, std::list<const
|
|||
int parlevel = 0;
|
||||
for ( ; tok; tok = tok->next )
|
||||
{
|
||||
if ( Match(tok, "(") )
|
||||
if ( Tokenizer::Match(tok, "(") )
|
||||
++parlevel;
|
||||
else if ( Match(tok, ")") )
|
||||
else if ( Tokenizer::Match(tok, ")") )
|
||||
{
|
||||
--parlevel;
|
||||
if ( parlevel < 1 )
|
||||
|
@ -217,16 +212,16 @@ const char * CheckMemoryLeakClass::call_func( const TOKEN *tok, std::list<const
|
|||
|
||||
if ( parlevel == 1 )
|
||||
{
|
||||
if ( Match(tok, ",") )
|
||||
if ( Tokenizer::Match(tok, ",") )
|
||||
++par;
|
||||
if ( Match(tok, "[,()] %var1% [,()]", varnames) )
|
||||
if ( Tokenizer::Match(tok, "[,()] %var1% [,()]", varnames) )
|
||||
{
|
||||
const TOKEN *ftok = _tokenizer->GetFunctionTokenByName(funcname);
|
||||
const char *parname = Tokenizer::getParameterName( ftok, par );
|
||||
if ( ! parname )
|
||||
return "use";
|
||||
// Check if the function deallocates the variable..
|
||||
while ( ftok && ! Match(ftok,"{") )
|
||||
while ( ftok && ! Tokenizer::Match(ftok,"{") )
|
||||
ftok = ftok->next;
|
||||
TOKEN *func = getcode( Tokenizer::gettok(ftok,1), callstack, parname, alloctype, dealloctype );
|
||||
simplifycode( func );
|
||||
|
@ -276,12 +271,12 @@ void CheckMemoryLeakClass::instoken(TOKEN *tok, const char str[])
|
|||
|
||||
bool CheckMemoryLeakClass::notvar(const TOKEN *tok, const char *varnames[])
|
||||
{
|
||||
return bool( Match(tok, "! %var1% [;)&|]", varnames) ||
|
||||
Match(tok, "! ( %var1% )", varnames) ||
|
||||
Match(tok, "unlikely ( ! %var1% )", varnames) ||
|
||||
Match(tok, "unlikely ( %var1% == 0 )", varnames) ||
|
||||
Match(tok, "0 == %var1% [;)&|]", varnames) ||
|
||||
Match(tok, "%var1% == 0", varnames) );
|
||||
return bool( Tokenizer::Match(tok, "! %var1% [;)&|]", varnames) ||
|
||||
Tokenizer::Match(tok, "! ( %var1% )", varnames) ||
|
||||
Tokenizer::Match(tok, "unlikely ( ! %var1% )", varnames) ||
|
||||
Tokenizer::Match(tok, "unlikely ( %var1% == 0 )", varnames) ||
|
||||
Tokenizer::Match(tok, "0 == %var1% [;)&|]", varnames) ||
|
||||
Tokenizer::Match(tok, "%var1% == 0", varnames) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -339,14 +334,14 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
|
|||
if ( parlevel == 0 && tok->str[0]==';')
|
||||
addtoken(";");
|
||||
|
||||
if (Match(tok, "[(;{}] %var1% =", varnames))
|
||||
if (Tokenizer::Match(tok, "[(;{}] %var1% =", varnames))
|
||||
{
|
||||
AllocType alloc = GetAllocationType(Tokenizer::gettok(tok,3));
|
||||
|
||||
// If "--all" hasn't been given, don't check classes..
|
||||
if ( alloc == New && ! _settings._showAll )
|
||||
{
|
||||
if ( Match(Tokenizer::gettok(tok,3), "new %type% [(;]") )
|
||||
if ( Tokenizer::Match(Tokenizer::gettok(tok,3), "new %type% [(;]") )
|
||||
{
|
||||
if ( isclass( Tokenizer::getstr(tok, 4) ) )
|
||||
alloc = No;
|
||||
|
@ -376,35 +371,35 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
|
|||
}
|
||||
|
||||
// if else switch
|
||||
if ( Match(tok, "if ( %var1% )", varnames) ||
|
||||
Match(tok, "if ( %var1% != 0 )", varnames) ||
|
||||
Match(tok, "if ( 0 != %var1% )", varnames) )
|
||||
if ( Tokenizer::Match(tok, "if ( %var1% )", varnames) ||
|
||||
Tokenizer::Match(tok, "if ( %var1% != 0 )", varnames) ||
|
||||
Tokenizer::Match(tok, "if ( 0 != %var1% )", varnames) )
|
||||
{
|
||||
addtoken("if(var)");
|
||||
tok = Tokenizer::gettok(tok, 3); // Make sure the "use" will not be added
|
||||
}
|
||||
else if ( Match(tok, "if (") && notvar(Tokenizer::gettok(tok,2), varnames) )
|
||||
else if ( Tokenizer::Match(tok, "if (") && notvar(Tokenizer::gettok(tok,2), varnames) )
|
||||
{
|
||||
addtoken("if(!var)");
|
||||
}
|
||||
else if ( Match(tok, "if") )
|
||||
else if ( Tokenizer::Match(tok, "if") )
|
||||
{
|
||||
// Check if the condition depends on var somehow..
|
||||
bool dep = false;
|
||||
int parlevel = 0;
|
||||
for ( const TOKEN *tok2 = tok; tok2; tok2 = tok2->next )
|
||||
{
|
||||
if ( Match(tok2,"(") )
|
||||
if ( Tokenizer::Match(tok2,"(") )
|
||||
++parlevel;
|
||||
if ( Match(tok2,")") )
|
||||
if ( Tokenizer::Match(tok2,")") )
|
||||
{
|
||||
--parlevel;
|
||||
if ( parlevel <= 0 )
|
||||
break;
|
||||
}
|
||||
if ( !Match(tok2,".") &&
|
||||
Match(tok2->next, "%var1%", varnames) &&
|
||||
!Match(tok2->next, "%var1% .", varnames) )
|
||||
if ( !Tokenizer::Match(tok2,".") &&
|
||||
Tokenizer::Match(tok2->next, "%var1%", varnames) &&
|
||||
!Tokenizer::Match(tok2->next, "%var1% .", varnames) )
|
||||
{
|
||||
dep = true;
|
||||
break;
|
||||
|
@ -412,30 +407,30 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
|
|||
}
|
||||
addtoken( (dep ? "ifv" : "if") );
|
||||
}
|
||||
else if ( Match(tok, "else") || Match(tok, "switch") )
|
||||
else if ( Tokenizer::Match(tok, "else") || Tokenizer::Match(tok, "switch") )
|
||||
{
|
||||
addtoken(tok->str);
|
||||
}
|
||||
|
||||
if ( Match(tok, "case") )
|
||||
if ( Tokenizer::Match(tok, "case") )
|
||||
{
|
||||
addtoken("case");
|
||||
addtoken(";");
|
||||
}
|
||||
|
||||
if ( Match(tok, "default") )
|
||||
if ( Tokenizer::Match(tok, "default") )
|
||||
{
|
||||
addtoken("case");
|
||||
addtoken(";");
|
||||
}
|
||||
|
||||
// Loops..
|
||||
if (Match(tok, "for") || Match(tok, "while") )
|
||||
if (Tokenizer::Match(tok, "for") || Tokenizer::Match(tok, "while") )
|
||||
{
|
||||
addtoken("loop");
|
||||
isloop = true;
|
||||
}
|
||||
if ( Match(tok, "do") )
|
||||
if ( Tokenizer::Match(tok, "do") )
|
||||
{
|
||||
addtoken("do");
|
||||
}
|
||||
|
@ -443,36 +438,36 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
|
|||
addtoken("!var");
|
||||
|
||||
// continue / break..
|
||||
if ( Match(tok, "continue") )
|
||||
if ( Tokenizer::Match(tok, "continue") )
|
||||
addtoken("continue");
|
||||
if ( Match(tok, "break") )
|
||||
if ( Tokenizer::Match(tok, "break") )
|
||||
addtoken("break");
|
||||
|
||||
// goto..
|
||||
if ( Match(tok, "goto") )
|
||||
if ( Tokenizer::Match(tok, "goto") )
|
||||
{
|
||||
addtoken("goto");
|
||||
}
|
||||
|
||||
// Return..
|
||||
if ( Match(tok, "return") )
|
||||
if ( Tokenizer::Match(tok, "return") )
|
||||
{
|
||||
addtoken("return");
|
||||
if ( Match(tok, "return %var1%", varnames) ||
|
||||
Match(tok, "return & %var1%", varnames) )
|
||||
if ( Tokenizer::Match(tok, "return %var1%", varnames) ||
|
||||
Tokenizer::Match(tok, "return & %var1%", varnames) )
|
||||
addtoken("use");
|
||||
}
|
||||
|
||||
// throw..
|
||||
if ( Match(tok, "throw") )
|
||||
if ( Tokenizer::Match(tok, "throw") )
|
||||
addtoken("throw");
|
||||
|
||||
// Assignment..
|
||||
if ( Match(tok,"[)=] %var1% [;)]", varnames) )
|
||||
if ( Tokenizer::Match(tok,"[)=] %var1% [;)]", varnames) )
|
||||
addtoken("use");
|
||||
|
||||
// Investigate function calls..
|
||||
if ( Match(tok, "%var% (") )
|
||||
if ( Tokenizer::Match(tok, "%var% (") )
|
||||
{
|
||||
const char *str = call_func(tok, callstack, varnames, alloctype, dealloctype);
|
||||
if ( str )
|
||||
|
@ -480,7 +475,7 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
|
|||
}
|
||||
|
||||
// Linux lists..
|
||||
if ( Match( tok, "[=(,] & %var1% [.[]", varnames ) )
|
||||
if ( Tokenizer::Match( tok, "[=(,] & %var1% [.[]", varnames ) )
|
||||
{
|
||||
// todo: better checking
|
||||
addtoken("use");
|
||||
|
@ -517,7 +512,7 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
// { x } while(y) { x }"
|
||||
for ( TOKEN *tok2 = tok; tok2; tok2 = tok2->next )
|
||||
{
|
||||
if ( ! Match(tok2->next, "do") )
|
||||
if ( ! Tokenizer::Match(tok2->next, "do") )
|
||||
continue;
|
||||
|
||||
// Remove the next token "do"
|
||||
|
@ -529,13 +524,13 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
int indentlevel = 0;
|
||||
for ( tok2_ = tok2; tok2_ && indentlevel>=0; tok2_ = tok2_->next )
|
||||
{
|
||||
if ( Match(tok2_, "{") )
|
||||
if ( Tokenizer::Match(tok2_, "{") )
|
||||
++indentlevel;
|
||||
|
||||
else if ( Match(tok2_, "}") )
|
||||
else if ( Tokenizer::Match(tok2_, "}") )
|
||||
--indentlevel;
|
||||
|
||||
else if ( indentlevel == 0 && Match(tok2_->next, ";") )
|
||||
else if ( indentlevel == 0 && Tokenizer::Match(tok2_->next, ";") )
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -547,9 +542,9 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
indentlevel = 0;
|
||||
do
|
||||
{
|
||||
if ( Match( tok2, "{" ) )
|
||||
if ( Tokenizer::Match( tok2, "{" ) )
|
||||
++indentlevel;
|
||||
else if ( Match(tok2, "}") )
|
||||
else if ( Tokenizer::Match(tok2, "}") )
|
||||
--indentlevel;
|
||||
|
||||
// Copy token..
|
||||
|
@ -572,14 +567,14 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
for (TOKEN *tok2 = tok; tok2; tok2 = tok2 ? tok2->next : NULL )
|
||||
{
|
||||
// Delete extra ";"
|
||||
while (Match(tok2,"[;{}] ;"))
|
||||
while (Tokenizer::Match(tok2,"[;{}] ;"))
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2,2));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Replace "{ }" with ";"
|
||||
if ( Match(tok2->next, "{ }") )
|
||||
if ( Tokenizer::Match(tok2->next, "{ }") )
|
||||
{
|
||||
tok2->next->setstr(";");
|
||||
erase(tok2->next, Tokenizer::gettok(tok2,3));
|
||||
|
@ -587,13 +582,13 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
}
|
||||
|
||||
// Delete braces around a single instruction..
|
||||
if ( Match(tok2->next, "{ %var% ; }") )
|
||||
if ( Tokenizer::Match(tok2->next, "{ %var% ; }") )
|
||||
{
|
||||
erase( tok2, Tokenizer::gettok(tok2,2) );
|
||||
erase( tok2->next->next, Tokenizer::gettok(tok2,4) );
|
||||
done = false;
|
||||
}
|
||||
if ( Match(tok2->next, "{ return use ; }") )
|
||||
if ( Tokenizer::Match(tok2->next, "{ return use ; }") )
|
||||
{
|
||||
erase( tok2, Tokenizer::gettok(tok2,2) );
|
||||
erase( tok2->next->next->next, Tokenizer::gettok(tok2,5) );
|
||||
|
@ -601,12 +596,12 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
}
|
||||
|
||||
// Delete empty if that is not followed by an else
|
||||
if ( Match(tok2,"[;{}] if ;") ||
|
||||
Match(tok2,"[;{}] if(var) ;") ||
|
||||
Match(tok2,"[;{}] if(!var) ;") ||
|
||||
Match(tok2,"[;{}] ifv ;") )
|
||||
if ( Tokenizer::Match(tok2,"[;{}] if ;") ||
|
||||
Tokenizer::Match(tok2,"[;{}] if(var) ;") ||
|
||||
Tokenizer::Match(tok2,"[;{}] if(!var) ;") ||
|
||||
Tokenizer::Match(tok2,"[;{}] ifv ;") )
|
||||
{
|
||||
if ( ! Match(Tokenizer::gettok(tok2,3), "else") )
|
||||
if ( ! Tokenizer::Match(Tokenizer::gettok(tok2,3), "else") )
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2, 3));
|
||||
done = false;
|
||||
|
@ -617,22 +612,22 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
// Delete "if dealloc ;" and "if use ;" that is not followed by an else..
|
||||
// This may cause false positives
|
||||
if (_settings._showAll &&
|
||||
(Match(tok2, "[;{}] if dealloc ;") || Match(tok2, "[;{}] if use ;")) &&
|
||||
!Match(Tokenizer::gettok(tok2,4), "else"))
|
||||
(Tokenizer::Match(tok2, "[;{}] if dealloc ;") || Tokenizer::Match(tok2, "[;{}] if use ;")) &&
|
||||
!Tokenizer::Match(Tokenizer::gettok(tok2,4), "else"))
|
||||
{
|
||||
erase(tok2->next, Tokenizer::gettok(tok2,3));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Delete if block: "alloc; if return use ;"
|
||||
if (Match(tok2,"alloc ; if return use ;") && !Match(Tokenizer::gettok(tok2,6),"else"))
|
||||
if (Tokenizer::Match(tok2,"alloc ; if return use ;") && !Tokenizer::Match(Tokenizer::gettok(tok2,6),"else"))
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2,5));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// "[;{}] if alloc ; else return ;" => "[;{}] alloc ;"
|
||||
if (Match(tok2,"[;{}] if alloc ; else return ;"))
|
||||
if (Tokenizer::Match(tok2,"[;{}] if alloc ; else return ;"))
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2,2)); // Remove "if"
|
||||
erase(tok2->next, Tokenizer::gettok(tok2,5)); // Remove "; else return"
|
||||
|
@ -640,68 +635,68 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
}
|
||||
|
||||
// Replace "dealloc use ;" with "dealloc ;"
|
||||
if ( Match(tok2, "dealloc use ;") )
|
||||
if ( Tokenizer::Match(tok2, "dealloc use ;") )
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2,2));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Reducing if..
|
||||
if (Match(tok2,"if dealloc ; else") || Match(tok2,"if use ; else"))
|
||||
if (Tokenizer::Match(tok2,"if dealloc ; else") || Tokenizer::Match(tok2,"if use ; else"))
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2, 2));
|
||||
done = false;
|
||||
}
|
||||
if (Match(tok2,"[;{}] if { dealloc ; return ; }") && !Match(Tokenizer::gettok(tok2,8),"else"))
|
||||
if (Tokenizer::Match(tok2,"[;{}] if { dealloc ; return ; }") && !Tokenizer::Match(Tokenizer::gettok(tok2,8),"else"))
|
||||
{
|
||||
erase(tok2,Tokenizer::gettok(tok2,8));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Replace "loop ;" with ";"
|
||||
if ( Match(tok2->next, "loop ;") )
|
||||
if ( Tokenizer::Match(tok2->next, "loop ;") )
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2,2));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Replace "loop !var ;" with ";"
|
||||
if ( Match(tok2->next, "loop !var ;") )
|
||||
if ( Tokenizer::Match(tok2->next, "loop !var ;") )
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2,4));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Replace "loop !var alloc ;" with " alloc ;"
|
||||
if ( Match(tok2->next, "loop !var alloc ;") )
|
||||
if ( Tokenizer::Match(tok2->next, "loop !var alloc ;") )
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2,3));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Delete if block in "alloc ; if(!var) return ;"
|
||||
if ( Match(tok2, "alloc ; if(!var) return ;") )
|
||||
if ( Tokenizer::Match(tok2, "alloc ; if(!var) return ;") )
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2,4));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Delete second use in "use ; use ;"
|
||||
while (Match(tok2, "[;{}] use ; use ;"))
|
||||
while (Tokenizer::Match(tok2, "[;{}] use ; use ;"))
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2,3));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Delete second case in "case ; case ;"
|
||||
while (Match(tok2, "case ; case ;"))
|
||||
while (Tokenizer::Match(tok2, "case ; case ;"))
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2,3));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Replace switch with if (if not complicated)
|
||||
if (Match(tok2, "switch {"))
|
||||
if (Tokenizer::Match(tok2, "switch {"))
|
||||
{
|
||||
// Right now, I just handle if there are a few case and perhaps a default.
|
||||
bool valid = false;
|
||||
|
@ -726,11 +721,11 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
else if (strcmp(_tok->str,"loop")==0)
|
||||
break;
|
||||
|
||||
else if (incase && Match(_tok,"case"))
|
||||
else if (incase && Tokenizer::Match(_tok,"case"))
|
||||
break;
|
||||
|
||||
incase |= Match(_tok,"case");
|
||||
incase &= !Match(_tok,"break");
|
||||
incase |= Tokenizer::Match(_tok,"case");
|
||||
incase &= !Tokenizer::Match(_tok,"break");
|
||||
}
|
||||
|
||||
if ( !incase && valid )
|
||||
|
@ -740,9 +735,9 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
erase( tok2, Tokenizer::gettok(tok2, 2) );
|
||||
tok2 = tok2->next;
|
||||
bool first = true;
|
||||
while (Match(tok2,"case") || Match(tok2,"default"))
|
||||
while (Tokenizer::Match(tok2,"case") || Tokenizer::Match(tok2,"default"))
|
||||
{
|
||||
bool def = Match(tok2, "default");
|
||||
bool def = Tokenizer::Match(tok2, "default");
|
||||
tok2->setstr(first ? "if" : "}");
|
||||
if ( first )
|
||||
{
|
||||
|
@ -757,9 +752,9 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
instoken( tok2, "if" );
|
||||
instoken( tok2, "else" );
|
||||
}
|
||||
while ( tok2 && tok2->str[0] != '}' && ! Match(tok2,"break ;") )
|
||||
while ( tok2 && tok2->str[0] != '}' && ! Tokenizer::Match(tok2,"break ;") )
|
||||
tok2 = tok2->next;
|
||||
if (Match(tok2,"break ;"))
|
||||
if (Tokenizer::Match(tok2,"break ;"))
|
||||
{
|
||||
tok2->setstr(";");
|
||||
tok2 = tok2->next->next;
|
||||
|
@ -768,7 +763,7 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
}
|
||||
}
|
||||
|
||||
if ( Match(tok2, "throw") )
|
||||
if ( Tokenizer::Match(tok2, "throw") )
|
||||
{
|
||||
tok2->setstr( "return" );
|
||||
done = false;
|
||||
|
@ -889,20 +884,20 @@ void CheckMemoryLeakClass::CheckMemoryLeak_InFunction()
|
|||
// In function..
|
||||
if ( indentlevel == 0 )
|
||||
{
|
||||
if ( Match(tok, ") {") )
|
||||
if ( Tokenizer::Match(tok, ") {") )
|
||||
infunc = true;
|
||||
|
||||
if ( Match(tok, "[;}]") )
|
||||
if ( Tokenizer::Match(tok, "[;}]") )
|
||||
infunc = false;
|
||||
}
|
||||
|
||||
// Declare a local variable => Check
|
||||
if (indentlevel>0 && infunc)
|
||||
{
|
||||
if ( Match(tok, "[{};] %type% * %var% [;=]") )
|
||||
if ( Tokenizer::Match(tok, "[{};] %type% * %var% [;=]") )
|
||||
CheckMemoryLeak_CheckScope( tok->next, Tokenizer::getstr(tok, 3) );
|
||||
|
||||
else if ( Match(tok, "[{};] %type% %type% * %var% [;=]") )
|
||||
else if ( Tokenizer::Match(tok, "[{};] %type% %type% * %var% [;=]") )
|
||||
CheckMemoryLeak_CheckScope( tok->next, Tokenizer::getstr(tok, 4) );
|
||||
}
|
||||
}
|
||||
|
@ -928,7 +923,7 @@ void CheckMemoryLeakClass::CheckMemoryLeak_ClassMembers()
|
|||
else if ( tok->str[0] == '}' )
|
||||
indentlevel--;
|
||||
|
||||
else if ( indentlevel == 0 && Match(tok, "class %var% [{:]") )
|
||||
else if ( indentlevel == 0 && Tokenizer::Match(tok, "class %var% [{:]") )
|
||||
{
|
||||
std::vector<const char *> classname;
|
||||
classname.push_back( Tokenizer::getstr(tok, 1) );
|
||||
|
@ -964,7 +959,7 @@ void CheckMemoryLeakClass::CheckMemoryLeak_ClassMembers_ParseClass( const TOKEN
|
|||
continue;
|
||||
|
||||
// Declaring subclass.. recursive checking
|
||||
if ( Match(tok, "class %var% [{:]") )
|
||||
if ( Tokenizer::Match(tok, "class %var% [{:]") )
|
||||
{
|
||||
classname.push_back( Tokenizer::getstr(tok, 1) );
|
||||
CheckMemoryLeak_ClassMembers_ParseClass( tok, classname );
|
||||
|
@ -972,9 +967,9 @@ void CheckMemoryLeakClass::CheckMemoryLeak_ClassMembers_ParseClass( const TOKEN
|
|||
}
|
||||
|
||||
// Declaring member variable.. check allocations and deallocations
|
||||
if ( Match(tok->next, "%type% * %var% ;") )
|
||||
if ( Tokenizer::Match(tok->next, "%type% * %var% ;") )
|
||||
{
|
||||
if ( IsName(tok->str) || strchr(";}", tok->str[0]) )
|
||||
if ( Tokenizer::IsName(tok->str) || strchr(";}", tok->str[0]) )
|
||||
{
|
||||
if (_settings._showAll || !isclass(Tokenizer::getstr(tok,1)))
|
||||
CheckMemoryLeak_ClassMembers_Variable( classname, Tokenizer::getstr(tok, 3) );
|
||||
|
@ -1031,7 +1026,7 @@ void CheckMemoryLeakClass::CheckMemoryLeak_ClassMembers_Variable( const std::vec
|
|||
{
|
||||
if ( strchr(";}", tok->str[0]) )
|
||||
memberfunction = false;
|
||||
else if ( Match( tok, fpattern.str().c_str() ) || Match( tok, destructor.str().c_str() ) )
|
||||
else if ( Tokenizer::Match( tok, fpattern.str().c_str() ) || Tokenizer::Match( tok, destructor.str().c_str() ) )
|
||||
memberfunction = true;
|
||||
}
|
||||
|
||||
|
@ -1039,7 +1034,7 @@ void CheckMemoryLeakClass::CheckMemoryLeak_ClassMembers_Variable( const std::vec
|
|||
if ( indentlevel > 0 && memberfunction )
|
||||
{
|
||||
// Allocate..
|
||||
if ( Match( tok, varname_eq.str().c_str() ) )
|
||||
if ( Tokenizer::Match( tok, varname_eq.str().c_str() ) )
|
||||
{
|
||||
AllocType alloc = GetAllocationType( Tokenizer::gettok( tok, 2 ) );
|
||||
if ( alloc != No )
|
||||
|
|
180
CheckOther.cpp
180
CheckOther.cpp
|
@ -20,8 +20,6 @@
|
|||
//---------------------------------------------------------------------------
|
||||
#include "CheckOther.h"
|
||||
|
||||
#include "CommonCheck.h"
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
|
@ -52,7 +50,7 @@ void CheckOther::WarningOldStylePointerCast()
|
|||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
// Old style pointer casting..
|
||||
if (!Match(tok, "( %type% * ) %var%"))
|
||||
if (!Tokenizer::Match(tok, "( %type% * ) %var%"))
|
||||
continue;
|
||||
|
||||
// Is "type" a class?
|
||||
|
@ -79,10 +77,10 @@ void CheckOther::WarningIsDigit()
|
|||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
bool err = false;
|
||||
err |= Match(tok, "%var% >= '0' && %var% <= '9'");
|
||||
err |= Match(tok, "* %var% >= '0' && * %var% <= '9'");
|
||||
err |= Match(tok, "( %var% >= '0' ) && ( %var% <= '9' )");
|
||||
err |= Match(tok, "( * %var% >= '0' ) && ( * %var% <= '9' )");
|
||||
err |= Tokenizer::Match(tok, "%var% >= '0' && %var% <= '9'");
|
||||
err |= Tokenizer::Match(tok, "* %var% >= '0' && * %var% <= '9'");
|
||||
err |= Tokenizer::Match(tok, "( %var% >= '0' ) && ( %var% <= '9' )");
|
||||
err |= Tokenizer::Match(tok, "( * %var% >= '0' ) && ( * %var% <= '9' )");
|
||||
if (err)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
|
@ -103,15 +101,15 @@ void CheckOther::WarningIsAlpha()
|
|||
{
|
||||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
if ( ! Match(tok, "(") )
|
||||
if ( ! Tokenizer::Match(tok, "(") )
|
||||
continue;
|
||||
|
||||
bool err = false;
|
||||
|
||||
err |= Match(tok, "( %var% >= 'A' && %var% <= 'Z' )");
|
||||
err |= Match(tok, "( * %var% >= 'A' && * %var% <= 'Z' )");
|
||||
err |= Match(tok, "( ( %var% >= 'A' ) && ( %var% <= 'Z' ) )");
|
||||
err |= Match(tok, "( ( * %var% >= 'A' ) && ( * %var% <= 'Z' ) )");
|
||||
err |= Tokenizer::Match(tok, "( %var% >= 'A' && %var% <= 'Z' )");
|
||||
err |= Tokenizer::Match(tok, "( * %var% >= 'A' && * %var% <= 'Z' )");
|
||||
err |= Tokenizer::Match(tok, "( ( %var% >= 'A' ) && ( %var% <= 'Z' ) )");
|
||||
err |= Tokenizer::Match(tok, "( ( * %var% >= 'A' ) && ( * %var% <= 'Z' ) )");
|
||||
if (err)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
|
@ -121,10 +119,10 @@ void CheckOther::WarningIsAlpha()
|
|||
}
|
||||
|
||||
err = false;
|
||||
err |= Match(tok, "( %var% >= 'a' && %var% <= 'z' )");
|
||||
err |= Match(tok, "( * %var% >= 'a' && * %var% <= 'z' )");
|
||||
err |= Match(tok, "( ( %var% >= 'a' ) && ( %var% <= 'z' ) )");
|
||||
err |= Match(tok, "( ( * %var% >= 'a' ) && ( * %var% <= 'z' ) )");
|
||||
err |= Tokenizer::Match(tok, "( %var% >= 'a' && %var% <= 'z' )");
|
||||
err |= Tokenizer::Match(tok, "( * %var% >= 'a' && * %var% <= 'z' )");
|
||||
err |= Tokenizer::Match(tok, "( ( %var% >= 'a' ) && ( %var% <= 'z' ) )");
|
||||
err |= Tokenizer::Match(tok, "( ( * %var% >= 'a' ) && ( * %var% <= 'z' ) )");
|
||||
if (err)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
|
@ -134,14 +132,14 @@ void CheckOther::WarningIsAlpha()
|
|||
}
|
||||
|
||||
err = false;
|
||||
err |= Match(tok, "( %var% >= 'A' && %var% <= 'Z' ) || ( %var% >= 'a' && %var% <= 'z' )");
|
||||
err |= Match(tok, "( %var% >= 'a' && %var% <= 'z' ) || ( %var% >= 'A' && %var% <= 'Z' )");
|
||||
err |= Match(tok, "( * %var% >= 'A' && * %var% <= 'Z' ) || ( * %var% >= 'a' && * %var% <= 'z' )");
|
||||
err |= Match(tok, "( * %var% >= 'a' && * %var% <= 'z' ) || ( * %var% >= 'A' && * %var% <= 'Z' )");
|
||||
err |= Match(tok, "( ( %var% >= 'A' ) && ( %var% <= 'Z' ) ) || ( ( %var% >= 'a' ) && ( %var% <= 'z' ) )");
|
||||
err |= Match(tok, "( ( %var% >= 'a' ) && ( %var% <= 'z' ) ) || ( ( %var% >= 'A' ) && ( %var% <= 'Z' ) )");
|
||||
err |= Match(tok, "( ( * %var% >= 'A' ) && ( * %var% <= 'Z' ) ) || ( ( * var >= 'a' ) && ( * %var% <= 'z' ) )");
|
||||
err |= Match(tok, "( ( * %var% >= 'a' ) && ( * %var% <= 'z' ) ) || ( ( * var >= 'A' ) && ( * %var% <= 'Z' ) )");
|
||||
err |= Tokenizer::Match(tok, "( %var% >= 'A' && %var% <= 'Z' ) || ( %var% >= 'a' && %var% <= 'z' )");
|
||||
err |= Tokenizer::Match(tok, "( %var% >= 'a' && %var% <= 'z' ) || ( %var% >= 'A' && %var% <= 'Z' )");
|
||||
err |= Tokenizer::Match(tok, "( * %var% >= 'A' && * %var% <= 'Z' ) || ( * %var% >= 'a' && * %var% <= 'z' )");
|
||||
err |= Tokenizer::Match(tok, "( * %var% >= 'a' && * %var% <= 'z' ) || ( * %var% >= 'A' && * %var% <= 'Z' )");
|
||||
err |= Tokenizer::Match(tok, "( ( %var% >= 'A' ) && ( %var% <= 'Z' ) ) || ( ( %var% >= 'a' ) && ( %var% <= 'z' ) )");
|
||||
err |= Tokenizer::Match(tok, "( ( %var% >= 'a' ) && ( %var% <= 'z' ) ) || ( ( %var% >= 'A' ) && ( %var% <= 'Z' ) )");
|
||||
err |= Tokenizer::Match(tok, "( ( * %var% >= 'A' ) && ( * %var% <= 'Z' ) ) || ( ( * var >= 'a' ) && ( * %var% <= 'z' ) )");
|
||||
err |= Tokenizer::Match(tok, "( ( * %var% >= 'a' ) && ( * %var% <= 'z' ) ) || ( ( * var >= 'A' ) && ( * %var% <= 'Z' ) )");
|
||||
if (err)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
|
@ -163,18 +161,18 @@ void CheckOther::WarningRedundantCode()
|
|||
// if (p) delete p
|
||||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
if (!Match(tok,"if"))
|
||||
if (!Tokenizer::Match(tok,"if"))
|
||||
continue;
|
||||
|
||||
const char *varname1 = NULL;
|
||||
const TOKEN *tok2 = NULL;
|
||||
|
||||
if (Match(tok,"if ( %var% )"))
|
||||
if (Tokenizer::Match(tok,"if ( %var% )"))
|
||||
{
|
||||
varname1 = Tokenizer::getstr(tok, 2);
|
||||
tok2 = Tokenizer::gettok(tok, 4);
|
||||
}
|
||||
else if (Match(tok,"if ( %var% != NULL )"))
|
||||
else if (Tokenizer::Match(tok,"if ( %var% != NULL )"))
|
||||
{
|
||||
varname1 = Tokenizer::getstr(tok, 2);
|
||||
tok2 = Tokenizer::gettok(tok, 6);
|
||||
|
@ -183,17 +181,17 @@ void CheckOther::WarningRedundantCode()
|
|||
if (varname1==NULL || tok2==NULL)
|
||||
continue;
|
||||
|
||||
if ( Match(tok2, "{") )
|
||||
if ( Tokenizer::Match(tok2, "{") )
|
||||
tok2 = tok2->next;
|
||||
|
||||
bool err = false;
|
||||
if (Match(tok2,"delete %var% ;"))
|
||||
if (Tokenizer::Match(tok2,"delete %var% ;"))
|
||||
err = (strcmp(Tokenizer::getstr(tok2,1),varname1)==0);
|
||||
else if (Match(tok2,"delete [ ] %var% ;"))
|
||||
else if (Tokenizer::Match(tok2,"delete [ ] %var% ;"))
|
||||
err = (strcmp(Tokenizer::getstr(tok2,1),varname1)==0);
|
||||
else if (Match(tok2,"free ( %var% )"))
|
||||
else if (Tokenizer::Match(tok2,"free ( %var% )"))
|
||||
err = (strcmp(Tokenizer::getstr(tok2,2),varname1)==0);
|
||||
else if (Match(tok2,"kfree ( %var% )"))
|
||||
else if (Tokenizer::Match(tok2,"kfree ( %var% )"))
|
||||
err = (strcmp(Tokenizer::getstr(tok2,2),varname1)==0);
|
||||
|
||||
if (err)
|
||||
|
@ -225,14 +223,14 @@ void CheckOther::WarningIf()
|
|||
// Search for 'if (condition);'
|
||||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
if (Match(tok,"if"))
|
||||
if (Tokenizer::Match(tok,"if"))
|
||||
{
|
||||
int parlevel = 0;
|
||||
for (const TOKEN *tok2 = tok->next; tok2; tok2 = tok2->next)
|
||||
{
|
||||
if (Match(tok2,"("))
|
||||
if (Tokenizer::Match(tok2,"("))
|
||||
parlevel++;
|
||||
else if (Match(tok2,")"))
|
||||
else if (Tokenizer::Match(tok2,")"))
|
||||
{
|
||||
parlevel--;
|
||||
if (parlevel<=0)
|
||||
|
@ -255,13 +253,13 @@ void CheckOther::WarningIf()
|
|||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
// Begin statement?
|
||||
if ( ! Match(tok, "[;{}]") )
|
||||
if ( ! Tokenizer::Match(tok, "[;{}]") )
|
||||
continue;
|
||||
tok = tok->next;
|
||||
if ( ! tok )
|
||||
break;
|
||||
|
||||
if (!Match(tok,"%var% = %var% ; if ( %var%"))
|
||||
if (!Tokenizer::Match(tok,"%var% = %var% ; if ( %var%"))
|
||||
continue;
|
||||
|
||||
if ( strcmp(Tokenizer::getstr(tok, 9), ")") != 0 )
|
||||
|
@ -314,7 +312,7 @@ void CheckOther::InvalidFunctionUsage()
|
|||
{
|
||||
for ( const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next )
|
||||
{
|
||||
if (!Match(tok, "strtol") && !Match(tok, "strtoul"))
|
||||
if (!Tokenizer::Match(tok, "strtol") && !Tokenizer::Match(tok, "strtoul"))
|
||||
continue;
|
||||
|
||||
// Locate the third parameter of the function call..
|
||||
|
@ -322,16 +320,16 @@ void CheckOther::InvalidFunctionUsage()
|
|||
int param = 1;
|
||||
for ( const TOKEN *tok2 = tok->next; tok2; tok2 = tok2->next )
|
||||
{
|
||||
if ( Match(tok2, "(") )
|
||||
if ( Tokenizer::Match(tok2, "(") )
|
||||
parlevel++;
|
||||
else if (Match(tok2, ")"))
|
||||
else if (Tokenizer::Match(tok2, ")"))
|
||||
parlevel--;
|
||||
else if (parlevel == 1 && Match(tok2, ","))
|
||||
else if (parlevel == 1 && Tokenizer::Match(tok2, ","))
|
||||
{
|
||||
param++;
|
||||
if (param==3)
|
||||
{
|
||||
if ( Match(tok2, ", %num% )") )
|
||||
if ( Tokenizer::Match(tok2, ", %num% )") )
|
||||
{
|
||||
int radix = atoi(Tokenizer::getstr(tok2, 1));
|
||||
if (!(radix==0 || (radix>=2 && radix<=36)))
|
||||
|
@ -358,9 +356,9 @@ void CheckOther::CheckIfAssignment()
|
|||
{
|
||||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
if (Match(tok, "if ( %var% = %num% )") ||
|
||||
Match(tok, "if ( %var% = %str% )") ||
|
||||
Match(tok, "if ( %var% = %var% )") )
|
||||
if (Tokenizer::Match(tok, "if ( %var% = %num% )") ||
|
||||
Tokenizer::Match(tok, "if ( %var% = %str% )") ||
|
||||
Tokenizer::Match(tok, "if ( %var% = %var% )") )
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << _tokenizer->fileLine(tok) << ": Possible bug. Should it be '==' instead of '='?";
|
||||
|
@ -381,17 +379,17 @@ void CheckOther::CheckUnsignedDivision()
|
|||
std::map<std::string, char> varsign;
|
||||
for ( const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next )
|
||||
{
|
||||
if ( Match(tok, "[{};(,] %type% %var% [;=,)]") )
|
||||
if ( Tokenizer::Match(tok, "[{};(,] %type% %var% [;=,)]") )
|
||||
{
|
||||
const char *type = Tokenizer::getstr(tok, 1);
|
||||
if (strcmp(type,"char")==0 || strcmp(type,"short")==0 || strcmp(type,"int")==0)
|
||||
varsign[Tokenizer::getstr(tok,2)] = 's';
|
||||
}
|
||||
|
||||
else if ( Match(tok, "[{};(,] unsigned %type% %var% [;=,)]") )
|
||||
else if ( Tokenizer::Match(tok, "[{};(,] unsigned %type% %var% [;=,)]") )
|
||||
varsign[Tokenizer::getstr(tok,3)] = 'u';
|
||||
|
||||
else if (!Match(tok,"[).]") && Match(tok->next, "%var% / %var%"))
|
||||
else if (!Tokenizer::Match(tok,"[).]") && Tokenizer::Match(tok->next, "%var% / %var%"))
|
||||
{
|
||||
const char *varname1 = Tokenizer::getstr(tok,1);
|
||||
const char *varname2 = Tokenizer::getstr(tok,3);
|
||||
|
@ -407,7 +405,7 @@ void CheckOther::CheckUnsignedDivision()
|
|||
}
|
||||
}
|
||||
|
||||
else if (!Match(tok,"[).]") && Match(tok->next, "%var% / - %num%"))
|
||||
else if (!Tokenizer::Match(tok,"[).]") && Tokenizer::Match(tok->next, "%var% / - %num%"))
|
||||
{
|
||||
const char *varname1 = Tokenizer::getstr(tok,1);
|
||||
char sign1 = varsign[varname1];
|
||||
|
@ -419,7 +417,7 @@ void CheckOther::CheckUnsignedDivision()
|
|||
}
|
||||
}
|
||||
|
||||
else if (Match(tok, "[([=*/+-] - %num% / %var%"))
|
||||
else if (Tokenizer::Match(tok, "[([=*/+-] - %num% / %var%"))
|
||||
{
|
||||
const char *varname2 = Tokenizer::getstr(tok,4);
|
||||
char sign2 = varsign[varname2];
|
||||
|
@ -449,21 +447,21 @@ void CheckOther::CheckVariableScope()
|
|||
for ( const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next )
|
||||
{
|
||||
// Skip class and struct declarations..
|
||||
if ( Match(tok, "class") || Match(tok, "struct") )
|
||||
if ( Tokenizer::Match(tok, "class") || Tokenizer::Match(tok, "struct") )
|
||||
{
|
||||
for (const TOKEN *tok2 = tok; tok2; tok2 = tok2->next)
|
||||
{
|
||||
if ( Match(tok2, "{") )
|
||||
if ( Tokenizer::Match(tok2, "{") )
|
||||
{
|
||||
int _indentlevel = 0;
|
||||
tok = tok2;
|
||||
for (tok = tok2; tok; tok = tok->next)
|
||||
{
|
||||
if ( Match(tok, "{") )
|
||||
if ( Tokenizer::Match(tok, "{") )
|
||||
{
|
||||
_indentlevel++;
|
||||
}
|
||||
if ( Match(tok, "}") )
|
||||
if ( Tokenizer::Match(tok, "}") )
|
||||
{
|
||||
_indentlevel--;
|
||||
if ( _indentlevel <= 0 )
|
||||
|
@ -475,7 +473,7 @@ void CheckOther::CheckVariableScope()
|
|||
}
|
||||
break;
|
||||
}
|
||||
if (Match(tok2, "[,);]"))
|
||||
if (Tokenizer::Match(tok2, "[,);]"))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -484,36 +482,36 @@ void CheckOther::CheckVariableScope()
|
|||
break;
|
||||
}
|
||||
|
||||
if ( Match(tok, "{") )
|
||||
if ( Tokenizer::Match(tok, "{") )
|
||||
{
|
||||
indentlevel++;
|
||||
}
|
||||
if ( Match(tok, "}") )
|
||||
if ( Tokenizer::Match(tok, "}") )
|
||||
{
|
||||
indentlevel--;
|
||||
if ( indentlevel == 0 )
|
||||
func = false;
|
||||
}
|
||||
if ( indentlevel == 0 && Match(tok, ") {") )
|
||||
if ( indentlevel == 0 && Tokenizer::Match(tok, ") {") )
|
||||
{
|
||||
func = true;
|
||||
}
|
||||
if ( indentlevel > 0 && func && Match(tok, "[{};]") )
|
||||
if ( indentlevel > 0 && func && Tokenizer::Match(tok, "[{};]") )
|
||||
{
|
||||
// First token of statement..
|
||||
const TOKEN *tok1 = tok->next;
|
||||
if ( ! tok1 )
|
||||
continue;
|
||||
|
||||
if (Match(tok1,"return") ||
|
||||
Match(tok1,"delete") ||
|
||||
Match(tok1,"goto") ||
|
||||
Match(tok1,"else"))
|
||||
if (Tokenizer::Match(tok1,"return") ||
|
||||
Tokenizer::Match(tok1,"delete") ||
|
||||
Tokenizer::Match(tok1,"goto") ||
|
||||
Tokenizer::Match(tok1,"else"))
|
||||
continue;
|
||||
|
||||
// Variable declaration?
|
||||
if (Match(tok1, "%var% %var% ;") ||
|
||||
Match(tok1, "%var% %var% =") )
|
||||
if (Tokenizer::Match(tok1, "%var% %var% ;") ||
|
||||
Tokenizer::Match(tok1, "%var% %var% =") )
|
||||
{
|
||||
CheckVariableScope_LookupVar( tok1, Tokenizer::getstr(tok1, 1) );
|
||||
}
|
||||
|
@ -528,7 +526,7 @@ void CheckOther::CheckVariableScope_LookupVar( const TOKEN *tok1, const char var
|
|||
const TOKEN *tok = tok1;
|
||||
|
||||
// Skip the variable declaration..
|
||||
while (tok && !Match(tok,";"))
|
||||
while (tok && !Tokenizer::Match(tok,";"))
|
||||
tok = tok->next;
|
||||
|
||||
// Check if the variable is used in this indentlevel..
|
||||
|
@ -538,12 +536,12 @@ void CheckOther::CheckVariableScope_LookupVar( const TOKEN *tok1, const char var
|
|||
bool for_or_while = false;
|
||||
while ( indentlevel >= 0 && tok )
|
||||
{
|
||||
if ( Match(tok, "{") )
|
||||
if ( Tokenizer::Match(tok, "{") )
|
||||
{
|
||||
indentlevel++;
|
||||
}
|
||||
|
||||
else if ( Match(tok, "}") )
|
||||
else if ( Tokenizer::Match(tok, "}") )
|
||||
{
|
||||
indentlevel--;
|
||||
if ( indentlevel == 0 )
|
||||
|
@ -555,12 +553,12 @@ void CheckOther::CheckVariableScope_LookupVar( const TOKEN *tok1, const char var
|
|||
}
|
||||
}
|
||||
|
||||
else if ( Match(tok, "(") )
|
||||
else if ( Tokenizer::Match(tok, "(") )
|
||||
{
|
||||
parlevel++;
|
||||
}
|
||||
|
||||
else if ( Match(tok, ")") )
|
||||
else if ( Tokenizer::Match(tok, ")") )
|
||||
{
|
||||
parlevel--;
|
||||
}
|
||||
|
@ -575,9 +573,9 @@ void CheckOther::CheckVariableScope_LookupVar( const TOKEN *tok1, const char var
|
|||
|
||||
else if ( indentlevel==0 )
|
||||
{
|
||||
if ( Match(tok,"for") || Match(tok,"while") )
|
||||
if ( Tokenizer::Match(tok,"for") || Tokenizer::Match(tok,"while") )
|
||||
for_or_while = true;
|
||||
if ( parlevel == 0 && Match(tok, ";") )
|
||||
if ( parlevel == 0 && Tokenizer::Match(tok, ";") )
|
||||
for_or_while = false;
|
||||
}
|
||||
|
||||
|
@ -600,14 +598,14 @@ void CheckOther::CheckConstantFunctionParameter()
|
|||
{
|
||||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
if ( Match(tok,"[,(] const std :: %type% %var% [,)]") )
|
||||
if ( Tokenizer::Match(tok,"[,(] const std :: %type% %var% [,)]") )
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << _tokenizer->fileLine(tok) << " " << Tokenizer::getstr(tok,5) << " is passed by value, it could be passed by reference/pointer instead";
|
||||
_errorLogger->reportErr( errmsg.str() );
|
||||
}
|
||||
|
||||
else if ( Match(tok,"[,(] const %type% %var% [,)]") )
|
||||
else if ( Tokenizer::Match(tok,"[,(] const %type% %var% [,)]") )
|
||||
{
|
||||
// Check if type is a struct or class.
|
||||
const char *pattern[3] = {"class","type",0};
|
||||
|
@ -643,21 +641,21 @@ void CheckOther::CheckStructMemberUsage()
|
|||
{
|
||||
if ( tok->FileIndex != 0 )
|
||||
continue;
|
||||
if ( Match(tok,"}") )
|
||||
if ( Tokenizer::Match(tok,"}") )
|
||||
structname = 0;
|
||||
if ( Match(tok, "struct %type% {") )
|
||||
if ( Tokenizer::Match(tok, "struct %type% {") )
|
||||
structname = Tokenizer::getstr(tok, 1);
|
||||
|
||||
if (structname && Match(tok, "[{;]"))
|
||||
if (structname && Tokenizer::Match(tok, "[{;]"))
|
||||
{
|
||||
const char *varname = 0;
|
||||
if (Match(tok->next, "%type% %var% [;[]"))
|
||||
if (Tokenizer::Match(tok->next, "%type% %var% [;[]"))
|
||||
varname = Tokenizer::getstr( tok, 2 );
|
||||
else if (Match(tok->next, "%type% %type% %var% [;[]"))
|
||||
else if (Tokenizer::Match(tok->next, "%type% %type% %var% [;[]"))
|
||||
varname = Tokenizer::getstr( tok, 2 );
|
||||
else if (Match(tok->next, "%type% * %var% [;[]"))
|
||||
else if (Tokenizer::Match(tok->next, "%type% * %var% [;[]"))
|
||||
varname = Tokenizer::getstr( tok, 3 );
|
||||
else if (Match(tok->next, "%type% %type% * %var% [;[]"))
|
||||
else if (Tokenizer::Match(tok->next, "%type% %type% * %var% [;[]"))
|
||||
varname = Tokenizer::getstr( tok, 4 );
|
||||
else
|
||||
continue;
|
||||
|
@ -671,7 +669,7 @@ void CheckOther::CheckStructMemberUsage()
|
|||
if ( tok->FileIndex != 0 )
|
||||
continue;
|
||||
|
||||
if (Match(tok2, ". %var%", varnames))
|
||||
if (Tokenizer::Match(tok2, ". %var%", varnames))
|
||||
{
|
||||
if ( strcmp("=", Tokenizer::getstr(tok2,2)) == 0 )
|
||||
continue;
|
||||
|
@ -703,7 +701,7 @@ void CheckOther::CheckCharVariable()
|
|||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
// Declaring the variable..
|
||||
if ( Match(tok, "[{};(,] char %var% [;=,)]") )
|
||||
if ( Tokenizer::Match(tok, "[{};(,] char %var% [;=,)]") )
|
||||
{
|
||||
const char *varname[2] = {0};
|
||||
varname[0] = Tokenizer::getstr(tok, 2);
|
||||
|
@ -712,17 +710,17 @@ void CheckOther::CheckCharVariable()
|
|||
int indentlevel = 0;
|
||||
for ( const TOKEN *tok2 = tok->next; tok2; tok2 = tok2->next )
|
||||
{
|
||||
if ( Match(tok2, "{") )
|
||||
if ( Tokenizer::Match(tok2, "{") )
|
||||
++indentlevel;
|
||||
|
||||
else if ( Match(tok2, "}") )
|
||||
else if ( Tokenizer::Match(tok2, "}") )
|
||||
{
|
||||
--indentlevel;
|
||||
if ( indentlevel <= 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
if (!Match(tok2,".") && Match(tok2->next, "%var% [ %var1% ]", varname))
|
||||
if (!Tokenizer::Match(tok2,".") && Tokenizer::Match(tok2->next, "%var% [ %var1% ]", varname))
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << _tokenizer->fileLine(tok2->next) << ": Warning - using char variable as array index";
|
||||
|
@ -730,7 +728,7 @@ void CheckOther::CheckCharVariable()
|
|||
break;
|
||||
}
|
||||
|
||||
if ( Match(tok2, "%var% [&|] %var1%", varname) || Match(tok2, "%var1% [&|]", varname) )
|
||||
if ( Tokenizer::Match(tok2, "%var% [&|] %var1%", varname) || Tokenizer::Match(tok2, "%var1% [&|]", varname) )
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << _tokenizer->fileLine(tok2) << ": Warning - using char variable in bit operation";
|
||||
|
@ -758,22 +756,22 @@ void CheckOther::CheckIncompleteStatement()
|
|||
|
||||
for ( const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next )
|
||||
{
|
||||
if ( Match(tok, "(") )
|
||||
if ( Tokenizer::Match(tok, "(") )
|
||||
++parlevel;
|
||||
else if ( Match(tok, ")") )
|
||||
else if ( Tokenizer::Match(tok, ")") )
|
||||
--parlevel;
|
||||
|
||||
if ( parlevel != 0 )
|
||||
continue;
|
||||
|
||||
if ( !Match(tok,"#") && Match(tok->next,"; %str%") && !Match(Tokenizer::gettok(tok,3), ",") )
|
||||
if ( !Tokenizer::Match(tok,"#") && Tokenizer::Match(tok->next,"; %str%") && !Tokenizer::Match(Tokenizer::gettok(tok,3), ",") )
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << _tokenizer->fileLine(tok->next) << ": Redundant code: Found a statement that begins with string constant";
|
||||
_errorLogger->reportErr(errmsg.str());
|
||||
}
|
||||
|
||||
if ( !Match(tok,"#") && Match(tok->next,"; %num%") && !Match(Tokenizer::gettok(tok,3), ",") )
|
||||
if ( !Tokenizer::Match(tok,"#") && Tokenizer::Match(tok->next,"; %num%") && !Tokenizer::Match(Tokenizer::gettok(tok,3), ",") )
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << _tokenizer->fileLine(tok->next) << ": Redundant code: Found a statement that begins with numeric constant";
|
||||
|
|
182
CommonCheck.cpp
182
CommonCheck.cpp
|
@ -1,182 +0,0 @@
|
|||
/*
|
||||
* c++check - c/c++ syntax checking
|
||||
* Copyright (C) 2007 Daniel Marjamäki
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#include "CommonCheck.h"
|
||||
#include "tokenize.h"
|
||||
#include <stdlib.h> // free
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool SameFileName( const char fname1[], const char fname2[] )
|
||||
{
|
||||
#ifdef __linux__
|
||||
return bool( strcmp(fname1, fname2) == 0 );
|
||||
#endif
|
||||
#ifdef __GNUC__
|
||||
return bool( strcasecmp(fname1, fname2) == 0 );
|
||||
#endif
|
||||
#ifdef __BORLANDC__
|
||||
return bool( stricmp(fname1, fname2) == 0 );
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
return bool( _stricmp(fname1, fname2) == 0 );
|
||||
#endif
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool IsName(const char str[])
|
||||
{
|
||||
return bool(str[0]=='_' || isalpha(str[0]));
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool IsNumber(const char str[])
|
||||
{
|
||||
return bool(isdigit(str[0]) != 0);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool IsStandardType(const char str[])
|
||||
{
|
||||
if (!str)
|
||||
return false;
|
||||
bool Ret = false;
|
||||
const char *type[] = {"bool","char","short","int","long","float","double",0};
|
||||
for (int i = 0; type[i]; i++)
|
||||
Ret |= (strcmp(str,type[i])==0);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
bool Match(const TOKEN *tok, const char pattern[], const char *varname1[], const char *varname2[])
|
||||
{
|
||||
if (!tok)
|
||||
return false;
|
||||
|
||||
const char *p = pattern;
|
||||
while (*p)
|
||||
{
|
||||
// Skip spaces in pattern..
|
||||
while ( *p == ' ' )
|
||||
p++;
|
||||
|
||||
// Extract token from pattern..
|
||||
char str[50];
|
||||
char *s = str;
|
||||
while (*p && *p!=' ')
|
||||
{
|
||||
*s = *p;
|
||||
s++;
|
||||
p++;
|
||||
}
|
||||
*s = 0;
|
||||
|
||||
// No token => Success!
|
||||
if (str[0] == 0)
|
||||
return true;
|
||||
|
||||
// Any symbolname..
|
||||
if (strcmp(str,"%var%")==0 || strcmp(str,"%type%")==0)
|
||||
{
|
||||
if (!IsName(tok->str))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Variable name..
|
||||
else if (strcmp(str,"%var1%")==0 || strcmp(str,"%var2%")==0)
|
||||
{
|
||||
const char **varname = (strcmp(str,"%var1%")==0) ? varname1 : varname2;
|
||||
|
||||
if ( ! varname )
|
||||
return false;
|
||||
|
||||
if (strcmp(tok->str, varname[0]) != 0)
|
||||
return false;
|
||||
|
||||
for ( int i = 1; varname[i]; i++ )
|
||||
{
|
||||
if ( ! Tokenizer::gettok(tok, 2) )
|
||||
return false;
|
||||
|
||||
if ( strcmp(Tokenizer::getstr(tok, 1), ".") )
|
||||
return false;
|
||||
|
||||
if ( strcmp(Tokenizer::getstr(tok, 2), varname[i]) )
|
||||
return false;
|
||||
|
||||
tok = Tokenizer::gettok(tok, 2);
|
||||
}
|
||||
}
|
||||
|
||||
else if (strcmp(str,"%num%")==0)
|
||||
{
|
||||
if ( ! IsNumber(tok->str) )
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
else if (strcmp(str,"%str%")==0)
|
||||
{
|
||||
if ( tok->str[0] != '\"' )
|
||||
return false;
|
||||
}
|
||||
|
||||
// [.. => search for a one-character token..
|
||||
else if (str[0]=='[' && strchr(str, ']') && tok->str[1] == 0)
|
||||
{
|
||||
*strrchr(str, ']') = 0;
|
||||
if ( strchr( str + 1, tok->str[0] ) == 0 )
|
||||
return false;
|
||||
}
|
||||
|
||||
else if (strcmp(str, tok->str) != 0)
|
||||
return false;
|
||||
|
||||
tok = tok->next;
|
||||
if (!tok)
|
||||
return false;
|
||||
}
|
||||
|
||||
// The end of the pattern has been reached and nothing wrong has been found
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* c++check - c/c++ syntax checking
|
||||
* Copyright (C) 2007 Daniel Marjamäki
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef CommonCheckH
|
||||
#define CommonCheckH
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include "tokenize.h"
|
||||
|
||||
|
||||
// Are two filenames the same? Case insensitive on windows
|
||||
bool SameFileName( const char fname1[], const char fname2[] );
|
||||
bool IsName(const char str[]);
|
||||
bool IsNumber(const char str[]);
|
||||
bool IsStandardType(const char str[]);
|
||||
bool Match(const TOKEN *tok, const char pattern[], const char *varname1[]=0, const char *varname2[]=0);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
26
Makefile
26
Makefile
|
@ -1,4 +1,4 @@
|
|||
SRCS=CheckBufferOverrun.cpp CheckClass.cpp CheckHeaders.cpp CheckMemoryLeak.cpp CheckOther.cpp CommonCheck.cpp FileLister.cpp preprocessor.cpp tokenize.cpp cppcheck.cpp settings.cpp
|
||||
SRCS=CheckBufferOverrun.cpp CheckClass.cpp CheckHeaders.cpp CheckMemoryLeak.cpp CheckOther.cpp FileLister.cpp preprocessor.cpp tokenize.cpp cppcheck.cpp settings.cpp
|
||||
OBJS=$(SRCS:%.cpp=%.o)
|
||||
TESTS=testbufferoverrun.o testcharvar.o testconstructors.o testdivision.o testincompletestatement.o testmemleak.o testpreprocessor.o testsimplifytokens.o testtokenize.o testunusedprivfunc.o testunusedvar.o settings.o cppcheck.o
|
||||
BIN = ${DESTDIR}/usr/bin
|
||||
|
@ -7,31 +7,29 @@ all: ${OBJS} main.o
|
|||
g++ -Wall -g -o cppcheck $^
|
||||
test: ${OBJS} testrunner.o testsuite.o ${TESTS}
|
||||
g++ -Wall -g -o testrunner $^
|
||||
cppcheck.o: cppcheck.cpp cppcheck.h preprocessor.h tokenize.h CommonCheck.h CheckMemoryLeak.h CheckBufferOverrun.h CheckClass.h CheckHeaders.h CheckOther.h FileLister.h settings.h
|
||||
cppcheck.o: cppcheck.cpp cppcheck.h preprocessor.h tokenize.h CheckMemoryLeak.h CheckBufferOverrun.h CheckClass.h CheckHeaders.h CheckOther.h FileLister.h settings.h
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
main.o: main.cpp cppcheck.h
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
settings.o: settings.cpp
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
CheckBufferOverrun.o: CheckBufferOverrun.cpp CheckBufferOverrun.h tokenize.h CommonCheck.h
|
||||
CheckBufferOverrun.o: CheckBufferOverrun.cpp CheckBufferOverrun.h tokenize.h
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
CheckClass.o: CheckClass.cpp CheckClass.h tokenize.h CommonCheck.h
|
||||
CheckClass.o: CheckClass.cpp CheckClass.h tokenize.h
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
CheckHeaders.o: CheckHeaders.cpp CheckHeaders.h tokenize.h CommonCheck.h
|
||||
CheckHeaders.o: CheckHeaders.cpp CheckHeaders.h tokenize.h
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
CheckMemoryLeak.o: CheckMemoryLeak.cpp CheckMemoryLeak.h tokenize.h CommonCheck.h
|
||||
CheckMemoryLeak.o: CheckMemoryLeak.cpp CheckMemoryLeak.h tokenize.h
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
CheckOther.o: CheckOther.cpp CheckOther.h tokenize.h CommonCheck.h
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
CommonCheck.o: CommonCheck.cpp CommonCheck.h tokenize.h
|
||||
CheckOther.o: CheckOther.cpp CheckOther.h tokenize.h
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
FileLister.o: FileLister.cpp FileLister.h
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
preprocessor.o: preprocessor.cpp preprocessor.h CommonCheck.h
|
||||
preprocessor.o: preprocessor.cpp preprocessor.h
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
testbufferoverrun.o: testbufferoverrun.cpp tokenize.h CommonCheck.h CheckBufferOverrun.h testsuite.h
|
||||
testbufferoverrun.o: testbufferoverrun.cpp tokenize.h CheckBufferOverrun.h testsuite.h
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
testcharvar.o: testcharvar.cpp tokenize.h CommonCheck.h CheckOther.h testsuite.h
|
||||
testcharvar.o: testcharvar.cpp tokenize.h CheckOther.h testsuite.h
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
testconstructors.o: testconstructors.cpp tokenize.h CheckClass.h testsuite.h
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
|
@ -39,7 +37,7 @@ testdivision.o: testdivision.cpp tokenize.h CheckOther.h testsuite.h
|
|||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
testincompletestatement.o: testincompletestatement.cpp testsuite.h tokenize.h CheckOther.h
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
testmemleak.o: testmemleak.cpp CommonCheck.h tokenize.h CheckMemoryLeak.h testsuite.h
|
||||
testmemleak.o: testmemleak.cpp tokenize.h CheckMemoryLeak.h testsuite.h
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
testpreprocessor.o: testpreprocessor.cpp testsuite.h preprocessor.h
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
|
@ -55,7 +53,7 @@ testunusedprivfunc.o: testunusedprivfunc.cpp tokenize.h CheckClass.h testsuite.h
|
|||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
testunusedvar.o: testunusedvar.cpp testsuite.h tokenize.h CheckOther.h
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
tokenize.o: tokenize.cpp tokenize.h CommonCheck.h
|
||||
tokenize.o: tokenize.cpp tokenize.h
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
clean:
|
||||
rm -f *.o testrunner cppcheck
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
#include "preprocessor.h" // preprocessor.
|
||||
|
||||
#include "CommonCheck.h"
|
||||
#include "CheckMemoryLeak.h"
|
||||
#include "CheckBufferOverrun.h"
|
||||
#include "CheckClass.h"
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
|
||||
#include "preprocessor.h"
|
||||
#include "CommonCheck.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
|
||||
#include "tokenize.h"
|
||||
#include "CommonCheck.h"
|
||||
#include "CheckBufferOverrun.h"
|
||||
#include "testsuite.h"
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
|
||||
#include "tokenize.h"
|
||||
#include "CommonCheck.h"
|
||||
#include "CheckOther.h"
|
||||
#include "testsuite.h"
|
||||
#include <sstream>
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
|
||||
|
||||
#include "CommonCheck.h"
|
||||
#include "tokenize.h"
|
||||
#include "CheckMemoryLeak.h"
|
||||
#include "testsuite.h"
|
||||
|
|
221
tokenize.cpp
221
tokenize.cpp
|
@ -19,7 +19,6 @@
|
|||
|
||||
//---------------------------------------------------------------------------
|
||||
#include "tokenize.h"
|
||||
#include "CommonCheck.h" // <- IsName
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
@ -29,7 +28,9 @@
|
|||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
#include <stdlib.h> // <- strtoul
|
||||
#include <stdio.h>
|
||||
|
@ -594,7 +595,7 @@ void Tokenizer::TokenizeCode(std::istream &code, const unsigned int FileIndex)
|
|||
// typedef..
|
||||
for ( TOKEN *tok = _tokens; tok; tok = tok->next )
|
||||
{
|
||||
if (Match(tok, "typedef %type% %type% ;"))
|
||||
if (Tokenizer::Match(tok, "typedef %type% %type% ;"))
|
||||
{
|
||||
const char *type1 = getstr(tok, 1);
|
||||
const char *type2 = getstr(tok, 2);
|
||||
|
@ -607,14 +608,14 @@ void Tokenizer::TokenizeCode(std::istream &code, const unsigned int FileIndex)
|
|||
}
|
||||
}
|
||||
|
||||
else if (Match(tok, "typedef %type% %type% %type% ;"))
|
||||
else if (Tokenizer::Match(tok, "typedef %type% %type% %type% ;"))
|
||||
{
|
||||
const char *type1 = getstr(tok, 1);
|
||||
const char *type2 = getstr(tok, 2);
|
||||
const char *type3 = getstr(tok, 3);
|
||||
|
||||
TOKEN *tok2 = tok;
|
||||
while ( ! Match(tok2, ";") )
|
||||
while ( ! Tokenizer::Match(tok2, ";") )
|
||||
tok2 = tok2->next;
|
||||
|
||||
for ( ; tok2; tok2 = tok2->next )
|
||||
|
@ -639,11 +640,11 @@ void Tokenizer::TokenizeCode(std::istream &code, const unsigned int FileIndex)
|
|||
// Remove __asm..
|
||||
for ( TOKEN *tok = _tokens; tok; tok = tok->next )
|
||||
{
|
||||
if ( Match(tok->next, "__asm {") )
|
||||
if ( Tokenizer::Match(tok->next, "__asm {") )
|
||||
{
|
||||
while ( tok->next )
|
||||
{
|
||||
bool last = Match( tok->next, "}" );
|
||||
bool last = Tokenizer::Match( tok->next, "}" );
|
||||
|
||||
// Unlink and delete tok->next
|
||||
TOKEN *next = tok->next;
|
||||
|
@ -686,7 +687,7 @@ void Tokenizer::SimplifyTokenList()
|
|||
// Replace constants..
|
||||
for (TOKEN *tok = _tokens; tok; tok = tok->next)
|
||||
{
|
||||
if (Match(tok,"const %type% %var% = %num% ;"))
|
||||
if (Tokenizer::Match(tok,"const %type% %var% = %num% ;"))
|
||||
{
|
||||
const char *sym = getstr(tok,2);
|
||||
const char *num = getstr(tok,4);
|
||||
|
@ -712,12 +713,12 @@ void Tokenizer::SimplifyTokenList()
|
|||
TypeSize["double"] = sizeof(double);
|
||||
for (TOKEN *tok = _tokens; tok; tok = tok->next)
|
||||
{
|
||||
if (Match(tok,"class %var%"))
|
||||
if (Tokenizer::Match(tok,"class %var%"))
|
||||
{
|
||||
TypeSize[getstr(tok,1)] = 11;
|
||||
}
|
||||
|
||||
else if (Match(tok, "struct %var%"))
|
||||
else if (Tokenizer::Match(tok, "struct %var%"))
|
||||
{
|
||||
TypeSize[getstr(tok,1)] = 13;
|
||||
}
|
||||
|
@ -730,7 +731,7 @@ void Tokenizer::SimplifyTokenList()
|
|||
if (strcmp(tok->str,"sizeof") != 0)
|
||||
continue;
|
||||
|
||||
if (Match(tok, "sizeof ( %type% * )"))
|
||||
if (Tokenizer::Match(tok, "sizeof ( %type% * )"))
|
||||
{
|
||||
std::ostringstream str;
|
||||
// 'sizeof(type *)' has the same size as 'sizeof(char *)'
|
||||
|
@ -743,7 +744,7 @@ void Tokenizer::SimplifyTokenList()
|
|||
}
|
||||
}
|
||||
|
||||
else if (Match(tok, "sizeof ( %type% )"))
|
||||
else if (Tokenizer::Match(tok, "sizeof ( %type% )"))
|
||||
{
|
||||
const char *type = getstr(tok, 2);
|
||||
int size = SizeOfType(type);
|
||||
|
@ -759,7 +760,7 @@ void Tokenizer::SimplifyTokenList()
|
|||
}
|
||||
}
|
||||
|
||||
else if (Match(tok, "sizeof ( * %var% )"))
|
||||
else if (Tokenizer::Match(tok, "sizeof ( * %var% )"))
|
||||
{
|
||||
tok->setstr("100");
|
||||
for ( int i = 0; i < 4; ++i )
|
||||
|
@ -771,7 +772,7 @@ void Tokenizer::SimplifyTokenList()
|
|||
for (TOKEN *tok = _tokens; tok; tok = tok->next)
|
||||
{
|
||||
// type array [ num ] ;
|
||||
if ( ! Match(tok, "%type% %var% [ %num% ] ;") )
|
||||
if ( ! Tokenizer::Match(tok, "%type% %var% [ %num% ] ;") )
|
||||
continue;
|
||||
|
||||
int size = SizeOfType(tok->str);
|
||||
|
@ -797,8 +798,8 @@ void Tokenizer::SimplifyTokenList()
|
|||
break;
|
||||
}
|
||||
|
||||
// Todo: Match varname directly
|
||||
else if (Match(tok2, "sizeof ( %var% )"))
|
||||
// Todo: Tokenizer::Match varname directly
|
||||
else if (Tokenizer::Match(tok2, "sizeof ( %var% )"))
|
||||
{
|
||||
if (strcmp(getstr(tok2,2), varname) == 0)
|
||||
{
|
||||
|
@ -827,7 +828,7 @@ void Tokenizer::SimplifyTokenList()
|
|||
|
||||
for (TOKEN *tok = _tokens; tok; tok = tok->next)
|
||||
{
|
||||
if (Match(tok->next, "* 1") || Match(tok->next, "1 *"))
|
||||
if (Tokenizer::Match(tok->next, "* 1") || Tokenizer::Match(tok->next, "1 *"))
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
DeleteNextToken(tok);
|
||||
|
@ -836,9 +837,9 @@ void Tokenizer::SimplifyTokenList()
|
|||
|
||||
// (1-2)
|
||||
if (strchr("[,(=<>",tok->str[0]) &&
|
||||
IsNumber(getstr(tok,1)) &&
|
||||
Tokenizer::IsNumber(getstr(tok,1)) &&
|
||||
strchr("+-*/",*(getstr(tok,2))) &&
|
||||
IsNumber(getstr(tok,3)) &&
|
||||
Tokenizer::IsNumber(getstr(tok,3)) &&
|
||||
strchr("],);=<>",*(getstr(tok,4))) )
|
||||
{
|
||||
int i1 = atoi(getstr(tok,1));
|
||||
|
@ -880,7 +881,7 @@ void Tokenizer::SimplifyTokenList()
|
|||
if ( ! next )
|
||||
break;
|
||||
|
||||
if (Match(next, "* ( %var% + %num% )"))
|
||||
if (Tokenizer::Match(next, "* ( %var% + %num% )"))
|
||||
{
|
||||
const char *str[4] = {"var","[","num","]"};
|
||||
str[0] = getstr(tok,3);
|
||||
|
@ -906,64 +907,64 @@ void Tokenizer::SimplifyTokenList()
|
|||
continue;
|
||||
|
||||
TOKEN *type0 = tok->next;
|
||||
if (!Match(type0, "%type%"))
|
||||
if (!Tokenizer::Match(type0, "%type%"))
|
||||
continue;
|
||||
if (Match(type0, "else") || Match(type0, "return"))
|
||||
if (Tokenizer::Match(type0, "else") || Tokenizer::Match(type0, "return"))
|
||||
continue;
|
||||
|
||||
TOKEN *tok2 = NULL;
|
||||
unsigned int typelen = 0;
|
||||
|
||||
if ( Match(type0, "%type% %var% ,") )
|
||||
if ( Tokenizer::Match(type0, "%type% %var% ,") )
|
||||
{
|
||||
tok2 = _gettok(type0, 2); // The ',' token
|
||||
typelen = 1;
|
||||
}
|
||||
|
||||
else if ( Match(type0, "%type% * %var% ,") )
|
||||
else if ( Tokenizer::Match(type0, "%type% * %var% ,") )
|
||||
{
|
||||
tok2 = _gettok(type0, 3); // The ',' token
|
||||
typelen = 1;
|
||||
}
|
||||
|
||||
else if ( Match(type0, "%type% %var% [ %num% ] ,") )
|
||||
else if ( Tokenizer::Match(type0, "%type% %var% [ %num% ] ,") )
|
||||
{
|
||||
tok2 = _gettok(type0, 5); // The ',' token
|
||||
typelen = 1;
|
||||
}
|
||||
|
||||
else if ( Match(type0, "%type% * %var% [ %num% ] ,") )
|
||||
else if ( Tokenizer::Match(type0, "%type% * %var% [ %num% ] ,") )
|
||||
{
|
||||
tok2 = _gettok(type0, 6); // The ',' token
|
||||
typelen = 1;
|
||||
}
|
||||
|
||||
else if ( Match(type0, "struct %type% %var% ,") )
|
||||
else if ( Tokenizer::Match(type0, "struct %type% %var% ,") )
|
||||
{
|
||||
tok2 = _gettok(type0, 3);
|
||||
typelen = 2;
|
||||
}
|
||||
|
||||
else if ( Match(type0, "struct %type% * %var% ,") )
|
||||
else if ( Tokenizer::Match(type0, "struct %type% * %var% ,") )
|
||||
{
|
||||
tok2 = _gettok(type0, 4);
|
||||
typelen = 2;
|
||||
}
|
||||
|
||||
|
||||
else if ( Match(type0, "%type% %var% =") )
|
||||
else if ( Tokenizer::Match(type0, "%type% %var% =") )
|
||||
{
|
||||
tok2 = _gettok(type0, 2);
|
||||
typelen = 1;
|
||||
}
|
||||
|
||||
else if ( Match(type0, "%type% * %var% =") )
|
||||
else if ( Tokenizer::Match(type0, "%type% * %var% =") )
|
||||
{
|
||||
tok2 = _gettok(type0, 3);
|
||||
typelen = 1;
|
||||
}
|
||||
|
||||
else if ( Match(type0, "struct %type% * %var% =") )
|
||||
else if ( Tokenizer::Match(type0, "struct %type% * %var% =") )
|
||||
{
|
||||
tok2 = _gettok(type0, 4);
|
||||
typelen = 2;
|
||||
|
@ -1023,16 +1024,16 @@ void Tokenizer::SimplifyTokenList()
|
|||
// Replace NULL with 0..
|
||||
for ( TOKEN *tok = _tokens; tok; tok = tok->next )
|
||||
{
|
||||
if ( Match(tok, "NULL") )
|
||||
if ( Tokenizer::Match(tok, "NULL") )
|
||||
tok->setstr("0");
|
||||
}
|
||||
|
||||
// Replace pointer casts of 0.. "(char *)0" => "0"
|
||||
for ( TOKEN *tok = _tokens; tok; tok = tok->next )
|
||||
{
|
||||
if ( Match(tok->next, "( %type% * ) 0") || Match(tok->next,"( %type% %type% * ) 0") )
|
||||
if ( Tokenizer::Match(tok->next, "( %type% * ) 0") || Tokenizer::Match(tok->next,"( %type% %type% * ) 0") )
|
||||
{
|
||||
while (!Match(tok->next,"0"))
|
||||
while (!Tokenizer::Match(tok->next,"0"))
|
||||
DeleteNextToken(tok);
|
||||
}
|
||||
}
|
||||
|
@ -1141,10 +1142,10 @@ void Tokenizer::FillFunctionList(const unsigned int file_id)
|
|||
{
|
||||
const char *funcname = 0;
|
||||
|
||||
if ( Match(tok,"%var% (") )
|
||||
if ( Tokenizer::Match(tok,"%var% (") )
|
||||
funcname = tok->str;
|
||||
else if ( Match(tok, "= %var% ;") ||
|
||||
Match(tok, "= %var% ,") )
|
||||
else if ( Tokenizer::Match(tok, "= %var% ;") ||
|
||||
Tokenizer::Match(tok, "= %var% ,") )
|
||||
funcname = tok->next->str;
|
||||
|
||||
if ( std::find(_usedfunc.begin(), _usedfunc.end(), funcname) == _usedfunc.end() )
|
||||
|
@ -1163,7 +1164,7 @@ void Tokenizer::FillFunctionList(const unsigned int file_id)
|
|||
else if ( strcmp( tok->str, "::" ) == 0 )
|
||||
classfunc = true;
|
||||
|
||||
else if (Match(tok, "%var% ("))
|
||||
else if (Tokenizer::Match(tok, "%var% ("))
|
||||
{
|
||||
// Check if this is the first token of a function implementation..
|
||||
for ( const TOKEN *tok2 = tok; tok2; tok2 = tok2->next )
|
||||
|
@ -1181,7 +1182,7 @@ void Tokenizer::FillFunctionList(const unsigned int file_id)
|
|||
|
||||
else if ( tok2->str[0] == ')' )
|
||||
{
|
||||
if ( Match(tok2, ") {") )
|
||||
if ( Tokenizer::Match(tok2, ") {") )
|
||||
{
|
||||
if (_settings._checkCodingStyle && !staticfunc && !classfunc && tok->FileIndex==0)
|
||||
GlobalFunctions.push_back( GlobalFunction(file_id, tok->str) );
|
||||
|
@ -1352,9 +1353,9 @@ const char *Tokenizer::getParameterName( const TOKEN *ftok, int par )
|
|||
int _par = 1;
|
||||
for ( ; ftok; ftok = ftok->next)
|
||||
{
|
||||
if ( Match(ftok, ",") )
|
||||
if ( Tokenizer::Match(ftok, ",") )
|
||||
++_par;
|
||||
if ( par==_par && Match(ftok, "%var% [,)]") )
|
||||
if ( par==_par && Tokenizer::Match(ftok, "%var% [,)]") )
|
||||
return ftok->str;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -1366,7 +1367,7 @@ const TOKEN *Tokenizer::findmatch(const TOKEN *tok, const char pattern[], const
|
|||
{
|
||||
for ( ; tok; tok = tok->next)
|
||||
{
|
||||
if ( Match(tok, pattern, varname1, varname2) )
|
||||
if ( Tokenizer::Match(tok, pattern, varname1, varname2) )
|
||||
return tok;
|
||||
}
|
||||
return 0;
|
||||
|
@ -1380,3 +1381,139 @@ std::string Tokenizer::fileLine( const TOKEN *tok )
|
|||
ostr << "[" << Files.at(tok->FileIndex) << ":" << tok->linenr << "]";
|
||||
return ostr.str();
|
||||
}
|
||||
|
||||
|
||||
bool Tokenizer::Match(const TOKEN *tok, const char pattern[], const char *varname1[], const char *varname2[])
|
||||
{
|
||||
if (!tok)
|
||||
return false;
|
||||
|
||||
const char *p = pattern;
|
||||
while (*p)
|
||||
{
|
||||
// Skip spaces in pattern..
|
||||
while ( *p == ' ' )
|
||||
p++;
|
||||
|
||||
// Extract token from pattern..
|
||||
char str[50];
|
||||
char *s = str;
|
||||
while (*p && *p!=' ')
|
||||
{
|
||||
*s = *p;
|
||||
s++;
|
||||
p++;
|
||||
}
|
||||
*s = 0;
|
||||
|
||||
// No token => Success!
|
||||
if (str[0] == 0)
|
||||
return true;
|
||||
|
||||
// Any symbolname..
|
||||
if (strcmp(str,"%var%")==0 || strcmp(str,"%type%")==0)
|
||||
{
|
||||
if (!Tokenizer::IsName(tok->str))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Variable name..
|
||||
else if (strcmp(str,"%var1%")==0 || strcmp(str,"%var2%")==0)
|
||||
{
|
||||
const char **varname = (strcmp(str,"%var1%")==0) ? varname1 : varname2;
|
||||
|
||||
if ( ! varname )
|
||||
return false;
|
||||
|
||||
if (strcmp(tok->str, varname[0]) != 0)
|
||||
return false;
|
||||
|
||||
for ( int i = 1; varname[i]; i++ )
|
||||
{
|
||||
if ( ! Tokenizer::gettok(tok, 2) )
|
||||
return false;
|
||||
|
||||
if ( strcmp(Tokenizer::getstr(tok, 1), ".") )
|
||||
return false;
|
||||
|
||||
if ( strcmp(Tokenizer::getstr(tok, 2), varname[i]) )
|
||||
return false;
|
||||
|
||||
tok = Tokenizer::gettok(tok, 2);
|
||||
}
|
||||
}
|
||||
|
||||
else if (strcmp(str,"%num%")==0)
|
||||
{
|
||||
if ( ! Tokenizer::IsNumber(tok->str) )
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
else if (strcmp(str,"%str%")==0)
|
||||
{
|
||||
if ( tok->str[0] != '\"' )
|
||||
return false;
|
||||
}
|
||||
|
||||
// [.. => search for a one-character token..
|
||||
else if (str[0]=='[' && strchr(str, ']') && tok->str[1] == 0)
|
||||
{
|
||||
*strrchr(str, ']') = 0;
|
||||
if ( strchr( str + 1, tok->str[0] ) == 0 )
|
||||
return false;
|
||||
}
|
||||
|
||||
else if (strcmp(str, tok->str) != 0)
|
||||
return false;
|
||||
|
||||
tok = tok->next;
|
||||
if (!tok)
|
||||
return false;
|
||||
}
|
||||
|
||||
// The end of the pattern has been reached and nothing wrong has been found
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool Tokenizer::SameFileName( const char fname1[], const char fname2[] )
|
||||
{
|
||||
#ifdef __linux__
|
||||
return bool( strcmp(fname1, fname2) == 0 );
|
||||
#endif
|
||||
#ifdef __GNUC__
|
||||
return bool( strcasecmp(fname1, fname2) == 0 );
|
||||
#endif
|
||||
#ifdef __BORLANDC__
|
||||
return bool( stricmp(fname1, fname2) == 0 );
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
return bool( _stricmp(fname1, fname2) == 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool Tokenizer::IsName(const char str[])
|
||||
{
|
||||
return bool(str[0]=='_' || isalpha(str[0]));
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool Tokenizer::IsNumber(const char str[])
|
||||
{
|
||||
return bool(isdigit(str[0]) != 0);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool Tokenizer::IsStandardType(const char str[])
|
||||
{
|
||||
if (!str)
|
||||
return false;
|
||||
bool Ret = false;
|
||||
const char *type[] = {"bool","char","short","int","long","float","double",0};
|
||||
for (int i = 0; type[i]; i++)
|
||||
Ret |= (strcmp(str,type[i])==0);
|
||||
return Ret;
|
||||
}
|
||||
|
|
|
@ -84,6 +84,12 @@ public:
|
|||
static void deleteTokens(TOKEN *tok);
|
||||
static const char *getParameterName( const TOKEN *ftok, int par );
|
||||
static const TOKEN *findmatch(const TOKEN *tok, const char pattern[], const char *varname1[]=0, const char *varname2[]=0);
|
||||
static bool Match(const TOKEN *tok, const char pattern[], const char *varname1[]=0, const char *varname2[]=0);
|
||||
static bool SameFileName( const char fname1[], const char fname2[] );
|
||||
static bool IsName(const char str[]);
|
||||
static bool IsNumber(const char str[]);
|
||||
static bool IsStandardType(const char str[]);
|
||||
|
||||
|
||||
std::string fileLine( const TOKEN *tok );
|
||||
|
||||
|
@ -100,7 +106,8 @@ public:
|
|||
const TOKEN *GetFunctionTokenByName( const char funcname[] ) const;
|
||||
void CheckGlobalFunctionUsage(const std::vector<std::string> &filenames);
|
||||
void settings( const Settings &settings );
|
||||
const TOKEN *tokens() const;
|
||||
const TOKEN *tokens() const;
|
||||
|
||||
|
||||
|
||||
#ifndef UNIT_TESTING
|
||||
|
|
Loading…
Reference in New Issue