Refactoring: Errors are no longer logged via global functions to a global stream. Instead callback function is used via interface.

ErrorLogger interface was added and taken into use.
This commit is contained in:
Reijo Tomperi 2008-11-20 22:19:26 +00:00
parent 180e3b99e6
commit 51e9d98a5f
33 changed files with 239 additions and 157 deletions

View File

@ -28,6 +28,7 @@
#include <list>
#include <cstring>
#include <stdlib.h> // <- strtoul
//---------------------------------------------------------------------------
@ -35,9 +36,10 @@
// CallStack used when parsing into subfunctions.
CheckBufferOverrunClass::CheckBufferOverrunClass( Tokenizer *tokenizer )
CheckBufferOverrunClass::CheckBufferOverrunClass( Tokenizer *tokenizer, ErrorLogger *errorLogger )
{
_tokenizer = tokenizer;
_errorLogger = errorLogger;
}
CheckBufferOverrunClass::~CheckBufferOverrunClass()
@ -53,7 +55,7 @@ void CheckBufferOverrunClass::ReportError(const TOKEN *tok, const char errmsg[])
for ( it = CallStack.begin(); it != CallStack.end(); it++ )
ostr << _tokenizer->fileLine(*it ) << " -> ";
ostr << _tokenizer->fileLine(tok) << ": " << errmsg;
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
}
//---------------------------------------------------------------------------
@ -504,14 +506,14 @@ void CheckBufferOverrunClass::WarningDangerousFunctions()
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok) << ": Found 'gets'. You should use 'fgets' instead";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
}
else if (Match(tok, "scanf (") && strcmp(Tokenizer::getstr(tok,2),"\"%s\"") == 0)
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok) << ": Found 'scanf'. You should use 'fgets' instead";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
}
}
}

View File

@ -23,11 +23,12 @@
//---------------------------------------------------------------------------
#include "tokenize.h"
#include "errorlogger.h"
class CheckBufferOverrunClass
{
public:
CheckBufferOverrunClass( Tokenizer *tokenizer );
CheckBufferOverrunClass( Tokenizer *tokenizer, ErrorLogger *errorLogger );
~CheckBufferOverrunClass();
// Buffer overrun..
@ -43,6 +44,7 @@ private:
void ReportError(const TOKEN *tok, const char errmsg[]);
Tokenizer *_tokenizer;
ErrorLogger *_errorLogger;
std::list<const TOKEN *> CallStack;
};

View File

@ -34,10 +34,11 @@
#endif
//---------------------------------------------------------------------------
CheckClass::CheckClass( Tokenizer *tokenizer, const Settings &settings )
CheckClass::CheckClass( Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger )
{
_tokenizer = tokenizer;
_settings = settings;
_errorLogger = errorLogger;
}
CheckClass::~CheckClass()
@ -339,7 +340,7 @@ void CheckClass::CheckConstructors()
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok1);
ostr << " The class '" << classname << "' has no constructor";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
}
// Delete the varlist..
while (varlist)
@ -378,7 +379,7 @@ void CheckClass::CheckConstructors()
std::ostringstream ostr;
ostr << _tokenizer->fileLine(constructor_token);
ostr << " Uninitialized member variable '" << classname << "::" << var->name << "'";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
}
}
@ -533,7 +534,7 @@ void CheckClass::CheckUnusedPrivateFunctions()
{
std::ostringstream ostr;
ostr << "Class '" << classname << "', unused private function: '" << FuncList.front() << "'";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
}
FuncList.pop_front();
}
@ -576,7 +577,7 @@ void CheckClass::CheckMemset()
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok) << ": Using '" << tok->str << "' on class.";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
continue;
}
@ -592,7 +593,7 @@ void CheckClass::CheckMemset()
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok) << ": Using '" << tok->str << "' on struct that contains a 'std::" << Tokenizer::getstr(tstruct,2) << "'";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
break;
}
}
@ -613,7 +614,7 @@ void CheckClass::CheckOperatorEq1()
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok) << ": 'operator=' should return something";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
}
}

View File

