Refactoring: Following new classes were created:

CheckBufferOverrunClass
CheckClass
CheckHeaders
CheckMemoryLeakClass
CheckOther
Preprocessor
This commit is contained in:
Reijo Tomperi 2008-11-11 06:42:09 +00:00
parent f752b0e375
commit f242c4fddd
23 changed files with 279 additions and 185 deletions

View File

@ -21,7 +21,6 @@
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#include "CheckBufferOverrun.h" #include "CheckBufferOverrun.h"
#include "tokenize.h"
#include "CommonCheck.h" #include "CommonCheck.h"
#include <algorithm> #include <algorithm>
@ -40,7 +39,7 @@ static std::list<const TOKEN *> CallStack;
// Modified version of 'ReportError' that also reports the callstack // Modified version of 'ReportError' that also reports the callstack
static void ReportError(const TOKEN *tok, const char errmsg[]) void CheckBufferOverrunClass::ReportError(const TOKEN *tok, const char errmsg[])
{ {
std::ostringstream ostr; std::ostringstream ostr;
std::list<const TOKEN *>::const_iterator it; std::list<const TOKEN *>::const_iterator it;
@ -56,7 +55,7 @@ static void ReportError(const TOKEN *tok, const char errmsg[])
// Check array usage.. // Check array usage..
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname[], const int size, const int total_size ) void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname[], const int size, const int total_size )
{ {
unsigned int varc = 1; unsigned int varc = 1;
while ( varname[varc] ) while ( varname[varc] )
@ -299,7 +298,7 @@ static void CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname
// Checking local variables in a scope // Checking local variables in a scope
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void CheckBufferOverrun_LocalVariable() void CheckBufferOverrunClass::CheckBufferOverrun_LocalVariable()
{ {
int indentlevel = 0; int indentlevel = 0;
for (const TOKEN *tok = tokens; tok; tok = tok->next) for (const TOKEN *tok = tokens; tok; tok = tok->next)
@ -350,7 +349,7 @@ static void CheckBufferOverrun_LocalVariable()
// Checking member variables of structs.. // Checking member variables of structs..
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void CheckBufferOverrun_StructVariable() void CheckBufferOverrunClass::CheckBufferOverrun_StructVariable()
{ {
const char *declstruct_pattern[] = {"","","{",0}; const char *declstruct_pattern[] = {"","","{",0};
for ( const TOKEN * tok = Tokenizer::findtoken( tokens, declstruct_pattern ); for ( const TOKEN * tok = Tokenizer::findtoken( tokens, declstruct_pattern );
@ -446,7 +445,7 @@ static void CheckBufferOverrun_StructVariable()
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckBufferOverrun() void CheckBufferOverrunClass::CheckBufferOverrun()
{ {
CheckBufferOverrun_LocalVariable(); CheckBufferOverrun_LocalVariable();
CheckBufferOverrun_StructVariable(); CheckBufferOverrun_StructVariable();
@ -464,7 +463,7 @@ void CheckBufferOverrun()
// Dangerous functions // Dangerous functions
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void WarningDangerousFunctions() void CheckBufferOverrunClass::WarningDangerousFunctions()
{ {
for (const TOKEN *tok = tokens; tok; tok = tok->next) for (const TOKEN *tok = tokens; tok; tok = tok->next)
{ {

View File

@ -22,13 +22,24 @@
#define CheckBufferOverrunH #define CheckBufferOverrunH
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Buffer overrun.. #include "tokenize.h"
void CheckBufferOverrun();
class CheckBufferOverrunClass
{
public:
// Buffer overrun..
void CheckBufferOverrun();
// Dangerous functions that can cause buffer overruns // Dangerous functions that can cause buffer overruns
void WarningDangerousFunctions(); void WarningDangerousFunctions();
private:
void CheckBufferOverrun_StructVariable();
void CheckBufferOverrun_LocalVariable();
void CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname[], const int size, const int total_size );
void ReportError(const TOKEN *tok, const char errmsg[]);
};
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#endif #endif

View File

@ -18,10 +18,10 @@
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#include "CheckClass.h" #include "CheckClass.h"
#include "tokenize.h"
#include "CommonCheck.h" #include "CommonCheck.h"
#include <locale> #include <locale>
#include <list>
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <cstring> #include <cstring>
@ -36,15 +36,10 @@
extern bool CheckCodingStyle; extern bool CheckCodingStyle;
struct VAR
{
const char *name;
bool init;
struct VAR *next;
};
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static struct VAR *ClassChecking_GetVarList(const TOKEN *tok1) struct VAR *CheckClass::ClassChecking_GetVarList(const TOKEN *tok1)
{ {
// Get variable list.. // Get variable list..
struct VAR *varlist = NULL; struct VAR *varlist = NULL;
@ -106,7 +101,7 @@ static struct VAR *ClassChecking_GetVarList(const TOKEN *tok1)
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static const TOKEN * FindClassFunction( const TOKEN *tok, const char classname[], const char funcname[], int &indentlevel ) const TOKEN * CheckClass::FindClassFunction( const TOKEN *tok, const char classname[], const char funcname[], int &indentlevel )
{ {
const char *_classname[2] = {0,0}; const char *_classname[2] = {0,0};
const char *_funcname[2] = {0,0}; const char *_funcname[2] = {0,0};
@ -186,7 +181,7 @@ static const TOKEN * FindClassFunction( const TOKEN *tok, const char classname[]
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void InitVar(struct VAR *varlist, const char varname[]) void CheckClass::InitVar(struct VAR *varlist, const char varname[])
{ {
for (struct VAR *var = varlist; var; var = var->next) for (struct VAR *var = varlist; var; var = var->next)
{ {
@ -199,7 +194,7 @@ static void InitVar(struct VAR *varlist, const char varname[])
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void ClassChecking_VarList_Initialize(const TOKEN *tok1, const TOKEN *ftok, struct VAR *varlist, const char classname[], std::list<std::string> &callstack) void CheckClass::ClassChecking_VarList_Initialize(const TOKEN *tok1, const TOKEN *ftok, struct VAR *varlist, const char classname[], std::list<std::string> &callstack)
{ {
bool Assign = false; bool Assign = false;
unsigned int indentlevel = 0; unsigned int indentlevel = 0;
@ -304,7 +299,7 @@ static void ClassChecking_VarList_Initialize(const TOKEN *tok1, const TOKEN *fto
// ClassCheck: Check that all class constructors are ok. // ClassCheck: Check that all class constructors are ok.
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckConstructors() void CheckClass::CheckConstructors()
{ {
// Locate class // Locate class
const char *pattern_classname[] = {"class","","{",NULL}; const char *pattern_classname[] = {"class","","{",NULL};
@ -404,7 +399,7 @@ void CheckConstructors()
// ClassCheck: Unused private functions // ClassCheck: Unused private functions
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckUnusedPrivateFunctions() void CheckClass::CheckUnusedPrivateFunctions()
{ {
// Locate some class // Locate some class
const char *pattern_class[] = {"class","","{",NULL}; const char *pattern_class[] = {"class","","{",NULL};
@ -538,7 +533,7 @@ void CheckUnusedPrivateFunctions()
// ClassCheck: Check that memset is not used on classes // ClassCheck: Check that memset is not used on classes
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckMemset() void CheckClass::CheckMemset()
{ {
// Locate all 'memset' tokens.. // Locate all 'memset' tokens..
for (const TOKEN *tok = tokens; tok; tok = tok->next) for (const TOKEN *tok = tokens; tok; tok = tok->next)
@ -600,7 +595,7 @@ void CheckMemset()
// ClassCheck: "void operator=(" // ClassCheck: "void operator=("
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckOperatorEq1() void CheckClass::CheckOperatorEq1()
{ {
const char *pattern[] = {"void", "operator", "=", "(", NULL}; const char *pattern[] = {"void", "operator", "=", "(", NULL};
if (const TOKEN *tok = Tokenizer::findtoken(tokens,pattern)) if (const TOKEN *tok = Tokenizer::findtoken(tokens,pattern))

View File

@ -21,15 +21,33 @@
#define CheckClassH #define CheckClassH
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#include "tokenize.h"
#include <list>
void CheckConstructors(); struct VAR
{
const char *name;
bool init;
struct VAR *next;
};
void CheckUnusedPrivateFunctions(); class CheckClass
{
public:
void CheckConstructors();
void CheckMemset(); void CheckUnusedPrivateFunctions();
void CheckOperatorEq1(); // Warning upon "void operator=(.." void CheckMemset();
void CheckOperatorEq1(); // Warning upon "void operator=(.."
private:
void ClassChecking_VarList_Initialize(const TOKEN *tok1, const TOKEN *ftok, struct VAR *varlist, const char classname[], std::list<std::string> &callstack);
void InitVar(struct VAR *varlist, const char varname[]);
const TOKEN *FindClassFunction( const TOKEN *tok, const char classname[], const char funcname[], int &indentlevel );
struct VAR *ClassChecking_GetVarList(const TOKEN *tok1);
};
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#endif #endif

View File

@ -35,7 +35,7 @@
// HEADERS - No implementation in a header // HEADERS - No implementation in a header
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void WarningHeaderWithImplementation() void CheckHeaders::WarningHeaderWithImplementation()
{ {
for (TOKEN *tok = tokens; tok; tok = tok->next) for (TOKEN *tok = tokens; tok; tok = tok->next)
{ {
@ -69,7 +69,7 @@ void WarningHeaderWithImplementation()
// HEADERS - Unneeded include // HEADERS - Unneeded include
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void WarningIncludeHeader() void CheckHeaders::WarningIncludeHeader()
{ {
// Including.. // Including..
for (TOKEN *includetok = tokens; includetok; includetok = includetok->next) for (TOKEN *includetok = tokens; includetok; includetok = includetok->next)

View File

@ -22,10 +22,13 @@
#define CheckHeadersH #define CheckHeadersH
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void WarningHeaderWithImplementation(); class CheckHeaders
{
void WarningIncludeHeader(); public:
void WarningHeaderWithImplementation();
void WarningIncludeHeader();
};
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#endif #endif

View File

@ -19,14 +19,14 @@
#include "CheckMemoryLeak.h" #include "CheckMemoryLeak.h"
#include "tokenize.h"
#include "CommonCheck.h" #include "CommonCheck.h"
#include <stdlib.h> // free #include <stdlib.h> // free
#include <algorithm> #include <algorithm>
#include <vector>
#include <sstream> #include <sstream>
#ifdef __BORLANDC__ #ifdef __BORLANDC__
@ -40,10 +40,8 @@
#endif #endif
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static TOKEN *getcode(const TOKEN *tok, const char varname[]);
static void simplifycode(TOKEN *tok);
static bool isclass( const std::string &typestr ) bool CheckMemoryLeakClass::isclass( const std::string &typestr )
{ {
if ( typestr == "char" || if ( typestr == "char" ||
typestr == "short" || typestr == "short" ||
@ -63,7 +61,7 @@ static bool isclass( const std::string &typestr )
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
enum AllocType { No, Malloc, gMalloc, New, NewA };
// Extra allocation.. // Extra allocation..
class AllocFunc class AllocFunc
@ -80,7 +78,7 @@ class AllocFunc
}; };
static std::list<AllocFunc> listallocfunc; static std::list<AllocFunc> listallocfunc;
static AllocType GetAllocationType( const TOKEN *tok2 ) AllocType CheckMemoryLeakClass::GetAllocationType( const TOKEN *tok2 )
{ {
// What we may have... // What we may have...
// * var = (char *)malloc(10); // * var = (char *)malloc(10);
@ -149,7 +147,7 @@ static AllocType GetAllocationType( const TOKEN *tok2 )
return No; return No;
} }
static AllocType GetDeallocationType( const TOKEN *tok, const char *varnames[] ) AllocType CheckMemoryLeakClass::GetDeallocationType( const TOKEN *tok, const char *varnames[] )
{ {
// Redundant condition.. // Redundant condition..
if ( Match(tok, "if ( %var1% )", varnames) ) if ( Match(tok, "if ( %var1% )", varnames) )
@ -180,7 +178,7 @@ static AllocType GetDeallocationType( const TOKEN *tok, const char *varnames[] )
static std::list<std::string> callstack; static std::list<std::string> callstack;
static const char * call_func( const TOKEN *tok, const char *varnames[] ) const char * CheckMemoryLeakClass::call_func( const TOKEN *tok, const char *varnames[] )
{ {
if (Match(tok,"if") || Match(tok,"for") || Match(tok,"while")) if (Match(tok,"if") || Match(tok,"for") || Match(tok,"while"))
return 0; return 0;
@ -238,7 +236,7 @@ static const char * call_func( const TOKEN *tok, const char *varnames[] )
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
static void MismatchError( const TOKEN *Tok1, const char varname[] ) void CheckMemoryLeakClass::MismatchError( const TOKEN *Tok1, const char varname[] )
{ {
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << FileLine(Tok1) << ": Mismatching allocation and deallocation: " << varname; errmsg << FileLine(Tok1) << ": Mismatching allocation and deallocation: " << varname;
@ -246,7 +244,7 @@ static void MismatchError( const TOKEN *Tok1, const char varname[] )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void MemoryLeak( const TOKEN *tok, const char varname[] ) void CheckMemoryLeakClass::MemoryLeak( const TOKEN *tok, const char varname[] )
{ {
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << FileLine(tok) << ": Memory leak: " << varname; errmsg << FileLine(tok) << ": Memory leak: " << varname;
@ -254,7 +252,7 @@ static void MemoryLeak( const TOKEN *tok, const char varname[] )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void instoken(TOKEN *tok, const char str[]) void CheckMemoryLeakClass::instoken(TOKEN *tok, const char str[])
{ {
TOKEN *newtok = new TOKEN; TOKEN *newtok = new TOKEN;
newtok->setstr(str); newtok->setstr(str);
@ -263,7 +261,7 @@ static void instoken(TOKEN *tok, const char str[])
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static bool notvar(const TOKEN *tok, const char *varnames[]) bool CheckMemoryLeakClass::notvar(const TOKEN *tok, const char *varnames[])
{ {
return bool( Match(tok, "! %var1% [;)&|]", varnames) || return bool( Match(tok, "! %var1% [;)&|]", varnames) ||
Match(tok, "! ( %var1% )", varnames) || Match(tok, "! ( %var1% )", varnames) ||
@ -283,7 +281,7 @@ extern bool ShowAll;
* varname - name of variable * varname - name of variable
*/ */
static TOKEN *getcode(const TOKEN *tok, const char varname[]) TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, const char varname[])
{ {
const char *varnames[2]; const char *varnames[2];
varnames[0] = varname; varnames[0] = varname;
@ -462,7 +460,7 @@ static TOKEN *getcode(const TOKEN *tok, const char varname[])
return rethead; return rethead;
} }
static void erase(TOKEN *begin, const TOKEN *end) void CheckMemoryLeakClass::erase(TOKEN *begin, const TOKEN *end)
{ {
if ( ! begin ) if ( ! begin )
return; return;
@ -481,7 +479,7 @@ static void erase(TOKEN *begin, const TOKEN *end)
* Simplify code * Simplify code
* \param tok first token * \param tok first token
*/ */
static void simplifycode(TOKEN *tok) void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
{ {
// Remove "do"... // Remove "do"...
// do { x } while (y); // do { x } while (y);
@ -758,7 +756,7 @@ static void simplifycode(TOKEN *tok)
// Simpler but less powerful than "CheckMemoryLeak_CheckScope_All" // Simpler but less powerful than "CheckMemoryLeak_CheckScope_All"
static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] ) void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] )
{ {
callstack.clear(); callstack.clear();
@ -826,7 +824,7 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[]
// Checks for memory leaks inside function.. // Checks for memory leaks inside function..
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void CheckMemoryLeak_InFunction() void CheckMemoryLeakClass::CheckMemoryLeak_InFunction()
{ {
bool infunc = false; bool infunc = false;
int indentlevel = 0; int indentlevel = 0;
@ -868,11 +866,9 @@ static void CheckMemoryLeak_InFunction()
// Checks for memory leaks in classes.. // Checks for memory leaks in classes..
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void CheckMemoryLeak_ClassMembers_ParseClass( const TOKEN *tok1, std::vector<const char *> &classname );
static void CheckMemoryLeak_ClassMembers_Variable( const std::vector<const char *> &classname, const char varname[] );
static void CheckMemoryLeak_ClassMembers() void CheckMemoryLeakClass::CheckMemoryLeak_ClassMembers()
{ {
int indentlevel = 0; int indentlevel = 0;
for ( const TOKEN *tok = tokens; tok; tok = tok->next ) for ( const TOKEN *tok = tokens; tok; tok = tok->next )
@ -893,7 +889,7 @@ static void CheckMemoryLeak_ClassMembers()
} }
static void CheckMemoryLeak_ClassMembers_ParseClass( const TOKEN *tok1, std::vector<const char *> &classname ) void CheckMemoryLeakClass::CheckMemoryLeak_ClassMembers_ParseClass( const TOKEN *tok1, std::vector<const char *> &classname )
{ {
// Go into class. // Go into class.
while ( tok1 && tok1->str[0] != '{' ) while ( tok1 && tok1->str[0] != '{' )
@ -938,7 +934,7 @@ static void CheckMemoryLeak_ClassMembers_ParseClass( const TOKEN *tok1, std::vec
} }
} }
static void CheckMemoryLeak_ClassMembers_Variable( const std::vector<const char *> &classname, const char varname[] ) void CheckMemoryLeakClass::CheckMemoryLeak_ClassMembers_Variable( const std::vector<const char *> &classname, const char varname[] )
{ {
// Function pattern.. Check if member function // Function pattern.. Check if member function
std::ostringstream fpattern; std::ostringstream fpattern;
@ -1035,7 +1031,7 @@ static void CheckMemoryLeak_ClassMembers_Variable( const std::vector<const char
// Checks for memory leaks.. // Checks for memory leaks..
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckMemoryLeak() void CheckMemoryLeakClass::CheckMemoryLeak()
{ {
listallocfunc.clear(); listallocfunc.clear();

View File

@ -25,7 +25,35 @@
/** \brief Check for memory leaks */ /** \brief Check for memory leaks */
void CheckMemoryLeak(); #include <vector>
#include "tokenize.h"
enum AllocType { No, Malloc, gMalloc, New, NewA };
class CheckMemoryLeakClass
{
public:
void CheckMemoryLeak();
private:
void CheckMemoryLeak_ClassMembers_Variable( const std::vector<const char *> &classname, const char varname[] );
void CheckMemoryLeak_ClassMembers_ParseClass( const TOKEN *tok1, std::vector<const char *> &classname );
void CheckMemoryLeak_ClassMembers();
void CheckMemoryLeak_InFunction();
void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] );
void simplifycode(TOKEN *tok);
void erase(TOKEN *begin, const TOKEN *end);
TOKEN *getcode(const TOKEN *tok, const char varname[]);
bool notvar(const TOKEN *tok, const char *varnames[]);
void instoken(TOKEN *tok, const char str[]);
void MemoryLeak( const TOKEN *tok, const char varname[] );
void MismatchError( const TOKEN *Tok1, const char varname[] );
const char * call_func( const TOKEN *tok, const char *varnames[] );
AllocType GetDeallocationType( const TOKEN *tok, const char *varnames[] );
AllocType GetAllocationType( const TOKEN *tok2 );
bool isclass( const std::string &typestr );
};
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#endif #endif

View File

@ -19,7 +19,7 @@
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#include "CheckOther.h" #include "CheckOther.h"
#include "tokenize.h"
#include "CommonCheck.h" #include "CommonCheck.h"
#include <list> #include <list>
#include <map> #include <map>
@ -35,7 +35,7 @@
// Warning on C-Style casts.. p = (kalle *)foo; // Warning on C-Style casts.. p = (kalle *)foo;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void WarningOldStylePointerCast() void CheckOther::WarningOldStylePointerCast()
{ {
for (const TOKEN *tok = tokens; tok; tok = tok->next) for (const TOKEN *tok = tokens; tok; tok = tok->next)
{ {
@ -62,7 +62,7 @@ void WarningOldStylePointerCast()
// Use standard function "isdigit" instead // Use standard function "isdigit" instead
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void WarningIsDigit() void CheckOther::WarningIsDigit()
{ {
for (const TOKEN *tok = tokens; tok; tok = tok->next) for (const TOKEN *tok = tokens; tok; tok = tok->next)
{ {
@ -87,7 +87,7 @@ void WarningIsDigit()
// Use standard function "isalpha" instead // Use standard function "isalpha" instead
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void WarningIsAlpha() void CheckOther::WarningIsAlpha()
{ {
for (const TOKEN *tok = tokens; tok; tok = tok->next) for (const TOKEN *tok = tokens; tok; tok = tok->next)
{ {
@ -145,7 +145,7 @@ void WarningIsAlpha()
// Redundant code.. // Redundant code..
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void WarningRedundantCode() void CheckOther::WarningRedundantCode()
{ {
// if (p) delete p // if (p) delete p
@ -207,7 +207,7 @@ void WarningRedundantCode()
// if (condition) .... // if (condition) ....
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void WarningIf() void CheckOther::WarningIf()
{ {
// Search for 'if (condition);' // Search for 'if (condition);'
@ -298,7 +298,7 @@ void WarningIf()
// strtol(str, 0, radix) <- radix must be 0 or 2-36 // strtol(str, 0, radix) <- radix must be 0 or 2-36
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void InvalidFunctionUsage() void CheckOther::InvalidFunctionUsage()
{ {
for ( const TOKEN *tok = tokens; tok; tok = tok->next ) for ( const TOKEN *tok = tokens; tok; tok = tok->next )
{ {
@ -342,7 +342,7 @@ void InvalidFunctionUsage()
// Assignment in condition // Assignment in condition
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckIfAssignment() void CheckOther::CheckIfAssignment()
{ {
for (const TOKEN *tok = tokens; tok; tok = tok->next) for (const TOKEN *tok = tokens; tok; tok = tok->next)
{ {
@ -363,7 +363,7 @@ void CheckIfAssignment()
// Check for unsigned divisions // Check for unsigned divisions
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckUnsignedDivision() void CheckOther::CheckUnsignedDivision()
{ {
// Check for "ivar / uvar" and "uvar / ivar" // Check for "ivar / uvar" and "uvar / ivar"
std::map<std::string, char> varsign; std::map<std::string, char> varsign;
@ -428,9 +428,8 @@ void CheckUnsignedDivision()
// Check scope of variables.. // Check scope of variables..
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void CheckVariableScope_LookupVar( const TOKEN *tok1, const char varname[] );
void CheckVariableScope() void CheckOther::CheckVariableScope()
{ {
// Walk through all tokens.. // Walk through all tokens..
bool func = false; bool func = false;
@ -512,7 +511,7 @@ void CheckVariableScope()
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void CheckVariableScope_LookupVar( const TOKEN *tok1, const char varname[] ) void CheckOther::CheckVariableScope_LookupVar( const TOKEN *tok1, const char varname[] )
{ {
const TOKEN *tok = tok1; const TOKEN *tok = tok1;
@ -585,7 +584,7 @@ static void CheckVariableScope_LookupVar( const TOKEN *tok1, const char varname[
// Check for constant function parameters // Check for constant function parameters
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckConstantFunctionParameter() void CheckOther::CheckConstantFunctionParameter()
{ {
for (const TOKEN *tok = tokens; tok; tok = tok->next) for (const TOKEN *tok = tokens; tok; tok = tok->next)
{ {
@ -624,7 +623,7 @@ void CheckConstantFunctionParameter()
// Check that all struct members are used // Check that all struct members are used
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckStructMemberUsage() void CheckOther::CheckStructMemberUsage()
{ {
const char *structname = 0; const char *structname = 0;
@ -687,7 +686,7 @@ void CheckStructMemberUsage()
// Check usage of char variables.. // Check usage of char variables..
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckCharVariable() void CheckOther::CheckCharVariable()
{ {
for (const TOKEN *tok = tokens; tok; tok = tok->next) for (const TOKEN *tok = tokens; tok; tok = tok->next)
{ {
@ -741,7 +740,7 @@ void CheckCharVariable()
// Incomplete statement.. // Incomplete statement..
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckIncompleteStatement() void CheckOther::CheckIncompleteStatement()
{ {
int parlevel = 0; int parlevel = 0;

View File

@ -23,48 +23,55 @@
#define CheckOtherH #define CheckOtherH
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#include "tokenize.h"
// Casting class CheckOther
void WarningOldStylePointerCast(); {
public:
// Casting
void WarningOldStylePointerCast();
// Use standard functions instead // Use standard functions instead
void WarningIsDigit(); void WarningIsDigit();
// Use standard functions instead // Use standard functions instead
void WarningIsAlpha(); void WarningIsAlpha();
// Redundant code // Redundant code
void WarningRedundantCode(); void WarningRedundantCode();
// Warning upon: if (condition); // Warning upon: if (condition);
void WarningIf(); void WarningIf();
// Assignment in condition // Assignment in condition
void CheckIfAssignment(); void CheckIfAssignment();
// Using dangerous functions // Using dangerous functions
void WarningDangerousFunctions(); void WarningDangerousFunctions();
// Invalid function usage.. // Invalid function usage..
void InvalidFunctionUsage(); void InvalidFunctionUsage();
// Check for unsigned division that might create bad results // Check for unsigned division that might create bad results
void CheckUnsignedDivision(); void CheckUnsignedDivision();
// Check scope of variables // Check scope of variables
void CheckVariableScope(); void CheckVariableScope();
// Check for constant function parameter // Check for constant function parameter
void CheckConstantFunctionParameter(); void CheckConstantFunctionParameter();
// Check that all struct members are used // Check that all struct members are used
void CheckStructMemberUsage(); void CheckStructMemberUsage();
// Using char variable as array index / as operand in bit operation // Using char variable as array index / as operand in bit operation
void CheckCharVariable(); void CheckCharVariable();
// Incomplete statement. A statement that only contains a constant or variable // Incomplete statement. A statement that only contains a constant or variable
void CheckIncompleteStatement(); void CheckIncompleteStatement();
private:
void CheckVariableScope_LookupVar( const TOKEN *tok1, const char varname[] );
};
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#endif #endif

View File

@ -11,7 +11,7 @@ all: ${OBJS} main.o
test: ${OBJS} testrunner.o testsuite.o ${TESTS} test: ${OBJS} testrunner.o testsuite.o ${TESTS}
g++ -Wall -g -o testrunner $^ g++ -Wall -g -o testrunner $^
clean: clean:
rm -f *.o cppcheck_test cppcheck rm -f *.o testrunner cppcheck
install: cppcheck install: cppcheck
install -d ${BIN} install -d ${BIN}
install cppcheck ${BIN} install cppcheck ${BIN}

View File

@ -127,7 +127,8 @@ int main(int argc, char* argv[])
std::ifstream fin( fname.c_str() ); std::ifstream fin( fname.c_str() );
std::map<std::string, std::string> code; std::map<std::string, std::string> code;
preprocess(fin, code, fname); Preprocessor preprocessor;
preprocessor.preprocess(fin, code, fname);
for ( std::map<std::string,std::string>::const_iterator it = code.begin(); it != code.end(); ++it ) for ( std::map<std::string,std::string>::const_iterator it = code.begin(); it != code.end(); ++it )
CppCheck(it->second, filenames[c].c_str(), c); CppCheck(it->second, filenames[c].c_str(), c);
@ -176,39 +177,46 @@ static void CppCheck(const std::string &code, const char FileName[], unsigned in
// Check that the memsets are valid. // Check that the memsets are valid.
// The 'memset' function can do dangerous things if used wrong. // The 'memset' function can do dangerous things if used wrong.
// Important: The checking doesn't work on simplified tokens list. // Important: The checking doesn't work on simplified tokens list.
CheckMemset(); CheckClass checkClass;
checkClass.CheckMemset();
// Check for unsigned divisions where one operand is signed // Check for unsigned divisions where one operand is signed
// Very important to run it before 'SimplifyTokenList' // Very important to run it before 'SimplifyTokenList'
CheckUnsignedDivision(); CheckOther checkOther;
checkOther.CheckUnsignedDivision();
// Give warning when using char variable as array index // Give warning when using char variable as array index
// Doesn't work on simplified token list ('unsigned') // Doesn't work on simplified token list ('unsigned')
if ( ShowAll ) if ( ShowAll )
CheckCharVariable(); checkOther.CheckCharVariable();
// Including header which is not needed (too many false positives) // Including header which is not needed (too many false positives)
//if ( CheckCodingStyle ) // if ( CheckCodingStyle )
// WarningIncludeHeader(); // {
// CheckHeaders checkHeaders;
// checkHeaders.WarningIncludeHeader();
// }
tokenizer.SimplifyTokenList(); tokenizer.SimplifyTokenList();
// Memory leak // Memory leak
CheckMemoryLeak(); CheckMemoryLeakClass checkMemoryLeak;
checkMemoryLeak.CheckMemoryLeak();
// Buffer overruns.. // Buffer overruns..
CheckBufferOverrun(); CheckBufferOverrunClass checkBufferOverrun;
checkBufferOverrun.CheckBufferOverrun();
// Check that all class constructors are ok. // Check that all class constructors are ok.
CheckConstructors(); checkClass.CheckConstructors();
if (ShowAll) if (ShowAll)
{ {
// Check for "if (a=b)" // Check for "if (a=b)"
CheckIfAssignment(); checkOther.CheckIfAssignment();
// Check for case without break // Check for case without break
// Disabled because it generates many false positives // Disabled because it generates many false positives
@ -222,47 +230,47 @@ static void CppCheck(const std::string &code, const char FileName[], unsigned in
// Dangerous functions, such as 'gets' and 'scanf' // Dangerous functions, such as 'gets' and 'scanf'
WarningDangerousFunctions(); checkBufferOverrun.WarningDangerousFunctions();
// Invalid function usage.. // Invalid function usage..
InvalidFunctionUsage(); checkOther.InvalidFunctionUsage();
if (CheckCodingStyle) if (CheckCodingStyle)
{ {
// Check that all private functions are called. // Check that all private functions are called.
CheckUnusedPrivateFunctions(); checkClass.CheckUnusedPrivateFunctions();
// Warning upon c-style pointer casts // Warning upon c-style pointer casts
const char *ext = strrchr(FileName, '.'); const char *ext = strrchr(FileName, '.');
if (ext && strcmp(ext,".cpp")==0) if (ext && strcmp(ext,".cpp")==0)
WarningOldStylePointerCast(); checkOther.WarningOldStylePointerCast();
// Use standard functions instead // Use standard functions instead
WarningIsDigit(); checkOther.WarningIsDigit();
WarningIsAlpha(); checkOther.WarningIsAlpha();
CheckOperatorEq1(); checkClass.CheckOperatorEq1();
// if (a) delete a; // if (a) delete a;
WarningRedundantCode(); checkOther.WarningRedundantCode();
// if (condition); // if (condition);
WarningIf(); checkOther.WarningIf();
// Variable scope (check if the scope could be limited) // Variable scope (check if the scope could be limited)
//CheckVariableScope(); //CheckVariableScope();
// Check if a constant function parameter is passed by value // Check if a constant function parameter is passed by value
CheckConstantFunctionParameter(); checkOther.CheckConstantFunctionParameter();
// Unused struct members.. // Unused struct members..
CheckStructMemberUsage(); checkOther.CheckStructMemberUsage();
// Check for various types of incomplete statements that could for example // Check for various types of incomplete statements that could for example
// mean that an ';' has been added by accident // mean that an ';' has been added by accident
CheckIncompleteStatement(); checkOther.CheckIncompleteStatement();
} }
// Clean up tokens.. // Clean up tokens..

View File

@ -21,7 +21,7 @@
#include "CommonCheck.h" #include "CommonCheck.h"
#include <algorithm> #include <algorithm>
#include <list>
#include <sstream> #include <sstream>
#ifdef __BORLANDC__ #ifdef __BORLANDC__
@ -29,15 +29,6 @@
#endif #endif
/**
* Get all possible configurations. By looking at the ifdefs and ifndefs in filedata
*/
static std::list<std::string> getcfgs( const std::string &filedata );
/**
* Get preprocessed code for a given configuration
*/
static std::string getcode(const std::string &filedata, std::string cfg);
/** /**
@ -45,7 +36,7 @@ static std::string getcode(const std::string &filedata, std::string cfg);
* \param istr The (file/string) stream to read from. * \param istr The (file/string) stream to read from.
* \param result The map that will get the results * \param result The map that will get the results
*/ */
void preprocess(std::istream &istr, std::map<std::string, std::string> &result, const std::string &filename) void Preprocessor::preprocess(std::istream &istr, std::map<std::string, std::string> &result, const std::string &filename)
{ {
// Get filedata from stream.. // Get filedata from stream..
bool ignoreSpace = true; bool ignoreSpace = true;
@ -178,7 +169,7 @@ void preprocess(std::istream &istr, std::map<std::string, std::string> &result,
// Get the DEF in this line: "#ifdef DEF" // Get the DEF in this line: "#ifdef DEF"
static std::string getdef(std::string line, bool def) std::string Preprocessor::getdef(std::string line, bool def)
{ {
// If def is true, the line must start with "#ifdef" // If def is true, the line must start with "#ifdef"
if ( def && line.find("#ifdef ") != 0 && line.find("#if ") != 0 && line.find("#elif ") != 0 ) if ( def && line.find("#ifdef ") != 0 && line.find("#if ") != 0 && line.find("#elif ") != 0 )
@ -205,7 +196,7 @@ static std::string getdef(std::string line, bool def)
static std::list<std::string> getcfgs( const std::string &filedata ) std::list<std::string> Preprocessor::getcfgs( const std::string &filedata )
{ {
std::list<std::string> ret; std::list<std::string> ret;
ret.push_back(""); ret.push_back("");
@ -254,7 +245,7 @@ static std::list<std::string> getcfgs( const std::string &filedata )
static bool match_cfg_def( std::string cfg, const std::string &def ) bool Preprocessor::match_cfg_def( std::string cfg, const std::string &def )
{ {
if ( def == "0" ) if ( def == "0" )
return false; return false;
@ -279,7 +270,7 @@ static bool match_cfg_def( std::string cfg, const std::string &def )
} }
static std::string getcode(const std::string &filedata, std::string cfg) std::string Preprocessor::getcode(const std::string &filedata, std::string cfg)
{ {
std::ostringstream ret; std::ostringstream ret;

View File

@ -24,9 +24,27 @@
#include <map> #include <map>
#include <istream> #include <istream>
#include <string> #include <string>
#include <list>
class Preprocessor
{
public:
void preprocess(std::istream &istr, std::map<std::string, std::string> &result, const std::string &filename);
private:
/**
* Get preprocessed code for a given configuration
*/
std::string getcode(const std::string &filedata, std::string cfg);
void preprocess(std::istream &istr, std::map<std::string, std::string> &result, const std::string &filename); /**
* Get all possible configurations. By looking at the ifdefs and ifndefs in filedata
*/
std::list<std::string> getcfgs( const std::string &filedata );
std::string getdef(std::string line, bool def);
bool match_cfg_def( std::string cfg, const std::string &def );
};
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#endif #endif

View File

@ -52,7 +52,8 @@ private:
// Check for memory leaks.. // Check for memory leaks..
ShowAll = true; ShowAll = true;
CheckBufferOverrun(); CheckBufferOverrunClass checkBufferOverrun;
checkBufferOverrun.CheckBufferOverrun();
tokenizer.DeallocateTokens(); tokenizer.DeallocateTokens();
} }

View File

@ -57,7 +57,8 @@ private:
// Check for memory leaks.. // Check for memory leaks..
ShowAll = true; ShowAll = true;
CheckCharVariable(); CheckOther checkOther;
checkOther.CheckCharVariable();
tokenizer.DeallocateTokens(); tokenizer.DeallocateTokens();
} }

View File

@ -46,7 +46,8 @@ private:
errout.str(""); errout.str("");
// Check for memory leaks.. // Check for memory leaks..
CheckConstructors(); CheckClass checkClass;
checkClass.CheckConstructors();
tokenizer.DeallocateTokens(); tokenizer.DeallocateTokens();
} }

View File

@ -51,7 +51,8 @@ private:
// Check for memory leaks.. // Check for memory leaks..
ShowAll = true; ShowAll = true;
CheckUnsignedDivision(); CheckOther checkOther;
checkOther.CheckUnsignedDivision();
tokenizer.DeallocateTokens(); tokenizer.DeallocateTokens();
} }

View File

@ -48,7 +48,8 @@ private:
errout.str(""); errout.str("");
// Check for unused variables.. // Check for unused variables..
CheckIncompleteStatement(); CheckOther checkOther;
checkOther.CheckIncompleteStatement();
tokenizer.DeallocateTokens(); tokenizer.DeallocateTokens();
} }

View File

@ -51,7 +51,8 @@ private:
// Check for memory leaks.. // Check for memory leaks..
ShowAll = false; ShowAll = false;
FillFunctionList(0); FillFunctionList(0);
CheckMemoryLeak(); CheckMemoryLeakClass checkMemoryLeak;
checkMemoryLeak.CheckMemoryLeak();
tokenizer.DeallocateTokens(); tokenizer.DeallocateTokens();
} }

View File

@ -140,7 +140,8 @@ private:
// Preprocess => actual result.. // Preprocess => actual result..
std::istringstream istr(filedata); std::istringstream istr(filedata);
std::map<std::string, std::string> actual; std::map<std::string, std::string> actual;
preprocess( istr, actual, "" ); Preprocessor preprocessor;
preprocessor.preprocess( istr, actual, "" );
// Compare results.. // Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected)); ASSERT_EQUALS( true, cmpmaps(actual, expected));
@ -163,7 +164,8 @@ private:
// Preprocess => actual result.. // Preprocess => actual result..
std::istringstream istr(filedata); std::istringstream istr(filedata);
std::map<std::string, std::string> actual; std::map<std::string, std::string> actual;
preprocess( istr, actual, "" ); Preprocessor preprocessor;
preprocessor.preprocess( istr, actual, "" );
// Compare results.. // Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected)); ASSERT_EQUALS( true, cmpmaps(actual, expected));
@ -185,7 +187,8 @@ private:
// Preprocess => actual result.. // Preprocess => actual result..
std::istringstream istr(filedata); std::istringstream istr(filedata);
std::map<std::string, std::string> actual; std::map<std::string, std::string> actual;
preprocess( istr, actual, "" ); Preprocessor preprocessor;
preprocessor.preprocess( istr, actual, "" );
// Compare results.. // Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected)); ASSERT_EQUALS( true, cmpmaps(actual, expected));
@ -210,7 +213,8 @@ private:
// Preprocess => actual result.. // Preprocess => actual result..
std::istringstream istr(filedata); std::istringstream istr(filedata);
std::map<std::string, std::string> actual; std::map<std::string, std::string> actual;
preprocess( istr, actual, "" ); Preprocessor preprocessor;
preprocessor.preprocess( istr, actual, "" );
// Compare results.. // Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected)); ASSERT_EQUALS( true, cmpmaps(actual, expected));
@ -233,7 +237,8 @@ private:
// Preprocess => actual result.. // Preprocess => actual result..
std::istringstream istr(filedata); std::istringstream istr(filedata);
std::map<std::string, std::string> actual; std::map<std::string, std::string> actual;
preprocess( istr, actual, "" ); Preprocessor preprocessor;
preprocessor.preprocess( istr, actual, "" );
// Compare results.. // Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected)); ASSERT_EQUALS( true, cmpmaps(actual, expected));
@ -259,7 +264,8 @@ private:
// Preprocess => actual result.. // Preprocess => actual result..
std::istringstream istr(filedata); std::istringstream istr(filedata);
std::map<std::string, std::string> actual; std::map<std::string, std::string> actual;
preprocess( istr, actual, "" ); Preprocessor preprocessor;
preprocessor.preprocess( istr, actual, "" );
// Compare results.. // Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected)); ASSERT_EQUALS( true, cmpmaps(actual, expected));
@ -281,7 +287,8 @@ private:
// Preprocess => actual result.. // Preprocess => actual result..
std::istringstream istr(filedata); std::istringstream istr(filedata);
std::map<std::string, std::string> actual; std::map<std::string, std::string> actual;
preprocess( istr, actual, "" ); Preprocessor preprocessor;
preprocessor.preprocess( istr, actual, "" );
// Compare results.. // Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected)); ASSERT_EQUALS( true, cmpmaps(actual, expected));
@ -303,7 +310,8 @@ private:
// Preprocess => actual result.. // Preprocess => actual result..
std::istringstream istr(filedata); std::istringstream istr(filedata);
std::map<std::string, std::string> actual; std::map<std::string, std::string> actual;
preprocess( istr, actual, "" ); Preprocessor preprocessor;
preprocessor.preprocess( istr, actual, "" );
// Compare results.. // Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected)); ASSERT_EQUALS( true, cmpmaps(actual, expected));
@ -322,7 +330,8 @@ private:
// Preprocess => actual result.. // Preprocess => actual result..
std::istringstream istr(filedata); std::istringstream istr(filedata);
std::map<std::string, std::string> actual; std::map<std::string, std::string> actual;
preprocess( istr, actual, "" ); Preprocessor preprocessor;
preprocessor.preprocess( istr, actual, "" );
// Compare results.. // Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected)); ASSERT_EQUALS( true, cmpmaps(actual, expected));
@ -346,7 +355,8 @@ private:
// Preprocess => actual result.. // Preprocess => actual result..
std::istringstream istr(filedata); std::istringstream istr(filedata);
std::map<std::string, std::string> actual; std::map<std::string, std::string> actual;
preprocess( istr, actual, "" ); Preprocessor preprocessor;
preprocessor.preprocess( istr, actual, "" );
// Compare results.. // Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected)); ASSERT_EQUALS( true, cmpmaps(actual, expected));
@ -365,7 +375,8 @@ private:
// Preprocess => actual result.. // Preprocess => actual result..
std::istringstream istr(filedata); std::istringstream istr(filedata);
std::map<std::string, std::string> actual; std::map<std::string, std::string> actual;
preprocess( istr, actual, "" ); Preprocessor preprocessor;
preprocessor.preprocess( istr, actual, "" );
// Compare results.. // Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected)); ASSERT_EQUALS( true, cmpmaps(actual, expected));
@ -389,7 +400,8 @@ private:
// Preprocess => actual result.. // Preprocess => actual result..
std::istringstream istr(filedata); std::istringstream istr(filedata);
std::map<std::string, std::string> actual; std::map<std::string, std::string> actual;
preprocess( istr, actual, "" ); Preprocessor preprocessor;
preprocessor.preprocess( istr, actual, "" );
// Compare results.. // Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected)); ASSERT_EQUALS( true, cmpmaps(actual, expected));
@ -408,7 +420,8 @@ private:
// Preprocess => actual result.. // Preprocess => actual result..
std::istringstream istr(filedata); std::istringstream istr(filedata);
std::map<std::string, std::string> actual; std::map<std::string, std::string> actual;
preprocess( istr, actual, "" ); Preprocessor preprocessor;
preprocessor.preprocess( istr, actual, "" );
// Compare results.. // Compare results..
ASSERT_EQUALS( true, cmpmaps(actual, expected)); ASSERT_EQUALS( true, cmpmaps(actual, expected));

View File

@ -51,7 +51,8 @@ private:
errout.str(""); errout.str("");
// Check for unused private functions.. // Check for unused private functions..
CheckUnusedPrivateFunctions(); CheckClass checkClass;
checkClass.CheckUnusedPrivateFunctions();
tokenizer.DeallocateTokens(); tokenizer.DeallocateTokens();
} }

View File

@ -48,7 +48,8 @@ private:
errout.str(""); errout.str("");
// Check for unused variables.. // Check for unused variables..
CheckStructMemberUsage(); CheckOther checkOther;
checkOther.CheckStructMemberUsage();
tokenizer.DeallocateTokens(); tokenizer.DeallocateTokens();
} }