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