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