Formatting: uniformize end of lines (part 2)
This commit is contained in:
parent
625b77ec33
commit
e8d2c7cfb3
|
@ -217,7 +217,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
|||
// Don't make recursive checking..
|
||||
if (std::find(_callStack.begin(), _callStack.end(), tok) != _callStack.end())
|
||||
continue;
|
||||
|
||||
|
||||
// Only perform this checking if showAll setting is enabled..
|
||||
if ( ! _settings._showAll )
|
||||
continue;
|
||||
|
|
|
@ -113,16 +113,16 @@ const TOKEN * CheckClass::FindClassFunction( const TOKEN *tok, const char classn
|
|||
{
|
||||
if ( indentlevel < 0 || tok == NULL )
|
||||
return NULL;
|
||||
|
||||
|
||||
std::ostringstream classPattern;
|
||||
classPattern << "class " << classname << " :|{";
|
||||
|
||||
|
||||
std::ostringstream internalPattern;
|
||||
internalPattern << funcname << " (";
|
||||
|
||||
|
||||
std::ostringstream externalPattern;
|
||||
externalPattern << classname << " :: " << funcname << " (";
|
||||
|
||||
|
||||
for ( ;tok; tok = tok->next() )
|
||||
{
|
||||
if ( indentlevel == 0 && TOKEN::Match(tok, classPattern.str().c_str()) )
|
||||
|
@ -406,7 +406,7 @@ void CheckClass::CheckConstructors()
|
|||
|
||||
// Check constructors
|
||||
CheckConstructors( tok1, varlist, className[0] );
|
||||
|
||||
|
||||
// Check assignment operators
|
||||
CheckConstructors( tok1, varlist, "operator =" );
|
||||
|
||||
|
@ -425,7 +425,7 @@ void CheckClass::CheckConstructors()
|
|||
void CheckClass::CheckConstructors(const TOKEN *tok1, struct VAR *varlist, const char funcname[])
|
||||
{
|
||||
const char * const className = tok1->strAt(1);
|
||||
|
||||
|
||||
int indentlevel = 0;
|
||||
const TOKEN *constructor_token = FindClassFunction( tok1, className, funcname, indentlevel );
|
||||
std::list<std::string> callstack;
|
||||
|
@ -437,23 +437,23 @@ void CheckClass::CheckConstructors(const TOKEN *tok1, struct VAR *varlist, const
|
|||
{
|
||||
if ( var->init )
|
||||
continue;
|
||||
|
||||
|
||||
// Is it a static member variable?
|
||||
std::ostringstream pattern;
|
||||
pattern << className << "::" << var->name << "=";
|
||||
if (TOKEN::findmatch(_tokenizer->tokens(), pattern.str().c_str()))
|
||||
continue;
|
||||
|
||||
|
||||
// It's non-static and it's not initialized => error
|
||||
std::ostringstream ostr;
|
||||
ostr << _tokenizer->fileLine(constructor_token);
|
||||
ostr << " Uninitialized member variable '" << className << "::" << var->name << "'";
|
||||
_errorLogger->reportErr(ostr.str());
|
||||
}
|
||||
|
||||
|
||||
for ( struct VAR *var = varlist; var; var = var->next )
|
||||
var->init = false;
|
||||
|
||||
|
||||
constructor_token = FindClassFunction( constructor_token->next(), className, funcname, indentlevel );
|
||||
callstack.clear();
|
||||
ClassChecking_VarList_Initialize(tok1, constructor_token, varlist, className, callstack);
|
||||
|
@ -694,7 +694,7 @@ void CheckClass::virtualDestructor()
|
|||
while ( TOKEN::Match(derived, "%var%") )
|
||||
{
|
||||
bool isPublic = TOKEN::Match(derived, "public");
|
||||
|
||||
|
||||
// What kind of inheritance is it.. public|protected|private
|
||||
if ( TOKEN::Match( derived, "public|protected|private" ) )
|
||||
derived = derived->next();
|
||||
|
@ -703,12 +703,12 @@ void CheckClass::virtualDestructor()
|
|||
const char *baseName[2];
|
||||
baseName[0] = derived->strAt(0);
|
||||
baseName[1] = 0;
|
||||
|
||||
|
||||
// Update derived so it's ready for the next loop.
|
||||
derived = derived->next();
|
||||
if ( TOKEN::Match(derived, ",") )
|
||||
derived = derived->next();
|
||||
|
||||
|
||||
// If not public inheritance, skip checking of this base class..
|
||||
if ( ! isPublic )
|
||||
continue;
|
||||
|
|
|
@ -49,7 +49,7 @@ private:
|
|||
bool init;
|
||||
struct VAR *next;
|
||||
};
|
||||
|
||||
|
||||
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 );
|
||||
|
|
|
@ -136,7 +136,7 @@ CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetAllocationType( const T
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetReallocationType( const TOKEN *tok2 )
|
||||
{
|
||||
// What we may have...
|
||||
|
@ -149,17 +149,17 @@ CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetReallocationType( const
|
|||
}
|
||||
if ( ! tok2 )
|
||||
return No;
|
||||
|
||||
|
||||
if ( TOKEN::Match(tok2, "realloc") )
|
||||
return Malloc;
|
||||
|
||||
|
||||
// GTK memory reallocation..
|
||||
if ( TOKEN::Match(tok2, "g_realloc|g_try_realloc|g_renew|g_try_renew") )
|
||||
return gMalloc;
|
||||
|
||||
|
||||
return No;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetDeallocationType( const TOKEN *tok, const char *varnames[] )
|
||||
{
|
||||
|
@ -243,7 +243,7 @@ const char * CheckMemoryLeakClass::call_func( const TOKEN *tok, std::list<const
|
|||
{
|
||||
std::cout << t->str() << "\n";
|
||||
}*/
|
||||
|
||||
|
||||
const char *ret = 0;
|
||||
if (TOKEN::findmatch(func_, "goto"))
|
||||
{
|
||||
|
@ -257,7 +257,7 @@ const char * CheckMemoryLeakClass::call_func( const TOKEN *tok, std::list<const
|
|||
ret = "dealloc";
|
||||
else if ( TOKEN::findmatch(func_, "use") )
|
||||
ret = "use";
|
||||
|
||||
|
||||
Tokenizer::deleteTokens(func);
|
||||
return ret;
|
||||
}
|
||||
|
@ -326,10 +326,10 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
|
|||
rettail=newtok; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
// The first token should be ";"
|
||||
addtoken(";");
|
||||
|
||||
|
||||
|
||||
bool isloop = false;
|
||||
|
||||
|
@ -362,7 +362,7 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
|
|||
if (TOKEN::Match(tok, "[(;{}] %var1% =", varnames))
|
||||
{
|
||||
AllocType alloc = GetAllocationType(tok->tokAt(3));
|
||||
|
||||
|
||||
if ( alloc == No )
|
||||
{
|
||||
alloc = GetReallocationType( tok->tokAt(3) );
|
||||
|
@ -392,7 +392,7 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
|
|||
MismatchError(tok, callstack, varname);
|
||||
alloctype = alloc;
|
||||
}
|
||||
|
||||
|
||||
// assignment..
|
||||
else
|
||||
{
|
||||
|
@ -417,7 +417,7 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
|
|||
TOKEN::Match(tok, "if ( 0 != %var1% )", varnames) )
|
||||
{
|
||||
addtoken("if(var)");
|
||||
|
||||
|
||||
// Make sure the "use" will not be added
|
||||
while ( tok->str() != ")" )
|
||||
tok = tok->next();
|
||||
|
@ -526,7 +526,7 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
|
|||
if ( str )
|
||||
addtoken( str );
|
||||
}
|
||||
|
||||
|
||||
// Callback..
|
||||
if ( TOKEN::Match(tok, "( * %var% ) (") )
|
||||
{
|
||||
|
@ -621,7 +621,7 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
erase( tok2, tok2->tokAt(4) );
|
||||
done = false;
|
||||
}
|
||||
|
||||
|
||||
// TODO Make this more generic. Delete "if ; else use ; use"
|
||||
if ( TOKEN::Match(tok2, "; if ; else use ; use") ||
|
||||
TOKEN::Match(tok2, "; if use ; else ; use") )
|
||||
|
@ -629,7 +629,7 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
erase( tok2, tok2->tokAt(4) );
|
||||
done = false;
|
||||
}
|
||||
|
||||
|
||||
// Reduce "if dealloc ;" and "if use ;" that is not followed by an else..
|
||||
// If "--all" has been given these are deleted
|
||||
// Otherwise, ony the "if" will be deleted
|
||||
|
@ -657,14 +657,14 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
erase(tok2, tok2->tokAt(2));
|
||||
done = false;
|
||||
}
|
||||
|
||||
|
||||
// Reduce "else ;" => ";"
|
||||
if ( TOKEN::Match(tok2->next(), "else ;") )
|
||||
{
|
||||
erase(tok2, tok2->tokAt(2));
|
||||
done = false;
|
||||
}
|
||||
|
||||
|
||||
// Delete if block: "alloc; if return use ;"
|
||||
if (TOKEN::Match(tok2,"alloc ; if return use ;") && !TOKEN::Match(tok2->tokAt(6),"else"))
|
||||
{
|
||||
|
@ -706,7 +706,7 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
erase(tok2,tok2->tokAt(8));
|
||||
done = false;
|
||||
}
|
||||
|
||||
|
||||
// Reduce "if ; else %var% ;" => "if %var% ;"
|
||||
if ( TOKEN::Match(tok2, "if ; else %var% ;") )
|
||||
{
|
||||
|
@ -738,14 +738,14 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
erase( tok2, tok2->tokAt(4) );
|
||||
done = false;
|
||||
}
|
||||
|
||||
|
||||
// Reduce "if(true) X ;" => "X ;"
|
||||
if (TOKEN::Match(tok2->next(), "if(true) %var% ;") && !TOKEN::Match(tok2->tokAt(4),"else"))
|
||||
{
|
||||
erase( tok2, tok2->tokAt(2) );
|
||||
done = false;
|
||||
}
|
||||
|
||||
|
||||
// Replace "loop { X ; break ; }" with "X ;"
|
||||
if ( TOKEN::Match(tok2->next(), "loop { %var% ; break ; }") )
|
||||
{
|
||||
|
@ -781,7 +781,7 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
erase(tok2, tok2->tokAt(4));
|
||||
done = false;
|
||||
}
|
||||
|
||||
|
||||
// Delete if block: "alloc; if return use ;"
|
||||
if (TOKEN::Match(tok2,"alloc ; if return use ;") && !TOKEN::Match(tok2->tokAt(6),"else"))
|
||||
{
|
||||
|
@ -795,21 +795,21 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
erase( tok2, tok2->tokAt(4) );
|
||||
done = false;
|
||||
}
|
||||
|
||||
|
||||
// Reduce "[;{}] return ; %var%" => "[;{}] return ;"
|
||||
if ( TOKEN::Match(tok2, "[;{}] return ; %var%") )
|
||||
{
|
||||
erase( tok2->next()->next(), tok2->tokAt(4) );
|
||||
done = false;
|
||||
}
|
||||
|
||||
|
||||
// Reduce "[;{}] return use ; %var%" => "[;{}] return use ;"
|
||||
if ( TOKEN::Match(tok2, "[;{}] return use ; %var%") )
|
||||
{
|
||||
erase( tok2->next()->next()->next(), tok2->tokAt(5) );
|
||||
done = false;
|
||||
}
|
||||
|
||||
|
||||
// Reduce "if(var) return use ;" => "return use ;"
|
||||
if ( TOKEN::Match(tok2->next(), "if(var) return use ;") && !TOKEN::Match(tok2->tokAt(5),"else"))
|
||||
{
|
||||
|
@ -823,14 +823,14 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
|||
erase( tok2, tok2->tokAt(2) );
|
||||
done = false;
|
||||
}
|
||||
|
||||
|
||||
// Reduce "[;{}] alloc ; dealloc ;" => "[;{}]"
|
||||
if ( TOKEN::Match(tok2, "[;{}] alloc ; dealloc ;") )
|
||||
{
|
||||
erase( tok2, tok2->tokAt(5) );
|
||||
done = false;
|
||||
}
|
||||
|
||||
|
||||
// Reduce "if* alloc ; dealloc ;" => ";"
|
||||
if ( TOKEN::Match(tok2->tokAt(2), "alloc ; dealloc ;") &&
|
||||
tok2->next()->str().find("if") == 0 )
|
||||
|
@ -1011,7 +1011,7 @@ void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const
|
|||
TOKEN *first = tok;
|
||||
while ( first && first->str() == ";" )
|
||||
first = first->next();
|
||||
|
||||
|
||||
bool noerr = false;
|
||||
noerr |= TOKEN::Match( first, "alloc ; }" );
|
||||
noerr |= TOKEN::Match( first, "alloc ; dealloc ; }" );
|
||||
|
@ -1023,7 +1023,7 @@ void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const
|
|||
noerr |= TOKEN::Match( first, "if alloc ; use ; }" );
|
||||
noerr |= TOKEN::Match( first, "alloc ; ifv return ; dealloc ; }" );
|
||||
noerr |= TOKEN::Match( first, "alloc ; if return ; dealloc; }" );
|
||||
|
||||
|
||||
// Unhandled case..
|
||||
if ( ! noerr )
|
||||
{
|
||||
|
@ -1033,7 +1033,7 @@ void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const
|
|||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Tokenizer::deleteTokens(tok);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -67,7 +67,7 @@ private:
|
|||
* @param tok first token. The tokens list can be modified.
|
||||
*/
|
||||
void simplifycode(TOKEN *tok);
|
||||
|
||||
|
||||
/**
|
||||
* Delete tokens between begin and end. E.g. if begin = 1
|
||||
* and end = 5, tokens 2,3 and 4 would be erased.
|
||||
|
|
|
@ -785,16 +785,16 @@ void CheckOther::CheckIncompleteStatement()
|
|||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Unreachable code below a 'return'
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
void CheckOther::unreachableCode()
|
||||
{
|
||||
const TOKEN *tok = TOKEN::findmatch( _tokenizer->tokens(), "[;{}] return" );
|
||||
|
@ -802,13 +802,13 @@ void CheckOther::unreachableCode()
|
|||
{
|
||||
// Goto the 'return' token
|
||||
tok = tok->next();
|
||||
|
||||
|
||||
// Locate the end of the 'return' statement
|
||||
while ( tok && ! TOKEN::Match(tok, ";") )
|
||||
tok = tok->next();
|
||||
while ( tok && TOKEN::Match(tok->next(), ";") )
|
||||
tok = tok->next();
|
||||
|
||||
|
||||
// If there is a statement below the return it is unreachable
|
||||
if (!TOKEN::Match(tok, "; case|default|}|#") && !TOKEN::Match(tok, "; %var% :"))
|
||||
{
|
||||
|
@ -816,22 +816,22 @@ void CheckOther::unreachableCode()
|
|||
errmsg << _tokenizer->fileLine(tok->next()) << ": Unreachable code below a 'return'";
|
||||
_errorLogger->reportErr(errmsg.str());
|
||||
}
|
||||
|
||||
|
||||
// Find the next 'return' statement
|
||||
tok = TOKEN::findmatch( tok, "[;{}] return" );
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Usage of function variables
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
static bool isOp(const TOKEN *tok)
|
||||
{
|
||||
return bool(tok &&
|
||||
|
@ -846,7 +846,7 @@ static bool isOp(const TOKEN *tok)
|
|||
tok->str() == "<<" ||
|
||||
TOKEN::Match(tok, "[+-*/&|,]")));
|
||||
}
|
||||
|
||||
|
||||
void CheckOther::functionVariableUsage()
|
||||
{
|
||||
// Parse all executing scopes..
|
||||
|
@ -858,7 +858,7 @@ void CheckOther::functionVariableUsage()
|
|||
static const unsigned int USAGE_DECLARE = 1;
|
||||
static const unsigned int USAGE_READ = 2;
|
||||
static const unsigned int USAGE_WRITE = 4;
|
||||
|
||||
|
||||
int indentlevel = 0;
|
||||
for ( const TOKEN *tok = tok1; tok; tok = tok->next() )
|
||||
{
|
||||
|
@ -870,61 +870,61 @@ void CheckOther::functionVariableUsage()
|
|||
if ( indentlevel <= 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if ( TOKEN::Match(tok, "[;{}] bool|char|short|int|long|float|double %var% ;|=") )
|
||||
varUsage[ tok->strAt(2) ] = USAGE_DECLARE;
|
||||
|
||||
|
||||
if ( TOKEN::Match(tok, "[;{}] bool|char|short|int|long|float|double * %var% ;|=") )
|
||||
varUsage[ tok->strAt(3) ] = USAGE_DECLARE;
|
||||
|
||||
|
||||
if ( TOKEN::Match(tok, "delete|return %var%") )
|
||||
varUsage[ tok->strAt(1) ] |= USAGE_READ;
|
||||
|
||||
|
||||
if ( TOKEN::Match(tok, "%var% =") )
|
||||
varUsage[ tok->str() ] |= USAGE_WRITE;
|
||||
|
||||
|
||||
if ( TOKEN::Match(tok, "else %var% =") )
|
||||
varUsage[ tok->strAt(1) ] |= USAGE_WRITE;
|
||||
|
||||
|
||||
if ( TOKEN::Match(tok, ">>|& %var%") )
|
||||
varUsage[ tok->strAt(1) ] |= USAGE_WRITE;
|
||||
|
||||
|
||||
if ((TOKEN::Match(tok,"[(=&!]") || isOp(tok)) && TOKEN::Match(tok->next(), "%var%"))
|
||||
varUsage[ tok->strAt(1) ] |= USAGE_READ;
|
||||
|
||||
|
||||
if (TOKEN::Match(tok, "%var%") && (tok->next()->str()==")" || isOp(tok->next())))
|
||||
varUsage[ tok->str() ] |= USAGE_READ;
|
||||
|
||||
|
||||
if ( TOKEN::Match(tok, "[(,] %var% [,)]") )
|
||||
varUsage[ tok->strAt(1) ] |= USAGE_WRITE;
|
||||
}
|
||||
|
||||
|
||||
// Check usage of all variables in the current scope..
|
||||
for ( std::map<std::string, unsigned int>::const_iterator it = varUsage.begin(); it != varUsage.end(); ++it )
|
||||
{
|
||||
std::string varname = it->first;
|
||||
unsigned int usage = it->second;
|
||||
|
||||
|
||||
if (!isalpha(varname[0]))
|
||||
continue;
|
||||
|
||||
|
||||
if ( ! ( usage & USAGE_DECLARE ) )
|
||||
continue;
|
||||
|
||||
|
||||
if ( usage == USAGE_DECLARE )
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << _tokenizer->fileLine(tok1->next()) << ": Unused variable '" << varname << "'";
|
||||
_errorLogger->reportErr(errmsg.str());
|
||||
}
|
||||
|
||||
|
||||
else if ( ! (usage & USAGE_READ) )
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << _tokenizer->fileLine(tok1->next()) << ": Variable '" << varname << "' is assigned a value that is never used";
|
||||
_errorLogger->reportErr(errmsg.str());
|
||||
}
|
||||
|
||||
|
||||
else if ( ! (usage & USAGE_WRITE) )
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
|
@ -932,7 +932,7 @@ void CheckOther::functionVariableUsage()
|
|||
_errorLogger->reportErr(errmsg.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Goto next executing scope..
|
||||
tok1 = TOKEN::findmatch( tok1->next(), ") const| {" );
|
||||
}
|
||||
|
|
|
@ -70,10 +70,10 @@ public:
|
|||
|
||||
// Incomplete statement. A statement that only contains a constant or variable
|
||||
void CheckIncompleteStatement();
|
||||
|
||||
|
||||
/** Unreachable code below a 'return' */
|
||||
void unreachableCode();
|
||||
|
||||
|
||||
/** Unused function variables */
|
||||
void functionVariableUsage();
|
||||
private:
|
||||
|
|
|
@ -39,14 +39,14 @@ class FileLister
|
|||
{
|
||||
public:
|
||||
static void RecursiveAddFiles( std::vector<std::string> &filenames, const std::string &path, bool recursive );
|
||||
|
||||
|
||||
private:
|
||||
static bool AcceptFile( const std::string &filename );
|
||||
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
static void AddFiles( std::vector<std::string> &filenames, const std::string &path, const std::string &pattern );
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
static void AddFiles( std::vector<std::string> &filenames, const std::string &path, const std::string &pattern );
|
||||
#endif
|
||||
|
|
136
cppcheck.cpp
136
cppcheck.cpp
|
@ -16,10 +16,10 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/
|
||||
*/
|
||||
#include "cppcheck.h"
|
||||
|
||||
|
||||
#include "preprocessor.h" // preprocessor.
|
||||
#include "tokenize.h" // <- Tokenizer
|
||||
|
||||
|
||||
#include "CheckMemoryLeak.h"
|
||||
#include "CheckBufferOverrun.h"
|
||||
#include "CheckClass.h"
|
||||
|
@ -27,76 +27,76 @@
|
|||
#include "CheckOther.h"
|
||||
#include "CheckFunctionUsage.h"
|
||||
#include "FileLister.h"
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
CppCheck::CppCheck( ErrorLogger &errorLogger ) : _checkFunctionUsage( this )
|
||||
{
|
||||
_errorLogger = &errorLogger;
|
||||
}
|
||||
|
||||
|
||||
CppCheck::~CppCheck()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CppCheck::settings( const Settings &settings )
|
||||
{
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
|
||||
void CppCheck::addFile( const std::string &path )
|
||||
{
|
||||
_filenames.push_back( path );
|
||||
}
|
||||
|
||||
|
||||
void CppCheck::addFile( const std::string &path, const std::string &content )
|
||||
{
|
||||
_filenames.push_back( path );
|
||||
_fileContents[ path ] = content;
|
||||
}
|
||||
|
||||
|
||||
std::string CppCheck::parseFromArgs( int argc, const char* const argv[] )
|
||||
{
|
||||
std::vector<std::string> pathnames;
|
||||
bool Recursive = false;
|
||||
|
||||
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
// Flag used for various purposes during debugging
|
||||
if (strcmp(argv[i],"--debug") == 0)
|
||||
_settings._debug = true;
|
||||
|
||||
|
||||
// Show all messages
|
||||
else if (strcmp(argv[i],"--all") == 0)
|
||||
_settings._showAll = true;
|
||||
|
||||
|
||||
// Only print something when there are errors
|
||||
else if (strcmp(argv[i],"--errorsonly")==0)
|
||||
_settings._errorsOnly = true;
|
||||
|
||||
|
||||
// Checking coding style
|
||||
else if (strcmp(argv[i],"--style")==0)
|
||||
_settings._checkCodingStyle = true;
|
||||
|
||||
|
||||
// Recursively check source files
|
||||
else if (strcmp(argv[i],"--recursive")==0)
|
||||
Recursive = true;
|
||||
|
||||
|
||||
// Verbose error messages (configuration info)
|
||||
else if (strcmp(argv[i],"--verbose")==0)
|
||||
_settings._verbose = true;
|
||||
|
||||
|
||||
else
|
||||
pathnames.push_back( argv[i] );
|
||||
}
|
||||
|
||||
|
||||
// --recursive was used
|
||||
if ( Recursive )
|
||||
{
|
||||
|
@ -108,7 +108,7 @@ std::string CppCheck::parseFromArgs( int argc, const char* const argv[] )
|
|||
else
|
||||
{
|
||||
// Handle situation: cppcheck --recursive path1 path2
|
||||
|
||||
|
||||
// Execute RecursiveAddFiles() to each given file parameter
|
||||
std::vector<std::string>::const_iterator iter;
|
||||
for(iter=pathnames.begin(); iter!=pathnames.end(); iter++)
|
||||
|
@ -121,7 +121,7 @@ std::string CppCheck::parseFromArgs( int argc, const char* const argv[] )
|
|||
for(iter=pathnames.begin(); iter!=pathnames.end(); iter++)
|
||||
FileLister::RecursiveAddFiles( _filenames, iter->c_str(), false );
|
||||
}
|
||||
|
||||
|
||||
if (_filenames.empty())
|
||||
{
|
||||
std::ostringstream oss;
|
||||
|
@ -141,15 +141,15 @@ std::string CppCheck::parseFromArgs( int argc, const char* const argv[] )
|
|||
" --verbose More detailed error reports\n";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
|
||||
// Check function usage if "--style" and "--all" was given.
|
||||
// There will be false positives for exported library functions
|
||||
if ( _settings._showAll && _settings._checkCodingStyle )
|
||||
_settings._checkFunctionUsage = true;
|
||||
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
void CppCheck::check()
|
||||
{
|
||||
std::sort( _filenames.begin(), _filenames.end() );
|
||||
|
@ -157,11 +157,11 @@ void CppCheck::check()
|
|||
{
|
||||
_errout.str("");
|
||||
std::string fname = _filenames[c];
|
||||
|
||||
|
||||
// If only errors are printed, print filename after the check
|
||||
if ( _settings._errorsOnly == false )
|
||||
_errorLogger->reportOut( std::string( "Checking " ) + fname + std::string( "..." ) );
|
||||
|
||||
|
||||
Preprocessor preprocessor( this );
|
||||
std::map<std::string, std::string> code;
|
||||
if( _fileContents.size() > 0 && _fileContents.find( _filenames[c] ) != _fileContents.end() )
|
||||
|
@ -176,17 +176,17 @@ void CppCheck::check()
|
|||
std::ifstream fin( fname.c_str() );
|
||||
preprocessor.preprocess(fin, code, fname);
|
||||
}
|
||||
|
||||
|
||||
for ( std::map<std::string,std::string>::const_iterator it = code.begin(); it != code.end(); ++it )
|
||||
{
|
||||
cfg = it->first;
|
||||
checkFile(it->second, _filenames[c].c_str());
|
||||
}
|
||||
|
||||
|
||||
if ( _settings._errorsOnly == false && _errout.str().empty() )
|
||||
_errorLogger->reportOut( "No errors found" );
|
||||
}
|
||||
|
||||
|
||||
// This generates false positives - especially for libraries
|
||||
_settings._verbose = false;
|
||||
if ( _settings._checkFunctionUsage )
|
||||
|
@ -194,47 +194,47 @@ void CppCheck::check()
|
|||
_errout.str("");
|
||||
if( _settings._errorsOnly == false )
|
||||
_errorLogger->reportOut( "Checking usage of global functions (this may take several minutes).." );
|
||||
|
||||
|
||||
_checkFunctionUsage.check();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// CppCheck - A function that checks a specified file
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
void CppCheck::checkFile(const std::string &code, const char FileName[])
|
||||
{
|
||||
Tokenizer _tokenizer;
|
||||
|
||||
|
||||
// Tokenize the file
|
||||
{
|
||||
std::istringstream istr(code);
|
||||
_tokenizer.tokenize(istr, FileName);
|
||||
}
|
||||
|
||||
|
||||
_tokenizer.fillFunctionList();
|
||||
|
||||
|
||||
// Check that the memsets are valid.
|
||||
// The 'memset' function can do dangerous things if used wrong.
|
||||
// Important: The checking doesn't work on simplified tokens list.
|
||||
CheckClass checkClass( &_tokenizer, _settings, this );
|
||||
checkClass.CheckMemset();
|
||||
|
||||
|
||||
|
||||
// Check for unsigned divisions where one operand is signed
|
||||
// Very important to run it before 'SimplifyTokenList'
|
||||
CheckOther checkOther( &_tokenizer, this );
|
||||
if ( _settings._checkCodingStyle )
|
||||
checkOther.CheckUnsignedDivision();
|
||||
|
||||
|
||||
// Give warning when using char variable as array index
|
||||
// Doesn't work on simplified token list ('unsigned')
|
||||
if ( _settings._checkCodingStyle )
|
||||
checkOther.CheckCharVariable();
|
||||
|
||||
|
||||
|
||||
// Including header which is not needed (too many false positives)
|
||||
// if ( _settings._checkCodingStyle )
|
||||
|
@ -242,96 +242,96 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
|
|||
// CheckHeaders checkHeaders( &tokenizer );
|
||||
// checkHeaders.WarningIncludeHeader();
|
||||
// }
|
||||
|
||||
|
||||
|
||||
_tokenizer.simplifyTokenList();
|
||||
|
||||
|
||||
|
||||
if ( _settings._checkFunctionUsage )
|
||||
_checkFunctionUsage.parseTokens(_tokenizer);
|
||||
|
||||
|
||||
// Memory leak
|
||||
CheckMemoryLeakClass checkMemoryLeak( &_tokenizer, _settings, this );
|
||||
checkMemoryLeak.CheckMemoryLeak();
|
||||
|
||||
|
||||
// Buffer overruns..
|
||||
CheckBufferOverrunClass checkBufferOverrun( &_tokenizer, _settings, this );
|
||||
checkBufferOverrun.CheckBufferOverrun();
|
||||
|
||||
|
||||
// Check that all class constructors are ok.
|
||||
checkClass.CheckConstructors();
|
||||
|
||||
|
||||
// Check that all base classes have virtual destructors
|
||||
checkClass.virtualDestructor();
|
||||
|
||||
|
||||
if (_settings._showAll)
|
||||
{
|
||||
// Check for "if (a=b)"
|
||||
checkOther.CheckIfAssignment();
|
||||
|
||||
|
||||
// Check for case without break
|
||||
// Disabled because it generates many false positives
|
||||
// CheckCaseWithoutBreak();
|
||||
|
||||
|
||||
// Dangerous usage of strtok
|
||||
// Disabled because it generates false positives
|
||||
//WarningStrTok();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Dangerous functions, such as 'gets' and 'scanf'
|
||||
checkBufferOverrun.WarningDangerousFunctions();
|
||||
|
||||
|
||||
|
||||
// Invalid function usage..
|
||||
checkOther.InvalidFunctionUsage();
|
||||
|
||||
|
||||
|
||||
if (_settings._checkCodingStyle)
|
||||
{
|
||||
// Check that all private functions are called.
|
||||
checkClass.CheckUnusedPrivateFunctions();
|
||||
|
||||
|
||||
// Warning upon c-style pointer casts
|
||||
const char *ext = strrchr(FileName, '.');
|
||||
if (ext && strcmp(ext,".cpp")==0)
|
||||
checkOther.WarningOldStylePointerCast();
|
||||
|
||||
|
||||
// Use standard functions instead
|
||||
checkOther.WarningIsDigit();
|
||||
checkOther.WarningIsAlpha();
|
||||
|
||||
|
||||
checkClass.CheckOperatorEq1();
|
||||
|
||||
|
||||
// if (a) delete a;
|
||||
checkOther.WarningRedundantCode();
|
||||
|
||||
|
||||
// if (condition);
|
||||
checkOther.WarningIf();
|
||||
|
||||
|
||||
// Variable scope (check if the scope could be limited)
|
||||
//CheckVariableScope();
|
||||
|
||||
|
||||
// Check if a constant function parameter is passed by value
|
||||
checkOther.CheckConstantFunctionParameter();
|
||||
|
||||
|
||||
// Unused struct members..
|
||||
checkOther.CheckStructMemberUsage();
|
||||
|
||||
|
||||
// Check for various types of incomplete statements that could for example
|
||||
// mean that an ';' has been added by accident
|
||||
checkOther.CheckIncompleteStatement();
|
||||
|
||||
|
||||
// Unreachable code below a 'return' statement
|
||||
checkOther.unreachableCode();
|
||||
|
||||
|
||||
// Usage of local functions
|
||||
checkOther.functionVariableUsage();
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
void CppCheck::reportErr( const std::string &errmsg)
|
||||
{
|
||||
if ( /*OnlyReportUniqueErrors*/ true )
|
||||
|
@ -340,19 +340,19 @@ void CppCheck::reportErr( const std::string &errmsg)
|
|||
return;
|
||||
_errorList.push_back( errmsg );
|
||||
}
|
||||
|
||||
|
||||
std::string errmsg2( errmsg );
|
||||
if ( _settings._verbose )
|
||||
{
|
||||
errmsg2 += "\n Defines=\'" + cfg + "\'\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
_errorLogger->reportErr( errmsg2 );
|
||||
|
||||
|
||||
_errout << errmsg2 << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void CppCheck::reportOut( const std::string &outmsg)
|
||||
{
|
||||
// This is currently never called. It is here just to comply with
|
||||
|
|
30
cppcheck.h
30
cppcheck.h
|
@ -15,10 +15,10 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CPPCHECK_H
|
||||
#define CPPCHECK_H
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
|
@ -27,7 +27,7 @@
|
|||
#include "settings.h"
|
||||
#include "errorlogger.h"
|
||||
#include "CheckFunctionUsage.h"
|
||||
|
||||
|
||||
/**
|
||||
* This is the base class which will use other classes to do
|
||||
* static code analysis for C and C++ code to find possible
|
||||
|
@ -41,18 +41,18 @@ class CppCheck : public ErrorLogger
|
|||
* Constructor.
|
||||
*/
|
||||
CppCheck( ErrorLogger &errorLogger );
|
||||
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~CppCheck();
|
||||
|
||||
|
||||
/**
|
||||
* This starts the actual checking. Note that you must call
|
||||
* parseFromArgs() or settings() and addFile() before calling this.
|
||||
*/
|
||||
void check();
|
||||
|
||||
|
||||
/**
|
||||
* Adjust the settings before doing the check. E.g. show only
|
||||
* actual bugs or also coding style issues.
|
||||
|
@ -60,7 +60,7 @@ class CppCheck : public ErrorLogger
|
|||
* @param settings New settings which will overwrite the old.
|
||||
*/
|
||||
void settings( const Settings &settings );
|
||||
|
||||
|
||||
/**
|
||||
* Add new file to be checked.
|
||||
*
|
||||
|
@ -69,7 +69,7 @@ class CppCheck : public ErrorLogger
|
|||
* should be added to the list. Include filese are gathered automatically.
|
||||
*/
|
||||
void addFile( const std::string &path );
|
||||
|
||||
|
||||
/**
|
||||
* Add new unreal file to be checked.
|
||||
*
|
||||
|
@ -78,7 +78,7 @@ class CppCheck : public ErrorLogger
|
|||
* the content of the file.
|
||||
*/
|
||||
void addFile( const std::string &path, const std::string &content );
|
||||
|
||||
|
||||
/**
|
||||
* Parse command line args and get settings and file lists
|
||||
* from there.
|
||||
|
@ -90,10 +90,10 @@ class CppCheck : public ErrorLogger
|
|||
* checked.
|
||||
*/
|
||||
std::string parseFromArgs( int argc, const char* const argv[] );
|
||||
|
||||
|
||||
private:
|
||||
void checkFile(const std::string &code, const char FileName[]);
|
||||
|
||||
|
||||
/**
|
||||
* Errors and warnings are directed here.
|
||||
*
|
||||
|
@ -102,14 +102,14 @@ class CppCheck : public ErrorLogger
|
|||
* "[main.cpp:4] Uninitialized member variable"
|
||||
*/
|
||||
virtual void reportErr( const std::string &errmsg);
|
||||
|
||||
|
||||
/**
|
||||
* Information about progress is directed here.
|
||||
*
|
||||
* @param outmsg, E.g. "Checking main.cpp..."
|
||||
*/
|
||||
virtual void reportOut( const std::string &outmsg);
|
||||
|
||||
|
||||
std::list<std::string> _errorList;
|
||||
std::ostringstream _errout;
|
||||
Settings _settings;
|
||||
|
@ -118,9 +118,9 @@ class CppCheck : public ErrorLogger
|
|||
std::map<std::string,std::string> _fileContents;
|
||||
CheckFunctionUsage _checkFunctionUsage;
|
||||
ErrorLogger *_errorLogger;
|
||||
|
||||
|
||||
/** Current configuration */
|
||||
std::string cfg;
|
||||
};
|
||||
|
||||
|
||||
#endif // CPPCHECK_H
|
||||
|
|
|
@ -15,21 +15,21 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
|
||||
#include "cppcheckexecutor.h"
|
||||
#include "cppcheck.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
CppCheckExecutor::CppCheckExecutor()
|
||||
{
|
||||
//ctor
|
||||
}
|
||||
|
||||
|
||||
CppCheckExecutor::~CppCheckExecutor()
|
||||
{
|
||||
//dtor
|
||||
}
|
||||
|
||||
|
||||
void CppCheckExecutor::check( int argc, const char* const argv[] )
|
||||
{
|
||||
CppCheck cppCheck( *this );
|
||||
|
@ -39,12 +39,12 @@ void CppCheckExecutor::check( int argc, const char* const argv[] )
|
|||
else
|
||||
std::cout << result;
|
||||
}
|
||||
|
||||
|
||||
void CppCheckExecutor::reportErr( const std::string &errmsg)
|
||||
{
|
||||
std::cerr << errmsg << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void CppCheckExecutor::reportOut( const std::string &outmsg)
|
||||
{
|
||||
std::cout << outmsg << std::endl;
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CPPCHECKEXECUTOR_H
|
||||
#define CPPCHECKEXECUTOR_H
|
||||
|
||||
|
||||
#include "errorlogger.h"
|
||||
|
||||
|
||||
/**
|
||||
* This class works as an example of how CppCheck can be used in external
|
||||
* programs without very little knowledge of the internal parts of the
|
||||
|
@ -35,12 +35,12 @@ public:
|
|||
* Constructor
|
||||
*/
|
||||
CppCheckExecutor();
|
||||
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~CppCheckExecutor();
|
||||
|
||||
|
||||
/**
|
||||
* Starts the checking.
|
||||
*
|
||||
|
@ -48,7 +48,7 @@ public:
|
|||
* @param argv from main()
|
||||
*/
|
||||
void check( int argc, const char* const argv[] );
|
||||
|
||||
|
||||
/**
|
||||
* Errors and warnings are directed here. This should be
|
||||
* called by the CppCheck class only.
|
||||
|
@ -58,7 +58,7 @@ public:
|
|||
* "[main.cpp:4] Uninitialized member variable"
|
||||
*/
|
||||
virtual void reportErr( const std::string &errmsg);
|
||||
|
||||
|
||||
/**
|
||||
* Information about progress is directed here. This should be
|
||||
* called by the CppCheck class only.
|
||||
|
@ -67,5 +67,5 @@ public:
|
|||
*/
|
||||
virtual void reportOut( const std::string &outmsg);
|
||||
};
|
||||
|
||||
|
||||
#endif // CPPCHECKEXECUTOR_H
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ERRORLOGGER_H
|
||||
#define ERRORLOGGER_H
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
/**
|
||||
* This is an interface, which the class responsible of error logging
|
||||
* should implement.
|
||||
|
@ -29,7 +29,7 @@ class ErrorLogger
|
|||
{
|
||||
public:
|
||||
virtual ~ErrorLogger() {}
|
||||
|
||||
|
||||
/**
|
||||
* Errors and warnings are directed here.
|
||||
*
|
||||
|
@ -38,7 +38,7 @@ public:
|
|||
* "[main.cpp:4] Uninitialized member variable"
|
||||
*/
|
||||
virtual void reportErr( const std::string &errmsg) = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Information about progress is directed here.
|
||||
*
|
||||
|
@ -46,5 +46,5 @@ public:
|
|||
*/
|
||||
virtual void reportOut( const std::string &outmsg) = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif // #ifndef ERRORLOGGER_H
|
||||
|
|
|
@ -114,7 +114,7 @@ std::string Preprocessor::read(std::istream &istr, const std::string &filename)
|
|||
{
|
||||
ch = (char)istr.get();
|
||||
code << std::string(1,ch);
|
||||
|
||||
|
||||
// Avoid exiting loop if string contains "-characters
|
||||
ch = 0;
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ std::string Preprocessor::read(std::istream &istr, const std::string &filename)
|
|||
code << std::string(1, ch);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return code.str();
|
||||
}
|
||||
|
||||
|
@ -159,7 +159,7 @@ void Preprocessor::preprocess(std::istream &istr, std::map<std::string, std::str
|
|||
std::string::size_type loc = 0;
|
||||
while ( (loc = codestr.find("\t", loc)) != std::string::npos )
|
||||
codestr[loc] = ' ';
|
||||
|
||||
|
||||
// Remove all indentation..
|
||||
if ( !codestr.empty() && codestr[0] == ' ' )
|
||||
codestr.erase( 0, codestr.find_first_not_of(" ") );
|
||||
|
|
|
@ -35,22 +35,22 @@ public:
|
|||
|
||||
/** Just read the code into a string. Perform simple cleanup of the code */
|
||||
std::string read(std::istream &istr, 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 );
|
||||
|
||||
|
||||
ErrorLogger *_errorLogger;
|
||||
};
|
||||
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
|
||||
Settings::Settings()
|
||||
{
|
||||
_debug = false;
|
||||
|
@ -27,8 +27,8 @@ Settings::Settings()
|
|||
_checkFunctionUsage = false;
|
||||
_verbose = false;
|
||||
}
|
||||
|
||||
|
||||
Settings::~Settings()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SETTINGS_H
|
||||
#define SETTINGS_H
|
||||
|
||||
|
||||
/**
|
||||
* This is just a container for general settings so that we don't need
|
||||
* to pass individual values to functions or constructors now or in the
|
||||
|
@ -29,7 +29,7 @@ class Settings
|
|||
public:
|
||||
Settings();
|
||||
virtual ~Settings();
|
||||
|
||||
|
||||
bool _debug;
|
||||
bool _showAll;
|
||||
bool _checkCodingStyle;
|
||||
|
@ -37,5 +37,5 @@ public:
|
|||
bool _checkFunctionUsage;
|
||||
bool _verbose;
|
||||
};
|
||||
|
||||
|
||||
#endif // SETTINGS_H
|
||||
|
|
|
@ -68,7 +68,7 @@ private:
|
|||
TEST_CASE( initvar_same_classname ); // BUG 2208157
|
||||
TEST_CASE( initvar_chained_assign ); // BUG 2270433
|
||||
TEST_CASE( initvar_2constructors ); // BUG 2270353
|
||||
|
||||
|
||||
TEST_CASE( initvar_private_constructor ); // BUG 2354171 - private constructor
|
||||
|
||||
TEST_CASE( initvar_destructor ); // No variables need to be initialized in a destructor
|
||||
|
@ -186,7 +186,7 @@ private:
|
|||
ASSERT_EQUALS( std::string(""), err );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void initvar_operator_eq2()
|
||||
{
|
||||
check( "class Fred\n"
|
||||
|
@ -198,7 +198,7 @@ private:
|
|||
"};\n" );
|
||||
ASSERT_EQUALS( std::string("[test.cpp:5] Uninitialized member variable 'Fred::i'\n"), errout.str() );
|
||||
}
|
||||
|
||||
|
||||
void initvar_operator_eq3()
|
||||
{
|
||||
check( "class Fred\n"
|
||||
|
@ -295,7 +295,7 @@ private:
|
|||
ASSERT_EQUALS( std::string(""), err );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void initvar_private_constructor()
|
||||
{
|
||||
check( "class Fred\n"
|
||||
|
|
|
@ -68,7 +68,7 @@ private:
|
|||
std::string err( errout.str() );
|
||||
ASSERT_EQUALS( std::string(""), errout.str() );
|
||||
}
|
||||
|
||||
|
||||
void return1()
|
||||
{
|
||||
check( "int f1()\n"
|
||||
|
@ -78,7 +78,7 @@ private:
|
|||
std::string err( errout.str() );
|
||||
ASSERT_EQUALS( std::string(""), errout.str() );
|
||||
}
|
||||
|
||||
|
||||
void callback1()
|
||||
{
|
||||
check( "void f1()\n"
|
||||
|
@ -88,7 +88,7 @@ private:
|
|||
std::string err( errout.str() );
|
||||
ASSERT_EQUALS( std::string(""), errout.str() );
|
||||
}
|
||||
|
||||
|
||||
void else1()
|
||||
{
|
||||
check( "void f1()\n"
|
||||
|
|
|
@ -123,10 +123,10 @@ private:
|
|||
TEST_CASE( linux_list_1 );
|
||||
|
||||
TEST_CASE( sizeof1 );
|
||||
|
||||
|
||||
TEST_CASE( realloc1 );
|
||||
TEST_CASE( realloc2 );
|
||||
|
||||
|
||||
TEST_CASE( assign );
|
||||
}
|
||||
|
||||
|
@ -807,7 +807,7 @@ private:
|
|||
std::string err( errout.str() );
|
||||
ASSERT_EQUALS( std::string("[test.cpp:11]: Memory leak: p\n"), err );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void func8()
|
||||
{
|
||||
|
@ -818,7 +818,7 @@ private:
|
|||
"}\n" );
|
||||
ASSERT_EQUALS( std::string(""), errout.str() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
@ -970,7 +970,7 @@ private:
|
|||
ASSERT_EQUALS( std::string("[test.cpp:12]: Memory leak: s2\n"), err );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void realloc1()
|
||||
{
|
||||
check( "void foo()\n"
|
||||
|
@ -978,10 +978,10 @@ private:
|
|||
" char *a = (char *)malloc(10);\n"
|
||||
" a = realloc(a, 100);\n"
|
||||
"}\n" );
|
||||
|
||||
|
||||
ASSERT_EQUALS( std::string("[test.cpp:5]: Memory leak: a\n"), errout.str() );
|
||||
}
|
||||
|
||||
|
||||
void realloc2()
|
||||
{
|
||||
check( "void foo()\n"
|
||||
|
@ -990,10 +990,10 @@ private:
|
|||
" a = (char *)realloc(a, 100);\n"
|
||||
" free(a);\n"
|
||||
"}\n" );
|
||||
|
||||
|
||||
ASSERT_EQUALS( std::string(""), errout.str() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void assign()
|
||||
{
|
||||
|
@ -1003,25 +1003,25 @@ private:
|
|||
" a = 0;\n"
|
||||
" free(a);\n"
|
||||
"}\n" );
|
||||
|
||||
|
||||
ASSERT_EQUALS( std::string("[test.cpp:3]: Memory leak: a\n"), errout.str() );
|
||||
|
||||
|
||||
check( "void foo()\n"
|
||||
"{\n"
|
||||
" char *a = (char *)malloc(10);\n"
|
||||
" char *p = a;\n"
|
||||
" free(p);\n"
|
||||
"}\n" );
|
||||
|
||||
|
||||
ASSERT_EQUALS( std::string(""), errout.str() );
|
||||
|
||||
|
||||
check( "void foo()\n"
|
||||
"{\n"
|
||||
" char *a = (char *)malloc(10);\n"
|
||||
" a += 10;\n"
|
||||
" free(a - 10);\n"
|
||||
"}\n" );
|
||||
|
||||
|
||||
ASSERT_EQUALS( std::string(""), errout.str() );
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ private:
|
|||
{
|
||||
// Just read the code into a string. Perform simple cleanup of the code
|
||||
TEST_CASE(readCode);
|
||||
|
||||
|
||||
// The bug that started the whole work with the new preprocessor
|
||||
TEST_CASE( Bug2190219 );
|
||||
|
||||
|
@ -63,7 +63,7 @@ private:
|
|||
TEST_CASE( multiline );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void readCode()
|
||||
{
|
||||
const char code[] = " \t a //\n"
|
||||
|
@ -73,7 +73,7 @@ private:
|
|||
std::string codestr( p.read(istr,"") );
|
||||
ASSERT_EQUALS( "a \n#aa b \n", codestr );
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool cmpmaps(const std::map<std::string, std::string> &m1, const std::map<std::string, std::string> &m2)
|
||||
{
|
||||
|
|
|
@ -15,53 +15,53 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "testsuite.h"
|
||||
#include "tokenize.h"
|
||||
#include <sstream>
|
||||
|
||||
|
||||
extern std::ostringstream errout;
|
||||
|
||||
|
||||
class TestSimplifyTokens : public TestFixture
|
||||
{
|
||||
public:
|
||||
TestSimplifyTokens() : TestFixture("TestSimplifyTokens")
|
||||
{ }
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
void run()
|
||||
{
|
||||
TEST_CASE( cast0 );
|
||||
TEST_CASE( sizeof1 );
|
||||
}
|
||||
|
||||
|
||||
std::string tok(const char code[])
|
||||
{
|
||||
std::istringstream istr(code);
|
||||
Tokenizer tokenizer;
|
||||
tokenizer.tokenize( istr, "test.cpp" );
|
||||
tokenizer.simplifyTokenList();
|
||||
|
||||
|
||||
std::string ret;
|
||||
for ( const TOKEN *tok = tokenizer.tokens(); tok; tok = tok->next() )
|
||||
{
|
||||
ret += std::string(tok->aaaa()) + " ";
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void cast0()
|
||||
{
|
||||
const char code1[] = " if ( p == (char *)0 ) ";
|
||||
const char code2[] = " if ( p == 0 ) ";
|
||||
ASSERT_EQUALS( tok(code1), tok(code2) );
|
||||
}
|
||||
|
||||
|
||||
void sizeof1()
|
||||
{
|
||||
const char code1[] = " struct ABC *abc = malloc(sizeof(*abc)); ";
|
||||
|
@ -69,5 +69,5 @@ private:
|
|||
ASSERT_EQUALS( tok(code1), tok(code2) );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
REGISTER_TEST( TestSimplifyTokens )
|
||||
|
|
|
@ -42,7 +42,7 @@ protected:
|
|||
|
||||
public:
|
||||
virtual void reportErr( const std::string &errmsg);
|
||||
|
||||
|
||||
virtual void reportOut( const std::string &outmsg);
|
||||
|
||||
TestFixture(const std::string &_name);
|
||||
|
|
|
@ -43,15 +43,15 @@ private:
|
|||
TEST_CASE( inlineasm );
|
||||
|
||||
TEST_CASE( dupfuncname );
|
||||
|
||||
|
||||
TEST_CASE( const_and_volatile_functions );
|
||||
|
||||
|
||||
TEST_CASE( numeric_true_condition );
|
||||
|
||||
|
||||
TEST_CASE( multi_compare );
|
||||
|
||||
|
||||
TEST_CASE( match1 );
|
||||
|
||||
|
||||
TEST_CASE( varid1 );
|
||||
}
|
||||
|
||||
|
@ -157,7 +157,7 @@ private:
|
|||
ASSERT_EQUALS( 1, static_cast<unsigned int>(tokenizer._functionList.size()) );
|
||||
ASSERT_EQUALS( std::string("b"), tokenizer._functionList[0]->aaaa() );
|
||||
}
|
||||
|
||||
|
||||
void const_and_volatile_functions()
|
||||
{
|
||||
const char code[] = "class B\n\
|
||||
|
@ -176,15 +176,15 @@ private:
|
|||
\n\
|
||||
void B::c() volatile\n\
|
||||
{}\n";
|
||||
|
||||
|
||||
|
||||
// tokenize..
|
||||
Tokenizer tokenizer;
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
|
||||
|
||||
tokenizer.fillFunctionList();
|
||||
|
||||
|
||||
ASSERT_EQUALS( 3, static_cast<unsigned int>(tokenizer._functionList.size()) );
|
||||
if( tokenizer._functionList.size() == 3 )
|
||||
{
|
||||
|
@ -193,7 +193,7 @@ private:
|
|||
ASSERT_EQUALS( std::string("c"), tokenizer._functionList[2]->str() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void numeric_true_condition()
|
||||
{
|
||||
|
@ -201,68 +201,68 @@ private:
|
|||
"{\n"
|
||||
" if (5==5);\n"
|
||||
"}\n";
|
||||
|
||||
|
||||
// tokenize..
|
||||
Tokenizer tokenizer;
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
|
||||
|
||||
tokenizer.simplifyTokenList();
|
||||
|
||||
|
||||
std::ostringstream ostr;
|
||||
for (const TOKEN *tok = tokenizer.tokens(); tok; tok = tok->next())
|
||||
ostr << " " << tok->str();
|
||||
ASSERT_EQUALS( std::string(" void f ( ) { if ( true ) ; }"), ostr.str() );
|
||||
}
|
||||
|
||||
|
||||
void multi_compare()
|
||||
{
|
||||
// Test for found
|
||||
ASSERT_EQUALS( 1, TOKEN::multiCompare( "one|two", "one" ) );
|
||||
ASSERT_EQUALS( 1, TOKEN::multiCompare( "one|two", "two" ) );
|
||||
ASSERT_EQUALS( 1, TOKEN::multiCompare( "verybig|two|", "two" ) );
|
||||
|
||||
|
||||
// Test for empty string found
|
||||
ASSERT_EQUALS( 0, TOKEN::multiCompare( "|one|two", "notfound" ) );
|
||||
ASSERT_EQUALS( 0, TOKEN::multiCompare( "one||two", "notfound" ) );
|
||||
ASSERT_EQUALS( 0, TOKEN::multiCompare( "one|two|", "notfound" ) );
|
||||
|
||||
|
||||
// Test for not found
|
||||
ASSERT_EQUALS( -1, TOKEN::multiCompare( "one|two", "notfound" ) );
|
||||
ASSERT_EQUALS( -1, TOKEN::multiCompare( "verybig|two", "s" ) );
|
||||
ASSERT_EQUALS( -1, TOKEN::multiCompare( "one|two", "ne" ) );
|
||||
ASSERT_EQUALS( -1, TOKEN::multiCompare( "abc|def", "a" ) );
|
||||
}
|
||||
|
||||
|
||||
void match1()
|
||||
{
|
||||
// Match "%var% | %var%"
|
||||
{
|
||||
const std::string code("abc|def");
|
||||
|
||||
|
||||
// tokenize..
|
||||
Tokenizer tokenizer;
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
|
||||
|
||||
// Match..
|
||||
ASSERT_EQUALS( true, TOKEN::Match(tokenizer.tokens(), "%var% | %var%") );
|
||||
}
|
||||
|
||||
|
||||
// Match "%var% || %var%"
|
||||
{
|
||||
const std::string code("abc||def");
|
||||
|
||||
|
||||
// tokenize..
|
||||
Tokenizer tokenizer;
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
|
||||
|
||||
// Match..
|
||||
ASSERT_EQUALS( true, TOKEN::Match(tokenizer.tokens(), "%var% || %var%") );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void varid1()
|
||||
{
|
||||
|
@ -274,13 +274,13 @@ private:
|
|||
" i = 3;\n"
|
||||
" i = 4;\n"
|
||||
"}\n" );
|
||||
|
||||
|
||||
// tokenize..
|
||||
Tokenizer tokenizer;
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
tokenizer.setVarId();
|
||||
|
||||
|
||||
for ( const TOKEN *tok = tokenizer.tokens(); tok; tok = tok->next() )
|
||||
{
|
||||
if ( tok->str() != "i" )
|
||||
|
|
|
@ -15,25 +15,25 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Check for unused variables..
|
||||
|
||||
|
||||
#define UNIT_TESTING
|
||||
#include "testsuite.h"
|
||||
#include "tokenize.h"
|
||||
#include "CheckOther.h"
|
||||
|
||||
|
||||
#include <sstream>
|
||||
extern std::ostringstream errout;
|
||||
|
||||
|
||||
class TestUnusedVar : public TestFixture
|
||||
{
|
||||
public:
|
||||
TestUnusedVar() : TestFixture("TestUnusedVar")
|
||||
{ }
|
||||
|
||||
|
||||
private:
|
||||
void check( const char code[] )
|
||||
{
|
||||
|
@ -42,27 +42,27 @@ private:
|
|||
std::istringstream istr(code);
|
||||
tokenizer.tokenize( istr, "test.cpp" );
|
||||
tokenizer.simplifyTokenList();
|
||||
|
||||
|
||||
// Clear the error buffer..
|
||||
errout.str("");
|
||||
|
||||
|
||||
// Check for unused variables..
|
||||
CheckOther checkOther( &tokenizer, this );
|
||||
checkOther.CheckStructMemberUsage();
|
||||
}
|
||||
|
||||
|
||||
void run()
|
||||
{
|
||||
TEST_CASE( structmember1 );
|
||||
TEST_CASE( structmember2 );
|
||||
TEST_CASE( structmember3 );
|
||||
|
||||
|
||||
TEST_CASE( localvar1 );
|
||||
TEST_CASE( localvar2 );
|
||||
TEST_CASE( localvar3 );
|
||||
TEST_CASE( localvar4 );
|
||||
}
|
||||
|
||||
|
||||
void structmember1()
|
||||
{
|
||||
check( "struct abc\n"
|
||||
|
@ -75,7 +75,7 @@ private:
|
|||
"[test.cpp:3]: struct member 'abc::b' is never read\n"
|
||||
"[test.cpp:4]: struct member 'abc::c' is never read\n"), errout.str() );
|
||||
}
|
||||
|
||||
|
||||
void structmember2()
|
||||
{
|
||||
check( "struct ABC\n"
|
||||
|
@ -94,7 +94,7 @@ private:
|
|||
"}\n" );
|
||||
ASSERT_EQUALS( std::string(""), errout.str() );
|
||||
}
|
||||
|
||||
|
||||
void structmember3()
|
||||
{
|
||||
check( "struct ABC\n"
|
||||
|
@ -114,11 +114,11 @@ private:
|
|||
"}\n" );
|
||||
ASSERT_EQUALS( std::string(""), errout.str() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void functionVariableUsage( const char code[] )
|
||||
{
|
||||
// Tokenize..
|
||||
|
@ -126,15 +126,15 @@ private:
|
|||
std::istringstream istr(code);
|
||||
tokenizer.tokenize( istr, "test.cpp" );
|
||||
tokenizer.simplifyTokenList();
|
||||
|
||||
|
||||
// Clear the error buffer..
|
||||
errout.str("");
|
||||
|
||||
|
||||
// Check for unused variables..
|
||||
CheckOther checkOther( &tokenizer, this );
|
||||
checkOther.functionVariableUsage();
|
||||
}
|
||||
|
||||
|
||||
void localvar1()
|
||||
{
|
||||
functionVariableUsage( "void foo()\n"
|
||||
|
@ -143,7 +143,7 @@ private:
|
|||
"}\n" );
|
||||
ASSERT_EQUALS( std::string("[test.cpp:2]: Variable 'i' is assigned a value that is never used\n"), errout.str() );
|
||||
}
|
||||
|
||||
|
||||
void localvar2()
|
||||
{
|
||||
functionVariableUsage( "void foo()\n"
|
||||
|
@ -153,7 +153,7 @@ private:
|
|||
"}\n" );
|
||||
ASSERT_EQUALS( std::string("[test.cpp:2]: Variable 'i' is not assigned a value\n"), errout.str() );
|
||||
}
|
||||
|
||||
|
||||
void localvar3()
|
||||
{
|
||||
functionVariableUsage( "void foo()\n"
|
||||
|
@ -165,7 +165,7 @@ private:
|
|||
"}\n" );
|
||||
ASSERT_EQUALS( std::string("[test.cpp:2]: Variable 'i' is assigned a value that is never used\n"), errout.str() );
|
||||
}
|
||||
|
||||
|
||||
void localvar4()
|
||||
{
|
||||
functionVariableUsage( "void foo()\n"
|
||||
|
@ -175,10 +175,10 @@ private:
|
|||
"}\n" );
|
||||
ASSERT_EQUALS( std::string(""), errout.str() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
REGISTER_TEST( TestUnusedVar )
|
||||
|
||||
|
||||
REGISTER_TEST( TestUnusedVar )
|
||||
|
||||
|
||||
|
|
36
token.cpp
36
token.cpp
|
@ -103,19 +103,19 @@ int TOKEN::multiCompare( const char *needle, const char *haystack )
|
|||
// If needle and haystack are both at the end, we have a match.
|
||||
if( *haystackPointer == 0 )
|
||||
return 1;
|
||||
|
||||
|
||||
haystackPointer = haystack;
|
||||
if( findNextOr )
|
||||
findNextOr = false;
|
||||
else
|
||||
emptyStringFound = true;
|
||||
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if( findNextOr )
|
||||
continue;
|
||||
|
||||
|
||||
// If haystack and needle don't share the same character, reset
|
||||
// haystackpointer and find next '|' character.
|
||||
if( *haystackPointer != *needle )
|
||||
|
@ -124,22 +124,22 @@ int TOKEN::multiCompare( const char *needle, const char *haystack )
|
|||
findNextOr = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// All characters in haystack and needle have matched this far
|
||||
haystackPointer++;
|
||||
}
|
||||
|
||||
|
||||
// If both needle and haystack are at the end, then we have a match.
|
||||
if( *haystackPointer == 0 )
|
||||
return 1;
|
||||
|
||||
|
||||
// If empty string was found or if last character in needle was '|'
|
||||
if( emptyStringFound || findNextOr == false )
|
||||
return 0;
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool TOKEN::Match(const TOKEN *tok, const char pattern[], const char *varname1[], const char *varname2[])
|
||||
{
|
||||
|
@ -176,11 +176,11 @@ bool TOKEN::Match(const TOKEN *tok, const char pattern[], const char *varname1[]
|
|||
if (!tok->isName())
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Accept any token
|
||||
else if (strcmp(str,"%any%")==0 )
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Variable name..
|
||||
|
@ -314,37 +314,37 @@ unsigned int TOKEN::varId() const
|
|||
{
|
||||
return _varId;
|
||||
}
|
||||
|
||||
|
||||
void TOKEN::varId( unsigned int id )
|
||||
{
|
||||
_varId = id;
|
||||
}
|
||||
|
||||
|
||||
TOKEN *TOKEN::next() const
|
||||
{
|
||||
return _next;
|
||||
}
|
||||
|
||||
|
||||
void TOKEN::next( TOKEN *next )
|
||||
{
|
||||
_next = next;
|
||||
}
|
||||
|
||||
|
||||
unsigned int TOKEN::fileIndex() const
|
||||
{
|
||||
return _fileIndex;
|
||||
}
|
||||
|
||||
|
||||
void TOKEN::fileIndex( unsigned int fileIndex )
|
||||
{
|
||||
_fileIndex = fileIndex;
|
||||
}
|
||||
|
||||
|
||||
unsigned int TOKEN::linenr() const
|
||||
{
|
||||
return _linenr;
|
||||
}
|
||||
|
||||
|
||||
void TOKEN::linenr( unsigned int linenr )
|
||||
{
|
||||
_linenr = linenr;
|
||||
|
|
40
token.h
40
token.h
|
@ -15,52 +15,52 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TOKEN_H
|
||||
#define TOKEN_H
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
class TOKEN
|
||||
{
|
||||
public:
|
||||
TOKEN();
|
||||
~TOKEN();
|
||||
void setstr( const char s[] );
|
||||
|
||||
|
||||
const std::string &str() const
|
||||
{ return _str; }
|
||||
|
||||
|
||||
const char *aaaa() const
|
||||
{ return _cstr; }
|
||||
|
||||
|
||||
char aaaa0() const
|
||||
{ return _cstr[0]; }
|
||||
|
||||
|
||||
char aaaa1() const
|
||||
{ return _cstr[1]; }
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Combine two tokens that belong to each other.
|
||||
* Ex: "<" and "=" may become "<="
|
||||
*/
|
||||
void combineWithNext(const char str1[], const char str2[]);
|
||||
|
||||
|
||||
/**
|
||||
* Unlink and delete next token.
|
||||
*/
|
||||
void deleteNext();
|
||||
|
||||
|
||||
/**
|
||||
* Returns token in given index, related to this token.
|
||||
* For example index 1 would return next token, and 2
|
||||
* would return next from that one.
|
||||
*/
|
||||
const TOKEN *tokAt(int index) const;
|
||||
|
||||
|
||||
const char *strAt(int index) const;
|
||||
|
||||
|
||||
/**
|
||||
* Match given token (or list of tokens) to a pattern list.
|
||||
*
|
||||
|
@ -89,13 +89,13 @@ public:
|
|||
* false if given token does not match with given pattern
|
||||
*/
|
||||
static bool Match(const TOKEN *tok, const char pattern[], const char *varname1[]=0, const char *varname2[]=0);
|
||||
|
||||
|
||||
bool isName() const;
|
||||
bool isNumber() const;
|
||||
bool isStandardType() const;
|
||||
static const TOKEN *findmatch(const TOKEN *tok, const char pattern[], const char *varname1[]=0, const char *varname2[]=0);
|
||||
static const TOKEN *findtoken(const TOKEN *tok1, const char *tokenstr[]);
|
||||
|
||||
|
||||
/**
|
||||
* Needle is build from multiple alternatives. If one of
|
||||
* them is equal to haystack, return value is 1. If there
|
||||
|
@ -110,20 +110,20 @@ public:
|
|||
* -1 if needle was not found
|
||||
*/
|
||||
static int multiCompare( const char *needle, const char *haystack );
|
||||
|
||||
|
||||
|
||||
unsigned int linenr() const;
|
||||
void linenr( unsigned int linenr );
|
||||
|
||||
|
||||
unsigned int fileIndex() const;
|
||||
void fileIndex( unsigned int fileIndex );
|
||||
|
||||
|
||||
TOKEN *next() const;
|
||||
void next( TOKEN *next );
|
||||
|
||||
|
||||
unsigned int varId() const;
|
||||
void varId( unsigned int id );
|
||||
|
||||
|
||||
private:
|
||||
std::string _str;
|
||||
char * _cstr;
|
||||
|
@ -134,5 +134,5 @@ private:
|
|||
unsigned int _fileIndex;
|
||||
unsigned int _linenr;
|
||||
};
|
||||
|
||||
|
||||
#endif // TOKEN_H
|
||||
|
|
24
tokenize.cpp
24
tokenize.cpp
|
@ -73,7 +73,7 @@ TOKEN *Tokenizer::_gettok(TOKEN *tok, int index)
|
|||
}
|
||||
return tok;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const TOKEN *Tokenizer::tokens() const
|
||||
|
@ -455,7 +455,7 @@ void Tokenizer::tokenizeCode(std::istream &code, const unsigned int FileIndex)
|
|||
{
|
||||
// Append token..
|
||||
CurrentToken += c;
|
||||
|
||||
|
||||
if ( c == '\n' )
|
||||
++lineno;
|
||||
|
||||
|
@ -600,7 +600,7 @@ void Tokenizer::tokenizeCode(std::istream &code, const unsigned int FileIndex)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Remove "volatile"
|
||||
while ( TOKEN::Match(_tokens, "volatile") )
|
||||
{
|
||||
|
@ -619,20 +619,20 @@ void Tokenizer::tokenizeCode(std::istream &code, const unsigned int FileIndex)
|
|||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
void Tokenizer::setVarId()
|
||||
{
|
||||
// Clear all variable ids
|
||||
for ( TOKEN *tok = _tokens; tok; tok = tok->next() )
|
||||
tok->varId( 0 );
|
||||
|
||||
|
||||
// Set variable ids..
|
||||
unsigned int _varId = 0;
|
||||
for ( TOKEN *tok = _tokens; tok; tok = tok->next() )
|
||||
{
|
||||
if ( ! TOKEN::Match(tok, "[;{}(] %type% %var%") )
|
||||
continue;
|
||||
|
||||
|
||||
// Determine name of declared variable..
|
||||
const char *varname = 0;
|
||||
TOKEN *tok2 = tok->next();
|
||||
|
@ -644,7 +644,7 @@ void Tokenizer::setVarId()
|
|||
break;
|
||||
tok2 = tok2->next();
|
||||
}
|
||||
|
||||
|
||||
// Variable declaration found => Set variable ids
|
||||
if ( TOKEN::Match(tok2, "[;[=]") && varname )
|
||||
{
|
||||
|
@ -669,7 +669,7 @@ void Tokenizer::setVarId()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Simplify token list
|
||||
|
@ -1059,7 +1059,7 @@ bool Tokenizer::simplifyConditions()
|
|||
tok->next()->setstr((tok->next()->str() != "0") ? "true" : "false");
|
||||
ret = false;
|
||||
}
|
||||
|
||||
|
||||
// Reduce "(%num% == %num%)" => "(true)"/"(false)"
|
||||
if ( (TOKEN::Match(tok, "&&") || TOKEN::Match(tok, "||") || TOKEN::Match(tok, "(")) &&
|
||||
TOKEN::Match(tok->tokAt(1), "%num% %any% %num%") &&
|
||||
|
@ -1068,7 +1068,7 @@ bool Tokenizer::simplifyConditions()
|
|||
double op1 = (strstr(tok->strAt(1), "0x")) ? strtol(tok->strAt(1),0,16) : atof( tok->strAt(1) );
|
||||
double op2 = (strstr(tok->strAt(3), "0x")) ? strtol(tok->strAt(3),0,16) : atof( tok->strAt(3) );
|
||||
std::string cmp = tok->strAt(2);
|
||||
|
||||
|
||||
bool result = false;
|
||||
if ( cmp == "==" )
|
||||
result = (op1 == op2);
|
||||
|
@ -1084,13 +1084,13 @@ bool Tokenizer::simplifyConditions()
|
|||
result = (op1 < op2);
|
||||
else
|
||||
cmp = "";
|
||||
|
||||
|
||||
if ( ! cmp.empty() )
|
||||
{
|
||||
tok = tok->next();
|
||||
tok->deleteNext();
|
||||
tok->deleteNext();
|
||||
|
||||
|
||||
tok->setstr( result ? "true" : "false" );
|
||||
ret = false;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ private:
|
|||
* Helper function for "tokenize". This recursively parses into included header files.
|
||||
*/
|
||||
void tokenizeCode(std::istream &code, const unsigned int FileIndex=0);
|
||||
|
||||
|
||||
public:
|
||||
Tokenizer();
|
||||
~Tokenizer();
|
||||
|
@ -50,7 +50,7 @@ public:
|
|||
* @param FileName The filename
|
||||
*/
|
||||
void tokenize(std::istream &code, const char FileName[]);
|
||||
|
||||
|
||||
/** Set variable id */
|
||||
void setVarId();
|
||||
|
||||
|
|
Loading…
Reference in New Issue