Refactoring: Following new classes were created:
CheckBufferOverrunClass CheckClass CheckHeaders CheckMemoryLeakClass CheckOther Preprocessor
This commit is contained in:
parent
f752b0e375
commit
f242c4fddd
|
@ -21,7 +21,6 @@
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "CheckBufferOverrun.h"
|
#include "CheckBufferOverrun.h"
|
||||||
#include "tokenize.h"
|
|
||||||
#include "CommonCheck.h"
|
#include "CommonCheck.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -40,8 +39,8 @@ 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;
|
||||||
for ( it = CallStack.begin(); it != CallStack.end(); it++ )
|
for ( it = CallStack.begin(); it != CallStack.end(); 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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,14 +21,25 @@
|
||||||
#ifndef CheckBufferOverrunH
|
#ifndef CheckBufferOverrunH
|
||||||
#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
|
||||||
|
|
|
@ -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))
|
||||||
|
|
30
CheckClass.h
30
CheckClass.h
|
@ -20,16 +20,34 @@
|
||||||
#ifndef CheckClassH
|
#ifndef CheckClassH
|
||||||
#define CheckClassH
|
#define CheckClassH
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "tokenize.h"
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
struct VAR
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
bool init;
|
||||||
|
struct VAR *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CheckClass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void CheckConstructors();
|
||||||
|
|
||||||
void CheckConstructors();
|
void CheckUnusedPrivateFunctions();
|
||||||
|
|
||||||
void CheckUnusedPrivateFunctions();
|
void CheckMemset();
|
||||||
|
|
||||||
void CheckMemset();
|
|
||||||
|
|
||||||
void CheckOperatorEq1(); // Warning upon "void operator=(.."
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -21,11 +21,14 @@
|
||||||
#ifndef CheckHeadersH
|
#ifndef CheckHeadersH
|
||||||
#define CheckHeadersH
|
#define CheckHeadersH
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class CheckHeaders
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void WarningHeaderWithImplementation();
|
||||||
|
void WarningIncludeHeader();
|
||||||
|
|
||||||
void WarningHeaderWithImplementation();
|
};
|
||||||
|
|
||||||
void WarningIncludeHeader();
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,36 @@
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
/** \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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
65
CheckOther.h
65
CheckOther.h
|
@ -22,49 +22,56 @@
|
||||||
#ifndef CheckOtherH
|
#ifndef CheckOtherH
|
||||||
#define CheckOtherH
|
#define CheckOtherH
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "tokenize.h"
|
||||||
|
|
||||||
|
class CheckOther
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Casting
|
||||||
|
void WarningOldStylePointerCast();
|
||||||
|
|
||||||
// Casting
|
// Use standard functions instead
|
||||||
void WarningOldStylePointerCast();
|
void WarningIsDigit();
|
||||||
|
|
||||||
// Use standard functions instead
|
// Use standard functions instead
|
||||||
void WarningIsDigit();
|
void WarningIsAlpha();
|
||||||
|
|
||||||
// Use standard functions instead
|
// Redundant code
|
||||||
void WarningIsAlpha();
|
void WarningRedundantCode();
|
||||||
|
|
||||||
// Redundant code
|
// Warning upon: if (condition);
|
||||||
void WarningRedundantCode();
|
void WarningIf();
|
||||||
|
|
||||||
// Warning upon: if (condition);
|
// Assignment in condition
|
||||||
void WarningIf();
|
void CheckIfAssignment();
|
||||||
|
|
||||||
// Assignment in condition
|
// Using dangerous functions
|
||||||
void CheckIfAssignment();
|
void WarningDangerousFunctions();
|
||||||
|
|
||||||
// Using dangerous functions
|
// Invalid function usage..
|
||||||
void WarningDangerousFunctions();
|
void InvalidFunctionUsage();
|
||||||
|
|
||||||
// Invalid function usage..
|
// Check for unsigned division that might create bad results
|
||||||
void InvalidFunctionUsage();
|
void CheckUnsignedDivision();
|
||||||
|
|
||||||
// Check for unsigned division that might create bad results
|
// Check scope of variables
|
||||||
void CheckUnsignedDivision();
|
void CheckVariableScope();
|
||||||
|
|
||||||
// Check scope of variables
|
// Check for constant function parameter
|
||||||
void CheckVariableScope();
|
void CheckConstantFunctionParameter();
|
||||||
|
|
||||||
// Check for constant function parameter
|
// Check that all struct members are used
|
||||||
void CheckConstantFunctionParameter();
|
void CheckStructMemberUsage();
|
||||||
|
|
||||||
// Check that all struct members are used
|
// Using char variable as array index / as operand in bit operation
|
||||||
void CheckStructMemberUsage();
|
void CheckCharVariable();
|
||||||
|
|
||||||
// Using char variable as array index / as operand in bit operation
|
// Incomplete statement. A statement that only contains a constant or variable
|
||||||
void CheckCharVariable();
|
void CheckIncompleteStatement();
|
||||||
|
private:
|
||||||
// Incomplete statement. A statement that only contains a constant or variable
|
void CheckVariableScope_LookupVar( const TOKEN *tok1, const char varname[] );
|
||||||
void CheckIncompleteStatement();
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
#endif
|
#endif
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -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}
|
||||||
|
|
58
main.cpp
58
main.cpp
|
@ -126,8 +126,9 @@ int main(int argc, char* argv[])
|
||||||
std::cout << "Checking " << fname << "...\n";
|
std::cout << "Checking " << fname << "...\n";
|
||||||
|
|
||||||
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..
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -271,7 +262,7 @@ static bool match_cfg_def( std::string cfg, const std::string &def )
|
||||||
return bool(cfg == def);
|
return bool(cfg == def);
|
||||||
std::string _cfg = cfg.substr( 0, cfg.find(";") );
|
std::string _cfg = cfg.substr( 0, cfg.find(";") );
|
||||||
if ( _cfg == def )
|
if ( _cfg == def )
|
||||||
return true;
|
return true;
|
||||||
cfg.erase( 0, cfg.find(";") + 1 );
|
cfg.erase( 0, cfg.find(";") + 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -313,13 +304,13 @@ static std::string getcode(const std::string &filedata, std::string cfg)
|
||||||
else if ( ! def.empty() )
|
else if ( ! def.empty() )
|
||||||
{
|
{
|
||||||
matching_ifdef.push_back( match_cfg_def(cfg, def) );
|
matching_ifdef.push_back( match_cfg_def(cfg, def) );
|
||||||
matched_ifdef.push_back( matching_ifdef.back() );
|
matched_ifdef.push_back( matching_ifdef.back() );
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( ! ndef.empty() )
|
else if ( ! ndef.empty() )
|
||||||
{
|
{
|
||||||
matching_ifdef.push_back( ! match_cfg_def(cfg, ndef) );
|
matching_ifdef.push_back( ! match_cfg_def(cfg, ndef) );
|
||||||
matched_ifdef.push_back( matching_ifdef.back() );
|
matched_ifdef.push_back( matching_ifdef.back() );
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( line == "#else" )
|
else if ( line == "#else" )
|
||||||
|
|
|
@ -24,9 +24,27 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <istream>
|
#include <istream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
class Preprocessor
|
||||||
void preprocess(std::istream &istr, std::map<std::string, std::string> &result, const std::string &filename);
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
|
|
@ -51,8 +51,9 @@ private:
|
||||||
errout.str("");
|
errout.str("");
|
||||||
|
|
||||||
// Check for memory leaks..
|
// Check for memory leaks..
|
||||||
ShowAll = true;
|
ShowAll = true;
|
||||||
CheckBufferOverrun();
|
CheckBufferOverrunClass checkBufferOverrun;
|
||||||
|
checkBufferOverrun.CheckBufferOverrun();
|
||||||
|
|
||||||
tokenizer.DeallocateTokens();
|
tokenizer.DeallocateTokens();
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,8 +56,9 @@ private:
|
||||||
errout.str("");
|
errout.str("");
|
||||||
|
|
||||||
// Check for memory leaks..
|
// Check for memory leaks..
|
||||||
ShowAll = true;
|
ShowAll = true;
|
||||||
CheckCharVariable();
|
CheckOther checkOther;
|
||||||
|
checkOther.CheckCharVariable();
|
||||||
|
|
||||||
tokenizer.DeallocateTokens();
|
tokenizer.DeallocateTokens();
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,8 +45,9 @@ private:
|
||||||
// Clear the error buffer..
|
// Clear the error buffer..
|
||||||
errout.str("");
|
errout.str("");
|
||||||
|
|
||||||
// Check for memory leaks..
|
// Check for memory leaks..
|
||||||
CheckConstructors();
|
CheckClass checkClass;
|
||||||
|
checkClass.CheckConstructors();
|
||||||
|
|
||||||
tokenizer.DeallocateTokens();
|
tokenizer.DeallocateTokens();
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,8 +50,9 @@ private:
|
||||||
errout.str("");
|
errout.str("");
|
||||||
|
|
||||||
// Check for memory leaks..
|
// Check for memory leaks..
|
||||||
ShowAll = true;
|
ShowAll = true;
|
||||||
CheckUnsignedDivision();
|
CheckOther checkOther;
|
||||||
|
checkOther.CheckUnsignedDivision();
|
||||||
|
|
||||||
tokenizer.DeallocateTokens();
|
tokenizer.DeallocateTokens();
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,8 +47,9 @@ private:
|
||||||
// Clear the error buffer..
|
// Clear the error buffer..
|
||||||
errout.str("");
|
errout.str("");
|
||||||
|
|
||||||
// Check for unused variables..
|
// Check for unused variables..
|
||||||
CheckIncompleteStatement();
|
CheckOther checkOther;
|
||||||
|
checkOther.CheckIncompleteStatement();
|
||||||
|
|
||||||
tokenizer.DeallocateTokens();
|
tokenizer.DeallocateTokens();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -50,8 +50,9 @@ private:
|
||||||
// Clear the error buffer..
|
// Clear the error buffer..
|
||||||
errout.str("");
|
errout.str("");
|
||||||
|
|
||||||
// Check for unused private functions..
|
// Check for unused private functions..
|
||||||
CheckUnusedPrivateFunctions();
|
CheckClass checkClass;
|
||||||
|
checkClass.CheckUnusedPrivateFunctions();
|
||||||
|
|
||||||
tokenizer.DeallocateTokens();
|
tokenizer.DeallocateTokens();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue