Refactoring: CommonCheck.* files are removed. Rest of the global functions from there were moved to Tokenizer class

This commit is contained in:
Reijo Tomperi 2008-11-21 21:14:24 +00:00
parent 66412ed4ae
commit 125692bc65
15 changed files with 484 additions and 580 deletions

View File

@ -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";

View File

@ -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) << "'";

View File

@ -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())

View File

@ -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 )

View File

@ -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";

View File

@ -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;
}
//---------------------------------------------------------------------------

View File

@ -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

View File

@ -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

View File

@ -19,7 +19,6 @@
#include "preprocessor.h" // preprocessor.
#include "CommonCheck.h"
#include "CheckMemoryLeak.h"
#include "CheckBufferOverrun.h"
#include "CheckClass.h"

View File

@ -18,7 +18,6 @@
#include "preprocessor.h"
#include "CommonCheck.h"
#include <algorithm>

View File

@ -19,7 +19,6 @@
#include "tokenize.h"
#include "CommonCheck.h"
#include "CheckBufferOverrun.h"
#include "testsuite.h"

View File

@ -18,7 +18,6 @@
#include "tokenize.h"
#include "CommonCheck.h"
#include "CheckOther.h"
#include "testsuite.h"
#include <sstream>

View File

@ -19,7 +19,6 @@
#include "CommonCheck.h"
#include "tokenize.h"
#include "CheckMemoryLeak.h"
#include "testsuite.h"

View File

@ -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;
}

View File

@ -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