@ -23,6 +23,7 @@
#include "tokenize.h"
#include "settings.h"
#include "errorlogger.h"
#include <list>
struct VAR
@ -35,7 +36,7 @@ struct VAR
class CheckClass
{
public:
CheckClass( Tokenizer *tokenizer, const Settings &settings );
CheckClass( Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger );
~CheckClass();
void CheckConstructors();
@ -54,6 +55,7 @@ private:
Tokenizer *_tokenizer;
Settings _settings;
ErrorLogger *_errorLogger;
};
//---------------------------------------------------------------------------
#endif

View File

@ -21,6 +21,7 @@
#include "CheckHeaders.h"
#include "tokenize.h"
#include "CommonCheck.h"
#include <algorithm>
#include <list>
#include <sstream>
@ -35,9 +36,10 @@
// HEADERS - No implementation in a header
//---------------------------------------------------------------------------
CheckHeaders::CheckHeaders( Tokenizer *tokenizer )
CheckHeaders::CheckHeaders( Tokenizer *tokenizer, ErrorLogger *errorLogger )
{
_tokenizer = tokenizer;
_errorLogger = errorLogger;
}
CheckHeaders::~CheckHeaders()
@ -57,7 +59,7 @@ void CheckHeaders::WarningHeaderWithImplementation()
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok) << ": Found implementation in header";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
// Goto next file..
unsigned int fileindex = tok->FileIndex;
@ -245,7 +247,7 @@ void CheckHeaders::WarningIncludeHeader()
ostr << _tokenizer->fileLine(includetok) << ": The included header '" << includefile << "' is not needed";
if (NeedDeclaration)
ostr << " (but a forward declaration is needed)";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
}
}
}

View File

@ -23,17 +23,19 @@
//---------------------------------------------------------------------------
#include "tokenize.h"
#include "errorlogger.h"
class CheckHeaders
{
public:
CheckHeaders( Tokenizer *tokenizer );
CheckHeaders( Tokenizer *tokenizer, ErrorLogger *errorLogger );
~CheckHeaders();
void WarningHeaderWithImplementation();
void WarningIncludeHeader();
private:
Tokenizer *_tokenizer;
ErrorLogger *_errorLogger;
};
//---------------------------------------------------------------------------

View File

@ -23,6 +23,7 @@
#include "CommonCheck.h"
#include <stdlib.h> // free
#include <algorithm>
@ -41,10 +42,11 @@
//---------------------------------------------------------------------------
CheckMemoryLeakClass::CheckMemoryLeakClass( Tokenizer *tokenizer, const Settings &settings )
CheckMemoryLeakClass::CheckMemoryLeakClass( Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger )
{
_tokenizer = tokenizer;
_settings = settings;
_errorLogger = errorLogger;
}
CheckMemoryLeakClass::~CheckMemoryLeakClass()
@ -239,7 +241,7 @@ void CheckMemoryLeakClass::MismatchError( const TOKEN *Tok1, const std::list<con
for ( std::list<const TOKEN *>::const_iterator tok = callstack.begin(); tok != callstack.end(); ++tok )
errmsg << _tokenizer->fileLine(*tok) << " -> ";
errmsg << _tokenizer->fileLine(Tok1) << ": Mismatching allocation and deallocation: " << varname;
ReportErr( errmsg.str() );
_errorLogger->reportErr( errmsg.str() );
}
//---------------------------------------------------------------------------
@ -247,7 +249,7 @@ void CheckMemoryLeakClass::MemoryLeak( const TOKEN *tok, const char varname[] )
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok) << ": Memory leak: " << varname;
ReportErr( errmsg.str() );
_errorLogger->reportErr( errmsg.str() );
}
//---------------------------------------------------------------------------

View File

@ -27,6 +27,7 @@
#include "tokenize.h"
#include "settings.h"
#include "errorlogger.h"
#include <list>
#include <vector>
@ -35,7 +36,7 @@ enum AllocType { No, Malloc, gMalloc, New, NewA };
class CheckMemoryLeakClass
{
public:
CheckMemoryLeakClass( Tokenizer *tokenizer, const Settings &settings );
CheckMemoryLeakClass( Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger );
~CheckMemoryLeakClass();
void CheckMemoryLeak();
@ -73,6 +74,7 @@ private:
bool isclass( const std::string &typestr );
Tokenizer *_tokenizer;
ErrorLogger *_errorLogger;
Settings _settings;
std::list<AllocFunc> listallocfunc;
};

View File

@ -21,6 +21,7 @@
#include "CheckOther.h"
#include "CommonCheck.h"
#include <list>
#include <map>
#include <sstream>
@ -35,9 +36,10 @@
// Warning on C-Style casts.. p = (kalle *)foo;
//---------------------------------------------------------------------------
CheckOther::CheckOther( Tokenizer *tokenizer )
CheckOther::CheckOther( Tokenizer *tokenizer, ErrorLogger *errorLogger )
{
_tokenizer = tokenizer;
_errorLogger = errorLogger;
}
CheckOther::~CheckOther()
@ -61,7 +63,7 @@ void CheckOther::WarningOldStylePointerCast()
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok) << ": C-style pointer casting";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
}
}
@ -85,7 +87,7 @@ void CheckOther::WarningIsDigit()
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok) << ": The condition can be simplified; use 'isdigit'";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
}
}
}
@ -114,7 +116,7 @@ void CheckOther::WarningIsAlpha()
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok) << ": The condition can be simplified; use 'isupper'";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
continue;
}
@ -127,7 +129,7 @@ void CheckOther::WarningIsAlpha()
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok) << ": The condition can be simplified; use 'islower'";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
continue;
}
@ -144,7 +146,7 @@ void CheckOther::WarningIsAlpha()
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok) << ": The condition can be simplified; use 'isalpha'";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
}
}
}
@ -198,7 +200,7 @@ void CheckOther::WarningRedundantCode()
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok) << ": Redundant condition. It is safe to deallocate a NULL pointer";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
}
}
@ -240,7 +242,7 @@ void CheckOther::WarningIf()
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok) << ": Found \"if (condition);\"";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
}
break;
}
@ -296,7 +298,7 @@ void CheckOther::WarningIf()
if (strcmp(cond, p[i]) == 0)
ostr << (i < 3 ? "True" : "False");
}
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
}
}
//---------------------------------------------------------------------------
@ -336,7 +338,7 @@ void CheckOther::InvalidFunctionUsage()
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok2) << ": Invalid radix in call to strtol or strtoul. Must be 0 or 2-36";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
}
}
break;
@ -362,7 +364,7 @@ void CheckOther::CheckIfAssignment()
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok) << ": Possible bug. Should it be '==' instead of '='?";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
}
}
}
@ -401,7 +403,7 @@ void CheckOther::CheckUnsignedDivision()
// One of the operands are signed, the other is unsigned..
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok->next) << ": Warning: Division with signed and unsigned operators";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
}
}
@ -413,7 +415,7 @@ void CheckOther::CheckUnsignedDivision()
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok->next) << ": Unsigned division. The result will be wrong.";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
}
}
@ -425,7 +427,7 @@ void CheckOther::CheckUnsignedDivision()
{
std::ostringstream ostr;
ostr << _tokenizer->fileLine(tok->next) << ": Unsigned division. The result will be wrong.";
ReportErr(ostr.str());
_errorLogger->reportErr(ostr.str());
}
}
}
@ -585,7 +587,7 @@ void CheckOther::CheckVariableScope_LookupVar( const TOKEN *tok1, const char var
// Warning if "used" is true
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok1) << " The scope of the variable '" << varname << "' can be limited";
ReportErr( errmsg.str() );
_errorLogger->reportErr( errmsg.str() );
}
//---------------------------------------------------------------------------
@ -602,7 +604,7 @@ void CheckOther::CheckConstantFunctionParameter()
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok) << " " << Tokenizer::getstr(tok,5) << " is passed by value, it could be passed by reference/pointer instead";
ReportErr( errmsg.str() );
_errorLogger->reportErr( errmsg.str() );
}
else if ( Match(tok,"[,(] const %type% %var% [,)]") )
@ -614,14 +616,14 @@ void CheckOther::CheckConstantFunctionParameter()
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok) << " " << Tokenizer::getstr(tok,3) << " is passed by value, it could be passed by reference/pointer instead";
ReportErr( errmsg.str() );
_errorLogger->reportErr( errmsg.str() );
}
pattern[0] = "struct";
if ( Tokenizer::findtoken(_tokenizer->tokens(), pattern) )
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok) << " " << Tokenizer::getstr(tok,3) << " is passed by value, it could be passed by reference/pointer instead";
ReportErr( errmsg.str() );
_errorLogger->reportErr( errmsg.str() );
}
}
}
@ -682,7 +684,7 @@ void CheckOther::CheckStructMemberUsage()
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok) << ": struct member '" << structname << "::" << varname << "' is never read";
ReportErr(errmsg.str());
_errorLogger->reportErr(errmsg.str());
}
}
}
@ -724,7 +726,7 @@ void CheckOther::CheckCharVariable()
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok2->next) << ": Warning - using char variable as array index";
ReportErr(errmsg.str());
_errorLogger->reportErr(errmsg.str());
break;
}
@ -732,7 +734,7 @@ void CheckOther::CheckCharVariable()
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok2) << ": Warning - using char variable in bit operation";
ReportErr(errmsg.str());
_errorLogger->reportErr(errmsg.str());
break;
}
}
@ -768,14 +770,14 @@ void CheckOther::CheckIncompleteStatement()
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok->next) << ": Redundant code: Found a statement that begins with string constant";
ReportErr(errmsg.str());
_errorLogger->reportErr(errmsg.str());
}
if ( !Match(tok,"#") && Match(tok->next,"; %num%") && !Match(Tokenizer::gettok(tok,3), ",") )
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(tok->next) << ": Redundant code: Found a statement that begins with numeric constant";
ReportErr(errmsg.str());
_errorLogger->reportErr(errmsg.str());
}
}
}

View File

@ -24,11 +24,12 @@
//---------------------------------------------------------------------------
#include "tokenize.h"
#include "errorlogger.h"
class CheckOther
{
public:
CheckOther( Tokenizer *tokenizer );
CheckOther( Tokenizer *tokenizer, ErrorLogger *errorLogger );
~CheckOther();
// Casting
@ -76,6 +77,7 @@ private:
void CheckVariableScope_LookupVar( const TOKEN *tok1, const char varname[] );
Tokenizer *_tokenizer;
ErrorLogger *_errorLogger;
};
//---------------------------------------------------------------------------

View File

@ -32,8 +32,7 @@
#include <ctype.h>
#endif
//---------------------------------------------------------------------------
bool OnlyReportUniqueErrors;
std::ostringstream errout;
@ -56,18 +55,7 @@ bool SameFileName( const char fname1[], const char fname2[] )
}
//---------------------------------------------------------------------------
std::list<std::string> ErrorList;
void ReportErr(const std::string &errmsg)
{
if ( OnlyReportUniqueErrors )
{
if ( std::find( ErrorList.begin(), ErrorList.end(), errmsg ) != ErrorList.end() )
return;
ErrorList.push_back( errmsg );
}
errout << errmsg << std::endl;
}
//---------------------------------------------------------------------------
bool IsName(const char str[])

View File

@ -32,25 +32,10 @@
// Are two filenames the same? Case insensitive on windows
bool SameFileName( const char fname1[], const char fname2[] );
extern bool OnlyReportUniqueErrors;
void ReportErr(const std::string &errmsg);
extern std::ostringstream errout;
bool IsName(const char str[]);
bool IsNumber(const char str[]);
bool IsStandardType(const char str[]);
bool Match(const TOKEN *tok, const char pattern[], const char *varname1[]=0, const char *varname2[]=0);
//---------------------------------------------------------------------------
#endif

View File

@ -36,7 +36,7 @@
//---------------------------------------------------------------------------
CppCheck::CppCheck()
CppCheck::CppCheck() : _tokenizer( this )
{
_settings._debug = false;
_settings._showAll = false;
@ -138,7 +138,7 @@ void CppCheck::check(int argc, char* argv[])
std::ifstream fin( fname.c_str() );
std::map<std::string, std::string> code;
Preprocessor preprocessor;
Preprocessor preprocessor( this );
preprocessor.preprocess(fin, code, fname);
for ( std::map<std::string,std::string>::const_iterator it = code.begin(); it != code.end(); ++it )
checkFile(it->second, filenames[c].c_str(), c);
@ -182,9 +182,6 @@ void CppCheck::check(int argc, char* argv[])
void CppCheck::checkFile(const std::string &code, const char FileName[], unsigned int FileId)
{
OnlyReportUniqueErrors = true;
// Tokenize the file
{
std::istringstream istr(code);
@ -196,13 +193,13 @@ void CppCheck::checkFile(const std::string &code, const char FileName[], unsigne
// 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 );
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 );
CheckOther checkOther( &_tokenizer, this );
checkOther.CheckUnsignedDivision();
// Give warning when using char variable as array index
@ -222,11 +219,11 @@ void CppCheck::checkFile(const std::string &code, const char FileName[], unsigne
_tokenizer.SimplifyTokenList();
// Memory leak
CheckMemoryLeakClass checkMemoryLeak( &_tokenizer, _settings );
CheckMemoryLeakClass checkMemoryLeak( &_tokenizer, _settings, this );
checkMemoryLeak.CheckMemoryLeak();
// Buffer overruns..
CheckBufferOverrunClass checkBufferOverrun( &_tokenizer );
CheckBufferOverrunClass checkBufferOverrun( &_tokenizer, this );
checkBufferOverrun.CheckBufferOverrun();
// Check that all class constructors are ok.
@ -298,4 +295,19 @@ void CppCheck::checkFile(const std::string &code, const char FileName[], unsigne
}
//---------------------------------------------------------------------------
void CppCheck::reportErr( const std::string &errmsg)
{
if ( /*OnlyReportUniqueErrors*/ true )
{
if ( std::find( _errorList.begin(), _errorList.end(), errmsg ) != _errorList.end() )
return;
_errorList.push_back( errmsg );
}
errout << errmsg << std::endl;
}
void CppCheck::reportErr( const TOKEN *token, const std::string &errmsg)
{
std::string message = _tokenizer.fileLine( token ) + errmsg;
reportErr( message );
}

View File

@ -20,24 +20,33 @@
#define CPPCHECK_H
#include <string>
#include <list>
#include <sstream>
#include "settings.h"
#include "tokenize.h" // <- Tokenizer
#include "errorlogger.h"
/**
* This is the base class which will use other classes to do
* static code analysis for C and C++ code to find possible
* errors or places that could be improved.
*/
class CppCheck
class CppCheck : public ErrorLogger
{
public:
CppCheck();
virtual ~CppCheck();
void check(int argc, char* argv[]);
virtual void reportErr( const TOKEN *token, const std::string &errmsg);
virtual void reportErr( const std::string &errmsg);
private:
void checkFile(const std::string &code, const char FileName[], unsigned int FileId);
Settings _settings;
Tokenizer _tokenizer;
std::list<std::string> _errorList;
std::ostringstream errout;
};
#endif // CPPCHECK_H

35
errorlogger.h Normal file
View File

@ -0,0 +1,35 @@
/*
* c++check - c/c++ syntax checking
* Copyright (C) 2007-2008 Daniel Marjamäki and Reijo Tomperi
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/
*/
#ifndef ERRORLOGGER_H
#define ERRORLOGGER_H
class TOKEN;
/**
* This is an interface, which the class responsible of error logging
* should implement.
*/
class ErrorLogger
{
public:
virtual void reportErr( const std::string &errmsg) = 0;
virtual void reportErr( const TOKEN *token, const std::string &errmsg) = 0;
};
#endif // #ifndef ERRORLOGGER_H

View File

@ -29,7 +29,10 @@
#endif
Preprocessor::Preprocessor( ErrorLogger *errorLogger )
{
_errorLogger = errorLogger;
}
/**
* Extract the code for each configuration
@ -49,7 +52,9 @@ void Preprocessor::preprocess(std::istream &istr, std::map<std::string, std::str
if ( ch < 0 )
{
// Bad content..
errout << "[" << filename << ":" << lineno << "] Bad character found: " << int((unsigned char)ch) << std::endl;
std::ostringstream oss;
oss << "[" << filename << ":" << lineno << "] Bad character found: " << int((unsigned char)ch) << std::endl;
_errorLogger->reportErr( oss.str() );
result.clear();
return;
}

View File

@ -25,10 +25,12 @@
#include <istream>
#include <string>
#include <list>
#include "errorlogger.h"
class Preprocessor
{
public:
Preprocessor( ErrorLogger *errorLogger );
void preprocess(std::istream &istr, std::map<std::string, std::string> &result, const std::string &filename);
private:
/**
@ -44,6 +46,8 @@ private:
std::string getdef(std::string line, bool def);
bool match_cfg_def( std::string cfg, const std::string &def );
ErrorLogger *_errorLogger;
};
//---------------------------------------------------------------------------

View File

@ -34,10 +34,13 @@ public:
{ }
private:
void check( const char code[] )
{
// Tokenize..
Tokenizer tokenizer;
Tokenizer tokenizer( this );
tokenizer.getFiles()->push_back( "test.cpp" );
std::istringstream istr(code);
tokenizer.TokenizeCode( istr );
@ -53,7 +56,7 @@ private:
errout.str("");
// Check for memory leaks..
CheckBufferOverrunClass checkBufferOverrun( &tokenizer );
CheckBufferOverrunClass checkBufferOverrun( &tokenizer, this );
checkBufferOverrun.CheckBufferOverrun();
tokenizer.DeallocateTokens();

View File

@ -21,7 +21,6 @@
#include "CommonCheck.h"
#include "CheckOther.h"
#include "testsuite.h"
#include <sstream>
extern std::ostringstream errout;
@ -33,6 +32,8 @@ public:
{ }
private:
void run()
{
TEST_CASE( array_index );
@ -43,7 +44,7 @@ private:
void check( const char code[] )
{
// Tokenize..
Tokenizer tokenizer;
Tokenizer tokenizer( this );
tokenizer.getFiles()->push_back( "test.cpp" );
std::istringstream istr(code);
tokenizer.TokenizeCode( istr );
@ -58,7 +59,7 @@ private:
errout.str("");
// Check for memory leaks..
CheckOther checkOther( &tokenizer );
CheckOther checkOther( &tokenizer, this );
checkOther.CheckCharVariable();
tokenizer.DeallocateTokens();

View File

@ -21,7 +21,6 @@
#include "tokenize.h"
#include "CheckClass.h"
#include "testsuite.h"
#include <sstream>
extern std::ostringstream errout;
@ -33,10 +32,12 @@ public:
{ }
private:
void check( const char code[] )
{
// Tokenize..
Tokenizer tokenizer;
Tokenizer tokenizer( this );
tokenizer.getFiles()->push_back( "test.cpp" );
std::istringstream istr(code);
tokenizer.TokenizeCode( istr );
@ -48,7 +49,7 @@ private:
// Check for memory leaks..
Settings settings;
settings._checkCodingStyle = true;
CheckClass checkClass( &tokenizer, settings );
CheckClass checkClass( &tokenizer, settings, this );
checkClass.CheckConstructors();
tokenizer.DeallocateTokens();

View File

@ -39,7 +39,7 @@ private:
void check( const char code[] )
{
// Tokenize..
Tokenizer tokenizer;
Tokenizer tokenizer( this );
tokenizer.getFiles()->push_back( "test.cpp" );
std::istringstream istr(code);
tokenizer.TokenizeCode( istr );
@ -49,7 +49,7 @@ private:
errout.str("");
// Check for memory leaks..
CheckOther checkOther( &tokenizer );
CheckOther checkOther( &tokenizer, this );
checkOther.CheckUnsignedDivision();
tokenizer.DeallocateTokens();

View File

@ -38,7 +38,7 @@ private:
void check( const char code[] )
{
// Tokenize..
Tokenizer tokenizer;
Tokenizer tokenizer( this );
tokenizer.getFiles()->push_back( "test.cpp" );
std::istringstream istr(code);
tokenizer.TokenizeCode( istr );
@ -48,7 +48,7 @@ private:
errout.str("");
// Check for unused variables..
CheckOther checkOther( &tokenizer );
CheckOther checkOther( &tokenizer, this );
checkOther.CheckIncompleteStatement();
tokenizer.DeallocateTokens();

View File

@ -38,7 +38,7 @@ private:
void check( const char code[] )
{
// Tokenize..
Tokenizer tokenizer;
Tokenizer tokenizer( this );
tokenizer.getFiles()->push_back( "test.cpp" );
std::istringstream istr(code);
tokenizer.TokenizeCode( istr );
@ -53,7 +53,7 @@ private:
settings._showAll = false;
tokenizer.settings( settings );
tokenizer.FillFunctionList(0);
CheckMemoryLeakClass checkMemoryLeak( &tokenizer, settings );
CheckMemoryLeakClass checkMemoryLeak( &tokenizer, settings, this );
checkMemoryLeak.CheckMemoryLeak();
tokenizer.DeallocateTokens();

View File

@ -140,7 +140,7 @@ private:
// Preprocess => actual result..
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
Preprocessor preprocessor( this );
preprocessor.preprocess( istr, actual, "" );
// Compare results..
@ -164,7 +164,7 @@ private:
// Preprocess => actual result..
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
Preprocessor preprocessor( this );
preprocessor.preprocess( istr, actual, "" );
// Compare results..
@ -187,7 +187,7 @@ private:
// Preprocess => actual result..
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
Preprocessor preprocessor( this );
preprocessor.preprocess( istr, actual, "" );
// Compare results..
@ -213,7 +213,7 @@ private:
// Preprocess => actual result..
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
Preprocessor preprocessor( this );
preprocessor.preprocess( istr, actual, "" );
// Compare results..
@ -237,7 +237,7 @@ private:
// Preprocess => actual result..
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
Preprocessor preprocessor( this );
preprocessor.preprocess( istr, actual, "" );
// Compare results..
@ -264,7 +264,7 @@ private:
// Preprocess => actual result..
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
Preprocessor preprocessor( this );
preprocessor.preprocess( istr, actual, "" );
// Compare results..
@ -287,7 +287,7 @@ private:
// Preprocess => actual result..
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
Preprocessor preprocessor( this );
preprocessor.preprocess( istr, actual, "" );
// Compare results..
@ -310,7 +310,7 @@ private:
// Preprocess => actual result..
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
Preprocessor preprocessor( this );
preprocessor.preprocess( istr, actual, "" );
// Compare results..
@ -330,7 +330,7 @@ private:
// Preprocess => actual result..
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
Preprocessor preprocessor( this );
preprocessor.preprocess( istr, actual, "" );
// Compare results..
@ -355,7 +355,7 @@ private:
// Preprocess => actual result..
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
Preprocessor preprocessor( this );
preprocessor.preprocess( istr, actual, "" );
// Compare results..
@ -375,7 +375,7 @@ private:
// Preprocess => actual result..
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
Preprocessor preprocessor( this );
preprocessor.preprocess( istr, actual, "" );
// Compare results..
@ -400,7 +400,7 @@ private:
// Preprocess => actual result..
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
Preprocessor preprocessor( this );
preprocessor.preprocess( istr, actual, "" );
// Compare results..
@ -420,7 +420,7 @@ private:
// Preprocess => actual result..
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Preprocessor preprocessor;
Preprocessor preprocessor( this );
preprocessor.preprocess( istr, actual, "" );
// Compare results..

View File

@ -16,7 +16,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/
*/
#include "testsuite.h"
#include <string>
#include <vector>

View File

@ -22,6 +22,8 @@
#include "tokenize.h"
#include <sstream>
extern std::ostringstream errout;
class TestSimplifyTokens : public TestFixture
{
public:
@ -37,10 +39,10 @@ private:
TEST_CASE( sizeof1 );
}
static std::string tok(const char code[])
std::string tok(const char code[])
{
std::istringstream istr(code);
Tokenizer tokenizer;
Tokenizer tokenizer( this );
tokenizer.TokenizeCode( istr );
tokenizer.SimplifyTokenList();

View File

@ -25,7 +25,7 @@
#include <iostream>
#include <list>
std::ostringstream errout;
/**
* TestRegistry
@ -130,4 +130,13 @@ void TestFixture::runTests(const char cmd[])
}
void TestFixture::reportErr( const std::string &errmsg)
{
errout << errmsg << std::endl;
}
void TestFixture::reportErr( const TOKEN *token, const std::string &errmsg)
{
reportErr( errmsg );
}

View File

@ -20,9 +20,11 @@
#include <sstream>
#include "errorlogger.h"
class TOKEN;
class TestFixture
class TestFixture : public ErrorLogger
{
private:
static std::ostringstream errmsg;
@ -38,6 +40,10 @@ protected:
void assertFail(const char *filename, int linenr);
public:
void reportErr( const std::string &errmsg);
void reportErr( const TOKEN *token, const std::string &errmsg);
TestFixture(const std::string &_name);
virtual ~TestFixture() { }

View File

@ -25,6 +25,7 @@
#define UNIT_TESTING // Get access to "private" data in Tokenizer
#include "tokenize.h"
extern std::ostringstream errout;
class TestTokenizer : public TestFixture
{
public:
@ -62,7 +63,7 @@ private:
" \"def\"\n";
// tokenize..
Tokenizer tokenizer;
Tokenizer tokenizer( this );
tokenizer.getFiles()->push_back( "test.cpp" );
std::istringstream istr(filedata);
tokenizer.TokenizeCode(istr, 0);
@ -88,7 +89,7 @@ private:
std::string filedata(10000,'a');
// tokenize..
Tokenizer tokenizer;
Tokenizer tokenizer( this );
tokenizer.getFiles()->push_back( "test.cpp" );
std::istringstream istr(filedata);
tokenizer.TokenizeCode(istr, 0);
@ -112,7 +113,7 @@ private:
"}\n";
// tokenize..
Tokenizer tokenizer;
Tokenizer tokenizer( this );
tokenizer.getFiles()->push_back( "test.cpp" );
std::istringstream istr(filedata);
tokenizer.TokenizeCode(istr, 0);
@ -145,7 +146,7 @@ private:
"void b()\n"
"{ }\n";
// tokenize..
Tokenizer tokenizer;
Tokenizer tokenizer( this );
tokenizer.getFiles()->push_back( "test.cpp" );
std::istringstream istr(code);
tokenizer.TokenizeCode(istr, 0);

View File

@ -44,7 +44,7 @@ private:
void check( const char code[] )
{
// Tokenize..
Tokenizer tokenizer;
Tokenizer tokenizer( this );
tokenizer.getFiles()->push_back( "test.cpp" );
std::istringstream istr(code);
tokenizer.TokenizeCode( istr );
@ -55,7 +55,7 @@ private:
// Check for unused private functions..
Settings settings;
settings._checkCodingStyle = true;
CheckClass checkClass( &tokenizer, settings );
CheckClass checkClass( &tokenizer, settings, this );
checkClass.CheckUnusedPrivateFunctions();
tokenizer.DeallocateTokens();

View File

@ -25,7 +25,6 @@
#include "CheckOther.h"
#include <sstream>
extern std::ostringstream errout;
class TestUnusedVar : public TestFixture
@ -38,7 +37,7 @@ private:
void check( const char code[] )
{
// Tokenize..
Tokenizer tokenizer;
Tokenizer tokenizer( this );
tokenizer.getFiles()->push_back( "test.cpp" );
std::istringstream istr(code);
tokenizer.TokenizeCode( istr );
@ -48,7 +47,7 @@ private:
errout.str("");
// Check for unused variables..
CheckOther checkOther( &tokenizer );
CheckOther checkOther( &tokenizer, this );
checkOther.CheckStructMemberUsage();
tokenizer.DeallocateTokens();

View File

@ -20,6 +20,7 @@
//---------------------------------------------------------------------------
#include "tokenize.h"
#include "CommonCheck.h" // <- IsName
//---------------------------------------------------------------------------
#include <locale>
@ -46,11 +47,12 @@
//---------------------------------------------------------------------------
Tokenizer::Tokenizer()
Tokenizer::Tokenizer(ErrorLogger *errorLogger)
{
_tokens = 0;
tokens_back = 0;
dsymlist = 0;
_errorLogger = errorLogger;
}
Tokenizer::~Tokenizer()
@ -1293,14 +1295,14 @@ void Tokenizer::CheckGlobalFunctionUsage(const std::vector<std::string> &filenam
std::ostringstream errmsg;
errmsg << "[" << filenames[func->file_id()] << "]: "
<< "The function '" << func->name() << "' is never used.";
ReportErr( errmsg.str() );
_errorLogger->reportErr( errmsg.str() );
}
else if ( ! UsedOtherFile )
{
std::ostringstream errmsg;
errmsg << "[" << filenames[func->file_id()] << "]: "
<< "The linkage of the function '" << func->name() << "' can be local (static) instead of global";
ReportErr( errmsg.str() );
_errorLogger->reportErr( errmsg.str() );
}
}

View File

@ -28,6 +28,7 @@
#include <cstdlib>
#include <cstring>
#include "settings.h"
#include "errorlogger.h"
class TOKEN
{
@ -62,7 +63,7 @@ public:
class Tokenizer
{
public:
Tokenizer();
Tokenizer(ErrorLogger *errorLogger);
~Tokenizer();
void Tokenize(std::istream &code, const char FileName[]);
@ -153,6 +154,7 @@ private:
struct DefineSymbol * dsymlist;
TOKEN *_tokens;
ErrorLogger *_errorLogger;
};