Refactoring: Replaced deprecated "match" with the new "Match"
This commit is contained in:
parent
bf6926232b
commit
4691999ede
|
@ -20,67 +20,6 @@ extern bool ShowAll;
|
|||
// CallStack used when parsing into subfunctions.
|
||||
static std::list<const TOKEN *> CallStack;
|
||||
|
||||
static std::list<const TOKEN *> FunctionList;
|
||||
static void FillFunctionList()
|
||||
{
|
||||
FunctionList.clear();
|
||||
int indentlevel = 0;
|
||||
for ( const TOKEN *tok = tokens; tok; tok = tok->next )
|
||||
{
|
||||
if ( tok->str[0] == '{' )
|
||||
indentlevel++;
|
||||
|
||||
else if ( tok->str[0] == '}' )
|
||||
indentlevel--;
|
||||
|
||||
else if (indentlevel==0 && match(tok, "var ("))
|
||||
{
|
||||
// Check if this is the first token of a function implementation..
|
||||
for ( const TOKEN *tok2 = tok; tok2; tok2 = tok2->next )
|
||||
{
|
||||
if ( tok2->str[0] == ';' )
|
||||
{
|
||||
tok = tok2;
|
||||
break;
|
||||
}
|
||||
|
||||
else if ( tok2->str[0] == '{' )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
else if ( tok2->str[0] == ')' )
|
||||
{
|
||||
if ( match(tok2, ") {") )
|
||||
{
|
||||
FunctionList.push_back( tok );
|
||||
tok = tok2;
|
||||
}
|
||||
else
|
||||
{
|
||||
tok = tok2;
|
||||
while (tok->next && !strchr(";{", tok->next->str[0]))
|
||||
tok = tok->next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const TOKEN *GetFunctionTokenByName( const char funcname[] )
|
||||
{
|
||||
std::list<const TOKEN *>::const_iterator it;
|
||||
for ( it = FunctionList.begin(); it != FunctionList.end(); it++ )
|
||||
{
|
||||
if ( strcmp( (*it)->str, funcname ) == 0 )
|
||||
{
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Modified version of 'ReportError' that also reports the callstack
|
||||
static void ReportError(const TOKEN *tok, const char errmsg[])
|
||||
|
@ -92,87 +31,6 @@ static void ReportError(const TOKEN *tok, const char errmsg[])
|
|||
ostr << FileLine(tok) << ": " << errmsg;
|
||||
ReportErr(ostr.str());
|
||||
}
|
||||
|
||||
|
||||
static bool Match1(const TOKEN *tok, const char pattern[], const char *varname[])
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (strcmp(tok->str, varname[0]) != 0)
|
||||
return false;
|
||||
|
||||
for ( int i = 1; varname[i]; i++ )
|
||||
{
|
||||
if ( ! gettok(tok, 2) )
|
||||
return false;
|
||||
|
||||
if ( strcmp(getstr(tok, 1), ".") )
|
||||
return false;
|
||||
|
||||
if ( strcmp(getstr(tok, 2), varname[i]) )
|
||||
return false;
|
||||
|
||||
tok = 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
@ -189,7 +47,7 @@ static void CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname
|
|||
|
||||
|
||||
// Array index..
|
||||
if ( Match1(tok, "%var1% [ %num% ]", varname) )
|
||||
if ( Match(tok, "%var1% [ %num% ]", varname) )
|
||||
{
|
||||
const char *num = getstr(tok, 2 + varc);
|
||||
if (strtol(num, NULL, 10) >= size)
|
||||
|
@ -215,7 +73,7 @@ static void CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname
|
|||
}
|
||||
|
||||
// Array index..
|
||||
if ( !IsName(tok->str) && Match1(tok->next, "%var1% [ %num% ]", varname) )
|
||||
if ( !IsName(tok->str) && Match(tok->next, "%var1% [ %num% ]", varname) )
|
||||
{
|
||||
const char *num = getstr(tok->next, 2 + varc);
|
||||
if (strtol(num, NULL, 10) >= size)
|
||||
|
@ -235,8 +93,8 @@ static void CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname
|
|||
strcmp(tok->str,"strncpy")==0 ||
|
||||
strcmp(tok->str,"fgets")==0 )
|
||||
{
|
||||
if ( Match1( tok->next, "( %var1% , %num% , %num% )", varname ) ||
|
||||
Match1( tok->next, "( %var% , %var1% , %num% )", varname ) )
|
||||
if ( Match( tok->next, "( %var1% , %num% , %num% )", varname ) ||
|
||||
Match( tok->next, "( %var% , %var1% , %num% )", varname ) )
|
||||
{
|
||||
const char *num = getstr(tok, varc + 6);
|
||||
if ( atoi(num) > total_size )
|
||||
|
@ -249,22 +107,22 @@ static void CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname
|
|||
|
||||
|
||||
// Loop..
|
||||
if ( match(tok, "for (") )
|
||||
if ( Match(tok, "for (") )
|
||||
{
|
||||
const TOKEN *tok2 = gettok( tok, 2 );
|
||||
|
||||
// for - setup..
|
||||
if ( match(tok2, "var = 0 ;") )
|
||||
if ( Match(tok2, "%var% = 0 ;") )
|
||||
tok2 = gettok(tok2, 4);
|
||||
else if ( match(tok2, "type var = 0 ;") )
|
||||
else if ( Match(tok2, "%type% %var% = 0 ;") )
|
||||
tok2 = gettok(tok2, 5);
|
||||
else if ( match(tok2, "type type var = 0 ;") )
|
||||
else if ( Match(tok2, "%type% %type% %var% = 0 ;") )
|
||||
tok2 = gettok(tok2, 6);
|
||||
else
|
||||
continue;
|
||||
|
||||
// for - condition..
|
||||
if ( ! match(tok2, "var < num ;") && ! match(tok2, "var <= num ;"))
|
||||
if ( ! Match(tok2, "%var% < %num% ;") && ! Match(tok2, "%var% <= %num% ;"))
|
||||
continue;
|
||||
|
||||
// Get index variable and stopsize.
|
||||
|
@ -298,7 +156,7 @@ static void CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname
|
|||
break;
|
||||
}
|
||||
|
||||
if ( Match1( tok2, pattern.str().c_str(), varname ) )
|
||||
if ( Match( tok2, pattern.str().c_str(), varname ) )
|
||||
{
|
||||
ReportError(tok2, "Buffer overrun");
|
||||
break;
|
||||
|
@ -311,7 +169,7 @@ static void CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname
|
|||
|
||||
|
||||
// Writing data into array..
|
||||
if ( Match1(tok, "strcpy ( %var1% , %str% )", varname) )
|
||||
if ( Match(tok, "strcpy ( %var1% , %str% )", varname) )
|
||||
{
|
||||
int len = 0;
|
||||
const char *str = getstr(tok, varc + 4 );
|
||||
|
@ -332,7 +190,7 @@ static void CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname
|
|||
|
||||
// Function call..
|
||||
// Todo: Handle struct member variables..
|
||||
if ( match( tok, "var (" ) )
|
||||
if ( Match( tok, "%var% (" ) )
|
||||
{
|
||||
// Don't make recursive checking..
|
||||
if (std::find(CallStack.begin(), CallStack.end(), tok) != CallStack.end())
|
||||
|
@ -363,7 +221,7 @@ static void CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname
|
|||
|
||||
if ( parlevel == 1 &&
|
||||
strchr( "(,", *getstr(tok2,0) ) &&
|
||||
Match1( tok2->next, "%var1%", varname ) &&
|
||||
Match( tok2->next, "%var1%", varname ) &&
|
||||
strchr( ",)", *getstr(tok2, 2+varc) ) )
|
||||
{
|
||||
par++;
|
||||
|
@ -393,7 +251,7 @@ static void CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname
|
|||
else if ( ftok->str[0] == ',' )
|
||||
par--;
|
||||
|
||||
else if (par==1 && parlevel==1 && (match(ftok, "var ,") || match(ftok, "var )")))
|
||||
else if (par==1 && parlevel==1 && (Match(ftok, "%var% ,") || Match(ftok, "%var% )")))
|
||||
{
|
||||
// Parameter name..
|
||||
const char *parname[2];
|
||||
|
@ -436,7 +294,7 @@ static void CheckBufferOverrun_LocalVariable()
|
|||
else if (tok->str[0]=='}')
|
||||
indentlevel--;
|
||||
|
||||
else if (indentlevel > 0 && match(tok, "type var [ num ] ;"))
|
||||
else if (indentlevel > 0 && Match(tok, "%type% %var% [ %num% ] ;"))
|
||||
{
|
||||
const char *varname[2];
|
||||
varname[0] = getstr(tok,1);
|
||||
|
@ -483,8 +341,8 @@ static void CheckBufferOverrun_StructVariable()
|
|||
if ( strchr( ";{,(", tok2->str[0] ) )
|
||||
{
|
||||
// Declare array..
|
||||
if ( match(tok2->next, "type var [ num ] ;") ||
|
||||
match(tok2->next, "type * var [ num ] ;") )
|
||||
if ( Match(tok2->next, "%type% %var% [ %num% ] ;") ||
|
||||
Match(tok2->next, "%type% * %var% [ %num% ] ;") )
|
||||
{
|
||||
const char *varname[3] = {0,0,0};
|
||||
int ivar = IsName(getstr(tok2, 2)) ? 2 : 3;
|
||||
|
@ -501,11 +359,11 @@ static void CheckBufferOverrun_StructVariable()
|
|||
continue;
|
||||
|
||||
// Declare variable: Fred fred1;
|
||||
if ( match( tok3->next, "var ;" ) )
|
||||
if ( Match( tok3->next, "%var% ;" ) )
|
||||
varname[0] = getstr(tok3, 1);
|
||||
|
||||
// Declare pointer: Fred *fred1
|
||||
else if ( match(tok3->next, "* var") && tok3->next->next->next && strchr(",);=", tok3->next->next->next->str[0]) )
|
||||
else if ( Match(tok3->next, "* %var%") && tok3->next->next->next && strchr(",);=", tok3->next->next->next->str[0]) )
|
||||
varname[0] = getstr(tok3, 2);
|
||||
|
||||
else
|
||||
|
@ -524,11 +382,11 @@ static void CheckBufferOverrun_StructVariable()
|
|||
}
|
||||
|
||||
// End of function declaration..
|
||||
if ( match(tok3, ") ;") )
|
||||
if ( Match(tok3, ") ;") )
|
||||
break;
|
||||
|
||||
// Function implementation..
|
||||
if ( match(tok3, ") {") )
|
||||
if ( Match(tok3, ") {") )
|
||||
{
|
||||
CheckTok = gettok(tok3, 2);
|
||||
break;
|
||||
|
@ -552,7 +410,6 @@ static void CheckBufferOverrun_StructVariable()
|
|||
|
||||
void CheckBufferOverrun()
|
||||
{
|
||||
FillFunctionList();
|
||||
CheckBufferOverrun_LocalVariable();
|
||||
CheckBufferOverrun_StructVariable();
|
||||
}
|
||||
|
@ -573,14 +430,14 @@ void WarningDangerousFunctions()
|
|||
{
|
||||
for (const TOKEN *tok = tokens; tok; tok = tok->next)
|
||||
{
|
||||
if (match(tok, "gets ("))
|
||||
if (Match(tok, "gets ("))
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << FileLine(tok) << ": Found 'gets'. You should use 'fgets' instead";
|
||||
ReportErr(ostr.str());
|
||||
}
|
||||
|
||||
else if (match(tok, "scanf (") && strcmp(getstr(tok,2),"\"%s\"") == 0)
|
||||
else if (Match(tok, "scanf (") && strcmp(getstr(tok,2),"\"%s\"") == 0)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << FileLine(tok) << ": Found 'scanf'. You should use 'fgets' instead";
|
||||
|
|
|
@ -55,7 +55,7 @@ static struct VAR *ClassChecking_GetVarList(const char classname[])
|
|||
const char *varname = 0;
|
||||
|
||||
// Is it a variable declaration?
|
||||
if ( match(next,"var var ;") )
|
||||
if ( Match(next,"%type% %var% ;") )
|
||||
{
|
||||
const char *types[] = {"bool", "char", "int", "short", "long", "float", "double", 0};
|
||||
for ( int type = 0; types[type]; type++ )
|
||||
|
@ -69,7 +69,7 @@ static struct VAR *ClassChecking_GetVarList(const char classname[])
|
|||
}
|
||||
|
||||
// Pointer?
|
||||
else if ( match(next, "var * var ;") )
|
||||
else if ( Match(next, "%type% * %var% ;") )
|
||||
{
|
||||
varname = getstr(next, 2);
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ static const TOKEN * FindClassFunction( const TOKEN *_tokens, const char classna
|
|||
else if ( indentlevel == 1 )
|
||||
{
|
||||
// Member function is implemented in the class declaration..
|
||||
if ( match( _tokens, "var (" ) && strcmp(_tokens->str,funcname) == 0 )
|
||||
if ( Match( _tokens, "%var% (" ) && strcmp(_tokens->str,funcname) == 0 )
|
||||
{
|
||||
const TOKEN *tok2 = _tokens;
|
||||
while ( tok2 && tok2->str[0] != '{' && tok2->str[0] != ';' )
|
||||
|
@ -114,13 +114,15 @@ static const TOKEN * FindClassFunction( const TOKEN *_tokens, const char classna
|
|||
}
|
||||
}
|
||||
|
||||
else if ( match(_tokens, "class var {") && strcmp(getstr(_tokens,1),classname)==0 )
|
||||
// Todo: Match the classname directly instead
|
||||
else if ( Match(_tokens, "class %var% {") && strcmp(getstr(_tokens,1),classname)==0 )
|
||||
{
|
||||
indentlevel = 1;
|
||||
_tokens = gettok( _tokens, 2 );
|
||||
}
|
||||
|
||||
else if ( match(_tokens, "var :: var (") &&
|
||||
// Todo: Match the classname and funcname directly instead
|
||||
else if ( Match(_tokens, "%var% :: %var% (") &&
|
||||
strcmp(_tokens->str,classname) == 0 &&
|
||||
strcmp(getstr(_tokens,2),funcname) == 0 )
|
||||
{
|
||||
|
@ -161,7 +163,7 @@ static void ClassChecking_VarList_Initialize(const TOKEN *ftok, struct VAR *varl
|
|||
// clKalle::clKalle() : var(value) { }
|
||||
if (indentlevel==0)
|
||||
{
|
||||
if (Assign && match(ftok, "var ("))
|
||||
if (Assign && Match(ftok, "%var% ("))
|
||||
{
|
||||
InitVar( varlist, ftok->str );
|
||||
}
|
||||
|
@ -188,14 +190,14 @@ static void ClassChecking_VarList_Initialize(const TOKEN *ftok, struct VAR *varl
|
|||
ftok = ftok->next;
|
||||
|
||||
// Clearing all variables..
|
||||
if (match(ftok,"memset ( this ,"))
|
||||
if (Match(ftok,"memset ( this ,"))
|
||||
{
|
||||
for (struct VAR *var = varlist; var; var = var->next)
|
||||
var->init = true;
|
||||
}
|
||||
|
||||
// Calling member function?
|
||||
else if (match(ftok, "var ("))
|
||||
else if (Match(ftok, "%var% ("))
|
||||
{
|
||||
unsigned int i = 0;
|
||||
const TOKEN *ftok2 = FindClassFunction( tokens, classname, ftok->str, i );
|
||||
|
@ -203,13 +205,13 @@ static void ClassChecking_VarList_Initialize(const TOKEN *ftok, struct VAR *varl
|
|||
}
|
||||
|
||||
// Assignment of member variable?
|
||||
else if (match(ftok, "var ="))
|
||||
else if (Match(ftok, "%var% ="))
|
||||
{
|
||||
InitVar( varlist, ftok->str );
|
||||
}
|
||||
|
||||
// The functions 'clear' and 'Clear' are supposed to initialize variable.
|
||||
if (match(ftok,"var . clear (") || match(ftok,"var . Clear ("))
|
||||
if (Match(ftok,"%var% . clear (") || Match(ftok,"%var% . Clear ("))
|
||||
{
|
||||
InitVar( varlist, ftok->str );
|
||||
}
|
||||
|
@ -347,7 +349,7 @@ void CheckUnusedPrivateFunctions()
|
|||
unsigned int indent_level = 0;
|
||||
for (const TOKEN *tok = tok1; tok; tok = tok->next)
|
||||
{
|
||||
if (match(tok,"friend class"))
|
||||
if (Match(tok,"friend %var%"))
|
||||
{
|
||||
// Todo: Handle friend classes
|
||||
FuncList.clear();
|
||||
|
@ -464,13 +466,13 @@ void CheckMemset()
|
|||
continue;
|
||||
|
||||
const char *type = NULL;
|
||||
if (match(tok, "memset ( var , num , sizeof ( type ) )"))
|
||||
if (Match(tok, "memset ( %var% , %num% , sizeof ( %type% ) )"))
|
||||
type = getstr(tok, 8);
|
||||
else if (match(tok, "memset ( & var , num , sizeof ( type ) )"))
|
||||
else if (Match(tok, "memset ( & %var% , %num% , sizeof ( %type% ) )"))
|
||||
type = getstr(tok, 9);
|
||||
else if (match(tok, "memset ( var , num , sizeof ( struct type ) )"))
|
||||
else if (Match(tok, "memset ( %var% , %num% , sizeof ( struct %type% ) )"))
|
||||
type = getstr(tok, 9);
|
||||
else if (match(tok, "memset ( & var , num , sizeof ( struct type ) )"))
|
||||
else if (Match(tok, "memset ( & %var% , %num% , sizeof ( struct %type% ) )"))
|
||||
type = getstr(tok, 10);
|
||||
|
||||
// No type defined => The tokens didn't match
|
||||
|
@ -496,7 +498,7 @@ void CheckMemset()
|
|||
if (tstruct->str[0] == '}')
|
||||
break;
|
||||
|
||||
if (match(tstruct, "std :: type var ;"))
|
||||
if (Match(tstruct, "std :: %type% %var% ;"))
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << FileLine(tok) << ": Using 'memset' on struct that contains a 'std::" << getstr(tstruct,2) << "'";
|
||||
|
|
|
@ -23,7 +23,7 @@ void WarningHeaderWithImplementation()
|
|||
if (tok->FileIndex == 0)
|
||||
continue;
|
||||
|
||||
if (match(tok, ") {"))
|
||||
if (Match(tok, ") {"))
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << FileLine(tok) << ": Found implementation in header";
|
||||
|
@ -102,21 +102,21 @@ void WarningIncludeHeader()
|
|||
|
||||
// Class or namespace declaration..
|
||||
// --------------------------------------
|
||||
if (match(tok1,"class var {") || match(tok1,"class var :") || match(tok1,"namespace var {"))
|
||||
if (Match(tok1,"class %var% {") || Match(tok1,"class %var% :") || Match(tok1,"namespace %var% {"))
|
||||
classlist.push_back(getstr(tok1, 1));
|
||||
|
||||
// Variable declaration..
|
||||
// --------------------------------------
|
||||
else if (match(tok1, "type var ;") || match(tok1, "type var ["))
|
||||
else if (Match(tok1, "%type% %var% ;") || Match(tok1, "%type% %var% ["))
|
||||
namelist.push_back(getstr(tok1, 1));
|
||||
|
||||
else if (match(tok1, "type * var ;") || match(tok1, "type * var ["))
|
||||
else if (Match(tok1, "%type% * %var% ;") || Match(tok1, "%type% * %var% ["))
|
||||
namelist.push_back(getstr(tok1, 2));
|
||||
|
||||
else if (match(tok1, "const type var =") || match(tok1, "const type var ["))
|
||||
else if (Match(tok1, "const %type% %var% =") || Match(tok1, "const %type% %var% ["))
|
||||
namelist.push_back(getstr(tok1, 2));
|
||||
|
||||
else if (match(tok1, "const type * var =") || match(tok1, "const type * var ["))
|
||||
else if (Match(tok1, "const %type% * %var% =") || Match(tok1, "const %type% * %var% ["))
|
||||
namelist.push_back(getstr(tok1, 3));
|
||||
|
||||
// enum..
|
||||
|
@ -134,16 +134,16 @@ void WarningIncludeHeader()
|
|||
|
||||
// function..
|
||||
// --------------------------------------
|
||||
else if (match(tok1,"type var ("))
|
||||
else if (Match(tok1,"%type% %var% ("))
|
||||
namelist.push_back(getstr(tok1, 1));
|
||||
|
||||
else if (match(tok1,"type * var ("))
|
||||
else if (Match(tok1,"%type% * %var% ("))
|
||||
namelist.push_back(getstr(tok1, 2));
|
||||
|
||||
else if (match(tok1,"const type var ("))
|
||||
else if (Match(tok1,"const %type% %var% ("))
|
||||
namelist.push_back(getstr(tok1, 2));
|
||||
|
||||
else if (match(tok1,"const type * var ("))
|
||||
else if (Match(tok1,"const %type% * %var% ("))
|
||||
namelist.push_back(getstr(tok1, 3));
|
||||
|
||||
// typedef..
|
||||
|
@ -166,7 +166,7 @@ void WarningIncludeHeader()
|
|||
if ( tok1->str[0] == ';' )
|
||||
break;
|
||||
|
||||
if ( match(tok1, "var ;") )
|
||||
if ( Match(tok1, "%var% ;") )
|
||||
namelist.push_back(tok1->str);
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ void WarningIncludeHeader()
|
|||
if (tok1->FileIndex != includetok->FileIndex)
|
||||
continue;
|
||||
|
||||
if ( match(tok1, ": var {") || match(tok1, ": type var {") )
|
||||
if ( Match(tok1, ": %var% {") || Match(tok1, ": %type% %var% {") )
|
||||
{
|
||||
std::string classname = getstr(tok1, (strcmp(getstr(tok1,2),"{")) ? 2 : 1);
|
||||
if (std::find(classlist.begin(),classlist.end(),classname)!=classlist.end())
|
||||
|
|
|
@ -364,21 +364,21 @@ static void _ClassMembers_CheckVar(const char *classname, const char *varname)
|
|||
{
|
||||
bool err = false;
|
||||
|
||||
if (match(tok, "delete var ;") &&
|
||||
if (Match(tok, "delete %var% ;") &&
|
||||
strcmp(getstr(tok,1),varname)==0)
|
||||
{
|
||||
err |= ( Alloc != No && Alloc != New );
|
||||
Dealloc = New;
|
||||
}
|
||||
|
||||
else if (match(tok, "delete [ ] var ;") &&
|
||||
else if (Match(tok, "delete [ ] %var% ;") &&
|
||||
strcmp(getstr(tok,3),varname)==0)
|
||||
{
|
||||
err |= ( Alloc != No && Alloc != NewA );
|
||||
Dealloc = NewA;
|
||||
}
|
||||
|
||||
else if (match(tok, "free ( var )") &&
|
||||
else if (Match(tok, "free ( %var% )") &&
|
||||
strcmp(getstr(tok,2),varname)==0)
|
||||
{
|
||||
err |= ( Alloc != No && Alloc != Malloc );
|
||||
|
@ -406,8 +406,8 @@ static void _ClassMembers_CheckVar(const char *classname, const char *varname)
|
|||
|
||||
if ( strcmp(getstr(tok,2), "new") == 0 )
|
||||
{
|
||||
if ( match(tok, "var = new type ;") ||
|
||||
match(tok, "var = new type (") )
|
||||
if ( Match(tok, "%var% = new %type% ;") ||
|
||||
Match(tok, "%var% = new %type% (") )
|
||||
{
|
||||
if ( ! ShowAll && ! IsStandardType(getstr(tok,3)) )
|
||||
continue;
|
||||
|
@ -415,7 +415,7 @@ static void _ClassMembers_CheckVar(const char *classname, const char *varname)
|
|||
Alloc = New;
|
||||
}
|
||||
|
||||
else if ( match(tok, "var = new type [") )
|
||||
else if ( Match(tok, "%var% = new %type% [") )
|
||||
{
|
||||
if ( ! ShowAll && ! IsStandardType(getstr(tok,3)) )
|
||||
continue;
|
||||
|
@ -424,8 +424,8 @@ static void _ClassMembers_CheckVar(const char *classname, const char *varname)
|
|||
}
|
||||
}
|
||||
|
||||
else if ( match(tok, "var = strdup (") ||
|
||||
match(tok, "var = ( type * ) malloc ("))
|
||||
else if ( Match(tok, "%var% = strdup (") ||
|
||||
Match(tok, "%var% = ( %type% * ) malloc ("))
|
||||
{
|
||||
if ( ! ShowAll &&
|
||||
tok->next->next->str[0] == '(' &&
|
||||
|
@ -461,7 +461,7 @@ static void _ClassMembers()
|
|||
{
|
||||
// Is this a class declaration?
|
||||
// -------------------------------------
|
||||
if ( ! match(ClassDecl, "class var {") )
|
||||
if ( ! Match(ClassDecl, "class %var% {") )
|
||||
continue;
|
||||
|
||||
const char *classname = getstr(ClassDecl, 1);
|
||||
|
@ -482,7 +482,7 @@ static void _ClassMembers()
|
|||
|
||||
else if (indentlevel == 1)
|
||||
{
|
||||
if ( match(ClassVar, "type * var ;") )
|
||||
if ( Match(ClassVar, "%type% * %var% ;") )
|
||||
{
|
||||
const char *varname = getstr(ClassVar, 2);
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ void WarningOldStylePointerCast()
|
|||
for (const TOKEN *tok = tokens; tok; tok = tok->next)
|
||||
{
|
||||
// Old style pointer casting..
|
||||
if (!match(tok, "( type * ) var"))
|
||||
if (!Match(tok, "( %type% * ) %var%"))
|
||||
continue;
|
||||
|
||||
// Is "type" a class?
|
||||
|
@ -46,10 +46,10 @@ void WarningIsDigit()
|
|||
for (const TOKEN *tok = tokens; tok; tok = tok->next)
|
||||
{
|
||||
bool err = false;
|
||||
err |= match(tok, "var >= '0' && var <= '9'");
|
||||
err |= match(tok, "* var >= '0' && * var <= '9'");
|
||||
err |= match(tok, "( var >= '0' ) && ( var <= '9' )");
|
||||
err |= match(tok, "( * var >= '0' ) && ( * var <= '9' )");
|
||||
err |= Match(tok, "%var% >= '0' && %var% <= '9'");
|
||||
err |= Match(tok, "* %var% >= '0' && * %var% <= '9'");
|
||||
err |= Match(tok, "( %var% >= '0' ) && ( %var% <= '9' )");
|
||||
err |= Match(tok, "( * %var% >= '0' ) && ( * %var% <= '9' )");
|
||||
if (err)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
|
@ -75,14 +75,14 @@ void WarningIsAlpha()
|
|||
if ( tok->str[0] != '(' )
|
||||
continue;
|
||||
|
||||
err |= match(tok, "( var >= 'A' && var <= 'Z' ) || ( var >= 'a' && var <= 'z' )");
|
||||
err |= match(tok, "( var >= 'a' && var <= 'z' ) || ( var >= 'A' && var <= 'Z' )");
|
||||
err |= match(tok, "( * var >= 'A' && * var <= 'Z' ) || ( * var >= 'a' && * var <= 'z' )");
|
||||
err |= match(tok, "( * var >= 'a' && * var <= 'z' ) || ( * var >= 'A' && * var <= 'Z' )");
|
||||
err |= match(tok, "( ( var >= 'A' ) && ( var <= 'Z' ) ) || ( ( var >= 'a' ) && ( var <= 'z' ) )");
|
||||
err |= match(tok, "( ( var >= 'a' ) && ( var <= 'z' ) ) || ( ( var >= 'A' ) && ( var <= 'Z' ) )");
|
||||
err |= match(tok, "( ( * var >= 'A' ) && ( * var <= 'Z' ) ) || ( ( * var >= 'a' ) && ( * var <= 'z' ) )");
|
||||
err |= match(tok, "( ( * var >= 'a' ) && ( * var <= 'z' ) ) || ( ( * var >= 'A' ) && ( * var <= 'Z' ) )");
|
||||
err |= Match(tok, "( %var% >= 'A' && %var% <= 'Z' ) || ( %var% >= 'a' && %var% <= 'z' )");
|
||||
err |= Match(tok, "( %var% >= 'a' && %var% <= 'z' ) || ( %var% >= 'A' && %var% <= 'Z' )");
|
||||
err |= Match(tok, "( * %var% >= 'A' && * %var% <= 'Z' ) || ( * %var% >= 'a' && * %var% <= 'z' )");
|
||||
err |= Match(tok, "( * %var% >= 'a' && * %var% <= 'z' ) || ( * %var% >= 'A' && * %var% <= 'Z' )");
|
||||
err |= Match(tok, "( ( %var% >= 'A' ) && ( %var% <= 'Z' ) ) || ( ( %var% >= 'a' ) && ( %var% <= 'z' ) )");
|
||||
err |= Match(tok, "( ( %var% >= 'a' ) && ( %var% <= 'z' ) ) || ( ( %var% >= 'A' ) && ( %var% <= 'Z' ) )");
|
||||
err |= Match(tok, "( ( * %var% >= 'A' ) && ( * %var% <= 'Z' ) ) || ( ( * var >= 'a' ) && ( * %var% <= 'z' ) )");
|
||||
err |= Match(tok, "( ( * %var% >= 'a' ) && ( * %var% <= 'z' ) ) || ( ( * var >= 'A' ) && ( * %var% <= 'Z' ) )");
|
||||
if (err)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
|
@ -110,12 +110,12 @@ void WarningRedundantCode()
|
|||
const char *varname1 = NULL;
|
||||
const TOKEN *tok2 = NULL;
|
||||
|
||||
if (match(tok,"if ( var )"))
|
||||
if (Match(tok,"if ( %var% )"))
|
||||
{
|
||||
varname1 = getstr(tok, 2);
|
||||
tok2 = gettok(tok, 4);
|
||||
}
|
||||
else if (match(tok,"if ( var != NULL )"))
|
||||
else if (Match(tok,"if ( %var% != NULL )"))
|
||||
{
|
||||
varname1 = getstr(tok, 2);
|
||||
tok2 = gettok(tok, 6);
|
||||
|
@ -125,17 +125,17 @@ void WarningRedundantCode()
|
|||
continue;
|
||||
|
||||
bool err = false;
|
||||
if (match(tok2,"delete var ;"))
|
||||
if (Match(tok2,"delete %var% ;"))
|
||||
err = (strcmp(getstr(tok2,1),varname1)==0);
|
||||
else if (match(tok2,"{ delete var ; }"))
|
||||
else if (Match(tok2,"{ delete %var% ; }"))
|
||||
err = (strcmp(getstr(tok2,2),varname1)==0);
|
||||
else if (match(tok2,"delete [ ] var ;"))
|
||||
else if (Match(tok2,"delete [ ] %var% ;"))
|
||||
err = (strcmp(getstr(tok2,1),varname1)==0);
|
||||
else if (match(tok2,"{ delete [ ] var ; }"))
|
||||
else if (Match(tok2,"{ delete [ ] %var% ; }"))
|
||||
err = (strcmp(getstr(tok2,2),varname1)==0);
|
||||
else if (match(tok2,"free ( var )"))
|
||||
else if (Match(tok2,"free ( %var% )"))
|
||||
err = (strcmp(getstr(tok2,2),varname1)==0);
|
||||
else if (match(tok2,"{ free ( var ) ; }"))
|
||||
else if (Match(tok2,"{ free ( %var% ) ; }"))
|
||||
err = (strcmp(getstr(tok2,3),varname1)==0);
|
||||
|
||||
if (err)
|
||||
|
@ -147,7 +147,7 @@ void WarningRedundantCode()
|
|||
}
|
||||
|
||||
|
||||
// TODO
|
||||
// TODO: Redundant condition
|
||||
// if (haystack.find(needle) != haystack.end())
|
||||
// haystack.remove(needle);
|
||||
|
||||
|
@ -203,7 +203,7 @@ void WarningIf()
|
|||
if ( ! tok )
|
||||
break;
|
||||
|
||||
if (!match(tok,"var = var ; if ( var"))
|
||||
if (!Match(tok,"%var% = %var% ; if ( %var%"))
|
||||
continue;
|
||||
|
||||
if ( strcmp(getstr(tok, 9), ")") != 0 )
|
||||
|
@ -273,7 +273,7 @@ void InvalidFunctionUsage()
|
|||
param++;
|
||||
if (param==3)
|
||||
{
|
||||
if ( match(tok2, ", num )") )
|
||||
if ( Match(tok2, ", %num% )") )
|
||||
{
|
||||
int radix = atoi(tok2->next->str);
|
||||
if (!(radix==0 || (radix>=2 && radix<=36)))
|
||||
|
@ -320,10 +320,10 @@ static const TOKEN *GetFunction( const TOKEN *content )
|
|||
if (tok->str[0] == ';')
|
||||
func = NULL;
|
||||
|
||||
else if ( match(tok, "var :: var (") )
|
||||
else if ( Match(tok, "%var% :: %var% (") )
|
||||
func = tok->next->next;
|
||||
|
||||
else if ( match(tok, "type var (") )
|
||||
else if ( Match(tok, "%type% %var% (") )
|
||||
func = tok->next;
|
||||
}
|
||||
|
||||
|
@ -409,7 +409,9 @@ void CheckIfAssignment()
|
|||
{
|
||||
for (const TOKEN *tok = tokens; tok; tok = tok->next)
|
||||
{
|
||||
if (match(tok,"if ( a = b )"))
|
||||
if (Match(tok, "if ( %var% = %num% )") ||
|
||||
Match(tok, "if ( %var% = %str% )") ||
|
||||
Match(tok, "if ( %var% = %var% )") )
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << FileLine(tok) << ": Possible bug. Should it be '==' instead of '='?";
|
||||
|
@ -596,7 +598,7 @@ void CheckVariableScope()
|
|||
if ( indentlevel == 0 )
|
||||
func = false;
|
||||
}
|
||||
if ( indentlevel == 0 && match(tok, ") {") )
|
||||
if ( indentlevel == 0 && Match(tok, ") {") )
|
||||
{
|
||||
func = true;
|
||||
}
|
||||
|
@ -611,8 +613,8 @@ void CheckVariableScope()
|
|||
continue;
|
||||
|
||||
// Variable declaration?
|
||||
if (match(tok1, "var var ;") ||
|
||||
match(tok1, "var var =") )
|
||||
if (Match(tok1, "%var% %var% ;") ||
|
||||
Match(tok1, "%var% %var% =") )
|
||||
{
|
||||
CheckVariableScope_LookupVar( tok1, getstr(tok1, 1) );
|
||||
}
|
||||
|
|
134
CommonCheck.cpp
134
CommonCheck.cpp
|
@ -9,6 +9,7 @@
|
|||
bool HasErrors;
|
||||
bool OnlyReportUniqueErrors;
|
||||
std::ostringstream errout;
|
||||
std::list<const TOKEN *> FunctionList;
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
std::string FileLine(const TOKEN *tok)
|
||||
|
@ -58,10 +59,10 @@ bool IsStandardType(const char str[])
|
|||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const TOKEN *FindFunction( const TOKEN *tok, const char funcname[] )
|
||||
void FillFunctionList()
|
||||
{
|
||||
int indentlevel = 0;
|
||||
for ( ; tok; tok = tok->next )
|
||||
for ( const TOKEN *tok = tokens; tok; tok = tok->next )
|
||||
{
|
||||
if ( tok->str[0] == '{' )
|
||||
indentlevel++;
|
||||
|
@ -69,32 +70,135 @@ const TOKEN *FindFunction( const TOKEN *tok, const char funcname[] )
|
|||
else if ( tok->str[0] == '}' )
|
||||
indentlevel--;
|
||||
|
||||
else if (indentlevel==0 && match(tok,"var ("))
|
||||
else if (indentlevel==0 && Match(tok, "%var% ("))
|
||||
{
|
||||
// Check if this is the first token of a function implementation..
|
||||
bool haspar = false;
|
||||
bool foundname = false;
|
||||
for ( const TOKEN *tok2 = tok; tok2; tok2 = tok2->next )
|
||||
{
|
||||
haspar |= bool(tok2->str[0] == '(');
|
||||
if ( ! haspar && match(tok2,"var (") )
|
||||
{
|
||||
if ( funcname && strcmp(funcname, tok2->str) != 0 )
|
||||
break;
|
||||
foundname = true;
|
||||
}
|
||||
if ( tok2->str[0] == ';' )
|
||||
{
|
||||
tok = tok2;
|
||||
break;
|
||||
}
|
||||
if ( tok2->str[0] == '{' )
|
||||
|
||||
else if ( tok2->str[0] == '{' )
|
||||
{
|
||||
break;
|
||||
if ( foundname && haspar && match(tok2, ") {") )
|
||||
return tok;
|
||||
}
|
||||
|
||||
else if ( tok2->str[0] == ')' )
|
||||
{
|
||||
if ( Match(tok2, ") {") )
|
||||
{
|
||||
FunctionList.push_back( tok );
|
||||
tok = tok2;
|
||||
}
|
||||
else
|
||||
{
|
||||
tok = tok2;
|
||||
while (tok->next && !strchr(";{", tok->next->str[0]))
|
||||
tok = tok->next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const TOKEN *GetFunctionTokenByName( const char funcname[] )
|
||||
{
|
||||
std::list<const TOKEN *>::const_iterator it;
|
||||
for ( it = FunctionList.begin(); it != FunctionList.end(); it++ )
|
||||
{
|
||||
if ( strcmp( (*it)->str, funcname ) == 0 )
|
||||
{
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool Match(const TOKEN *tok, const char pattern[], const char *varname[])
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (strcmp(tok->str, varname[0]) != 0)
|
||||
return false;
|
||||
|
||||
for ( int i = 1; varname[i]; i++ )
|
||||
{
|
||||
if ( ! gettok(tok, 2) )
|
||||
return false;
|
||||
|
||||
if ( strcmp(getstr(tok, 1), ".") )
|
||||
return false;
|
||||
|
||||
if ( strcmp(getstr(tok, 2), varname[i]) )
|
||||
return false;
|
||||
|
||||
tok = 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -3,11 +3,14 @@
|
|||
#define CommonCheckH
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
struct TOKEN;
|
||||
|
||||
extern std::list<const TOKEN *> FunctionList;
|
||||
|
||||
std::string FileLine(const TOKEN *tok);
|
||||
|
||||
extern bool OnlyReportUniqueErrors;
|
||||
|
@ -21,7 +24,12 @@ bool IsNumber(const char str[]);
|
|||
|
||||
bool IsStandardType(const char str[]);
|
||||
|
||||
const TOKEN *FindFunction( const TOKEN *tok, const char funcname[] );
|
||||
void FillFunctionList();
|
||||
const TOKEN *GetFunctionTokenByName( const char funcname[] );
|
||||
|
||||
|
||||
bool Match(const TOKEN *tok, const char pattern[], const char *varname[]=0);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
|
|
|
@ -213,32 +213,32 @@ void CreateStatementList()
|
|||
TOKEN *rs = eq->next;
|
||||
|
||||
bool ismalloc = false;
|
||||
if (match(rs, "strdup ("))
|
||||
if (Match(rs, "strdup ("))
|
||||
{
|
||||
ismalloc = true;
|
||||
}
|
||||
else if (rs->str[0]=='(' && IsName(getstr(rs,1)))
|
||||
{
|
||||
ismalloc |= match(rs, "( type * ) malloc (");
|
||||
ismalloc |= match(rs, "( type * * ) malloc (");
|
||||
ismalloc |= match(rs, "( type type * ) malloc (");
|
||||
ismalloc |= match(rs, "( type type * * ) malloc (");
|
||||
ismalloc |= match(rs, "( type * ) kmalloc (");
|
||||
ismalloc |= match(rs, "( type * * ) kmalloc (");
|
||||
ismalloc |= match(rs, "( type type * ) kmalloc (");
|
||||
ismalloc |= match(rs, "( type type * * ) kmalloc (");
|
||||
ismalloc |= Match(rs, "( %type% * ) malloc (");
|
||||
ismalloc |= Match(rs, "( %type% * * ) malloc (");
|
||||
ismalloc |= Match(rs, "( %type% %type% * ) malloc (");
|
||||
ismalloc |= Match(rs, "( %type% %type% * * ) malloc (");
|
||||
ismalloc |= Match(rs, "( %type% * ) kmalloc (");
|
||||
ismalloc |= Match(rs, "( %type% * * ) kmalloc (");
|
||||
ismalloc |= Match(rs, "( %type% %type% * ) kmalloc (");
|
||||
ismalloc |= Match(rs, "( %type% %type% * * ) kmalloc (");
|
||||
}
|
||||
|
||||
if ( ismalloc )
|
||||
AppendStatement(STATEMENT::MALLOC, tok2, varname);
|
||||
|
||||
else if ( match(rs,"new type ;") )
|
||||
else if ( Match(rs,"new %type% ;") )
|
||||
AppendStatement(STATEMENT::NEW, tok2, varname);
|
||||
|
||||
else if ( match(rs, "new type (") )
|
||||
else if ( Match(rs, "new %type% (") )
|
||||
AppendStatement(STATEMENT::NEW, tok2, varname);
|
||||
|
||||
else if ( match(rs, "new type [") )
|
||||
else if ( Match(rs, "new %type% [") )
|
||||
AppendStatement(STATEMENT::NEWARRAY, tok2, varname);
|
||||
|
||||
else
|
||||
|
@ -254,16 +254,16 @@ void CreateStatementList()
|
|||
if (strchr("{};", tok2->str[0]))
|
||||
break;
|
||||
|
||||
if (match(tok2, "free ( var ) ;"))
|
||||
if (Match(tok2, "free ( %var% ) ;"))
|
||||
AppendStatement(STATEMENT::FREE, tok2, getstr(tok2, 2));
|
||||
|
||||
if (match(tok2, "kfree ( var ) ;"))
|
||||
if (Match(tok2, "kfree ( %var% ) ;"))
|
||||
AppendStatement(STATEMENT::FREE, tok2, getstr(tok2, 2));
|
||||
|
||||
if (match(tok2, "delete var ;"))
|
||||
if (Match(tok2, "delete %var% ;"))
|
||||
AppendStatement(STATEMENT::DELETE, tok2, getstr(tok2,1));
|
||||
|
||||
if (match(tok2, "delete [ ] var ;"))
|
||||
if (Match(tok2, "delete [ ] %var% ;"))
|
||||
AppendStatement(STATEMENT::DELETEARRAY, tok2, getstr(tok2,3));
|
||||
}
|
||||
|
||||
|
@ -275,7 +275,7 @@ void CreateStatementList()
|
|||
if (parlevel==0 && strchr("{};", tok2->str[0]))
|
||||
break;
|
||||
|
||||
if (match(tok2,"free ( var )"))
|
||||
if (Match(tok2,"free ( %var% )"))
|
||||
break;
|
||||
|
||||
if (tok2->str[0] == '(')
|
||||
|
|
1
main.cpp
1
main.cpp
|
@ -178,6 +178,7 @@ static void CppCheck(const char FileName[])
|
|||
Files.clear();
|
||||
Tokenize(FileName);
|
||||
|
||||
FunctionList.clear();
|
||||
|
||||
// Check that the memsets are valid.
|
||||
// The 'memset' function can do dangerous things if used wrong.
|
||||
|
|
|
@ -86,6 +86,9 @@ static void check(void (chk)(),
|
|||
if ( chk != CheckUnsignedDivision )
|
||||
SimplifyTokenList();
|
||||
|
||||
FunctionList.clear();
|
||||
FillFunctionList();
|
||||
|
||||
// Check for buffer overruns..
|
||||
errout.str("");
|
||||
chk();
|
||||
|
|
80
tokenize.cpp
80
tokenize.cpp
|
@ -576,7 +576,7 @@ void SimplifyTokenList()
|
|||
// Replace constants..
|
||||
for (TOKEN *tok = tokens; tok; tok = tok->next)
|
||||
{
|
||||
if (match(tok,"const type var = num ;"))
|
||||
if (Match(tok,"const %type% %var% = %num% ;"))
|
||||
{
|
||||
const char *sym = getstr(tok,2);
|
||||
const char *num = getstr(tok,4);
|
||||
|
@ -705,12 +705,12 @@ void SimplifyTokenList()
|
|||
TypeSize["double"] = sizeof(double);
|
||||
for (TOKEN *tok = tokens; tok; tok = tok->next)
|
||||
{
|
||||
if (match(tok,"class type"))
|
||||
if (Match(tok,"class %var%"))
|
||||
{
|
||||
TypeSize[getstr(tok,1)] = 11;
|
||||
}
|
||||
|
||||
else if (match(tok, "struct type"))
|
||||
else if (Match(tok, "struct %var%"))
|
||||
{
|
||||
TypeSize[getstr(tok,1)] = 13;
|
||||
}
|
||||
|
@ -723,7 +723,7 @@ void SimplifyTokenList()
|
|||
if (strcmp(tok->str,"sizeof") != 0)
|
||||
continue;
|
||||
|
||||
if (match(tok, "sizeof ( type * )"))
|
||||
if (Match(tok, "sizeof ( %type% * )"))
|
||||
{
|
||||
free(tok->str);
|
||||
char str[10];
|
||||
|
@ -737,7 +737,7 @@ void SimplifyTokenList()
|
|||
}
|
||||
}
|
||||
|
||||
else if (match(tok, "sizeof ( type )"))
|
||||
else if (Match(tok, "sizeof ( %type% )"))
|
||||
{
|
||||
const char *type = getstr(tok, 2);
|
||||
int size = SizeOfType(type);
|
||||
|
@ -759,7 +759,7 @@ void SimplifyTokenList()
|
|||
for (TOKEN *tok = tokens; tok; tok = tok->next)
|
||||
{
|
||||
// type array [ num ] ;
|
||||
if ( ! match(tok, "type var [ num ] ;") )
|
||||
if ( ! Match(tok, "%type% %var% [ %num% ] ;") )
|
||||
continue;
|
||||
|
||||
int size = SizeOfType(tok->str);
|
||||
|
@ -785,7 +785,8 @@ void SimplifyTokenList()
|
|||
break;
|
||||
}
|
||||
|
||||
else if (match(tok2, "sizeof ( var )"))
|
||||
// Todo: Match varname directly
|
||||
else if (Match(tok2, "sizeof ( %var% )"))
|
||||
{
|
||||
if (strcmp(getstr(tok2,2), varname) == 0)
|
||||
{
|
||||
|
@ -815,7 +816,7 @@ void SimplifyTokenList()
|
|||
|
||||
for (TOKEN *tok = tokens; tok; tok = tok->next)
|
||||
{
|
||||
if (match(tok->next, "* 1") || match(tok->next, "1 *"))
|
||||
if (Match(tok->next, "* 1") || Match(tok->next, "1 *"))
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
DeleteNextToken(tok);
|
||||
|
@ -869,7 +870,7 @@ void SimplifyTokenList()
|
|||
if ( ! next )
|
||||
break;
|
||||
|
||||
if (match(next, "* ( var + num )"))
|
||||
if (Match(next, "* ( %var% + %num% )"))
|
||||
{
|
||||
const char *str[4] = {"var","[","num","]"};
|
||||
str[0] = getstr(tok,3);
|
||||
|
@ -904,56 +905,56 @@ void SimplifyTokenList()
|
|||
TOKEN *tok2 = NULL;
|
||||
unsigned int typelen = 0;
|
||||
|
||||
if ( match(type0, "type var ,") )
|
||||
if ( Match(type0, "%type% %var% ,") )
|
||||
{
|
||||
tok2 = _gettok(type0, 2); // The ',' token
|
||||
typelen = 1;
|
||||
}
|
||||
|
||||
else if ( match(type0, "type * var ,") )
|
||||
else if ( Match(type0, "%type% * %var% ,") )
|
||||
{
|
||||
tok2 = _gettok(type0, 3); // The ',' token
|
||||
typelen = 1;
|
||||
}
|
||||
|
||||
else if ( match(type0, "type var [ num ] ,") )
|
||||
else if ( Match(type0, "%type% %var% [ %num% ] ,") )
|
||||
{
|
||||
tok2 = _gettok(type0, 5); // The ',' token
|
||||
typelen = 1;
|
||||
}
|
||||
|
||||
else if ( match(type0, "type * var [ num ] ,") )
|
||||
else if ( Match(type0, "%type% * %var% [ %num% ] ,") )
|
||||
{
|
||||
tok2 = _gettok(type0, 6); // The ',' token
|
||||
typelen = 1;
|
||||
}
|
||||
|
||||
else if ( match(type0, "struct type var ,") )
|
||||
else if ( Match(type0, "struct %type% %var% ,") )
|
||||
{
|
||||
tok2 = _gettok(type0, 3);
|
||||
typelen = 2;
|
||||
}
|
||||
|
||||
else if ( match(type0, "struct type * var ,") )
|
||||
else if ( Match(type0, "struct %type% * %var% ,") )
|
||||
{
|
||||
tok2 = _gettok(type0, 4);
|
||||
typelen = 2;
|
||||
}
|
||||
|
||||
|
||||
else if ( match(type0, "type var =") )
|
||||
else if ( Match(type0, "%type% %var% =") )
|
||||
{
|
||||
tok2 = _gettok(type0, 2);
|
||||
typelen = 1;
|
||||
}
|
||||
|
||||
else if ( match(type0, "type * var =") )
|
||||
else if ( Match(type0, "%type% * %var% =") )
|
||||
{
|
||||
tok2 = _gettok(type0, 3);
|
||||
typelen = 1;
|
||||
}
|
||||
|
||||
else if ( match(type0, "struct type * var =") )
|
||||
else if ( Match(type0, "struct %type% * %var% =") )
|
||||
{
|
||||
tok2 = _gettok(type0, 4);
|
||||
typelen = 2;
|
||||
|
@ -1051,49 +1052,6 @@ const TOKEN *findtoken(const TOKEN *tok1, const char *tokenstr[])
|
|||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool match(const TOKEN *tok, const char pattern[])
|
||||
{
|
||||
if (!tok)
|
||||
return false;
|
||||
|
||||
const char *p = pattern;
|
||||
while (*p)
|
||||
{
|
||||
char str[50];
|
||||
char *s = str;
|
||||
while (*p==' ')
|
||||
p++;
|
||||
while (*p && *p!=' ')
|
||||
{
|
||||
*s = *p;
|
||||
s++;
|
||||
p++;
|
||||
}
|
||||
*s = 0;
|
||||
if (str[0] == 0)
|
||||
return true;
|
||||
|
||||
if (strcmp(str,"var")==0 || strcmp(str,"type")==0)
|
||||
{
|
||||
if (!IsName(tok->str))
|
||||
return false;
|
||||
}
|
||||
else if (strcmp(str,"num")==0)
|
||||
{
|
||||
if (!std::isdigit(tok->str[0]))
|
||||
return false;
|
||||
}
|
||||
else if (strcmp(str, tok->str) != 0)
|
||||
return false;
|
||||
|
||||
tok = tok->next;
|
||||
if (!tok)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const TOKEN *gettok(const TOKEN *tok, int index)
|
||||
{
|
||||
while (tok && index>0)
|
||||
|
|
|
@ -36,7 +36,6 @@ void DeallocateTokens();
|
|||
|
||||
// Helper functions for handling the tokens list..
|
||||
const TOKEN *findtoken(const TOKEN *tok1, const char *tokenstr[]);
|
||||
bool match(const TOKEN *tok, const char pattern[]);
|
||||
const TOKEN *gettok(const TOKEN *tok, int index);
|
||||
const char *getstr(const TOKEN *tok, int index);
|
||||
|
||||
|
|
Loading…
Reference in New Issue