Refactoring: token.* files added, Some functions from Tokenizer moved under TOKEN. Renamed few functions, like gettok() -> at(), combineWithNext() and deleteNext() are also new
names for old functions. Usage was gettok( tok, 2 ), but now it is tok->at( 2 ).
This commit is contained in:
parent
2a85d68803
commit
3ba83b6620
|
@ -72,9 +72,9 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
|
||||
|
||||
// Array index..
|
||||
if ( Tokenizer::Match(tok, "%var1% [ %num% ]", varname) )
|
||||
if ( TOKEN::Match(tok, "%var1% [ %num% ]", varname) )
|
||||
{
|
||||
const char *num = Tokenizer::getstr(tok, 2 + varc);
|
||||
const char *num = TOKEN::getstr(tok, 2 + varc);
|
||||
if (strtol(num, NULL, 10) >= size)
|
||||
{
|
||||
ReportError(tok->next, "Array index out of bounds");
|
||||
|
@ -85,12 +85,12 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
int indentlevel = 0;
|
||||
for ( ; tok; tok = tok->next )
|
||||
{
|
||||
if (Tokenizer::Match(tok, "{"))
|
||||
if (TOKEN::Match(tok, "{"))
|
||||
{
|
||||
indentlevel++;
|
||||
}
|
||||
|
||||
else if (Tokenizer::Match(tok, "}"))
|
||||
else if (TOKEN::Match(tok, "}"))
|
||||
{
|
||||
indentlevel--;
|
||||
if ( indentlevel < 0 )
|
||||
|
@ -98,30 +98,30 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
}
|
||||
|
||||
// Array index..
|
||||
if ( !Tokenizer::Match(tok, "%var%") && !Tokenizer::Match(tok,"[.&]") && Tokenizer::Match(tok->next, "%var1% [ %num% ]", varname) )
|
||||
if ( !TOKEN::Match(tok, "%var%") && !TOKEN::Match(tok,"[.&]") && TOKEN::Match(tok->next, "%var1% [ %num% ]", varname) )
|
||||
{
|
||||
const char *num = Tokenizer::getstr(tok->next, 2 + varc);
|
||||
const char *num = TOKEN::getstr(tok->next, 2 + varc);
|
||||
if (strtol(num, NULL, 10) >= size)
|
||||
{
|
||||
ReportError(tok->next, "Array index out of bounds");
|
||||
}
|
||||
tok = Tokenizer::gettok(tok, 4);
|
||||
tok = tok->at(4);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// memset, memcmp, memcpy, strncpy, 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 (TOKEN::Match(tok,"memset") ||
|
||||
TOKEN::Match(tok,"memcpy") ||
|
||||
TOKEN::Match(tok,"memmove") ||
|
||||
TOKEN::Match(tok,"memcmp") ||
|
||||
TOKEN::Match(tok,"strncpy") ||
|
||||
TOKEN::Match(tok,"fgets") )
|
||||
{
|
||||
if ( Tokenizer::Match( tok->next, "( %var1% , %num% , %num% )", varname ) ||
|
||||
Tokenizer::Match( tok->next, "( %var% , %var1% , %num% )", varname ) )
|
||||
if ( TOKEN::Match( tok->next, "( %var1% , %num% , %num% )", varname ) ||
|
||||
TOKEN::Match( tok->next, "( %var% , %var1% , %num% )", varname ) )
|
||||
{
|
||||
const char *num = Tokenizer::getstr(tok, varc + 6);
|
||||
const char *num = TOKEN::getstr(tok, varc + 6);
|
||||
if ( atoi(num) > total_size )
|
||||
{
|
||||
ReportError(tok, "Buffer overrun");
|
||||
|
@ -132,34 +132,34 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
|
||||
|
||||
// Loop..
|
||||
if ( Tokenizer::Match(tok, "for (") )
|
||||
if ( TOKEN::Match(tok, "for (") )
|
||||
{
|
||||
const TOKEN *tok2 = Tokenizer::gettok( tok, 2 );
|
||||
const TOKEN *tok2 = tok->at(2);
|
||||
|
||||
// for - setup..
|
||||
if ( Tokenizer::Match(tok2, "%var% = 0 ;") )
|
||||
tok2 = Tokenizer::gettok(tok2, 4);
|
||||
else if ( Tokenizer::Match(tok2, "%type% %var% = 0 ;") )
|
||||
tok2 = Tokenizer::gettok(tok2, 5);
|
||||
else if ( Tokenizer::Match(tok2, "%type% %type% %var% = 0 ;") )
|
||||
tok2 = Tokenizer::gettok(tok2, 6);
|
||||
if ( TOKEN::Match(tok2, "%var% = 0 ;") )
|
||||
tok2 = tok2->at(4);
|
||||
else if ( TOKEN::Match(tok2, "%type% %var% = 0 ;") )
|
||||
tok2 = tok2->at(5);
|
||||
else if ( TOKEN::Match(tok2, "%type% %type% %var% = 0 ;") )
|
||||
tok2 = tok2->at(6);
|
||||
else
|
||||
continue;
|
||||
|
||||
// for - condition..
|
||||
if ( ! Tokenizer::Match(tok2, "%var% < %num% ;") && ! Tokenizer::Match(tok2, "%var% <= %num% ;"))
|
||||
if ( ! TOKEN::Match(tok2, "%var% < %num% ;") && ! TOKEN::Match(tok2, "%var% <= %num% ;"))
|
||||
continue;
|
||||
|
||||
// Get index variable and stopsize.
|
||||
const char *strindex = tok2->str;
|
||||
int value = (tok2->next->str[1] ? 1 : 0) + atoi(Tokenizer::getstr(tok2, 2));
|
||||
int value = (tok2->next->str[1] ? 1 : 0) + atoi(TOKEN::getstr(tok2, 2));
|
||||
if ( value <= size )
|
||||
continue;
|
||||
|
||||
// Goto the end of the for loop..
|
||||
while (tok2 && !Tokenizer::Match(tok2,")"))
|
||||
while (tok2 && !TOKEN::Match(tok2,")"))
|
||||
tok2 = tok2->next;
|
||||
if (!Tokenizer::gettok(tok2,5))
|
||||
if (!(tok2->at(5)))
|
||||
break;
|
||||
|
||||
std::ostringstream pattern;
|
||||
|
@ -168,20 +168,20 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
int indentlevel2 = 0;
|
||||
while (tok2)
|
||||
{
|
||||
if ( Tokenizer::Match(tok2, ";") && indentlevel2 == 0 )
|
||||
if ( TOKEN::Match(tok2, ";") && indentlevel2 == 0 )
|
||||
break;
|
||||
|
||||
if ( Tokenizer::Match(tok2, "{") )
|
||||
if ( TOKEN::Match(tok2, "{") )
|
||||
indentlevel2++;
|
||||
|
||||
if ( Tokenizer::Match(tok2, "}") )
|
||||
if ( TOKEN::Match(tok2, "}") )
|
||||
{
|
||||
indentlevel2--;
|
||||
if ( indentlevel2 <= 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( Tokenizer::Match( tok2, pattern.str().c_str(), varname ) )
|
||||
if ( TOKEN::Match( tok2, pattern.str().c_str(), varname ) )
|
||||
{
|
||||
ReportError(tok2, "Buffer overrun");
|
||||
break;
|
||||
|
@ -194,10 +194,10 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
|
||||
|
||||
// Writing data into array..
|
||||
if ( Tokenizer::Match(tok, "strcpy ( %var1% , %str% )", varname) )
|
||||
if ( TOKEN::Match(tok, "strcpy ( %var1% , %str% )", varname) )
|
||||
{
|
||||
int len = 0;
|
||||
const char *str = Tokenizer::getstr(tok, varc + 4 );
|
||||
const char *str = TOKEN::getstr(tok, varc + 4 );
|
||||
while ( *str )
|
||||
{
|
||||
if (*str=='\\')
|
||||
|
@ -216,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 ( Tokenizer::Match( tok, "%var% (" ) )
|
||||
if ( TOKEN::Match( tok, "%var% (" ) )
|
||||
{
|
||||
// Don't make recursive checking..
|
||||
if (std::find(CallStack.begin(), CallStack.end(), tok) != CallStack.end())
|
||||
|
@ -225,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 ( Tokenizer::Match(tok2, "(") )
|
||||
if ( TOKEN::Match(tok2, "(") )
|
||||
{
|
||||
parlevel++;
|
||||
}
|
||||
|
||||
else if ( Tokenizer::Match(tok2, ")") )
|
||||
else if ( TOKEN::Match(tok2, ")") )
|
||||
{
|
||||
parlevel--;
|
||||
if ( parlevel < 1 )
|
||||
|
@ -240,12 +240,12 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
}
|
||||
}
|
||||
|
||||
else if ( parlevel == 1 && Tokenizer::Match(tok2, ",") )
|
||||
else if ( parlevel == 1 && TOKEN::Match(tok2, ",") )
|
||||
{
|
||||
par++;
|
||||
}
|
||||
|
||||
if ( parlevel == 1 && Tokenizer::Match(tok2, "[(,] %var1% [,)]", varname) )
|
||||
if ( parlevel == 1 && TOKEN::Match(tok2, "[(,] %var1% [,)]", varname) )
|
||||
{
|
||||
par++;
|
||||
break;
|
||||
|
@ -261,20 +261,20 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
continue;
|
||||
|
||||
// Parse head of function..
|
||||
ftok = Tokenizer::gettok( ftok, 2 );
|
||||
ftok = ftok->at(2);
|
||||
parlevel = 1;
|
||||
while ( ftok && parlevel == 1 && par >= 1 )
|
||||
{
|
||||
if ( Tokenizer::Match(ftok, "(") )
|
||||
if ( TOKEN::Match(ftok, "(") )
|
||||
parlevel++;
|
||||
|
||||
else if ( Tokenizer::Match(ftok, ")") )
|
||||
else if ( TOKEN::Match(ftok, ")") )
|
||||
parlevel--;
|
||||
|
||||
else if ( Tokenizer::Match(ftok, ",") )
|
||||
else if ( TOKEN::Match(ftok, ",") )
|
||||
par--;
|
||||
|
||||
else if (par==1 && parlevel==1 && (Tokenizer::Match(ftok, "%var% ,") || Tokenizer::Match(ftok, "%var% )")))
|
||||
else if (par==1 && parlevel==1 && (TOKEN::Match(ftok, "%var% ,") || TOKEN::Match(ftok, "%var% )")))
|
||||
{
|
||||
// Parameter name..
|
||||
const char *parname[2];
|
||||
|
@ -282,7 +282,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
parname[1] = 0;
|
||||
|
||||
// Goto function body..
|
||||
while ( ftok && !Tokenizer::Match(ftok,"{") )
|
||||
while ( ftok && !TOKEN::Match(ftok,"{") )
|
||||
ftok = ftok->next;
|
||||
ftok = ftok ? ftok->next : 0;
|
||||
|
||||
|
@ -311,10 +311,10 @@ void CheckBufferOverrunClass::CheckBufferOverrun_LocalVariable()
|
|||
int indentlevel = 0;
|
||||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
if (Tokenizer::Match(tok, "{"))
|
||||
if (TOKEN::Match(tok, "{"))
|
||||
indentlevel++;
|
||||
|
||||
else if (Tokenizer::Match(tok, "}"))
|
||||
else if (TOKEN::Match(tok, "}"))
|
||||
indentlevel--;
|
||||
|
||||
else if (indentlevel > 0)
|
||||
|
@ -323,17 +323,17 @@ void CheckBufferOverrunClass::CheckBufferOverrun_LocalVariable()
|
|||
unsigned int size = 0;
|
||||
const char *type = 0;
|
||||
|
||||
if (Tokenizer::Match(tok, "%type% %var% [ %num% ] ;"))
|
||||
if (TOKEN::Match(tok, "%type% %var% [ %num% ] ;"))
|
||||
{
|
||||
varname[0] = Tokenizer::getstr(tok,1);
|
||||
size = strtoul(Tokenizer::getstr(tok,3), NULL, 10);
|
||||
varname[0] = TOKEN::getstr(tok,1);
|
||||
size = strtoul(TOKEN::getstr(tok,3), NULL, 10);
|
||||
type = tok->str;
|
||||
}
|
||||
else if (indentlevel > 0 && Tokenizer::Match(tok, "[*;{}] %var% = new %type% [ %num% ]"))
|
||||
else if (indentlevel > 0 && TOKEN::Match(tok, "[*;{}] %var% = new %type% [ %num% ]"))
|
||||
{
|
||||
varname[0] = Tokenizer::getstr(tok,1);
|
||||
size = strtoul(Tokenizer::getstr(tok,6), NULL, 10);
|
||||
type = Tokenizer::getstr(tok, 4);
|
||||
varname[0] = TOKEN::getstr(tok,1);
|
||||
size = strtoul(TOKEN::getstr(tok,6), NULL, 10);
|
||||
type = TOKEN::getstr(tok, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -346,7 +346,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_LocalVariable()
|
|||
|
||||
// The callstack is empty
|
||||
CallStack.clear();
|
||||
CheckBufferOverrun_CheckScope( Tokenizer::gettok(tok,5), varname, size, total_size );
|
||||
CheckBufferOverrun_CheckScope( tok->at(5), varname, size, total_size );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -360,64 +360,64 @@ void CheckBufferOverrunClass::CheckBufferOverrun_LocalVariable()
|
|||
void CheckBufferOverrunClass::CheckBufferOverrun_StructVariable()
|
||||
{
|
||||
const char *declstruct_pattern[] = {"","","{",0};
|
||||
for ( const TOKEN * tok = Tokenizer::findtoken( _tokenizer->tokens(), declstruct_pattern );
|
||||
for ( const TOKEN * tok = TOKEN::findtoken( _tokenizer->tokens(), declstruct_pattern );
|
||||
tok;
|
||||
tok = Tokenizer::findtoken( tok->next, declstruct_pattern ) )
|
||||
tok = TOKEN::findtoken( tok->next, declstruct_pattern ) )
|
||||
{
|
||||
if (!Tokenizer::Match(tok,"struct") && !Tokenizer::Match(tok,"class"))
|
||||
if (!TOKEN::Match(tok,"struct") && !TOKEN::Match(tok,"class"))
|
||||
continue;
|
||||
|
||||
const char *structname = tok->next->str;
|
||||
|
||||
if ( ! Tokenizer::IsName( structname ) )
|
||||
if ( ! TOKEN::IsName( structname ) )
|
||||
continue;
|
||||
|
||||
// Found a struct declaration. Search for arrays..
|
||||
for ( TOKEN * tok2 = tok->next->next; tok2; tok2 = tok2->next )
|
||||
{
|
||||
if ( Tokenizer::Match(tok2, "}") )
|
||||
if ( TOKEN::Match(tok2, "}") )
|
||||
break;
|
||||
|
||||
int ivar = 0;
|
||||
if ( Tokenizer::Match(tok2->next, "%type% %var% [ %num% ] ;") )
|
||||
if ( TOKEN::Match(tok2->next, "%type% %var% [ %num% ] ;") )
|
||||
ivar = 2;
|
||||
else if ( Tokenizer::Match(tok2->next, "%type% %type% %var% [ %num% ] ;") )
|
||||
else if ( TOKEN::Match(tok2->next, "%type% %type% %var% [ %num% ] ;") )
|
||||
ivar = 3;
|
||||
else if ( Tokenizer::Match(tok2->next, "%type% * %var% [ %num% ] ;") )
|
||||
else if ( TOKEN::Match(tok2->next, "%type% * %var% [ %num% ] ;") )
|
||||
ivar = 3;
|
||||
else if ( Tokenizer::Match(tok2->next, "%type% %type% * %var% [ %num% ] ;") )
|
||||
else if ( TOKEN::Match(tok2->next, "%type% %type% * %var% [ %num% ] ;") )
|
||||
ivar = 4;
|
||||
else
|
||||
continue;
|
||||
|
||||
const char *varname[3] = {0,0,0};
|
||||
varname[1] = Tokenizer::getstr(tok2, ivar);
|
||||
int arrsize = atoi(Tokenizer::getstr(tok2, ivar+2));
|
||||
varname[1] = TOKEN::getstr(tok2, ivar);
|
||||
int arrsize = atoi(TOKEN::getstr(tok2, ivar+2));
|
||||
int total_size = arrsize * _tokenizer->SizeOfType(tok2->next->str);
|
||||
if (total_size == 0)
|
||||
continue;
|
||||
|
||||
|
||||
// Class member variable => Check functions
|
||||
if ( Tokenizer::Match(tok, "class") )
|
||||
if ( TOKEN::Match(tok, "class") )
|
||||
{
|
||||
std::string func_pattern(structname + std::string(" :: %var% ("));
|
||||
const TOKEN *tok3 = Tokenizer::findmatch(_tokenizer->tokens(), func_pattern.c_str());
|
||||
const TOKEN *tok3 = TOKEN::findmatch(_tokenizer->tokens(), func_pattern.c_str());
|
||||
while ( tok3 )
|
||||
{
|
||||
for ( const TOKEN *tok4 = tok3; tok4; tok4 = tok4->next )
|
||||
{
|
||||
if ( Tokenizer::Match(tok4,"[;{}]") )
|
||||
if ( TOKEN::Match(tok4,"[;{}]") )
|
||||
break;
|
||||
|
||||
if ( Tokenizer::Match(tok4, ") {") )
|
||||
if ( TOKEN::Match(tok4, ") {") )
|
||||
{
|
||||
const char *names[2] = {varname[1], 0};
|
||||
CheckBufferOverrun_CheckScope( Tokenizer::gettok(tok4, 2), names, arrsize, total_size );
|
||||
CheckBufferOverrun_CheckScope( tok4->at(2), names, arrsize, total_size );
|
||||
break;
|
||||
}
|
||||
}
|
||||
tok3 = Tokenizer::findmatch(tok3->next, func_pattern.c_str());
|
||||
tok3 = TOKEN::findmatch(tok3->next, func_pattern.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -427,12 +427,12 @@ void CheckBufferOverrunClass::CheckBufferOverrun_StructVariable()
|
|||
continue;
|
||||
|
||||
// Declare variable: Fred fred1;
|
||||
if ( Tokenizer::Match( tok3->next, "%var% ;" ) )
|
||||
varname[0] = Tokenizer::getstr(tok3, 1);
|
||||
if ( TOKEN::Match( tok3->next, "%var% ;" ) )
|
||||
varname[0] = TOKEN::getstr(tok3, 1);
|
||||
|
||||
// Declare pointer: Fred *fred1
|
||||
else if ( Tokenizer::Match(tok3->next, "* %var% [,);=]") )
|
||||
varname[0] = Tokenizer::getstr(tok3, 2);
|
||||
else if ( TOKEN::Match(tok3->next, "* %var% [,);=]") )
|
||||
varname[0] = TOKEN::getstr(tok3, 2);
|
||||
|
||||
else
|
||||
continue;
|
||||
|
@ -443,20 +443,20 @@ void CheckBufferOverrunClass::CheckBufferOverrun_StructVariable()
|
|||
while ( tok3 )
|
||||
{
|
||||
// End of statement.
|
||||
if ( Tokenizer::Match(tok3, ";") )
|
||||
if ( TOKEN::Match(tok3, ";") )
|
||||
{
|
||||
CheckTok = tok3;
|
||||
break;
|
||||
}
|
||||
|
||||
// End of function declaration..
|
||||
if ( Tokenizer::Match(tok3, ") ;") )
|
||||
if ( TOKEN::Match(tok3, ") ;") )
|
||||
break;
|
||||
|
||||
// Function implementation..
|
||||
if ( Tokenizer::Match(tok3, ") {") )
|
||||
if ( TOKEN::Match(tok3, ") {") )
|
||||
{
|
||||
CheckTok = Tokenizer::gettok(tok3, 2);
|
||||
CheckTok = tok3->at(2);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -501,14 +501,14 @@ void CheckBufferOverrunClass::WarningDangerousFunctions()
|
|||
{
|
||||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
if (Tokenizer::Match(tok, "gets ("))
|
||||
if (TOKEN::Match(tok, "gets ("))
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << _tokenizer->fileLine(tok) << ": Found 'gets'. You should use 'fgets' instead";
|
||||
_errorLogger->reportErr(ostr.str());
|
||||
}
|
||||
|
||||
else if (Tokenizer::Match(tok, "scanf (") && strcmp(Tokenizer::getstr(tok,2),"\"%s\"") == 0)
|
||||
else if (TOKEN::Match(tok, "scanf (") && strcmp(TOKEN::getstr(tok,2),"\"%s\"") == 0)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << _tokenizer->fileLine(tok) << ": Found 'scanf'. You should use 'fgets' instead";
|
||||
|
|
114
CheckClass.cpp
114
CheckClass.cpp
|
@ -74,7 +74,7 @@ struct VAR *CheckClass::ClassChecking_GetVarList(const TOKEN *tok1)
|
|||
const char *varname = 0;
|
||||
|
||||
// Is it a variable declaration?
|
||||
if ( Tokenizer::Match(next,"%type% %var% ;") )
|
||||
if ( TOKEN::Match(next,"%type% %var% ;") )
|
||||
{
|
||||
const char *types[] = {"bool", "char", "int", "short", "long", "float", "double", 0};
|
||||
for ( int type = 0; types[type]; type++ )
|
||||
|
@ -88,9 +88,9 @@ struct VAR *CheckClass::ClassChecking_GetVarList(const TOKEN *tok1)
|
|||
}
|
||||
|
||||
// Pointer?
|
||||
else if ( Tokenizer::Match(next, "%type% * %var% ;") )
|
||||
else if ( TOKEN::Match(next, "%type% * %var% ;") )
|
||||
{
|
||||
varname = Tokenizer::getstr(next, 2);
|
||||
varname = TOKEN::getstr(next, 2);
|
||||
}
|
||||
|
||||
if (varname)
|
||||
|
@ -122,13 +122,13 @@ const TOKEN * CheckClass::FindClassFunction( const TOKEN *tok, const char classn
|
|||
for ( ;tok; tok = tok->next )
|
||||
{
|
||||
if ( indentlevel == 0 &&
|
||||
( Tokenizer::Match(tok, "class %var1% {", _classname) ||
|
||||
Tokenizer::Match(tok, "class %var1% : %type% {", _classname) ) )
|
||||
( TOKEN::Match(tok, "class %var1% {", _classname) ||
|
||||
TOKEN::Match(tok, "class %var1% : %type% {", _classname) ) )
|
||||
{
|
||||
if ( Tokenizer::Match(tok, "class %var% {") )
|
||||
tok = Tokenizer::gettok(tok, 3);
|
||||
if ( TOKEN::Match(tok, "class %var% {") )
|
||||
tok = tok->at(3);
|
||||
else
|
||||
tok = Tokenizer::gettok(tok, 5);
|
||||
tok = tok->at(5);
|
||||
indentlevel = 1;
|
||||
}
|
||||
|
||||
|
@ -168,7 +168,7 @@ const TOKEN * CheckClass::FindClassFunction( const TOKEN *tok, const char classn
|
|||
if ( indentlevel == 1 )
|
||||
{
|
||||
// Member function implemented in the class declaration?
|
||||
if ( Tokenizer::Match( tok, "%var1% (", _funcname ) )
|
||||
if ( TOKEN::Match( tok, "%var1% (", _funcname ) )
|
||||
{
|
||||
const TOKEN *tok2 = tok;
|
||||
while ( tok2 && tok2->str[0] != '{' && tok2->str[0] != ';' )
|
||||
|
@ -178,7 +178,7 @@ const TOKEN * CheckClass::FindClassFunction( const TOKEN *tok, const char classn
|
|||
}
|
||||
}
|
||||
|
||||
else if ( indentlevel == 0 && Tokenizer::Match(tok, "%var1% :: %var2% (", _classname, _funcname) )
|
||||
else if ( indentlevel == 0 && TOKEN::Match(tok, "%var1% :: %var2% (", _classname, _funcname) )
|
||||
{
|
||||
return tok;
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ void CheckClass::ClassChecking_VarList_Initialize(const TOKEN *tok1, const TOKEN
|
|||
// clKalle::clKalle() : var(value) { }
|
||||
if (indentlevel==0)
|
||||
{
|
||||
if (Assign && Tokenizer::Match(ftok, "%var% ("))
|
||||
if (Assign && TOKEN::Match(ftok, "%var% ("))
|
||||
{
|
||||
InitVar( varlist, ftok->str );
|
||||
}
|
||||
|
@ -242,29 +242,29 @@ void CheckClass::ClassChecking_VarList_Initialize(const TOKEN *tok1, const TOKEN
|
|||
continue;
|
||||
|
||||
// Before a new statement there is "[{};)=]" or "else"
|
||||
if ( ! Tokenizer::Match(ftok, "[{};)=]") && ! Tokenizer::Match(ftok, "else") )
|
||||
if ( ! TOKEN::Match(ftok, "[{};)=]") && ! TOKEN::Match(ftok, "else") )
|
||||
continue;
|
||||
|
||||
// Using the operator= function to initialize all variables..
|
||||
if ( Tokenizer::Match(ftok->next, "* this = ") )
|
||||
if ( TOKEN::Match(ftok->next, "* this = ") )
|
||||
{
|
||||
for (struct VAR *var = varlist; var; var = var->next)
|
||||
var->init = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!Tokenizer::Match(ftok->next, "%var%") && !Tokenizer::Match(ftok->next, "this . %var%"))
|
||||
if (!TOKEN::Match(ftok->next, "%var%") && !TOKEN::Match(ftok->next, "this . %var%"))
|
||||
continue;
|
||||
|
||||
// Goto the first token in this statement..
|
||||
ftok = ftok->next;
|
||||
|
||||
// Skip "this->"
|
||||
if ( Tokenizer::Match(ftok, "this .") )
|
||||
ftok = Tokenizer::gettok(ftok, 2);
|
||||
if ( TOKEN::Match(ftok, "this .") )
|
||||
ftok = ftok->at(2);
|
||||
|
||||
// Clearing all variables..
|
||||
if (Tokenizer::Match(ftok,"memset ( this ,"))
|
||||
if (TOKEN::Match(ftok,"memset ( this ,"))
|
||||
{
|
||||
for (struct VAR *var = varlist; var; var = var->next)
|
||||
var->init = true;
|
||||
|
@ -272,7 +272,7 @@ void CheckClass::ClassChecking_VarList_Initialize(const TOKEN *tok1, const TOKEN
|
|||
}
|
||||
|
||||
// Calling member function?
|
||||
else if (Tokenizer::Match(ftok, "%var% ("))
|
||||
else if (TOKEN::Match(ftok, "%var% ("))
|
||||
{
|
||||
// No recursive calls!
|
||||
if ( std::find(callstack.begin(),callstack.end(),ftok->str) == callstack.end() )
|
||||
|
@ -285,13 +285,13 @@ void CheckClass::ClassChecking_VarList_Initialize(const TOKEN *tok1, const TOKEN
|
|||
}
|
||||
|
||||
// Assignment of member variable?
|
||||
else if (Tokenizer::Match(ftok, "%var% ="))
|
||||
else if (TOKEN::Match(ftok, "%var% ="))
|
||||
{
|
||||
InitVar( varlist, ftok->str );
|
||||
}
|
||||
|
||||
// The functions 'clear' and 'Clear' are supposed to initialize variable.
|
||||
if (Tokenizer::Match(ftok,"%var% . clear (") || Tokenizer::Match(ftok,"%var% . Clear ("))
|
||||
if (TOKEN::Match(ftok,"%var% . clear (") || TOKEN::Match(ftok,"%var% . Clear ("))
|
||||
{
|
||||
InitVar( varlist, ftok->str );
|
||||
}
|
||||
|
@ -311,22 +311,22 @@ void CheckClass::CheckConstructors()
|
|||
{
|
||||
// Locate class
|
||||
const char *pattern_classname[] = {"class","","{",NULL};
|
||||
const TOKEN *tok1 = Tokenizer::findtoken(_tokenizer->tokens(), pattern_classname);
|
||||
const TOKEN *tok1 = TOKEN::findtoken(_tokenizer->tokens(), pattern_classname);
|
||||
while (tok1)
|
||||
{
|
||||
const char *classname = tok1->next->str;
|
||||
if ( ! Tokenizer::IsName(classname) )
|
||||
if ( ! TOKEN::IsName(classname) )
|
||||
{
|
||||
tok1 = Tokenizer::findtoken( tok1->next, pattern_classname );
|
||||
tok1 = TOKEN::findtoken( tok1->next, pattern_classname );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Are there a class constructor?
|
||||
const char *constructor_pattern[] = {"","clKalle","(",NULL};
|
||||
constructor_pattern[1] = classname;
|
||||
const TOKEN *constructor_token = Tokenizer::findtoken( _tokenizer->tokens(), constructor_pattern );
|
||||
const TOKEN *constructor_token = TOKEN::findtoken( _tokenizer->tokens(), constructor_pattern );
|
||||
while ( constructor_token && constructor_token->str[0] == '~' )
|
||||
constructor_token = Tokenizer::findtoken( constructor_token->next, constructor_pattern );
|
||||
constructor_token = TOKEN::findtoken( constructor_token->next, constructor_pattern );
|
||||
if ( ! constructor_token )
|
||||
{
|
||||
// There's no class constructor
|
||||
|
@ -350,7 +350,7 @@ void CheckClass::CheckConstructors()
|
|||
}
|
||||
}
|
||||
|
||||
tok1 = Tokenizer::findtoken( tok1->next, pattern_classname );
|
||||
tok1 = TOKEN::findtoken( tok1->next, pattern_classname );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -370,7 +370,7 @@ void CheckClass::CheckConstructors()
|
|||
const char *pattern[] = {"","::","","=",NULL};
|
||||
pattern[0] = classname;
|
||||
pattern[2] = var->name;
|
||||
if (Tokenizer::findtoken(_tokenizer->tokens(), pattern))
|
||||
if (TOKEN::findtoken(_tokenizer->tokens(), pattern))
|
||||
continue;
|
||||
|
||||
if (!var->init)
|
||||
|
@ -398,7 +398,7 @@ void CheckClass::CheckConstructors()
|
|||
varlist = nextvar;
|
||||
}
|
||||
|
||||
tok1 = Tokenizer::findtoken( tok1->next, pattern_classname );
|
||||
tok1 = TOKEN::findtoken( tok1->next, pattern_classname );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -412,7 +412,7 @@ void CheckClass::CheckUnusedPrivateFunctions()
|
|||
{
|
||||
// Locate some class
|
||||
const char *pattern_class[] = {"class","","{",NULL};
|
||||
for (const TOKEN *tok1 = Tokenizer::findtoken(_tokenizer->tokens(), pattern_class); tok1; tok1 = Tokenizer::findtoken(tok1->next, pattern_class))
|
||||
for (const TOKEN *tok1 = TOKEN::findtoken(_tokenizer->tokens(), pattern_class); tok1; tok1 = TOKEN::findtoken(tok1->next, pattern_class))
|
||||
{
|
||||
const char *classname = tok1->next->str;
|
||||
|
||||
|
@ -420,7 +420,7 @@ void CheckClass::CheckUnusedPrivateFunctions()
|
|||
const char *pattern_classconstructor[] = {"","::","",NULL};
|
||||
pattern_classconstructor[0] = classname;
|
||||
pattern_classconstructor[2] = classname;
|
||||
if (!Tokenizer::findtoken(_tokenizer->tokens(),pattern_classconstructor))
|
||||
if (!TOKEN::findtoken(_tokenizer->tokens(),pattern_classconstructor))
|
||||
continue;
|
||||
|
||||
// Get private functions..
|
||||
|
@ -430,7 +430,7 @@ void CheckClass::CheckUnusedPrivateFunctions()
|
|||
unsigned int indent_level = 0;
|
||||
for (const TOKEN *tok = tok1; tok; tok = tok->next)
|
||||
{
|
||||
if (Tokenizer::Match(tok,"friend %var%"))
|
||||
if (TOKEN::Match(tok,"friend %var%"))
|
||||
{
|
||||
// Todo: Handle friend classes
|
||||
FuncList.clear();
|
||||
|
@ -455,11 +455,11 @@ void CheckClass::CheckUnusedPrivateFunctions()
|
|||
priv = false;
|
||||
else if (priv && indent_level == 1)
|
||||
{
|
||||
if ( Tokenizer::Match(tok, "typedef %type% (") )
|
||||
tok = Tokenizer::gettok(tok, 2);
|
||||
if ( TOKEN::Match(tok, "typedef %type% (") )
|
||||
tok = tok->at(2);
|
||||
|
||||
if (Tokenizer::Match(tok, "%var% (") &&
|
||||
!Tokenizer::Match(tok,classname))
|
||||
if (TOKEN::Match(tok, "%var% (") &&
|
||||
!TOKEN::Match(tok,classname))
|
||||
{
|
||||
FuncList.push_back(tok->str);
|
||||
}
|
||||
|
@ -473,7 +473,7 @@ void CheckClass::CheckUnusedPrivateFunctions()
|
|||
const TOKEN *ftok = _tokenizer->tokens();
|
||||
while (ftok)
|
||||
{
|
||||
ftok = Tokenizer::findtoken(ftok,pattern_function);
|
||||
ftok = TOKEN::findtoken(ftok,pattern_function);
|
||||
int numpar = 0;
|
||||
while (ftok && ftok->str[0]!=';' && ftok->str[0]!='{')
|
||||
{
|
||||
|
@ -519,15 +519,15 @@ void CheckClass::CheckUnusedPrivateFunctions()
|
|||
// Final check; check if the function pointer is used somewhere..
|
||||
const char *_pattern[] = {"=","",NULL};
|
||||
_pattern[1] = FuncList.front().c_str();
|
||||
fp |= (Tokenizer::findtoken(_tokenizer->tokens(), _pattern) != NULL);
|
||||
fp |= (TOKEN::findtoken(_tokenizer->tokens(), _pattern) != NULL);
|
||||
_pattern[0] = "return";
|
||||
fp |= (Tokenizer::findtoken(_tokenizer->tokens(), _pattern) != NULL);
|
||||
fp |= (TOKEN::findtoken(_tokenizer->tokens(), _pattern) != NULL);
|
||||
_pattern[0] = "(";
|
||||
fp |= (Tokenizer::findtoken(_tokenizer->tokens(), _pattern) != NULL);
|
||||
fp |= (TOKEN::findtoken(_tokenizer->tokens(), _pattern) != NULL);
|
||||
_pattern[0] = ")";
|
||||
fp |= (Tokenizer::findtoken(_tokenizer->tokens(), _pattern) != NULL);
|
||||
fp |= (TOKEN::findtoken(_tokenizer->tokens(), _pattern) != NULL);
|
||||
_pattern[0] = ",";
|
||||
fp |= (Tokenizer::findtoken(_tokenizer->tokens(), _pattern) != NULL);
|
||||
fp |= (TOKEN::findtoken(_tokenizer->tokens(), _pattern) != NULL);
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
|
@ -549,21 +549,21 @@ void CheckClass::CheckMemset()
|
|||
// Locate all 'memset' tokens..
|
||||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
if (!Tokenizer::Match(tok,"memset") && !Tokenizer::Match(tok,"memcpy") && !Tokenizer::Match(tok,"memmove"))
|
||||
if (!TOKEN::Match(tok,"memset") && !TOKEN::Match(tok,"memcpy") && !TOKEN::Match(tok,"memmove"))
|
||||
continue;
|
||||
|
||||
// Todo: Handle memcpy and memmove
|
||||
const char *type = NULL;
|
||||
if (Tokenizer::Match(tok, "memset ( %var% , %num% , sizeof ( %type% ) )"))
|
||||
type = Tokenizer::getstr(tok, 8);
|
||||
else if (Tokenizer::Match(tok, "memset ( & %var% , %num% , sizeof ( %type% ) )"))
|
||||
type = Tokenizer::getstr(tok, 9);
|
||||
else if (Tokenizer::Match(tok, "memset ( %var% , %num% , sizeof ( struct %type% ) )"))
|
||||
type = Tokenizer::getstr(tok, 9);
|
||||
else if (Tokenizer::Match(tok, "memset ( & %var% , %num% , sizeof ( struct %type% ) )"))
|
||||
type = Tokenizer::getstr(tok, 10);
|
||||
else if (Tokenizer::Match(tok, "%type% ( %var% , %var% , sizeof ( %type% ) )"))
|
||||
type = Tokenizer::getstr(tok, 8);
|
||||
if (TOKEN::Match(tok, "memset ( %var% , %num% , sizeof ( %type% ) )"))
|
||||
type = TOKEN::getstr(tok, 8);
|
||||
else if (TOKEN::Match(tok, "memset ( & %var% , %num% , sizeof ( %type% ) )"))
|
||||
type = TOKEN::getstr(tok, 9);
|
||||
else if (TOKEN::Match(tok, "memset ( %var% , %num% , sizeof ( struct %type% ) )"))
|
||||
type = TOKEN::getstr(tok, 9);
|
||||
else if (TOKEN::Match(tok, "memset ( & %var% , %num% , sizeof ( struct %type% ) )"))
|
||||
type = TOKEN::getstr(tok, 10);
|
||||
else if (TOKEN::Match(tok, "%type% ( %var% , %var% , sizeof ( %type% ) )"))
|
||||
type = TOKEN::getstr(tok, 8);
|
||||
|
||||
// No type defined => The tokens didn't match
|
||||
if (!(type && type[0]))
|
||||
|
@ -572,7 +572,7 @@ void CheckClass::CheckMemset()
|
|||
// Warn if type is a class..
|
||||
const char *pattern1[] = {"class","",NULL};
|
||||
pattern1[1] = type;
|
||||
if (Tokenizer::findtoken(_tokenizer->tokens(),pattern1))
|
||||
if (TOKEN::findtoken(_tokenizer->tokens(),pattern1))
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << _tokenizer->fileLine(tok) << ": Using '" << tok->str << "' on class.";
|
||||
|
@ -583,15 +583,15 @@ void CheckClass::CheckMemset()
|
|||
// Warn if type is a struct that contains any std::*
|
||||
const char *pattern2[] = {"struct","","{",NULL};
|
||||
pattern2[1] = type;
|
||||
for (const TOKEN *tstruct = Tokenizer::findtoken(_tokenizer->tokens(), pattern2); tstruct; tstruct = tstruct->next)
|
||||
for (const TOKEN *tstruct = TOKEN::findtoken(_tokenizer->tokens(), pattern2); tstruct; tstruct = tstruct->next)
|
||||
{
|
||||
if (tstruct->str[0] == '}')
|
||||
break;
|
||||
|
||||
if (Tokenizer::Match(tstruct, "std :: %type% %var% ;"))
|
||||
if (TOKEN::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) << "'";
|
||||
ostr << _tokenizer->fileLine(tok) << ": Using '" << tok->str << "' on struct that contains a 'std::" << TOKEN::getstr(tstruct,2) << "'";
|
||||
_errorLogger->reportErr(ostr.str());
|
||||
break;
|
||||
}
|
||||
|
@ -609,7 +609,7 @@ void CheckClass::CheckMemset()
|
|||
void CheckClass::CheckOperatorEq1()
|
||||
{
|
||||
const char *pattern[] = {"void", "operator", "=", "(", NULL};
|
||||
if (const TOKEN *tok = Tokenizer::findtoken(_tokenizer->tokens(),pattern))
|
||||
if (const TOKEN *tok = TOKEN::findtoken(_tokenizer->tokens(),pattern))
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << _tokenizer->fileLine(tok) << ": 'operator=' should return something";
|
||||
|
|
|
@ -53,12 +53,12 @@ void CheckFunctionUsage::parseTokens( const std::string &filename )
|
|||
|
||||
const TOKEN *funcname = 0;
|
||||
|
||||
if ( Tokenizer::Match( tok, "%type% %var% (" ) )
|
||||
funcname = _tokenizer->gettok(tok, 1);
|
||||
else if ( Tokenizer::Match(tok, "%type% * %var% (") )
|
||||
funcname = _tokenizer->gettok(tok, 2);
|
||||
if ( TOKEN::Match( tok, "%type% %var% (" ) )
|
||||
funcname = tok->at(1);
|
||||
else if ( TOKEN::Match(tok, "%type% * %var% (") )
|
||||
funcname = tok->at(2);
|
||||
|
||||
if ( Tokenizer::Match(funcname, "%var% ( )") || Tokenizer::Match(funcname, "%var% ( %type%") )
|
||||
if ( TOKEN::Match(funcname, "%var% ( )") || TOKEN::Match(funcname, "%var% ( %type%") )
|
||||
{
|
||||
FunctionUsage &func = functions[ funcname->str ];
|
||||
|
||||
|
@ -80,10 +80,10 @@ void CheckFunctionUsage::parseTokens( const std::string &filename )
|
|||
{
|
||||
const TOKEN *funcname = 0;
|
||||
|
||||
if ( Tokenizer::Match( tok, "[;{}.)[=] %var% (" ) )
|
||||
if ( TOKEN::Match( tok, "[;{}.)[=] %var% (" ) )
|
||||
funcname = tok;
|
||||
|
||||
else if ( Tokenizer::Match(tok, "= %var% ;") )
|
||||
else if ( TOKEN::Match(tok, "= %var% ;") )
|
||||
funcname = tok->next;
|
||||
|
||||
if ( funcname )
|
||||
|
|
|
@ -54,7 +54,7 @@ void CheckHeaders::WarningHeaderWithImplementation()
|
|||
if (tok->FileIndex == 0)
|
||||
continue;
|
||||
|
||||
if (Tokenizer::Match(tok, ") {"))
|
||||
if (TOKEN::Match(tok, ") {"))
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << _tokenizer->fileLine(tok) << ": Found implementation in header";
|
||||
|
@ -129,22 +129,22 @@ void CheckHeaders::WarningIncludeHeader()
|
|||
|
||||
// Class or namespace declaration..
|
||||
// --------------------------------------
|
||||
if (Tokenizer::Match(tok1,"class %var% {") || Tokenizer::Match(tok1,"class %var% :") || Tokenizer::Match(tok1,"namespace %var% {"))
|
||||
classlist.push_back(Tokenizer::getstr(tok1, 1));
|
||||
if (TOKEN::Match(tok1,"class %var% {") || TOKEN::Match(tok1,"class %var% :") || TOKEN::Match(tok1,"namespace %var% {"))
|
||||
classlist.push_back(TOKEN::getstr(tok1, 1));
|
||||
|
||||
// Variable declaration..
|
||||
// --------------------------------------
|
||||
else if (Tokenizer::Match(tok1, "%type% %var% ;") || Tokenizer::Match(tok1, "%type% %var% ["))
|
||||
namelist.push_back(Tokenizer::getstr(tok1, 1));
|
||||
else if (TOKEN::Match(tok1, "%type% %var% ;") || TOKEN::Match(tok1, "%type% %var% ["))
|
||||
namelist.push_back(TOKEN::getstr(tok1, 1));
|
||||
|
||||
else if (Tokenizer::Match(tok1, "%type% * %var% ;") || Tokenizer::Match(tok1, "%type% * %var% ["))
|
||||
namelist.push_back(Tokenizer::getstr(tok1, 2));
|
||||
else if (TOKEN::Match(tok1, "%type% * %var% ;") || TOKEN::Match(tok1, "%type% * %var% ["))
|
||||
namelist.push_back(TOKEN::getstr(tok1, 2));
|
||||
|
||||
else if (Tokenizer::Match(tok1, "const %type% %var% =") || Tokenizer::Match(tok1, "const %type% %var% ["))
|
||||
namelist.push_back(Tokenizer::getstr(tok1, 2));
|
||||
else if (TOKEN::Match(tok1, "const %type% %var% =") || TOKEN::Match(tok1, "const %type% %var% ["))
|
||||
namelist.push_back(TOKEN::getstr(tok1, 2));
|
||||
|
||||
else if (Tokenizer::Match(tok1, "const %type% * %var% =") || Tokenizer::Match(tok1, "const %type% * %var% ["))
|
||||
namelist.push_back(Tokenizer::getstr(tok1, 3));
|
||||
else if (TOKEN::Match(tok1, "const %type% * %var% =") || TOKEN::Match(tok1, "const %type% * %var% ["))
|
||||
namelist.push_back(TOKEN::getstr(tok1, 3));
|
||||
|
||||
// enum..
|
||||
// --------------------------------------
|
||||
|
@ -153,7 +153,7 @@ void CheckHeaders::WarningIncludeHeader()
|
|||
tok1 = tok1->next;
|
||||
while (tok1->next && tok1->str[0]!=';')
|
||||
{
|
||||
if ( Tokenizer::IsName(tok1->str) )
|
||||
if ( TOKEN::IsName(tok1->str) )
|
||||
namelist.push_back(tok1->str);
|
||||
tok1 = tok1->next;
|
||||
}
|
||||
|
@ -161,23 +161,23 @@ void CheckHeaders::WarningIncludeHeader()
|
|||
|
||||
// function..
|
||||
// --------------------------------------
|
||||
else if (Tokenizer::Match(tok1,"%type% %var% ("))
|
||||
namelist.push_back(Tokenizer::getstr(tok1, 1));
|
||||
else if (TOKEN::Match(tok1,"%type% %var% ("))
|
||||
namelist.push_back(TOKEN::getstr(tok1, 1));
|
||||
|
||||
else if (Tokenizer::Match(tok1,"%type% * %var% ("))
|
||||
namelist.push_back(Tokenizer::getstr(tok1, 2));
|
||||
else if (TOKEN::Match(tok1,"%type% * %var% ("))
|
||||
namelist.push_back(TOKEN::getstr(tok1, 2));
|
||||
|
||||
else if (Tokenizer::Match(tok1,"const %type% %var% ("))
|
||||
namelist.push_back(Tokenizer::getstr(tok1, 2));
|
||||
else if (TOKEN::Match(tok1,"const %type% %var% ("))
|
||||
namelist.push_back(TOKEN::getstr(tok1, 2));
|
||||
|
||||
else if (Tokenizer::Match(tok1,"const %type% * %var% ("))
|
||||
namelist.push_back(Tokenizer::getstr(tok1, 3));
|
||||
else if (TOKEN::Match(tok1,"const %type% * %var% ("))
|
||||
namelist.push_back(TOKEN::getstr(tok1, 3));
|
||||
|
||||
// typedef..
|
||||
// --------------------------------------
|
||||
else if (strcmp(tok1->str,"typedef")==0)
|
||||
{
|
||||
if (strcmp(Tokenizer::getstr(tok1,1),"enum")==0)
|
||||
if (strcmp(TOKEN::getstr(tok1,1),"enum")==0)
|
||||
continue;
|
||||
int parlevel = 0;
|
||||
while (tok1->next)
|
||||
|
@ -193,7 +193,7 @@ void CheckHeaders::WarningIncludeHeader()
|
|||
if ( tok1->str[0] == ';' )
|
||||
break;
|
||||
|
||||
if ( Tokenizer::Match(tok1, "%var% ;") )
|
||||
if ( TOKEN::Match(tok1, "%var% ;") )
|
||||
namelist.push_back(tok1->str);
|
||||
}
|
||||
|
||||
|
@ -211,9 +211,9 @@ void CheckHeaders::WarningIncludeHeader()
|
|||
if (tok1->FileIndex != includetok->FileIndex)
|
||||
continue;
|
||||
|
||||
if ( Tokenizer::Match(tok1, ": %var% {") || Tokenizer::Match(tok1, ": %type% %var% {") )
|
||||
if ( TOKEN::Match(tok1, ": %var% {") || TOKEN::Match(tok1, ": %type% %var% {") )
|
||||
{
|
||||
std::string classname = Tokenizer::getstr(tok1, (strcmp(Tokenizer::getstr(tok1,2),"{")) ? 2 : 1);
|
||||
std::string classname = TOKEN::getstr(tok1, (strcmp(TOKEN::getstr(tok1,2),"{")) ? 2 : 1);
|
||||
if (std::find(classlist.begin(),classlist.end(),classname)!=classlist.end())
|
||||
{
|
||||
Needed = true;
|
||||
|
@ -221,7 +221,7 @@ void CheckHeaders::WarningIncludeHeader()
|
|||
}
|
||||
}
|
||||
|
||||
if ( ! Tokenizer::IsName(tok1->str) )
|
||||
if ( ! TOKEN::IsName(tok1->str) )
|
||||
continue;
|
||||
|
||||
if (std::find(namelist.begin(),namelist.end(),tok1->str ) != namelist.end())
|
||||
|
|
|
@ -61,7 +61,7 @@ bool CheckMemoryLeakClass::isclass( const std::string &typestr )
|
|||
|
||||
std::ostringstream pattern;
|
||||
pattern << "struct " << typestr;
|
||||
if ( Tokenizer::findmatch( _tokenizer->tokens(), pattern.str().c_str() ) )
|
||||
if ( TOKEN::findmatch( _tokenizer->tokens(), pattern.str().c_str() ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -119,16 +119,16 @@ CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetAllocationType( const T
|
|||
return gMalloc;
|
||||
}
|
||||
|
||||
if ( Tokenizer::Match( tok2, "new %type% [;(]" ) )
|
||||
if ( TOKEN::Match( tok2, "new %type% [;(]" ) )
|
||||
return New;
|
||||
|
||||
if ( Tokenizer::Match( tok2, "new %type% [" ) )
|
||||
if ( TOKEN::Match( tok2, "new %type% [" ) )
|
||||
return NewA;
|
||||
|
||||
if ( Tokenizer::Match( tok2, "fopen (" ) )
|
||||
if ( TOKEN::Match( tok2, "fopen (" ) )
|
||||
return FOPEN;
|
||||
|
||||
if ( Tokenizer::Match( tok2, "popen (" ) )
|
||||
if ( TOKEN::Match( tok2, "popen (" ) )
|
||||
return POPEN;
|
||||
|
||||
// Userdefined allocation function..
|
||||
|
@ -146,32 +146,32 @@ CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetAllocationType( const T
|
|||
CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetDeallocationType( const TOKEN *tok, const char *varnames[] )
|
||||
{
|
||||
// Redundant condition..
|
||||
if ( Tokenizer::Match(tok, "if ( %var1% )", varnames) )
|
||||
if ( TOKEN::Match(tok, "if ( %var1% )", varnames) )
|
||||
{
|
||||
tok = Tokenizer::gettok( tok, 4 );
|
||||
if ( Tokenizer::Match(tok,"{") )
|
||||
tok = tok->at(4);
|
||||
if ( TOKEN::Match(tok,"{") )
|
||||
tok = tok->next;
|
||||
}
|
||||
|
||||
if ( Tokenizer::Match(tok, "delete %var1% ;", varnames) )
|
||||
if ( TOKEN::Match(tok, "delete %var1% ;", varnames) )
|
||||
return New;
|
||||
|
||||
if ( Tokenizer::Match(tok, "delete [ ] %var1% ;", varnames) )
|
||||
if ( TOKEN::Match(tok, "delete [ ] %var1% ;", varnames) )
|
||||
return NewA;
|
||||
|
||||
if ( Tokenizer::Match(tok, "free ( %var1% ) ;", varnames) ||
|
||||
Tokenizer::Match(tok, "kfree ( %var1% ) ;", varnames) )
|
||||
if ( TOKEN::Match(tok, "free ( %var1% ) ;", varnames) ||
|
||||
TOKEN::Match(tok, "kfree ( %var1% ) ;", varnames) )
|
||||
{
|
||||
return Malloc;
|
||||
}
|
||||
|
||||
if ( Tokenizer::Match(tok, "g_free ( %var1% ) ;", varnames) )
|
||||
if ( TOKEN::Match(tok, "g_free ( %var1% ) ;", varnames) )
|
||||
return gMalloc;
|
||||
|
||||
if ( Tokenizer::Match(tok, "fclose ( %var1% )", varnames) )
|
||||
if ( TOKEN::Match(tok, "fclose ( %var1% )", varnames) )
|
||||
return FOPEN;
|
||||
|
||||
if ( Tokenizer::Match(tok, "pclose ( %var1% )", varnames) )
|
||||
if ( TOKEN::Match(tok, "pclose ( %var1% )", varnames) )
|
||||
return POPEN;
|
||||
|
||||
return No;
|
||||
|
@ -180,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 (Tokenizer::Match(tok,"if") || Tokenizer::Match(tok,"for") || Tokenizer::Match(tok,"while"))
|
||||
if (TOKEN::Match(tok,"if") || TOKEN::Match(tok,"for") || TOKEN::Match(tok,"while"))
|
||||
return 0;
|
||||
|
||||
if (GetAllocationType(tok)!=No || GetDeallocationType(tok,varnames)!=No)
|
||||
|
@ -201,9 +201,9 @@ const char * CheckMemoryLeakClass::call_func( const TOKEN *tok, std::list<const
|
|||
int parlevel = 0;
|
||||
for ( ; tok; tok = tok->next )
|
||||
{
|
||||
if ( Tokenizer::Match(tok, "(") )
|
||||
if ( TOKEN::Match(tok, "(") )
|
||||
++parlevel;
|
||||
else if ( Tokenizer::Match(tok, ")") )
|
||||
else if ( TOKEN::Match(tok, ")") )
|
||||
{
|
||||
--parlevel;
|
||||
if ( parlevel < 1 )
|
||||
|
@ -212,25 +212,25 @@ const char * CheckMemoryLeakClass::call_func( const TOKEN *tok, std::list<const
|
|||
|
||||
if ( parlevel == 1 )
|
||||
{
|
||||
if ( Tokenizer::Match(tok, ",") )
|
||||
if ( TOKEN::Match(tok, ",") )
|
||||
++par;
|
||||
if ( Tokenizer::Match(tok, "[,()] %var1% [,()]", varnames) )
|
||||
if ( TOKEN::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 && ! Tokenizer::Match(ftok,"{") )
|
||||
while ( ftok && ! TOKEN::Match(ftok,"{") )
|
||||
ftok = ftok->next;
|
||||
TOKEN *func = getcode( Tokenizer::gettok(ftok,1), callstack, parname, alloctype, dealloctype );
|
||||
TOKEN *func = getcode( ftok->at(1), callstack, parname, alloctype, dealloctype );
|
||||
simplifycode( func );
|
||||
const char *ret = 0;
|
||||
if (Tokenizer::findmatch(func, "goto"))
|
||||
if (TOKEN::findmatch(func, "goto"))
|
||||
ret = "dealloc"; // TODO : "goto" isn't handled well
|
||||
else if (Tokenizer::findmatch(func, "use"))
|
||||
else if (TOKEN::findmatch(func, "use"))
|
||||
ret = "use";
|
||||
else if (Tokenizer::findmatch(func, "dealloc"))
|
||||
else if (TOKEN::findmatch(func, "dealloc"))
|
||||
ret = "dealloc";
|
||||
Tokenizer::deleteTokens(func);
|
||||
return ret;
|
||||
|
@ -271,12 +271,12 @@ void CheckMemoryLeakClass::instoken(TOKEN *tok, const char str[])
|
|||
|
||||
bool CheckMemoryLeakClass::notvar(const TOKEN *tok, const char *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) );
|
||||
return bool( TOKEN::Match(tok, "! %var1% [;)&|]", varnames) ||
|
||||
TOKEN::Match(tok, "! ( %var1% )", varnames) ||
|
||||
TOKEN::Match(tok, "unlikely ( ! %var1% )", varnames) ||
|
||||
TOKEN::Match(tok, "unlikely ( %var1% == 0 )", varnames) ||
|
||||
TOKEN::Match(tok, "0 == %var1% [;)&|]", varnames) ||
|
||||
TOKEN::Match(tok, "%var1% == 0", varnames) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -334,16 +334,16 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
|
|||
if ( parlevel == 0 && tok->str[0]==';')
|
||||
addtoken(";");
|
||||
|
||||
if (Tokenizer::Match(tok, "[(;{}] %var1% =", varnames))
|
||||
if (TOKEN::Match(tok, "[(;{}] %var1% =", varnames))
|
||||
{
|
||||
AllocType alloc = GetAllocationType(Tokenizer::gettok(tok,3));
|
||||
AllocType alloc = GetAllocationType(tok->at(3));
|
||||
|
||||
// If "--all" hasn't been given, don't check classes..
|
||||
if ( alloc == New && ! _settings._showAll )
|
||||
{
|
||||
if ( Tokenizer::Match(Tokenizer::gettok(tok,3), "new %type% [(;]") )
|
||||
{
|
||||
if ( isclass( Tokenizer::getstr(tok, 4) ) )
|
||||
if ( TOKEN::Match(tok->at(3), "new %type% [(;]") )
|
||||
{
|
||||
if ( isclass( TOKEN::getstr(tok, 4) ) )
|
||||
alloc = No;
|
||||
}
|
||||
}
|
||||
|
@ -371,43 +371,43 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
|
|||
}
|
||||
|
||||
// if else switch
|
||||
if ( Tokenizer::Match(tok, "if ( %var1% )", varnames) ||
|
||||
Tokenizer::Match(tok, "if ( %var1% != 0 )", varnames) ||
|
||||
Tokenizer::Match(tok, "if ( 0 != %var1% )", varnames) )
|
||||
if ( TOKEN::Match(tok, "if ( %var1% )", varnames) ||
|
||||
TOKEN::Match(tok, "if ( %var1% != 0 )", varnames) ||
|
||||
TOKEN::Match(tok, "if ( 0 != %var1% )", varnames) )
|
||||
{
|
||||
addtoken("if(var)");
|
||||
tok = Tokenizer::gettok(tok, 3); // Make sure the "use" will not be added
|
||||
tok = tok->at(3); // Make sure the "use" will not be added
|
||||
}
|
||||
else if ( Tokenizer::Match(tok, "if (") && notvar(Tokenizer::gettok(tok,2), varnames) )
|
||||
else if ( TOKEN::Match(tok, "if (") && notvar(tok->at(2), varnames) )
|
||||
{
|
||||
addtoken("if(!var)");
|
||||
}
|
||||
else if ( Tokenizer::Match(tok, "if ( true )") )
|
||||
else if ( TOKEN::Match(tok, "if ( true )") )
|
||||
{
|
||||
addtoken("if(true)");
|
||||
}
|
||||
else if ( Tokenizer::Match(tok, "if ( false )") )
|
||||
else if ( TOKEN::Match(tok, "if ( false )") )
|
||||
{
|
||||
addtoken("if(false)");
|
||||
}
|
||||
else if ( Tokenizer::Match(tok, "if") )
|
||||
else if ( TOKEN::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 ( Tokenizer::Match(tok2,"(") )
|
||||
if ( TOKEN::Match(tok2,"(") )
|
||||
++parlevel;
|
||||
if ( Tokenizer::Match(tok2,")") )
|
||||
if ( TOKEN::Match(tok2,")") )
|
||||
{
|
||||
--parlevel;
|
||||
if ( parlevel <= 0 )
|
||||
break;
|
||||
}
|
||||
if ( !Tokenizer::Match(tok2,".") &&
|
||||
Tokenizer::Match(tok2->next, "%var1%", varnames) &&
|
||||
!Tokenizer::Match(tok2->next, "%var1% .", varnames) )
|
||||
if ( !TOKEN::Match(tok2,".") &&
|
||||
TOKEN::Match(tok2->next, "%var1%", varnames) &&
|
||||
!TOKEN::Match(tok2->next, "%var1% .", varnames) )
|
||||
{
|
||||
dep = true;
|
||||
break;
|
||||
|
@ -415,30 +415,30 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
|
|||
}
|
||||
addtoken( (dep ? "ifv" : "if") );
|
||||
}
|
||||
else if ( Tokenizer::Match(tok, "else") || Tokenizer::Match(tok, "switch") )
|
||||
else if ( TOKEN::Match(tok, "else") || TOKEN::Match(tok, "switch") )
|
||||
{
|
||||
addtoken(tok->str);
|
||||
}
|
||||
|
||||
if ( Tokenizer::Match(tok, "case") )
|
||||
if ( TOKEN::Match(tok, "case") )
|
||||
{
|
||||
addtoken("case");
|
||||
addtoken(";");
|
||||
}
|
||||
|
||||
if ( Tokenizer::Match(tok, "default") )
|
||||
if ( TOKEN::Match(tok, "default") )
|
||||
{
|
||||
addtoken("case");
|
||||
addtoken(";");
|
||||
}
|
||||
|
||||
// Loops..
|
||||
if (Tokenizer::Match(tok, "for") || Tokenizer::Match(tok, "while") )
|
||||
if (TOKEN::Match(tok, "for") || TOKEN::Match(tok, "while") )
|
||||
{
|
||||
addtoken("loop");
|
||||
isloop = true;
|
||||
}
|
||||
if ( Tokenizer::Match(tok, "do") )
|
||||
if ( TOKEN::Match(tok, "do") )
|
||||
{
|
||||
addtoken("do");
|
||||
}
|
||||
|
@ -446,36 +446,36 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
|
|||
addtoken("!var");
|
||||
|
||||
// continue / break..
|
||||
if ( Tokenizer::Match(tok, "continue") )
|
||||
if ( TOKEN::Match(tok, "continue") )
|
||||
addtoken("continue");
|
||||
if ( Tokenizer::Match(tok, "break") )
|
||||
if ( TOKEN::Match(tok, "break") )
|
||||
addtoken("break");
|
||||
|
||||
// goto..
|
||||
if ( Tokenizer::Match(tok, "goto") )
|
||||
if ( TOKEN::Match(tok, "goto") )
|
||||
{
|
||||
addtoken("goto");
|
||||
}
|
||||
|
||||
// Return..
|
||||
if ( Tokenizer::Match(tok, "return") )
|
||||
if ( TOKEN::Match(tok, "return") )
|
||||
{
|
||||
addtoken("return");
|
||||
if ( Tokenizer::Match(tok, "return %var1%", varnames) ||
|
||||
Tokenizer::Match(tok, "return & %var1%", varnames) )
|
||||
if ( TOKEN::Match(tok, "return %var1%", varnames) ||
|
||||
TOKEN::Match(tok, "return & %var1%", varnames) )
|
||||
addtoken("use");
|
||||
}
|
||||
|
||||
// throw..
|
||||
if ( Tokenizer::Match(tok, "throw") )
|
||||
if ( TOKEN::Match(tok, "throw") )
|
||||
addtoken("throw");
|
||||
|
||||
// Assignment..
|
||||
if ( Tokenizer::Match(tok,"[)=] %var1% [;)]", varnames) )
|
||||
if ( TOKEN::Match(tok,"[)=] %var1% [;)]", varnames) )
|
||||
addtoken("use");
|
||||
|
||||
// Investigate function calls..
|
||||
if ( Tokenizer::Match(tok, "%var% (") )
|
||||
if ( TOKEN::Match(tok, "%var% (") )
|
||||
{
|
||||
const char *str = call_func(tok, callstack, varnames, alloctype, dealloctype);
|
||||
if ( str )
|
||||
|
@ -483,7 +483,7 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
|
|||
}
|
||||
|
||||
// Linux lists..
|
||||
if ( Tokenizer::Match( tok, "[=(,] & %var1% [.[]", varnames ) )
|
||||
if ( TOKEN::Match( tok, "[=(,] & %var1% [.[]", varnames ) )
|
||||
{
|
||||
// todo: better checking
|
||||
addtoken("use");
|
||||
|
@ -520,11 +520,11 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
// { x } while(y) { x }"
|
||||
for ( TOKEN *tok2 = tok; tok2; tok2 = tok2->next )
|
||||
{
|
||||
if ( ! Tokenizer::Match(tok2->next, "do") )
|
||||
if ( ! TOKEN::Match(tok2->next, "do") )
|
||||
continue;
|
||||
|
||||
// Remove the next token "do"
|
||||
erase( tok2, Tokenizer::gettok(tok2, 2) );
|
||||
erase( tok2, tok2->at(2) );
|
||||
tok2 = tok2->next;
|
||||
|
||||
// Find the end of the "do" block..
|
||||
|
@ -532,13 +532,13 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
int indentlevel = 0;
|
||||
for ( tok2_ = tok2; tok2_ && indentlevel>=0; tok2_ = tok2_->next )
|
||||
{
|
||||
if ( Tokenizer::Match(tok2_, "{") )
|
||||
if ( TOKEN::Match(tok2_, "{") )
|
||||
++indentlevel;
|
||||
|
||||
else if ( Tokenizer::Match(tok2_, "}") )
|
||||
else if ( TOKEN::Match(tok2_, "}") )
|
||||
--indentlevel;
|
||||
|
||||
else if ( indentlevel == 0 && Tokenizer::Match(tok2_->next, ";") )
|
||||
else if ( indentlevel == 0 && TOKEN::Match(tok2_->next, ";") )
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -550,9 +550,9 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
indentlevel = 0;
|
||||
do
|
||||
{
|
||||
if ( Tokenizer::Match( tok2, "{" ) )
|
||||
if ( TOKEN::Match( tok2, "{" ) )
|
||||
++indentlevel;
|
||||
else if ( Tokenizer::Match(tok2, "}") )
|
||||
else if ( TOKEN::Match(tok2, "}") )
|
||||
--indentlevel;
|
||||
|
||||
// Copy token..
|
||||
|
@ -575,45 +575,45 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
for (TOKEN *tok2 = tok; tok2; tok2 = tok2 ? tok2->next : NULL )
|
||||
{
|
||||
// Delete extra ";"
|
||||
while (Tokenizer::Match(tok2,"[;{}] ;"))
|
||||
while (TOKEN::Match(tok2,"[;{}] ;"))
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2,2));
|
||||
erase(tok2, tok2->at(2));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Replace "{ }" with ";"
|
||||
if ( Tokenizer::Match(tok2->next, "{ }") )
|
||||
if ( TOKEN::Match(tok2->next, "{ }") )
|
||||
{
|
||||
tok2->next->setstr(";");
|
||||
erase(tok2->next, Tokenizer::gettok(tok2,3));
|
||||
erase(tok2->next, tok2->at(3));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Delete braces around a single instruction..
|
||||
if ( Tokenizer::Match(tok2->next, "{ %var% ; }") )
|
||||
if ( TOKEN::Match(tok2->next, "{ %var% ; }") )
|
||||
{
|
||||
erase( tok2, Tokenizer::gettok(tok2,2) );
|
||||
erase( tok2->next->next, Tokenizer::gettok(tok2,4) );
|
||||
erase( tok2, tok2->at(2) );
|
||||
erase( tok2->next->next, tok2->at(4) );
|
||||
done = false;
|
||||
}
|
||||
if ( Tokenizer::Match(tok2->next, "{ return use ; }") )
|
||||
if ( TOKEN::Match(tok2->next, "{ return use ; }") )
|
||||
{
|
||||
erase( tok2, Tokenizer::gettok(tok2,2) );
|
||||
erase( tok2->next->next->next, Tokenizer::gettok(tok2,5) );
|
||||
erase( tok2, tok2->at(2) );
|
||||
erase( tok2->next->next->next, tok2->at(5) );
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Delete empty if that is not followed by an else
|
||||
if ( Tokenizer::Match(tok2,"[;{}] if ;") ||
|
||||
Tokenizer::Match(tok2,"[;{}] if(var) ;") ||
|
||||
Tokenizer::Match(tok2,"[;{}] if(!var) ;") ||
|
||||
Tokenizer::Match(tok2,"[;{}] if(true) ;") ||
|
||||
Tokenizer::Match(tok2,"[;{}] if(false) ;") ||
|
||||
Tokenizer::Match(tok2,"[;{}] ifv ;") )
|
||||
if ( TOKEN::Match(tok2,"[;{}] if ;") ||
|
||||
TOKEN::Match(tok2,"[;{}] if(var) ;") ||
|
||||
TOKEN::Match(tok2,"[;{}] if(!var) ;") ||
|
||||
TOKEN::Match(tok2,"[;{}] if(true) ;") ||
|
||||
TOKEN::Match(tok2,"[;{}] if(false) ;") ||
|
||||
TOKEN::Match(tok2,"[;{}] ifv ;") )
|
||||
{
|
||||
if ( ! Tokenizer::Match(Tokenizer::gettok(tok2,3), "else") )
|
||||
if ( ! TOKEN::Match(tok2->at(3), "else") )
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2, 3));
|
||||
erase(tok2, tok2->at(3));
|
||||
done = false;
|
||||
continue;
|
||||
}
|
||||
|
@ -622,96 +622,96 @@ 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 &&
|
||||
(Tokenizer::Match(tok2, "[;{}] if dealloc ;") || Tokenizer::Match(tok2, "[;{}] if use ;")) &&
|
||||
!Tokenizer::Match(Tokenizer::gettok(tok2,4), "else"))
|
||||
(TOKEN::Match(tok2, "[;{}] if dealloc ;") || TOKEN::Match(tok2, "[;{}] if use ;")) &&
|
||||
!TOKEN::Match(tok2->at(4), "else"))
|
||||
{
|
||||
erase(tok2->next, Tokenizer::gettok(tok2,3));
|
||||
erase(tok2->next, tok2->at(3));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Delete if block: "alloc; if return use ;"
|
||||
if (Tokenizer::Match(tok2,"alloc ; if return use ;") && !Tokenizer::Match(Tokenizer::gettok(tok2,6),"else"))
|
||||
if (TOKEN::Match(tok2,"alloc ; if return use ;") && !TOKEN::Match(tok2->at(6),"else"))
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2,5));
|
||||
erase(tok2, tok2->at(5));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// "[;{}] if alloc ; else return ;" => "[;{}] alloc ;"
|
||||
if (Tokenizer::Match(tok2,"[;{}] if alloc ; else return ;"))
|
||||
if (TOKEN::Match(tok2,"[;{}] if alloc ; else return ;"))
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2,2)); // Remove "if"
|
||||
erase(tok2->next, Tokenizer::gettok(tok2,5)); // Remove "; else return"
|
||||
erase(tok2, tok2->at(2)); // Remove "if"
|
||||
erase(tok2->next, tok2->at(5)); // Remove "; else return"
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Replace "dealloc use ;" with "dealloc ;"
|
||||
if ( Tokenizer::Match(tok2, "dealloc use ;") )
|
||||
if ( TOKEN::Match(tok2, "dealloc use ;") )
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2,2));
|
||||
erase(tok2, tok2->at(2));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Reducing if..
|
||||
if (Tokenizer::Match(tok2,"if dealloc ; else") || Tokenizer::Match(tok2,"if use ; else"))
|
||||
if (TOKEN::Match(tok2,"if dealloc ; else") || TOKEN::Match(tok2,"if use ; else"))
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2, 2));
|
||||
erase(tok2, tok2->at(2));
|
||||
done = false;
|
||||
}
|
||||
if (Tokenizer::Match(tok2,"[;{}] if { dealloc ; return ; }") && !Tokenizer::Match(Tokenizer::gettok(tok2,8),"else"))
|
||||
if (TOKEN::Match(tok2,"[;{}] if { dealloc ; return ; }") && !TOKEN::Match(tok2->at(8),"else"))
|
||||
{
|
||||
erase(tok2,Tokenizer::gettok(tok2,8));
|
||||
erase(tok2,tok2->at(8));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Replace "loop ;" with ";"
|
||||
if ( Tokenizer::Match(tok2->next, "loop ;") )
|
||||
if ( TOKEN::Match(tok2->next, "loop ;") )
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2,2));
|
||||
erase(tok2, tok2->at(2));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Replace "loop !var ;" with ";"
|
||||
if ( Tokenizer::Match(tok2->next, "loop !var ;") )
|
||||
if ( TOKEN::Match(tok2->next, "loop !var ;") )
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2,4));
|
||||
erase(tok2, tok2->at(4));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Replace "loop !var alloc ;" with " alloc ;"
|
||||
if ( Tokenizer::Match(tok2->next, "loop !var alloc ;") )
|
||||
if ( TOKEN::Match(tok2->next, "loop !var alloc ;") )
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2,3));
|
||||
erase(tok2, tok2->at(3));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Delete if block in "alloc ; if(!var) return ;"
|
||||
if ( Tokenizer::Match(tok2, "alloc ; if(!var) return ;") )
|
||||
if ( TOKEN::Match(tok2, "alloc ; if(!var) return ;") )
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2,4));
|
||||
erase(tok2, tok2->at(4));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Delete second use in "use ; use ;"
|
||||
while (Tokenizer::Match(tok2, "[;{}] use ; use ;"))
|
||||
while (TOKEN::Match(tok2, "[;{}] use ; use ;"))
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2,3));
|
||||
erase(tok2, tok2->at(3));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Delete second case in "case ; case ;"
|
||||
while (Tokenizer::Match(tok2, "case ; case ;"))
|
||||
while (TOKEN::Match(tok2, "case ; case ;"))
|
||||
{
|
||||
erase(tok2, Tokenizer::gettok(tok2,3));
|
||||
erase(tok2, tok2->at(3));
|
||||
done = false;
|
||||
}
|
||||
|
||||
// Replace switch with if (if not complicated)
|
||||
if (Tokenizer::Match(tok2, "switch {"))
|
||||
if (TOKEN::Match(tok2, "switch {"))
|
||||
{
|
||||
// Right now, I just handle if there are a few case and perhaps a default.
|
||||
bool valid = false;
|
||||
bool incase = false;
|
||||
for ( const TOKEN * _tok = Tokenizer::gettok(tok2,2); _tok; _tok = _tok->next )
|
||||
for ( const TOKEN * _tok = tok2->at(2); _tok; _tok = _tok->next )
|
||||
{
|
||||
if ( _tok->str[0] == '{' )
|
||||
break;
|
||||
|
@ -731,23 +731,23 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
else if (strcmp(_tok->str,"loop")==0)
|
||||
break;
|
||||
|
||||
else if (incase && Tokenizer::Match(_tok,"case"))
|
||||
else if (incase && TOKEN::Match(_tok,"case"))
|
||||
break;
|
||||
|
||||
incase |= Tokenizer::Match(_tok,"case");
|
||||
incase &= !Tokenizer::Match(_tok,"break");
|
||||
incase |= TOKEN::Match(_tok,"case");
|
||||
incase &= !TOKEN::Match(_tok,"break");
|
||||
}
|
||||
|
||||
if ( !incase && valid )
|
||||
{
|
||||
done = false;
|
||||
tok2->setstr(";");
|
||||
erase( tok2, Tokenizer::gettok(tok2, 2) );
|
||||
erase( tok2, tok2->at(2) );
|
||||
tok2 = tok2->next;
|
||||
bool first = true;
|
||||
while (Tokenizer::Match(tok2,"case") || Tokenizer::Match(tok2,"default"))
|
||||
while (TOKEN::Match(tok2,"case") || TOKEN::Match(tok2,"default"))
|
||||
{
|
||||
bool def = Tokenizer::Match(tok2, "default");
|
||||
bool def = TOKEN::Match(tok2, "default");
|
||||
tok2->setstr(first ? "if" : "}");
|
||||
if ( first )
|
||||
{
|
||||
|
@ -762,9 +762,9 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
instoken( tok2, "if" );
|
||||
instoken( tok2, "else" );
|
||||
}
|
||||
while ( tok2 && tok2->str[0] != '}' && ! Tokenizer::Match(tok2,"break ;") )
|
||||
while ( tok2 && tok2->str[0] != '}' && ! TOKEN::Match(tok2,"break ;") )
|
||||
tok2 = tok2->next;
|
||||
if (Tokenizer::Match(tok2,"break ;"))
|
||||
if (TOKEN::Match(tok2,"break ;"))
|
||||
{
|
||||
tok2->setstr(";");
|
||||
tok2 = tok2->next->next;
|
||||
|
@ -773,7 +773,7 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
}
|
||||
}
|
||||
|
||||
if ( Tokenizer::Match(tok2, "throw") )
|
||||
if ( TOKEN::Match(tok2, "throw") )
|
||||
{
|
||||
tok2->setstr( "return" );
|
||||
done = false;
|
||||
|
@ -797,14 +797,14 @@ void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const
|
|||
TOKEN *tok = getcode( Tok1, callstack, varname, alloctype, dealloctype );
|
||||
|
||||
// If the variable is not allocated at all => no memory leak
|
||||
if (Tokenizer::findmatch(tok, "alloc") == 0)
|
||||
if (TOKEN::findmatch(tok, "alloc") == 0)
|
||||
{
|
||||
Tokenizer::deleteTokens(tok);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO : handle "goto"
|
||||
if (Tokenizer::findmatch(tok, "goto"))
|
||||
if (TOKEN::findmatch(tok, "goto"))
|
||||
{
|
||||
Tokenizer::deleteTokens(tok);
|
||||
return;
|
||||
|
@ -812,54 +812,55 @@ void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const
|
|||
|
||||
simplifycode( tok );
|
||||
|
||||
if ( Tokenizer::findmatch(tok, "loop alloc ;") )
|
||||
if ( TOKEN::findmatch(tok, "loop alloc ;") )
|
||||
{
|
||||
MemoryLeak(Tokenizer::findmatch(tok, "loop alloc ;"), varname);
|
||||
MemoryLeak(TOKEN::findmatch(tok, "loop alloc ;"), varname);
|
||||
}
|
||||
|
||||
else if ( Tokenizer::findmatch(tok, "alloc ; if continue ;") )
|
||||
else if ( TOKEN::findmatch(tok, "alloc ; if continue ;") )
|
||||
{
|
||||
MemoryLeak(Tokenizer::gettok(Tokenizer::findmatch(tok, "alloc ; if continue ;"), 3), varname);
|
||||
// MemoryLeak(Tokenizer::gettok(TOKEN::findmatch(tok, "alloc ; if continue ;"), 3), varname);
|
||||
MemoryLeak((TOKEN::findmatch(tok, "alloc ; if continue ;"))->at(3), varname);
|
||||
}
|
||||
|
||||
else if ( Tokenizer::findmatch(tok, "alloc ; if break ;") )
|
||||
else if ( TOKEN::findmatch(tok, "alloc ; if break ;") )
|
||||
{
|
||||
MemoryLeak(Tokenizer::gettok(Tokenizer::findmatch(tok, "alloc ; if break ;"), 3), varname);
|
||||
MemoryLeak((TOKEN::findmatch(tok, "alloc ; if break ;"))->at(3), varname);
|
||||
}
|
||||
|
||||
else if ( Tokenizer::findmatch(tok, "alloc ; if return ;") )
|
||||
else if ( TOKEN::findmatch(tok, "alloc ; if return ;") )
|
||||
{
|
||||
MemoryLeak(Tokenizer::gettok(Tokenizer::findmatch(tok, "alloc ; if return ;"), 3), varname);
|
||||
MemoryLeak((TOKEN::findmatch(tok, "alloc ; if return ;"))->at(3), varname);
|
||||
}
|
||||
|
||||
else if ( _settings._showAll && Tokenizer::findmatch(tok, "alloc ; ifv continue ;") )
|
||||
else if ( _settings._showAll && TOKEN::findmatch(tok, "alloc ; ifv continue ;") )
|
||||
{
|
||||
MemoryLeak(Tokenizer::gettok(Tokenizer::findmatch(tok, "alloc ; ifv continue ;"), 3), varname);
|
||||
MemoryLeak((TOKEN::findmatch(tok, "alloc ; ifv continue ;"))->at(3), varname);
|
||||
}
|
||||
|
||||
else if ( _settings._showAll && Tokenizer::findmatch(tok, "alloc ; ifv break ;") )
|
||||
else if ( _settings._showAll && TOKEN::findmatch(tok, "alloc ; ifv break ;") )
|
||||
{
|
||||
MemoryLeak(Tokenizer::gettok(Tokenizer::findmatch(tok, "alloc ; ifv break ;"), 3), varname);
|
||||
MemoryLeak((TOKEN::findmatch(tok, "alloc ; ifv break ;"))->at(3), varname);
|
||||
}
|
||||
|
||||
else if ( _settings._showAll && Tokenizer::findmatch(tok, "alloc ; ifv return ;") )
|
||||
else if ( _settings._showAll && TOKEN::findmatch(tok, "alloc ; ifv return ;") )
|
||||
{
|
||||
MemoryLeak(Tokenizer::gettok(Tokenizer::findmatch(tok, "alloc ; ifv return ;"), 3), varname);
|
||||
MemoryLeak((TOKEN::findmatch(tok, "alloc ; ifv return ;"))->at(3), varname);
|
||||
}
|
||||
|
||||
else if ( Tokenizer::findmatch(tok, "alloc ; return ;") )
|
||||
else if ( TOKEN::findmatch(tok, "alloc ; return ;") )
|
||||
{
|
||||
MemoryLeak(Tokenizer::gettok(Tokenizer::findmatch(tok,"alloc ; return ;"),2), varname);
|
||||
MemoryLeak((TOKEN::findmatch(tok,"alloc ; return ;"))->at(2), varname);
|
||||
}
|
||||
|
||||
else if ( Tokenizer::findmatch(tok, "alloc ; alloc") )
|
||||
else if ( TOKEN::findmatch(tok, "alloc ; alloc") )
|
||||
{
|
||||
MemoryLeak(Tokenizer::gettok(Tokenizer::findmatch(tok,"alloc ; alloc"),2), varname);
|
||||
MemoryLeak((TOKEN::findmatch(tok,"alloc ; alloc"))->at(2), varname);
|
||||
}
|
||||
|
||||
else if ( ! Tokenizer::findmatch(tok,"dealloc") &&
|
||||
! Tokenizer::findmatch(tok,"use") &&
|
||||
! Tokenizer::findmatch(tok,"return use ;") )
|
||||
else if ( ! TOKEN::findmatch(tok,"dealloc") &&
|
||||
! TOKEN::findmatch(tok,"use") &&
|
||||
! TOKEN::findmatch(tok,"return use ;") )
|
||||
{
|
||||
const TOKEN *last = tok;
|
||||
while (last->next)
|
||||
|
@ -894,21 +895,21 @@ void CheckMemoryLeakClass::CheckMemoryLeak_InFunction()
|
|||
// In function..
|
||||
if ( indentlevel == 0 )
|
||||
{
|
||||
if ( Tokenizer::Match(tok, ") {") )
|
||||
if ( TOKEN::Match(tok, ") {") )
|
||||
infunc = true;
|
||||
|
||||
if ( Tokenizer::Match(tok, "[;}]") )
|
||||
if ( TOKEN::Match(tok, "[;}]") )
|
||||
infunc = false;
|
||||
}
|
||||
|
||||
// Declare a local variable => Check
|
||||
if (indentlevel>0 && infunc)
|
||||
{
|
||||
if ( Tokenizer::Match(tok, "[{};] %type% * %var% [;=]") )
|
||||
CheckMemoryLeak_CheckScope( tok->next, Tokenizer::getstr(tok, 3) );
|
||||
if ( TOKEN::Match(tok, "[{};] %type% * %var% [;=]") )
|
||||
CheckMemoryLeak_CheckScope( tok->next, TOKEN::getstr(tok, 3) );
|
||||
|
||||
else if ( Tokenizer::Match(tok, "[{};] %type% %type% * %var% [;=]") )
|
||||
CheckMemoryLeak_CheckScope( tok->next, Tokenizer::getstr(tok, 4) );
|
||||
else if ( TOKEN::Match(tok, "[{};] %type% %type% * %var% [;=]") )
|
||||
CheckMemoryLeak_CheckScope( tok->next, TOKEN::getstr(tok, 4) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -933,10 +934,10 @@ void CheckMemoryLeakClass::CheckMemoryLeak_ClassMembers()
|
|||
else if ( tok->str[0] == '}' )
|
||||
indentlevel--;
|
||||
|
||||
else if ( indentlevel == 0 && Tokenizer::Match(tok, "class %var% [{:]") )
|
||||
else if ( indentlevel == 0 && TOKEN::Match(tok, "class %var% [{:]") )
|
||||
{
|
||||
std::vector<const char *> classname;
|
||||
classname.push_back( Tokenizer::getstr(tok, 1) );
|
||||
classname.push_back( TOKEN::getstr(tok, 1) );
|
||||
CheckMemoryLeak_ClassMembers_ParseClass( tok, classname );
|
||||
}
|
||||
}
|
||||
|
@ -969,20 +970,20 @@ void CheckMemoryLeakClass::CheckMemoryLeak_ClassMembers_ParseClass( const TOKEN
|
|||
continue;
|
||||
|
||||
// Declaring subclass.. recursive checking
|
||||
if ( Tokenizer::Match(tok, "class %var% [{:]") )
|
||||
if ( TOKEN::Match(tok, "class %var% [{:]") )
|
||||
{
|
||||
classname.push_back( Tokenizer::getstr(tok, 1) );
|
||||
classname.push_back( TOKEN::getstr(tok, 1) );
|
||||
CheckMemoryLeak_ClassMembers_ParseClass( tok, classname );
|
||||
classname.pop_back();
|
||||
}
|
||||
|
||||
// Declaring member variable.. check allocations and deallocations
|
||||
if ( Tokenizer::Match(tok->next, "%type% * %var% ;") )
|
||||
if ( TOKEN::Match(tok->next, "%type% * %var% ;") )
|
||||
{
|
||||
if ( Tokenizer::IsName(tok->str) || strchr(";}", tok->str[0]) )
|
||||
if ( TOKEN::IsName(tok->str) || strchr(";}", tok->str[0]) )
|
||||
{
|
||||
if (_settings._showAll || !isclass(Tokenizer::getstr(tok,1)))
|
||||
CheckMemoryLeak_ClassMembers_Variable( classname, Tokenizer::getstr(tok, 3) );
|
||||
if (_settings._showAll || !isclass(TOKEN::getstr(tok,1)))
|
||||
CheckMemoryLeak_ClassMembers_Variable( classname, TOKEN::getstr(tok, 3) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1036,7 +1037,7 @@ void CheckMemoryLeakClass::CheckMemoryLeak_ClassMembers_Variable( const std::vec
|
|||
{
|
||||
if ( strchr(";}", tok->str[0]) )
|
||||
memberfunction = false;
|
||||
else if ( Tokenizer::Match( tok, fpattern.str().c_str() ) || Tokenizer::Match( tok, destructor.str().c_str() ) )
|
||||
else if ( TOKEN::Match( tok, fpattern.str().c_str() ) || TOKEN::Match( tok, destructor.str().c_str() ) )
|
||||
memberfunction = true;
|
||||
}
|
||||
|
||||
|
@ -1044,9 +1045,9 @@ void CheckMemoryLeakClass::CheckMemoryLeak_ClassMembers_Variable( const std::vec
|
|||
if ( indentlevel > 0 && memberfunction )
|
||||
{
|
||||
// Allocate..
|
||||
if ( Tokenizer::Match( tok, varname_eq.str().c_str() ) )
|
||||
if ( TOKEN::Match( tok, varname_eq.str().c_str() ) )
|
||||
{
|
||||
AllocType alloc = GetAllocationType( Tokenizer::gettok( tok, 2 ) );
|
||||
AllocType alloc = GetAllocationType( tok->at(2) );
|
||||
if ( alloc != No )
|
||||
{
|
||||
std::list<const TOKEN *> callstack;
|
||||
|
|
262
CheckOther.cpp
262
CheckOther.cpp
|
@ -50,13 +50,13 @@ void CheckOther::WarningOldStylePointerCast()
|
|||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
// Old style pointer casting..
|
||||
if (!Tokenizer::Match(tok, "( %type% * ) %var%"))
|
||||
if (!TOKEN::Match(tok, "( %type% * ) %var%"))
|
||||
continue;
|
||||
|
||||
// Is "type" a class?
|
||||
const char *pattern[] = {"class","",NULL};
|
||||
pattern[1] = Tokenizer::getstr(tok, 1);
|
||||
if (!Tokenizer::findtoken(_tokenizer->tokens(), pattern))
|
||||
pattern[1] = TOKEN::getstr(tok, 1);
|
||||
if (!TOKEN::findtoken(_tokenizer->tokens(), pattern))
|
||||
continue;
|
||||
|
||||
std::ostringstream ostr;
|
||||
|
@ -77,10 +77,10 @@ void CheckOther::WarningIsDigit()
|
|||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
bool err = false;
|
||||
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' )");
|
||||
err |= TOKEN::Match(tok, "%var% >= '0' && %var% <= '9'");
|
||||
err |= TOKEN::Match(tok, "* %var% >= '0' && * %var% <= '9'");
|
||||
err |= TOKEN::Match(tok, "( %var% >= '0' ) && ( %var% <= '9' )");
|
||||
err |= TOKEN::Match(tok, "( * %var% >= '0' ) && ( * %var% <= '9' )");
|
||||
if (err)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
|
@ -101,15 +101,15 @@ void CheckOther::WarningIsAlpha()
|
|||
{
|
||||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
if ( ! Tokenizer::Match(tok, "(") )
|
||||
if ( ! TOKEN::Match(tok, "(") )
|
||||
continue;
|
||||
|
||||
bool err = false;
|
||||
|
||||
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' ) )");
|
||||
err |= TOKEN::Match(tok, "( %var% >= 'A' && %var% <= 'Z' )");
|
||||
err |= TOKEN::Match(tok, "( * %var% >= 'A' && * %var% <= 'Z' )");
|
||||
err |= TOKEN::Match(tok, "( ( %var% >= 'A' ) && ( %var% <= 'Z' ) )");
|
||||
err |= TOKEN::Match(tok, "( ( * %var% >= 'A' ) && ( * %var% <= 'Z' ) )");
|
||||
if (err)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
|
@ -119,10 +119,10 @@ void CheckOther::WarningIsAlpha()
|
|||
}
|
||||
|
||||
err = false;
|
||||
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' ) )");
|
||||
err |= TOKEN::Match(tok, "( %var% >= 'a' && %var% <= 'z' )");
|
||||
err |= TOKEN::Match(tok, "( * %var% >= 'a' && * %var% <= 'z' )");
|
||||
err |= TOKEN::Match(tok, "( ( %var% >= 'a' ) && ( %var% <= 'z' ) )");
|
||||
err |= TOKEN::Match(tok, "( ( * %var% >= 'a' ) && ( * %var% <= 'z' ) )");
|
||||
if (err)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
|
@ -132,14 +132,14 @@ void CheckOther::WarningIsAlpha()
|
|||
}
|
||||
|
||||
err = false;
|
||||
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' ) )");
|
||||
err |= TOKEN::Match(tok, "( %var% >= 'A' && %var% <= 'Z' ) || ( %var% >= 'a' && %var% <= 'z' )");
|
||||
err |= TOKEN::Match(tok, "( %var% >= 'a' && %var% <= 'z' ) || ( %var% >= 'A' && %var% <= 'Z' )");
|
||||
err |= TOKEN::Match(tok, "( * %var% >= 'A' && * %var% <= 'Z' ) || ( * %var% >= 'a' && * %var% <= 'z' )");
|
||||
err |= TOKEN::Match(tok, "( * %var% >= 'a' && * %var% <= 'z' ) || ( * %var% >= 'A' && * %var% <= 'Z' )");
|
||||
err |= TOKEN::Match(tok, "( ( %var% >= 'A' ) && ( %var% <= 'Z' ) ) || ( ( %var% >= 'a' ) && ( %var% <= 'z' ) )");
|
||||
err |= TOKEN::Match(tok, "( ( %var% >= 'a' ) && ( %var% <= 'z' ) ) || ( ( %var% >= 'A' ) && ( %var% <= 'Z' ) )");
|
||||
err |= TOKEN::Match(tok, "( ( * %var% >= 'A' ) && ( * %var% <= 'Z' ) ) || ( ( * var >= 'a' ) && ( * %var% <= 'z' ) )");
|
||||
err |= TOKEN::Match(tok, "( ( * %var% >= 'a' ) && ( * %var% <= 'z' ) ) || ( ( * var >= 'A' ) && ( * %var% <= 'Z' ) )");
|
||||
if (err)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
|
@ -161,38 +161,38 @@ void CheckOther::WarningRedundantCode()
|
|||
// if (p) delete p
|
||||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
if (!Tokenizer::Match(tok,"if"))
|
||||
if (!TOKEN::Match(tok,"if"))
|
||||
continue;
|
||||
|
||||
const char *varname1 = NULL;
|
||||
const TOKEN *tok2 = NULL;
|
||||
|
||||
if (Tokenizer::Match(tok,"if ( %var% )"))
|
||||
if (TOKEN::Match(tok,"if ( %var% )"))
|
||||
{
|
||||
varname1 = Tokenizer::getstr(tok, 2);
|
||||
tok2 = Tokenizer::gettok(tok, 4);
|
||||
varname1 = TOKEN::getstr(tok, 2);
|
||||
tok2 = tok->at(4);
|
||||
}
|
||||
else if (Tokenizer::Match(tok,"if ( %var% != NULL )"))
|
||||
else if (TOKEN::Match(tok,"if ( %var% != NULL )"))
|
||||
{
|
||||
varname1 = Tokenizer::getstr(tok, 2);
|
||||
tok2 = Tokenizer::gettok(tok, 6);
|
||||
varname1 = TOKEN::getstr(tok, 2);
|
||||
tok2 = tok->at(6);
|
||||
}
|
||||
|
||||
if (varname1==NULL || tok2==NULL)
|
||||
continue;
|
||||
|
||||
if ( Tokenizer::Match(tok2, "{") )
|
||||
if ( TOKEN::Match(tok2, "{") )
|
||||
tok2 = tok2->next;
|
||||
|
||||
bool err = false;
|
||||
if (Tokenizer::Match(tok2,"delete %var% ;"))
|
||||
err = (strcmp(Tokenizer::getstr(tok2,1),varname1)==0);
|
||||
else if (Tokenizer::Match(tok2,"delete [ ] %var% ;"))
|
||||
err = (strcmp(Tokenizer::getstr(tok2,1),varname1)==0);
|
||||
else if (Tokenizer::Match(tok2,"free ( %var% )"))
|
||||
err = (strcmp(Tokenizer::getstr(tok2,2),varname1)==0);
|
||||
else if (Tokenizer::Match(tok2,"kfree ( %var% )"))
|
||||
err = (strcmp(Tokenizer::getstr(tok2,2),varname1)==0);
|
||||
if (TOKEN::Match(tok2,"delete %var% ;"))
|
||||
err = (strcmp(TOKEN::getstr(tok2,1),varname1)==0);
|
||||
else if (TOKEN::Match(tok2,"delete [ ] %var% ;"))
|
||||
err = (strcmp(TOKEN::getstr(tok2,1),varname1)==0);
|
||||
else if (TOKEN::Match(tok2,"free ( %var% )"))
|
||||
err = (strcmp(TOKEN::getstr(tok2,2),varname1)==0);
|
||||
else if (TOKEN::Match(tok2,"kfree ( %var% )"))
|
||||
err = (strcmp(TOKEN::getstr(tok2,2),varname1)==0);
|
||||
|
||||
if (err)
|
||||
{
|
||||
|
@ -223,20 +223,20 @@ void CheckOther::WarningIf()
|
|||
// Search for 'if (condition);'
|
||||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
if (Tokenizer::Match(tok,"if"))
|
||||
if (TOKEN::Match(tok,"if"))
|
||||
{
|
||||
int parlevel = 0;
|
||||
for (const TOKEN *tok2 = tok->next; tok2; tok2 = tok2->next)
|
||||
{
|
||||
if (Tokenizer::Match(tok2,"("))
|
||||
if (TOKEN::Match(tok2,"("))
|
||||
parlevel++;
|
||||
else if (Tokenizer::Match(tok2,")"))
|
||||
else if (TOKEN::Match(tok2,")"))
|
||||
{
|
||||
parlevel--;
|
||||
if (parlevel<=0)
|
||||
{
|
||||
if (strcmp(Tokenizer::getstr(tok2,1), ";") == 0 &&
|
||||
strcmp(Tokenizer::getstr(tok2,2), "else") != 0)
|
||||
if (strcmp(TOKEN::getstr(tok2,1), ";") == 0 &&
|
||||
strcmp(TOKEN::getstr(tok2,2), "else") != 0)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << _tokenizer->fileLine(tok) << ": Found \"if (condition);\"";
|
||||
|
@ -253,24 +253,24 @@ void CheckOther::WarningIf()
|
|||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
// Begin statement?
|
||||
if ( ! Tokenizer::Match(tok, "[;{}]") )
|
||||
if ( ! TOKEN::Match(tok, "[;{}]") )
|
||||
continue;
|
||||
tok = tok->next;
|
||||
if ( ! tok )
|
||||
break;
|
||||
|
||||
if (!Tokenizer::Match(tok,"%var% = %var% ; if ( %var%"))
|
||||
if (!TOKEN::Match(tok,"%var% = %var% ; if ( %var%"))
|
||||
continue;
|
||||
|
||||
if ( strcmp(Tokenizer::getstr(tok, 9), ")") != 0 )
|
||||
if ( strcmp(TOKEN::getstr(tok, 9), ")") != 0 )
|
||||
continue;
|
||||
|
||||
// var1 = var2 ; if ( var3 cond var4 )
|
||||
const char *var1 = Tokenizer::getstr(tok, 0);
|
||||
const char *var2 = Tokenizer::getstr(tok, 2);
|
||||
const char *var3 = Tokenizer::getstr(tok, 6);
|
||||
const char *cond = Tokenizer::getstr(tok, 7);
|
||||
const char *var4 = Tokenizer::getstr(tok, 8);
|
||||
const char *var1 = TOKEN::getstr(tok, 0);
|
||||
const char *var2 = TOKEN::getstr(tok, 2);
|
||||
const char *var3 = TOKEN::getstr(tok, 6);
|
||||
const char *cond = TOKEN::getstr(tok, 7);
|
||||
const char *var4 = TOKEN::getstr(tok, 8);
|
||||
|
||||
// Check that var3 is equal with either var1 or var2
|
||||
if (strcmp(var1,var3) && strcmp(var2,var3))
|
||||
|
@ -290,7 +290,7 @@ void CheckOther::WarningIf()
|
|||
|
||||
// we found the error. Report.
|
||||
std::ostringstream ostr;
|
||||
ostr << _tokenizer->fileLine(Tokenizer::gettok(tok,4)) << ": The condition is always ";
|
||||
ostr << _tokenizer->fileLine(tok->at(4)) << ": The condition is always ";
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (strcmp(cond, p[i]) == 0)
|
||||
|
@ -312,7 +312,7 @@ void CheckOther::InvalidFunctionUsage()
|
|||
{
|
||||
for ( const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next )
|
||||
{
|
||||
if (!Tokenizer::Match(tok, "strtol") && !Tokenizer::Match(tok, "strtoul"))
|
||||
if (!TOKEN::Match(tok, "strtol") && !TOKEN::Match(tok, "strtoul"))
|
||||
continue;
|
||||
|
||||
// Locate the third parameter of the function call..
|
||||
|
@ -320,18 +320,18 @@ void CheckOther::InvalidFunctionUsage()
|
|||
int param = 1;
|
||||
for ( const TOKEN *tok2 = tok->next; tok2; tok2 = tok2->next )
|
||||
{
|
||||
if ( Tokenizer::Match(tok2, "(") )
|
||||
if ( TOKEN::Match(tok2, "(") )
|
||||
parlevel++;
|
||||
else if (Tokenizer::Match(tok2, ")"))
|
||||
else if (TOKEN::Match(tok2, ")"))
|
||||
parlevel--;
|
||||
else if (parlevel == 1 && Tokenizer::Match(tok2, ","))
|
||||
else if (parlevel == 1 && TOKEN::Match(tok2, ","))
|
||||
{
|
||||
param++;
|
||||
if (param==3)
|
||||
{
|
||||
if ( Tokenizer::Match(tok2, ", %num% )") )
|
||||
if ( TOKEN::Match(tok2, ", %num% )") )
|
||||
{
|
||||
int radix = atoi(Tokenizer::getstr(tok2, 1));
|
||||
int radix = atoi(TOKEN::getstr(tok2, 1));
|
||||
if (!(radix==0 || (radix>=2 && radix<=36)))
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
|
@ -356,9 +356,9 @@ void CheckOther::CheckIfAssignment()
|
|||
{
|
||||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
if (Tokenizer::Match(tok, "if ( %var% = %num% )") ||
|
||||
Tokenizer::Match(tok, "if ( %var% = %str% )") ||
|
||||
Tokenizer::Match(tok, "if ( %var% = %var% )") )
|
||||
if (TOKEN::Match(tok, "if ( %var% = %num% )") ||
|
||||
TOKEN::Match(tok, "if ( %var% = %str% )") ||
|
||||
TOKEN::Match(tok, "if ( %var% = %var% )") )
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << _tokenizer->fileLine(tok) << ": Possible bug. Should it be '==' instead of '='?";
|
||||
|
@ -379,20 +379,20 @@ void CheckOther::CheckUnsignedDivision()
|
|||
std::map<std::string, char> varsign;
|
||||
for ( const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next )
|
||||
{
|
||||
if ( Tokenizer::Match(tok, "[{};(,] %type% %var% [;=,)]") )
|
||||
if ( TOKEN::Match(tok, "[{};(,] %type% %var% [;=,)]") )
|
||||
{
|
||||
const char *type = Tokenizer::getstr(tok, 1);
|
||||
const char *type = TOKEN::getstr(tok, 1);
|
||||
if (strcmp(type,"char")==0 || strcmp(type,"short")==0 || strcmp(type,"int")==0)
|
||||
varsign[Tokenizer::getstr(tok,2)] = 's';
|
||||
varsign[TOKEN::getstr(tok,2)] = 's';
|
||||
}
|
||||
|
||||
else if ( Tokenizer::Match(tok, "[{};(,] unsigned %type% %var% [;=,)]") )
|
||||
varsign[Tokenizer::getstr(tok,3)] = 'u';
|
||||
else if ( TOKEN::Match(tok, "[{};(,] unsigned %type% %var% [;=,)]") )
|
||||
varsign[TOKEN::getstr(tok,3)] = 'u';
|
||||
|
||||
else if (!Tokenizer::Match(tok,"[).]") && Tokenizer::Match(tok->next, "%var% / %var%"))
|
||||
else if (!TOKEN::Match(tok,"[).]") && TOKEN::Match(tok->next, "%var% / %var%"))
|
||||
{
|
||||
const char *varname1 = Tokenizer::getstr(tok,1);
|
||||
const char *varname2 = Tokenizer::getstr(tok,3);
|
||||
const char *varname1 = TOKEN::getstr(tok,1);
|
||||
const char *varname2 = TOKEN::getstr(tok,3);
|
||||
char sign1 = varsign[varname1];
|
||||
char sign2 = varsign[varname2];
|
||||
|
||||
|
@ -405,9 +405,9 @@ void CheckOther::CheckUnsignedDivision()
|
|||
}
|
||||
}
|
||||
|
||||
else if (!Tokenizer::Match(tok,"[).]") && Tokenizer::Match(tok->next, "%var% / - %num%"))
|
||||
else if (!TOKEN::Match(tok,"[).]") && TOKEN::Match(tok->next, "%var% / - %num%"))
|
||||
{
|
||||
const char *varname1 = Tokenizer::getstr(tok,1);
|
||||
const char *varname1 = TOKEN::getstr(tok,1);
|
||||
char sign1 = varsign[varname1];
|
||||
if ( sign1 == 'u' )
|
||||
{
|
||||
|
@ -417,9 +417,9 @@ void CheckOther::CheckUnsignedDivision()
|
|||
}
|
||||
}
|
||||
|
||||
else if (Tokenizer::Match(tok, "[([=*/+-] - %num% / %var%"))
|
||||
else if (TOKEN::Match(tok, "[([=*/+-] - %num% / %var%"))
|
||||
{
|
||||
const char *varname2 = Tokenizer::getstr(tok,4);
|
||||
const char *varname2 = TOKEN::getstr(tok,4);
|
||||
char sign2 = varsign[varname2];
|
||||
if ( sign2 == 'u' )
|
||||
{
|
||||
|
@ -447,21 +447,21 @@ void CheckOther::CheckVariableScope()
|
|||
for ( const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next )
|
||||
{
|
||||
// Skip class and struct declarations..
|
||||
if ( Tokenizer::Match(tok, "class") || Tokenizer::Match(tok, "struct") )
|
||||
if ( TOKEN::Match(tok, "class") || TOKEN::Match(tok, "struct") )
|
||||
{
|
||||
for (const TOKEN *tok2 = tok; tok2; tok2 = tok2->next)
|
||||
{
|
||||
if ( Tokenizer::Match(tok2, "{") )
|
||||
if ( TOKEN::Match(tok2, "{") )
|
||||
{
|
||||
int _indentlevel = 0;
|
||||
tok = tok2;
|
||||
for (tok = tok2; tok; tok = tok->next)
|
||||
{
|
||||
if ( Tokenizer::Match(tok, "{") )
|
||||
if ( TOKEN::Match(tok, "{") )
|
||||
{
|
||||
_indentlevel++;
|
||||
}
|
||||
if ( Tokenizer::Match(tok, "}") )
|
||||
if ( TOKEN::Match(tok, "}") )
|
||||
{
|
||||
_indentlevel--;
|
||||
if ( _indentlevel <= 0 )
|
||||
|
@ -473,7 +473,7 @@ void CheckOther::CheckVariableScope()
|
|||
}
|
||||
break;
|
||||
}
|
||||
if (Tokenizer::Match(tok2, "[,);]"))
|
||||
if (TOKEN::Match(tok2, "[,);]"))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -482,38 +482,38 @@ void CheckOther::CheckVariableScope()
|
|||
break;
|
||||
}
|
||||
|
||||
if ( Tokenizer::Match(tok, "{") )
|
||||
if ( TOKEN::Match(tok, "{") )
|
||||
{
|
||||
indentlevel++;
|
||||
}
|
||||
if ( Tokenizer::Match(tok, "}") )
|
||||
if ( TOKEN::Match(tok, "}") )
|
||||
{
|
||||
indentlevel--;
|
||||
if ( indentlevel == 0 )
|
||||
func = false;
|
||||
}
|
||||
if ( indentlevel == 0 && Tokenizer::Match(tok, ") {") )
|
||||
if ( indentlevel == 0 && TOKEN::Match(tok, ") {") )
|
||||
{
|
||||
func = true;
|
||||
}
|
||||
if ( indentlevel > 0 && func && Tokenizer::Match(tok, "[{};]") )
|
||||
if ( indentlevel > 0 && func && TOKEN::Match(tok, "[{};]") )
|
||||
{
|
||||
// First token of statement..
|
||||
const TOKEN *tok1 = tok->next;
|
||||
if ( ! tok1 )
|
||||
continue;
|
||||
|
||||
if (Tokenizer::Match(tok1,"return") ||
|
||||
Tokenizer::Match(tok1,"delete") ||
|
||||
Tokenizer::Match(tok1,"goto") ||
|
||||
Tokenizer::Match(tok1,"else"))
|
||||
if (TOKEN::Match(tok1,"return") ||
|
||||
TOKEN::Match(tok1,"delete") ||
|
||||
TOKEN::Match(tok1,"goto") ||
|
||||
TOKEN::Match(tok1,"else"))
|
||||
continue;
|
||||
|
||||
// Variable declaration?
|
||||
if (Tokenizer::Match(tok1, "%var% %var% ;") ||
|
||||
Tokenizer::Match(tok1, "%var% %var% =") )
|
||||
if (TOKEN::Match(tok1, "%var% %var% ;") ||
|
||||
TOKEN::Match(tok1, "%var% %var% =") )
|
||||
{
|
||||
CheckVariableScope_LookupVar( tok1, Tokenizer::getstr(tok1, 1) );
|
||||
CheckVariableScope_LookupVar( tok1, TOKEN::getstr(tok1, 1) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -526,7 +526,7 @@ void CheckOther::CheckVariableScope_LookupVar( const TOKEN *tok1, const char var
|
|||
const TOKEN *tok = tok1;
|
||||
|
||||
// Skip the variable declaration..
|
||||
while (tok && !Tokenizer::Match(tok,";"))
|
||||
while (tok && !TOKEN::Match(tok,";"))
|
||||
tok = tok->next;
|
||||
|
||||
// Check if the variable is used in this indentlevel..
|
||||
|
@ -536,12 +536,12 @@ void CheckOther::CheckVariableScope_LookupVar( const TOKEN *tok1, const char var
|
|||
bool for_or_while = false;
|
||||
while ( indentlevel >= 0 && tok )
|
||||
{
|
||||
if ( Tokenizer::Match(tok, "{") )
|
||||
if ( TOKEN::Match(tok, "{") )
|
||||
{
|
||||
indentlevel++;
|
||||
}
|
||||
|
||||
else if ( Tokenizer::Match(tok, "}") )
|
||||
else if ( TOKEN::Match(tok, "}") )
|
||||
{
|
||||
indentlevel--;
|
||||
if ( indentlevel == 0 )
|
||||
|
@ -553,18 +553,18 @@ void CheckOther::CheckVariableScope_LookupVar( const TOKEN *tok1, const char var
|
|||
}
|
||||
}
|
||||
|
||||
else if ( Tokenizer::Match(tok, "(") )
|
||||
else if ( TOKEN::Match(tok, "(") )
|
||||
{
|
||||
parlevel++;
|
||||
}
|
||||
|
||||
else if ( Tokenizer::Match(tok, ")") )
|
||||
else if ( TOKEN::Match(tok, ")") )
|
||||
{
|
||||
parlevel--;
|
||||
}
|
||||
|
||||
|
||||
else if ( strcmp(Tokenizer::getstr(tok, 0), varname) == 0 )
|
||||
else if ( strcmp(TOKEN::getstr(tok, 0), varname) == 0 )
|
||||
{
|
||||
if ( indentlevel == 0 || used1 )
|
||||
return;
|
||||
|
@ -573,9 +573,9 @@ void CheckOther::CheckVariableScope_LookupVar( const TOKEN *tok1, const char var
|
|||
|
||||
else if ( indentlevel==0 )
|
||||
{
|
||||
if ( Tokenizer::Match(tok,"for") || Tokenizer::Match(tok,"while") )
|
||||
if ( TOKEN::Match(tok,"for") || TOKEN::Match(tok,"while") )
|
||||
for_or_while = true;
|
||||
if ( parlevel == 0 && Tokenizer::Match(tok, ";") )
|
||||
if ( parlevel == 0 && TOKEN::Match(tok, ";") )
|
||||
for_or_while = false;
|
||||
}
|
||||
|
||||
|
@ -598,29 +598,29 @@ void CheckOther::CheckConstantFunctionParameter()
|
|||
{
|
||||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
if ( Tokenizer::Match(tok,"[,(] const std :: %type% %var% [,)]") )
|
||||
if ( TOKEN::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";
|
||||
errmsg << _tokenizer->fileLine(tok) << " " << TOKEN::getstr(tok,5) << " is passed by value, it could be passed by reference/pointer instead";
|
||||
_errorLogger->reportErr( errmsg.str() );
|
||||
}
|
||||
|
||||
else if ( Tokenizer::Match(tok,"[,(] const %type% %var% [,)]") )
|
||||
else if ( TOKEN::Match(tok,"[,(] const %type% %var% [,)]") )
|
||||
{
|
||||
// Check if type is a struct or class.
|
||||
const char *pattern[3] = {"class","type",0};
|
||||
pattern[1] = Tokenizer::getstr(tok, 2);
|
||||
if ( Tokenizer::findtoken(_tokenizer->tokens(), pattern) )
|
||||
pattern[1] = TOKEN::getstr(tok, 2);
|
||||
if ( TOKEN::findtoken(_tokenizer->tokens(), pattern) )
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << _tokenizer->fileLine(tok) << " " << Tokenizer::getstr(tok,3) << " is passed by value, it could be passed by reference/pointer instead";
|
||||
errmsg << _tokenizer->fileLine(tok) << " " << TOKEN::getstr(tok,3) << " is passed by value, it could be passed by reference/pointer instead";
|
||||
_errorLogger->reportErr( errmsg.str() );
|
||||
}
|
||||
pattern[0] = "struct";
|
||||
if ( Tokenizer::findtoken(_tokenizer->tokens(), pattern) )
|
||||
if ( TOKEN::findtoken(_tokenizer->tokens(), pattern) )
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << _tokenizer->fileLine(tok) << " " << Tokenizer::getstr(tok,3) << " is passed by value, it could be passed by reference/pointer instead";
|
||||
errmsg << _tokenizer->fileLine(tok) << " " << TOKEN::getstr(tok,3) << " is passed by value, it could be passed by reference/pointer instead";
|
||||
_errorLogger->reportErr( errmsg.str() );
|
||||
}
|
||||
}
|
||||
|
@ -641,22 +641,22 @@ void CheckOther::CheckStructMemberUsage()
|
|||
{
|
||||
if ( tok->FileIndex != 0 )
|
||||
continue;
|
||||
if ( Tokenizer::Match(tok,"}") )
|
||||
if ( TOKEN::Match(tok,"}") )
|
||||
structname = 0;
|
||||
if ( Tokenizer::Match(tok, "struct %type% {") )
|
||||
structname = Tokenizer::getstr(tok, 1);
|
||||
if ( TOKEN::Match(tok, "struct %type% {") )
|
||||
structname = TOKEN::getstr(tok, 1);
|
||||
|
||||
if (structname && Tokenizer::Match(tok, "[{;]"))
|
||||
if (structname && TOKEN::Match(tok, "[{;]"))
|
||||
{
|
||||
const char *varname = 0;
|
||||
if (Tokenizer::Match(tok->next, "%type% %var% [;[]"))
|
||||
varname = Tokenizer::getstr( tok, 2 );
|
||||
else if (Tokenizer::Match(tok->next, "%type% %type% %var% [;[]"))
|
||||
varname = Tokenizer::getstr( tok, 2 );
|
||||
else if (Tokenizer::Match(tok->next, "%type% * %var% [;[]"))
|
||||
varname = Tokenizer::getstr( tok, 3 );
|
||||
else if (Tokenizer::Match(tok->next, "%type% %type% * %var% [;[]"))
|
||||
varname = Tokenizer::getstr( tok, 4 );
|
||||
if (TOKEN::Match(tok->next, "%type% %var% [;[]"))
|
||||
varname = TOKEN::getstr( tok, 2 );
|
||||
else if (TOKEN::Match(tok->next, "%type% %type% %var% [;[]"))
|
||||
varname = TOKEN::getstr( tok, 2 );
|
||||
else if (TOKEN::Match(tok->next, "%type% * %var% [;[]"))
|
||||
varname = TOKEN::getstr( tok, 3 );
|
||||
else if (TOKEN::Match(tok->next, "%type% %type% * %var% [;[]"))
|
||||
varname = TOKEN::getstr( tok, 4 );
|
||||
else
|
||||
continue;
|
||||
|
||||
|
@ -669,9 +669,9 @@ void CheckOther::CheckStructMemberUsage()
|
|||
if ( tok->FileIndex != 0 )
|
||||
continue;
|
||||
|
||||
if (Tokenizer::Match(tok2, ". %var%", varnames))
|
||||
if (TOKEN::Match(tok2, ". %var%", varnames))
|
||||
{
|
||||
if ( strcmp("=", Tokenizer::getstr(tok2,2)) == 0 )
|
||||
if ( strcmp("=", TOKEN::getstr(tok2,2)) == 0 )
|
||||
continue;
|
||||
used = true;
|
||||
break;
|
||||
|
@ -701,26 +701,26 @@ void CheckOther::CheckCharVariable()
|
|||
for (const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next)
|
||||
{
|
||||
// Declaring the variable..
|
||||
if ( Tokenizer::Match(tok, "[{};(,] char %var% [;=,)]") )
|
||||
if ( TOKEN::Match(tok, "[{};(,] char %var% [;=,)]") )
|
||||
{
|
||||
const char *varname[2] = {0};
|
||||
varname[0] = Tokenizer::getstr(tok, 2);
|
||||
varname[0] = TOKEN::getstr(tok, 2);
|
||||
|
||||
// Check usage of char variable..
|
||||
int indentlevel = 0;
|
||||
for ( const TOKEN *tok2 = tok->next; tok2; tok2 = tok2->next )
|
||||
{
|
||||
if ( Tokenizer::Match(tok2, "{") )
|
||||
if ( TOKEN::Match(tok2, "{") )
|
||||
++indentlevel;
|
||||
|
||||
else if ( Tokenizer::Match(tok2, "}") )
|
||||
else if ( TOKEN::Match(tok2, "}") )
|
||||
{
|
||||
--indentlevel;
|
||||
if ( indentlevel <= 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
if (!Tokenizer::Match(tok2,".") && Tokenizer::Match(tok2->next, "%var% [ %var1% ]", varname))
|
||||
if (!TOKEN::Match(tok2,".") && TOKEN::Match(tok2->next, "%var% [ %var1% ]", varname))
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << _tokenizer->fileLine(tok2->next) << ": Warning - using char variable as array index";
|
||||
|
@ -728,7 +728,7 @@ void CheckOther::CheckCharVariable()
|
|||
break;
|
||||
}
|
||||
|
||||
if ( Tokenizer::Match(tok2, "%var% [&|] %var1%", varname) || Tokenizer::Match(tok2, "%var1% [&|]", varname) )
|
||||
if ( TOKEN::Match(tok2, "%var% [&|] %var1%", varname) || TOKEN::Match(tok2, "%var1% [&|]", varname) )
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << _tokenizer->fileLine(tok2) << ": Warning - using char variable in bit operation";
|
||||
|
@ -756,22 +756,22 @@ void CheckOther::CheckIncompleteStatement()
|
|||
|
||||
for ( const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next )
|
||||
{
|
||||
if ( Tokenizer::Match(tok, "(") )
|
||||
if ( TOKEN::Match(tok, "(") )
|
||||
++parlevel;
|
||||
else if ( Tokenizer::Match(tok, ")") )
|
||||
else if ( TOKEN::Match(tok, ")") )
|
||||
--parlevel;
|
||||
|
||||
if ( parlevel != 0 )
|
||||
continue;
|
||||
|
||||
if ( !Tokenizer::Match(tok,"#") && Tokenizer::Match(tok->next,"; %str%") && !Tokenizer::Match(Tokenizer::gettok(tok,3), ",") )
|
||||
if ( !TOKEN::Match(tok,"#") && TOKEN::Match(tok->next,"; %str%") && !TOKEN::Match(tok->at(3), ",") )
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << _tokenizer->fileLine(tok->next) << ": Redundant code: Found a statement that begins with string constant";
|
||||
_errorLogger->reportErr(errmsg.str());
|
||||
}
|
||||
|
||||
if ( !Tokenizer::Match(tok,"#") && Tokenizer::Match(tok->next,"; %num%") && !Tokenizer::Match(Tokenizer::gettok(tok,3), ",") )
|
||||
if ( !TOKEN::Match(tok,"#") && TOKEN::Match(tok->next,"; %num%") && !TOKEN::Match(tok->at(3), ",") )
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << _tokenizer->fileLine(tok->next) << ": Redundant code: Found a statement that begins with numeric constant";
|
||||
|
|
10
Makefile
10
Makefile
|
@ -1,18 +1,20 @@
|
|||
SRCS=CheckBufferOverrun.cpp CheckClass.cpp CheckHeaders.cpp CheckMemoryLeak.cpp CheckFunctionUsage.cpp CheckOther.cpp FileLister.cpp preprocessor.cpp tokenize.cpp cppcheck.cpp settings.cpp
|
||||
SRCS=CheckBufferOverrun.cpp CheckClass.cpp CheckHeaders.cpp CheckMemoryLeak.cpp CheckFunctionUsage.cpp CheckOther.cpp FileLister.cpp preprocessor.cpp tokenize.cpp cppcheck.cpp settings.cpp token.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
|
||||
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 token.o
|
||||
BIN = ${DESTDIR}/usr/bin
|
||||
|
||||
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 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 token.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
|
||||
token.o: token.cpp
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
CheckBufferOverrun.o: CheckBufferOverrun.cpp CheckBufferOverrun.h tokenize.h
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
CheckClass.o: CheckClass.cpp CheckClass.h tokenize.h
|
||||
|
@ -55,7 +57,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
|
||||
tokenize.o: tokenize.cpp tokenize.h token.h
|
||||
g++ -Wall -pedantic -g -I. -o $@ -c $*.cpp
|
||||
clean:
|
||||
rm -f *.o testrunner cppcheck
|
||||
|
|
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
* c++check - c/c++ syntax checking
|
||||
* Copyright (C) 2007-2008 Daniel Marjamäki and Reijo Tomperi
|
||||
*
|
||||
* 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 "token.h"
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
TOKEN::TOKEN()
|
||||
{
|
||||
FileIndex = 0;
|
||||
_str = 0;
|
||||
linenr = 0;
|
||||
next = 0;
|
||||
}
|
||||
|
||||
TOKEN::~TOKEN()
|
||||
{
|
||||
std::free(_str);
|
||||
}
|
||||
|
||||
void TOKEN::setstr( const char s[] )
|
||||
{
|
||||
std::free(_str);
|
||||
#ifndef _MSC_VER
|
||||
_str = strdup(s);
|
||||
#else
|
||||
_str = _strdup(s);
|
||||
#endif
|
||||
str = _str ? _str : "";
|
||||
}
|
||||
|
||||
void TOKEN::combineWithNext(const char str1[], const char str2[])
|
||||
{
|
||||
if (!(next))
|
||||
return;
|
||||
if (strcmp(str,str1) || strcmp(next->str,str2))
|
||||
return;
|
||||
|
||||
std::string newstr(std::string(str1) + std::string(str2));
|
||||
setstr( newstr.c_str() );
|
||||
deleteNext();
|
||||
}
|
||||
|
||||
void TOKEN::deleteNext()
|
||||
{
|
||||
TOKEN *n = next;
|
||||
next = n->next;
|
||||
delete n;
|
||||
}
|
||||
|
||||
const TOKEN *TOKEN::at(int index) const
|
||||
{
|
||||
const TOKEN *tok = this;
|
||||
while (index>0 && tok)
|
||||
{
|
||||
tok = tok->next;
|
||||
index--;
|
||||
}
|
||||
return tok;
|
||||
}
|
||||
|
||||
|
||||
bool TOKEN::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 (!TOKEN::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 ( !(tok->at(2)) )
|
||||
return false;
|
||||
|
||||
if ( strcmp(TOKEN::getstr(tok, 1), ".") )
|
||||
return false;
|
||||
|
||||
if ( strcmp(TOKEN::getstr(tok, 2), varname[i]) )
|
||||
return false;
|
||||
|
||||
tok = tok->at(2);
|
||||
}
|
||||
}
|
||||
|
||||
else if (strcmp(str,"%num%")==0)
|
||||
{
|
||||
if ( ! TOKEN::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 && *p)
|
||||
return false;
|
||||
}
|
||||
|
||||
// The end of the pattern has been reached and nothing wrong has been found
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TOKEN::IsName(const char str[])
|
||||
{
|
||||
return bool(str[0]=='_' || isalpha(str[0]));
|
||||
}
|
||||
|
||||
bool TOKEN::IsNumber(const char str[])
|
||||
{
|
||||
return bool(isdigit(str[0]) != 0);
|
||||
}
|
||||
|
||||
const char *TOKEN::getstr(const TOKEN *tok, int index)
|
||||
{
|
||||
tok = tok->at(index);
|
||||
return tok ? tok->str : "";
|
||||
}
|
||||
|
||||
bool TOKEN::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;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const TOKEN *TOKEN::findmatch(const TOKEN *tok, const char pattern[], const char *varname1[], const char *varname2[])
|
||||
{
|
||||
for ( ; tok; tok = tok->next)
|
||||
{
|
||||
if ( TOKEN::Match(tok, pattern, varname1, varname2) )
|
||||
return tok;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const TOKEN *TOKEN::findtoken(const TOKEN *tok1, const char *tokenstr[])
|
||||
{
|
||||
for (const TOKEN *ret = tok1; ret; ret = ret->next)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
const TOKEN *tok = ret;
|
||||
while (tokenstr[i])
|
||||
{
|
||||
if (!tok)
|
||||
return NULL;
|
||||
if (*(tokenstr[i]) && strcmp(tokenstr[i],tok->str))
|
||||
break;
|
||||
tok = tok->next;
|
||||
i++;
|
||||
}
|
||||
if (!tokenstr[i])
|
||||
return ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* c++check - c/c++ syntax checking
|
||||
* Copyright (C) 2007-2008 Daniel Marjamäki and Reijo Tomperi
|
||||
*
|
||||
* 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 TOKEN_H
|
||||
#define TOKEN_H
|
||||
|
||||
class TOKEN
|
||||
{
|
||||
public:
|
||||
TOKEN();
|
||||
~TOKEN();
|
||||
void setstr( const char s[] );
|
||||
|
||||
/**
|
||||
* Combine two tokens that belong to each other.
|
||||
* Ex: "<" and "=" may become "<="
|
||||
*/
|
||||
void combineWithNext(const char str1[], const char str2[]);
|
||||
|
||||
/**
|
||||
* Unlink and delete next token.
|
||||
*/
|
||||
void deleteNext();
|
||||
|
||||
/**
|
||||
* Returns token in given index, related to this token.
|
||||
* For example index 1 would return next token, and 2
|
||||
* would return next from that one.
|
||||
*/
|
||||
const TOKEN *at(int index) const;
|
||||
|
||||
static bool Match(const TOKEN *tok, const char pattern[], const char *varname1[]=0, const char *varname2[]=0);
|
||||
static bool IsName(const char str[]);
|
||||
static bool IsNumber(const char str[]);
|
||||
static const char *getstr(const TOKEN *tok, int index);
|
||||
static bool IsStandardType(const char str[]);
|
||||
static const TOKEN *findmatch(const TOKEN *tok, const char pattern[], const char *varname1[]=0, const char *varname2[]=0);
|
||||
static const TOKEN *findtoken(const TOKEN *tok1, const char *tokenstr[]);
|
||||
const char *str;
|
||||
unsigned int FileIndex;
|
||||
unsigned int linenr;
|
||||
TOKEN *next;
|
||||
|
||||
private:
|
||||
char * _str;
|
||||
};
|
||||
|
||||
#endif // TOKEN_H
|
452
tokenize.cpp
452
tokenize.cpp
|
@ -72,7 +72,8 @@ TOKEN *Tokenizer::_gettok(TOKEN *tok, int index)
|
|||
index--;
|
||||
}
|
||||
return tok;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const TOKEN *Tokenizer::tokens() const
|
||||
|
@ -137,12 +138,6 @@ void Tokenizer::Define(const char Name[], const char Value[])
|
|||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// addtoken
|
||||
// add a token. Used by 'Tokenizer'
|
||||
|
@ -190,35 +185,6 @@ void Tokenizer::addtoken(const char str[], const unsigned int lineno, const unsi
|
|||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// combine_2tokens
|
||||
// Combine two tokens that belong to each other. Ex: "<" and "=" may become "<="
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void Tokenizer::combine_2tokens(TOKEN *tok, const char str1[], const char str2[])
|
||||
{
|
||||
if (!(tok && tok->next))
|
||||
return;
|
||||
if (strcmp(tok->str,str1) || strcmp(tok->next->str,str2))
|
||||
return;
|
||||
|
||||
std::string newstr(std::string(str1) + std::string(str2));
|
||||
tok->setstr( newstr.c_str() );
|
||||
|
||||
DeleteNextToken(tok);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// SizeOfType - gives the size of a type
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -238,27 +204,6 @@ int Tokenizer::SizeOfType(const char type[]) const
|
|||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// DeleteNextToken. Unlink and delete next token.
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void Tokenizer::DeleteNextToken(TOKEN *tok)
|
||||
{
|
||||
TOKEN *next = tok->next;
|
||||
tok->next = next->next;
|
||||
delete next;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// InsertTokens - Copy and insert tokens
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -282,10 +227,6 @@ void Tokenizer::InsertTokens(TOKEN *dest, TOKEN *src, unsigned int n)
|
|||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Tokenize - tokenizes a given file.
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -307,10 +248,6 @@ void Tokenizer::Tokenize(std::istream &code, const char FileName[])
|
|||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Tokenize - tokenizes input stream
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -560,30 +497,30 @@ void Tokenizer::TokenizeCode(std::istream &code, const unsigned int FileIndex)
|
|||
// Combine tokens..
|
||||
for (TOKEN *tok = _tokens; tok && tok->next; tok = tok->next)
|
||||
{
|
||||
combine_2tokens(tok, "<", "<");
|
||||
combine_2tokens(tok, ">", ">");
|
||||
tok->combineWithNext("<", "<");
|
||||
tok->combineWithNext(">", ">");
|
||||
|
||||
combine_2tokens(tok, "&", "&");
|
||||
combine_2tokens(tok, "|", "|");
|
||||
tok->combineWithNext("&", "&");
|
||||
tok->combineWithNext("|", "|");
|
||||
|
||||
combine_2tokens(tok, "+", "=");
|
||||
combine_2tokens(tok, "-", "=");
|
||||
combine_2tokens(tok, "*", "=");
|
||||
combine_2tokens(tok, "/", "=");
|
||||
combine_2tokens(tok, "&", "=");
|
||||
combine_2tokens(tok, "|", "=");
|
||||
tok->combineWithNext("+", "=");
|
||||
tok->combineWithNext("-", "=");
|
||||
tok->combineWithNext("*", "=");
|
||||
tok->combineWithNext("/", "=");
|
||||
tok->combineWithNext("&", "=");
|
||||
tok->combineWithNext("|", "=");
|
||||
|
||||
combine_2tokens(tok, "=", "=");
|
||||
combine_2tokens(tok, "!", "=");
|
||||
combine_2tokens(tok, "<", "=");
|
||||
combine_2tokens(tok, ">", "=");
|
||||
tok->combineWithNext("=", "=");
|
||||
tok->combineWithNext("!", "=");
|
||||
tok->combineWithNext("<", "=");
|
||||
tok->combineWithNext(">", "=");
|
||||
|
||||
combine_2tokens(tok, ":", ":");
|
||||
combine_2tokens(tok, "-", ">");
|
||||
tok->combineWithNext(":", ":");
|
||||
tok->combineWithNext("-", ">");
|
||||
|
||||
combine_2tokens(tok, "private", ":");
|
||||
combine_2tokens(tok, "protected", ":");
|
||||
combine_2tokens(tok, "public", ":");
|
||||
tok->combineWithNext("private", ":");
|
||||
tok->combineWithNext("protected", ":");
|
||||
tok->combineWithNext("public", ":");
|
||||
}
|
||||
|
||||
// Replace "->" with "."
|
||||
|
@ -598,10 +535,10 @@ void Tokenizer::TokenizeCode(std::istream &code, const unsigned int FileIndex)
|
|||
// typedef..
|
||||
for ( TOKEN *tok = _tokens; tok; tok = tok->next )
|
||||
{
|
||||
if (Tokenizer::Match(tok, "typedef %type% %type% ;"))
|
||||
if (TOKEN::Match(tok, "typedef %type% %type% ;"))
|
||||
{
|
||||
const char *type1 = getstr(tok, 1);
|
||||
const char *type2 = getstr(tok, 2);
|
||||
const char *type1 = TOKEN::getstr(tok, 1);
|
||||
const char *type2 = TOKEN::getstr(tok, 2);
|
||||
for ( TOKEN *tok2 = tok; tok2; tok2 = tok2->next )
|
||||
{
|
||||
if (tok2->str!=type1 && tok2->str!=type2 && strcmp(tok2->str,type2)==0)
|
||||
|
@ -611,14 +548,14 @@ void Tokenizer::TokenizeCode(std::istream &code, const unsigned int FileIndex)
|
|||
}
|
||||
}
|
||||
|
||||
else if (Tokenizer::Match(tok, "typedef %type% %type% %type% ;"))
|
||||
else if (TOKEN::Match(tok, "typedef %type% %type% %type% ;"))
|
||||
{
|
||||
const char *type1 = getstr(tok, 1);
|
||||
const char *type2 = getstr(tok, 2);
|
||||
const char *type3 = getstr(tok, 3);
|
||||
const char *type1 = TOKEN::getstr(tok, 1);
|
||||
const char *type2 = TOKEN::getstr(tok, 2);
|
||||
const char *type3 = TOKEN::getstr(tok, 3);
|
||||
|
||||
TOKEN *tok2 = tok;
|
||||
while ( ! Tokenizer::Match(tok2, ";") )
|
||||
while ( ! TOKEN::Match(tok2, ";") )
|
||||
tok2 = tok2->next;
|
||||
|
||||
for ( ; tok2; tok2 = tok2->next )
|
||||
|
@ -643,11 +580,11 @@ void Tokenizer::TokenizeCode(std::istream &code, const unsigned int FileIndex)
|
|||
// Remove __asm..
|
||||
for ( TOKEN *tok = _tokens; tok; tok = tok->next )
|
||||
{
|
||||
if ( Tokenizer::Match(tok->next, "__asm {") )
|
||||
if ( TOKEN::Match(tok->next, "__asm {") )
|
||||
{
|
||||
while ( tok->next )
|
||||
{
|
||||
bool last = Tokenizer::Match( tok->next, "}" );
|
||||
bool last = TOKEN::Match( tok->next, "}" );
|
||||
|
||||
// Unlink and delete tok->next
|
||||
TOKEN *next = tok->next;
|
||||
|
@ -664,13 +601,6 @@ void Tokenizer::TokenizeCode(std::istream &code, const unsigned int FileIndex)
|
|||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Simplify token list
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -682,18 +612,18 @@ void Tokenizer::SimplifyTokenList()
|
|||
for ( TOKEN *tok = _tokens; tok; tok = tok->next )
|
||||
{
|
||||
if (tok->next && strcmp(tok->next->str,"unsigned")==0)
|
||||
{
|
||||
DeleteNextToken( tok );
|
||||
{
|
||||
tok->deleteNext();
|
||||
}
|
||||
}
|
||||
|
||||
// Replace constants..
|
||||
for (TOKEN *tok = _tokens; tok; tok = tok->next)
|
||||
{
|
||||
if (Tokenizer::Match(tok,"const %type% %var% = %num% ;"))
|
||||
if (TOKEN::Match(tok,"const %type% %var% = %num% ;"))
|
||||
{
|
||||
const char *sym = getstr(tok,2);
|
||||
const char *num = getstr(tok,4);
|
||||
const char *sym = TOKEN::getstr(tok,2);
|
||||
const char *num = TOKEN::getstr(tok,4);
|
||||
|
||||
for (TOKEN *tok2 = _gettok(tok,6); tok2; tok2 = tok2->next)
|
||||
{
|
||||
|
@ -716,14 +646,14 @@ void Tokenizer::SimplifyTokenList()
|
|||
TypeSize["double"] = sizeof(double);
|
||||
for (TOKEN *tok = _tokens; tok; tok = tok->next)
|
||||
{
|
||||
if (Tokenizer::Match(tok,"class %var%"))
|
||||
if (TOKEN::Match(tok,"class %var%"))
|
||||
{
|
||||
TypeSize[getstr(tok,1)] = 11;
|
||||
TypeSize[TOKEN::getstr(tok,1)] = 11;
|
||||
}
|
||||
|
||||
else if (Tokenizer::Match(tok, "struct %var%"))
|
||||
else if (TOKEN::Match(tok, "struct %var%"))
|
||||
{
|
||||
TypeSize[getstr(tok,1)] = 13;
|
||||
TypeSize[TOKEN::getstr(tok,1)] = 13;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -734,7 +664,7 @@ void Tokenizer::SimplifyTokenList()
|
|||
if (strcmp(tok->str,"sizeof") != 0)
|
||||
continue;
|
||||
|
||||
if (Tokenizer::Match(tok, "sizeof ( %type% * )"))
|
||||
if (TOKEN::Match(tok, "sizeof ( %type% * )"))
|
||||
{
|
||||
std::ostringstream str;
|
||||
// 'sizeof(type *)' has the same size as 'sizeof(char *)'
|
||||
|
@ -743,13 +673,13 @@ void Tokenizer::SimplifyTokenList()
|
|||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
DeleteNextToken(tok);
|
||||
tok->deleteNext();
|
||||
}
|
||||
}
|
||||
|
||||
else if (Tokenizer::Match(tok, "sizeof ( %type% )"))
|
||||
else if (TOKEN::Match(tok, "sizeof ( %type% )"))
|
||||
{
|
||||
const char *type = getstr(tok, 2);
|
||||
const char *type = TOKEN::getstr(tok, 2);
|
||||
int size = SizeOfType(type);
|
||||
if (size > 0)
|
||||
{
|
||||
|
@ -758,16 +688,16 @@ void Tokenizer::SimplifyTokenList()
|
|||
tok->setstr( str.str().c_str() );
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
DeleteNextToken(tok);
|
||||
tok->deleteNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (Tokenizer::Match(tok, "sizeof ( * %var% )"))
|
||||
else if (TOKEN::Match(tok, "sizeof ( * %var% )"))
|
||||
{
|
||||
tok->setstr("100");
|
||||
for ( int i = 0; i < 4; ++i )
|
||||
DeleteNextToken(tok);
|
||||
tok->deleteNext();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -775,15 +705,15 @@ void Tokenizer::SimplifyTokenList()
|
|||
for (TOKEN *tok = _tokens; tok; tok = tok->next)
|
||||
{
|
||||
// type array [ num ] ;
|
||||
if ( ! Tokenizer::Match(tok, "%type% %var% [ %num% ] ;") )
|
||||
if ( ! TOKEN::Match(tok, "%type% %var% [ %num% ] ;") )
|
||||
continue;
|
||||
|
||||
int size = SizeOfType(tok->str);
|
||||
if (size <= 0)
|
||||
continue;
|
||||
|
||||
const char *varname = getstr(tok, 1);
|
||||
int total_size = size * atoi( getstr(tok, 3) );
|
||||
const char *varname = TOKEN::getstr(tok, 1);
|
||||
int total_size = size * atoi( TOKEN::getstr(tok, 3) );
|
||||
|
||||
// Replace 'sizeof(var)' with number
|
||||
int indentlevel = 0;
|
||||
|
@ -801,10 +731,10 @@ void Tokenizer::SimplifyTokenList()
|
|||
break;
|
||||
}
|
||||
|
||||
// Todo: Tokenizer::Match varname directly
|
||||
else if (Tokenizer::Match(tok2, "sizeof ( %var% )"))
|
||||
// Todo: TOKEN::Match varname directly
|
||||
else if (TOKEN::Match(tok2, "sizeof ( %var% )"))
|
||||
{
|
||||
if (strcmp(getstr(tok2,2), varname) == 0)
|
||||
if (strcmp(TOKEN::getstr(tok2,2), varname) == 0)
|
||||
{
|
||||
std::ostringstream str;
|
||||
str << total_size;
|
||||
|
@ -812,7 +742,7 @@ void Tokenizer::SimplifyTokenList()
|
|||
// Delete the other tokens..
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
DeleteNextToken(tok2);
|
||||
tok2->deleteNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -827,28 +757,28 @@ void Tokenizer::SimplifyTokenList()
|
|||
{
|
||||
for (TOKEN *tok = _tokens; tok; tok = tok->next)
|
||||
{
|
||||
if (Tokenizer::Match(tok->next, "* 1") || Tokenizer::Match(tok->next, "1 *"))
|
||||
if (TOKEN::Match(tok->next, "* 1") || TOKEN::Match(tok->next, "1 *"))
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
DeleteNextToken(tok);
|
||||
tok->deleteNext();
|
||||
done = false;
|
||||
}
|
||||
|
||||
// (1-2)
|
||||
if (strchr("[,(=<>",tok->str[0]) &&
|
||||
Tokenizer::IsNumber(getstr(tok,1)) &&
|
||||
strchr("+-*/",*(getstr(tok,2))) &&
|
||||
Tokenizer::IsNumber(getstr(tok,3)) &&
|
||||
strchr("],);=<>",*(getstr(tok,4))) )
|
||||
TOKEN::IsNumber(TOKEN::getstr(tok,1)) &&
|
||||
strchr("+-*/",*(TOKEN::getstr(tok,2))) &&
|
||||
TOKEN::IsNumber(TOKEN::getstr(tok,3)) &&
|
||||
strchr("],);=<>",*(TOKEN::getstr(tok,4))) )
|
||||
{
|
||||
int i1 = atoi(getstr(tok,1));
|
||||
int i2 = atoi(getstr(tok,3));
|
||||
if ( i2 == 0 && *(getstr(tok,2)) == '/' )
|
||||
int i1 = atoi(TOKEN::getstr(tok,1));
|
||||
int i2 = atoi(TOKEN::getstr(tok,3));
|
||||
if ( i2 == 0 && *(TOKEN::getstr(tok,2)) == '/' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (*(getstr(tok,2)))
|
||||
switch (*(TOKEN::getstr(tok,2)))
|
||||
{
|
||||
case '+': i1 += i2; break;
|
||||
case '-': i1 -= i2; break;
|
||||
|
@ -861,7 +791,7 @@ void Tokenizer::SimplifyTokenList()
|
|||
tok->setstr(str.str().c_str());
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
DeleteNextToken(tok);
|
||||
tok->deleteNext();
|
||||
}
|
||||
|
||||
done = false;
|
||||
|
@ -880,11 +810,11 @@ void Tokenizer::SimplifyTokenList()
|
|||
if ( ! next )
|
||||
break;
|
||||
|
||||
if (Tokenizer::Match(next, "* ( %var% + %num% )"))
|
||||
if (TOKEN::Match(next, "* ( %var% + %num% )"))
|
||||
{
|
||||
const char *str[4] = {"var","[","num","]"};
|
||||
str[0] = getstr(tok,3);
|
||||
str[2] = getstr(tok,5);
|
||||
str[0] = TOKEN::getstr(tok,3);
|
||||
str[2] = TOKEN::getstr(tok,5);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
|
@ -892,8 +822,8 @@ void Tokenizer::SimplifyTokenList()
|
|||
tok->setstr(str[i]);
|
||||
}
|
||||
|
||||
DeleteNextToken(tok);
|
||||
DeleteNextToken(tok);
|
||||
tok->deleteNext();
|
||||
tok->deleteNext();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -906,64 +836,64 @@ void Tokenizer::SimplifyTokenList()
|
|||
continue;
|
||||
|
||||
TOKEN *type0 = tok->next;
|
||||
if (!Tokenizer::Match(type0, "%type%"))
|
||||
if (!TOKEN::Match(type0, "%type%"))
|
||||
continue;
|
||||
if (Tokenizer::Match(type0, "else") || Tokenizer::Match(type0, "return"))
|
||||
if (TOKEN::Match(type0, "else") || TOKEN::Match(type0, "return"))
|
||||
continue;
|
||||
|
||||
TOKEN *tok2 = NULL;
|
||||
unsigned int typelen = 0;
|
||||
|
||||
if ( Tokenizer::Match(type0, "%type% %var% ,") )
|
||||
if ( TOKEN::Match(type0, "%type% %var% ,") )
|
||||
{
|
||||
tok2 = _gettok(type0, 2); // The ',' token
|
||||
typelen = 1;
|
||||
}
|
||||
|
||||
else if ( Tokenizer::Match(type0, "%type% * %var% ,") )
|
||||
else if ( TOKEN::Match(type0, "%type% * %var% ,") )
|
||||
{
|
||||
tok2 = _gettok(type0, 3); // The ',' token
|
||||
typelen = 1;
|
||||
}
|
||||
|
||||
else if ( Tokenizer::Match(type0, "%type% %var% [ %num% ] ,") )
|
||||
else if ( TOKEN::Match(type0, "%type% %var% [ %num% ] ,") )
|
||||
{
|
||||
tok2 = _gettok(type0, 5); // The ',' token
|
||||
typelen = 1;
|
||||
}
|
||||
|
||||
else if ( Tokenizer::Match(type0, "%type% * %var% [ %num% ] ,") )
|
||||
else if ( TOKEN::Match(type0, "%type% * %var% [ %num% ] ,") )
|
||||
{
|
||||
tok2 = _gettok(type0, 6); // The ',' token
|
||||
typelen = 1;
|
||||
}
|
||||
|
||||
else if ( Tokenizer::Match(type0, "struct %type% %var% ,") )
|
||||
else if ( TOKEN::Match(type0, "struct %type% %var% ,") )
|
||||
{
|
||||
tok2 = _gettok(type0, 3);
|
||||
typelen = 2;
|
||||
}
|
||||
|
||||
else if ( Tokenizer::Match(type0, "struct %type% * %var% ,") )
|
||||
else if ( TOKEN::Match(type0, "struct %type% * %var% ,") )
|
||||
{
|
||||
tok2 = _gettok(type0, 4);
|
||||
typelen = 2;
|
||||
}
|
||||
|
||||
|
||||
else if ( Tokenizer::Match(type0, "%type% %var% =") )
|
||||
else if ( TOKEN::Match(type0, "%type% %var% =") )
|
||||
{
|
||||
tok2 = _gettok(type0, 2);
|
||||
typelen = 1;
|
||||
}
|
||||
|
||||
else if ( Tokenizer::Match(type0, "%type% * %var% =") )
|
||||
else if ( TOKEN::Match(type0, "%type% * %var% =") )
|
||||
{
|
||||
tok2 = _gettok(type0, 3);
|
||||
typelen = 1;
|
||||
}
|
||||
|
||||
else if ( Tokenizer::Match(type0, "struct %type% * %var% =") )
|
||||
else if ( TOKEN::Match(type0, "struct %type% * %var% =") )
|
||||
{
|
||||
tok2 = _gettok(type0, 4);
|
||||
typelen = 2;
|
||||
|
@ -1023,17 +953,17 @@ void Tokenizer::SimplifyTokenList()
|
|||
// Replace NULL with 0..
|
||||
for ( TOKEN *tok = _tokens; tok; tok = tok->next )
|
||||
{
|
||||
if ( Tokenizer::Match(tok, "NULL") )
|
||||
if ( TOKEN::Match(tok, "NULL") )
|
||||
tok->setstr("0");
|
||||
}
|
||||
|
||||
// Replace pointer casts of 0.. "(char *)0" => "0"
|
||||
for ( TOKEN *tok = _tokens; tok; tok = tok->next )
|
||||
{
|
||||
if ( Tokenizer::Match(tok->next, "( %type% * ) 0") || Tokenizer::Match(tok->next,"( %type% %type% * ) 0") )
|
||||
if ( TOKEN::Match(tok->next, "( %type% * ) 0") || TOKEN::Match(tok->next,"( %type% %type% * ) 0") )
|
||||
{
|
||||
while (!Tokenizer::Match(tok->next,"0"))
|
||||
DeleteNextToken(tok);
|
||||
while (!TOKEN::Match(tok->next,"0"))
|
||||
tok->deleteNext();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1052,25 +982,25 @@ bool Tokenizer::simplifyConditions()
|
|||
|
||||
for ( TOKEN *tok = _tokens; tok; tok = tok->next )
|
||||
{
|
||||
if (Match(tok, "( true &&") || Match(tok, "&& true &&") || Match(tok->next, "&& true )"))
|
||||
if (TOKEN::Match(tok, "( true &&") || TOKEN::Match(tok, "&& true &&") || TOKEN::Match(tok->next, "&& true )"))
|
||||
{
|
||||
DeleteNextToken( tok );
|
||||
DeleteNextToken( tok );
|
||||
tok->deleteNext();
|
||||
tok->deleteNext();
|
||||
ret = false;
|
||||
}
|
||||
|
||||
else if (Match(tok, "( false ||") || Match(tok, "|| false ||") || Match(tok->next, "|| false )"))
|
||||
else if (TOKEN::Match(tok, "( false ||") || TOKEN::Match(tok, "|| false ||") || TOKEN::Match(tok->next, "|| false )"))
|
||||
{
|
||||
DeleteNextToken( tok );
|
||||
DeleteNextToken( tok );
|
||||
tok->deleteNext();
|
||||
tok->deleteNext();
|
||||
ret = false;
|
||||
}
|
||||
|
||||
// Change numeric constant in condition to "true" or "false"
|
||||
const TOKEN *tok2 = gettok(tok, 2);
|
||||
if ((Match(tok, "(") || Match(tok, "&&") || Match(tok, "||")) &&
|
||||
Match(tok->next, "%num%") &&
|
||||
(Match(tok2, ")") || Match(tok2, "&&") || Match(tok2, "||")) )
|
||||
const TOKEN *tok2 = tok->at(2);
|
||||
if ((TOKEN::Match(tok, "(") || TOKEN::Match(tok, "&&") || TOKEN::Match(tok, "||")) &&
|
||||
TOKEN::Match(tok->next, "%num%") &&
|
||||
(TOKEN::Match(tok2, ")") || TOKEN::Match(tok2, "&&") || TOKEN::Match(tok2, "||")) )
|
||||
{
|
||||
tok->next->setstr((strcmp(tok->next->str, "0")!=0) ? "true" : "false");
|
||||
ret = false;
|
||||
|
@ -1081,62 +1011,10 @@ bool Tokenizer::simplifyConditions()
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Helper functions for handling the tokens list
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const TOKEN *Tokenizer::findtoken(const TOKEN *tok1, const char *tokenstr[])
|
||||
{
|
||||
for (const TOKEN *ret = tok1; ret; ret = ret->next)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
const TOKEN *tok = ret;
|
||||
while (tokenstr[i])
|
||||
{
|
||||
if (!tok)
|
||||
return NULL;
|
||||
if (*(tokenstr[i]) && strcmp(tokenstr[i],tok->str))
|
||||
break;
|
||||
tok = tok->next;
|
||||
i++;
|
||||
}
|
||||
if (!tokenstr[i])
|
||||
return ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const TOKEN *Tokenizer::gettok(const TOKEN *tok, int index)
|
||||
{
|
||||
while (tok && index>0)
|
||||
{
|
||||
tok = tok->next;
|
||||
index--;
|
||||
}
|
||||
return tok;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const char *Tokenizer::getstr(const TOKEN *tok, int index)
|
||||
{
|
||||
tok = gettok(tok, index);
|
||||
return tok ? tok->str : "";
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -1184,7 +1062,7 @@ void Tokenizer::FillFunctionList(const unsigned int file_id)
|
|||
else if ( strcmp( tok->str, "::" ) == 0 )
|
||||
classfunc = true;
|
||||
|
||||
else if (Tokenizer::Match(tok, "%var% ("))
|
||||
else if (TOKEN::Match(tok, "%var% ("))
|
||||
{
|
||||
// Check if this is the first token of a function implementation..
|
||||
for ( const TOKEN *tok2 = tok; tok2; tok2 = tok2->next )
|
||||
|
@ -1202,7 +1080,7 @@ void Tokenizer::FillFunctionList(const unsigned int file_id)
|
|||
|
||||
else if ( tok2->str[0] == ')' )
|
||||
{
|
||||
if ( Tokenizer::Match(tok2, ") {") )
|
||||
if ( TOKEN::Match(tok2, ") {") )
|
||||
{
|
||||
FunctionList.push_back( tok );
|
||||
tok = tok2;
|
||||
|
@ -1282,8 +1160,7 @@ void Tokenizer::deleteTokens(TOKEN *tok)
|
|||
delete tok;
|
||||
tok = next;
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
@ -1292,9 +1169,9 @@ const char *Tokenizer::getParameterName( const TOKEN *ftok, int par )
|
|||
int _par = 1;
|
||||
for ( ; ftok; ftok = ftok->next)
|
||||
{
|
||||
if ( Tokenizer::Match(ftok, ",") )
|
||||
if ( TOKEN::Match(ftok, ",") )
|
||||
++_par;
|
||||
if ( par==_par && Tokenizer::Match(ftok, "%var% [,)]") )
|
||||
if ( par==_par && TOKEN::Match(ftok, "%var% [,)]") )
|
||||
return ftok->str;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -1302,18 +1179,6 @@ const char *Tokenizer::getParameterName( const TOKEN *ftok, int par )
|
|||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const TOKEN *Tokenizer::findmatch(const TOKEN *tok, const char pattern[], const char *varname1[], const char *varname2[])
|
||||
{
|
||||
for ( ; tok; tok = tok->next)
|
||||
{
|
||||
if ( Tokenizer::Match(tok, pattern, varname1, varname2) )
|
||||
return tok;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
std::string Tokenizer::fileLine( const TOKEN *tok ) const
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
|
@ -1321,100 +1186,6 @@ std::string Tokenizer::fileLine( const TOKEN *tok ) const
|
|||
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 && *p)
|
||||
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[] )
|
||||
|
@ -1433,27 +1204,4 @@ bool Tokenizer::SameFileName( const char fname1[], const char fname2[] )
|
|||
#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;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
57
tokenize.h
57
tokenize.h
|
@ -25,40 +25,9 @@
|
|||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include "settings.h"
|
||||
#include "errorlogger.h"
|
||||
|
||||
class TOKEN
|
||||
{
|
||||
private:
|
||||
char * _str;
|
||||
|
||||
public:
|
||||
TOKEN()
|
||||
{ FileIndex = 0; _str = 0; linenr = 0; next = 0; }
|
||||
|
||||
~TOKEN()
|
||||
{ std::free(_str); }
|
||||
|
||||
void setstr( const char s[] )
|
||||
{
|
||||
std::free(_str);
|
||||
#ifndef _MSC_VER
|
||||
_str = strdup(s);
|
||||
#else
|
||||
_str = _strdup(s);
|
||||
#endif
|
||||
str = _str ? _str : "";
|
||||
}
|
||||
|
||||
const char *str;
|
||||
|
||||
unsigned int FileIndex;
|
||||
unsigned int linenr;
|
||||
TOKEN *next;
|
||||
};
|
||||
#include "errorlogger.h"
|
||||
#include "token.h"
|
||||
|
||||
class Tokenizer
|
||||
{
|
||||
|
@ -79,17 +48,12 @@ public:
|
|||
void TokenizeCode(std::istream &code, const unsigned int FileIndex=0);
|
||||
|
||||
// Helper functions for handling the tokens list..
|
||||
static const TOKEN *findtoken(const TOKEN *tok1, const char *tokenstr[]);
|
||||
static const TOKEN *gettok(const TOKEN *tok, int index);
|
||||
static const char *getstr(const TOKEN *tok, int index);
|
||||
|
||||
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 ) const;
|
||||
|
||||
|
@ -121,10 +85,6 @@ private:
|
|||
|
||||
void addtoken(const char str[], const unsigned int lineno, const unsigned int fileno);
|
||||
|
||||
void combine_2tokens(TOKEN *tok, const char str1[], const char str2[]);
|
||||
|
||||
void DeleteNextToken(TOKEN *tok);
|
||||
|
||||
bool simplifyConditions();
|
||||
|
||||
TOKEN *_gettok(TOKEN *tok, int index);
|
||||
|
@ -142,10 +102,5 @@ private:
|
|||
TOKEN *_tokens;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue