From 07b5ebe72b144810792f4ccbf9e122eb11ab848f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 22 Nov 2008 19:39:12 +0000 Subject: [PATCH] Check Function Usage: Removed much of the old checking and made some refactoring --- cppcheck.cpp | 31 ++++++----- cppcheck.h | 11 ++-- testbufferoverrun.cpp | 2 +- testcharvar.cpp | 2 +- testconstructors.cpp | 2 +- testdivision.cpp | 2 +- testincompletestatement.cpp | 2 +- testmemleak.cpp | 2 +- testrunner.cbp | 3 ++ testsimplifytokens.cpp | 2 +- testtokenize.cpp | 8 +-- testunusedprivfunc.cpp | 2 +- testunusedvar.cpp | 2 +- tokenize.cpp | 105 +----------------------------------- tokenize.h | 37 +++---------- 15 files changed, 45 insertions(+), 168 deletions(-) diff --git a/cppcheck.cpp b/cppcheck.cpp index a3735b58c..e525dc65d 100644 --- a/cppcheck.cpp +++ b/cppcheck.cpp @@ -18,6 +18,7 @@ #include "cppcheck.h" #include "preprocessor.h" // preprocessor. +#include "tokenize.h" // <- Tokenizer #include "CheckMemoryLeak.h" #include "CheckBufferOverrun.h" @@ -35,12 +36,9 @@ //--------------------------------------------------------------------------- -CppCheck::CppCheck() : _tokenizer( this ) +CppCheck::CppCheck() { - _settings._debug = false; - _settings._showAll = false; - _settings._checkCodingStyle = false; - _settings._errorsOnly = false; + } CppCheck::~CppCheck() @@ -53,6 +51,8 @@ void CppCheck::check(int argc, char* argv[]) std::vector pathnames; bool Recursive = false; + Settings _settings; + for (int i = 1; i < argc; i++) { if (strcmp(argv[i],"--debug") == 0) @@ -76,8 +76,6 @@ void CppCheck::check(int argc, char* argv[]) pathnames.push_back( argv[i] ); } - _tokenizer.settings( _settings ); - std::vector filenames; // --recursive was used if ( Recursive ) @@ -140,7 +138,7 @@ void CppCheck::check(int argc, char* argv[]) Preprocessor preprocessor( this ); preprocessor.preprocess(fin, code, fname); for ( std::map::const_iterator it = code.begin(); it != code.end(); ++it ) - checkFile(it->second, filenames[c].c_str(), c); + checkFile(it->second, filenames[c].c_str(), c, _settings); if (_settings._errorsOnly) { @@ -164,7 +162,7 @@ void CppCheck::check(int argc, char* argv[]) { errout.str(""); std::cout << "Checking usage of global functions (this may take several minutes)..\n"; - _tokenizer.CheckGlobalFunctionUsage(filenames); + //_tokenizer.CheckGlobalFunctionUsage(filenames); if ( ! errout.str().empty() ) { std::cerr << "\n"; @@ -179,8 +177,11 @@ void CppCheck::check(int argc, char* argv[]) // CppCheck - A function that checks a specified file //--------------------------------------------------------------------------- -void CppCheck::checkFile(const std::string &code, const char FileName[], unsigned int FileId) +void CppCheck::checkFile(const std::string &code, const char FileName[], unsigned int FileId, Settings &_settings) { + Tokenizer _tokenizer; + _tokenizer.settings( _settings ); + // Tokenize the file { std::istringstream istr(code); @@ -288,10 +289,6 @@ void CppCheck::checkFile(const std::string &code, const char FileName[], unsigne // mean that an ';' has been added by accident checkOther.CheckIncompleteStatement(); } - - // Clean up tokens.. - _tokenizer.DeallocateTokens(); - } //--------------------------------------------------------------------------- @@ -308,6 +305,12 @@ void CppCheck::reportErr( const std::string &errmsg) void CppCheck::reportErr( const TOKEN *token, const std::string &errmsg) { +/* std::string message = _tokenizer.fileLine( token ) + errmsg; reportErr( message ); +*/ + reportErr( errmsg ); } + + + diff --git a/cppcheck.h b/cppcheck.h index dffa6db92..4b9753798 100644 --- a/cppcheck.h +++ b/cppcheck.h @@ -23,7 +23,6 @@ #include #include #include "settings.h" -#include "tokenize.h" // <- Tokenizer #include "errorlogger.h" /** @@ -38,15 +37,13 @@ class CppCheck : public ErrorLogger 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; + void checkFile(const std::string &code, const char FileName[], unsigned int FileId, Settings &_settings); std::list _errorList; std::ostringstream errout; + + void reportErr( const std::string &errmsg); + void reportErr( const TOKEN *token, const std::string &errmsg); }; #endif // CPPCHECK_H diff --git a/testbufferoverrun.cpp b/testbufferoverrun.cpp index a4b8333d4..290945efc 100644 --- a/testbufferoverrun.cpp +++ b/testbufferoverrun.cpp @@ -39,7 +39,7 @@ private: void check( const char code[] ) { // Tokenize.. - Tokenizer tokenizer( this ); + Tokenizer tokenizer; tokenizer.getFiles()->push_back( "test.cpp" ); std::istringstream istr(code); tokenizer.TokenizeCode( istr ); diff --git a/testcharvar.cpp b/testcharvar.cpp index f264e83be..ecbce317a 100644 --- a/testcharvar.cpp +++ b/testcharvar.cpp @@ -43,7 +43,7 @@ private: void check( const char code[] ) { // Tokenize.. - Tokenizer tokenizer( this ); + Tokenizer tokenizer; tokenizer.getFiles()->push_back( "test.cpp" ); std::istringstream istr(code); tokenizer.TokenizeCode( istr ); diff --git a/testconstructors.cpp b/testconstructors.cpp index fdc7f4736..3f29f5a18 100644 --- a/testconstructors.cpp +++ b/testconstructors.cpp @@ -37,7 +37,7 @@ private: void check( const char code[] ) { // Tokenize.. - Tokenizer tokenizer( this ); + Tokenizer tokenizer; tokenizer.getFiles()->push_back( "test.cpp" ); std::istringstream istr(code); tokenizer.TokenizeCode( istr ); diff --git a/testdivision.cpp b/testdivision.cpp index 9013e5ade..ccbc06300 100644 --- a/testdivision.cpp +++ b/testdivision.cpp @@ -39,7 +39,7 @@ private: void check( const char code[] ) { // Tokenize.. - Tokenizer tokenizer( this ); + Tokenizer tokenizer; tokenizer.getFiles()->push_back( "test.cpp" ); std::istringstream istr(code); tokenizer.TokenizeCode( istr ); diff --git a/testincompletestatement.cpp b/testincompletestatement.cpp index b224801a5..85ae74162 100644 --- a/testincompletestatement.cpp +++ b/testincompletestatement.cpp @@ -38,7 +38,7 @@ private: void check( const char code[] ) { // Tokenize.. - Tokenizer tokenizer( this ); + Tokenizer tokenizer; tokenizer.getFiles()->push_back( "test.cpp" ); std::istringstream istr(code); tokenizer.TokenizeCode( istr ); diff --git a/testmemleak.cpp b/testmemleak.cpp index ca247ec70..bf77deb78 100644 --- a/testmemleak.cpp +++ b/testmemleak.cpp @@ -37,7 +37,7 @@ private: void check( const char code[] ) { // Tokenize.. - Tokenizer tokenizer( this ); + Tokenizer tokenizer; tokenizer.getFiles()->push_back( "test.cpp" ); std::istringstream istr(code); tokenizer.TokenizeCode( istr ); diff --git a/testrunner.cbp b/testrunner.cbp index 6ca9a9ba5..8b9631677 100644 --- a/testrunner.cbp +++ b/testrunner.cbp @@ -23,6 +23,8 @@ + + @@ -35,6 +37,7 @@ + diff --git a/testsimplifytokens.cpp b/testsimplifytokens.cpp index 5dd9ed7a0..a8ed8658b 100644 --- a/testsimplifytokens.cpp +++ b/testsimplifytokens.cpp @@ -42,7 +42,7 @@ private: std::string tok(const char code[]) { std::istringstream istr(code); - Tokenizer tokenizer( this ); + Tokenizer tokenizer; tokenizer.TokenizeCode( istr ); tokenizer.SimplifyTokenList(); diff --git a/testtokenize.cpp b/testtokenize.cpp index f24d980c5..2dcfc68ed 100644 --- a/testtokenize.cpp +++ b/testtokenize.cpp @@ -65,7 +65,7 @@ private: " \"def\"\n"; // tokenize.. - Tokenizer tokenizer( this ); + Tokenizer tokenizer; tokenizer.getFiles()->push_back( "test.cpp" ); std::istringstream istr(filedata); tokenizer.TokenizeCode(istr, 0); @@ -89,7 +89,7 @@ private: std::string filedata(10000,'a'); // tokenize.. - Tokenizer tokenizer( this ); + Tokenizer tokenizer; tokenizer.getFiles()->push_back( "test.cpp" ); std::istringstream istr(filedata); tokenizer.TokenizeCode(istr, 0); @@ -111,7 +111,7 @@ private: "}\n"; // tokenize.. - Tokenizer tokenizer( this ); + Tokenizer tokenizer; tokenizer.getFiles()->push_back( "test.cpp" ); std::istringstream istr(filedata); tokenizer.TokenizeCode(istr, 0); @@ -142,7 +142,7 @@ private: "void b()\n" "{ }\n"; // tokenize.. - Tokenizer tokenizer( this ); + Tokenizer tokenizer; tokenizer.getFiles()->push_back( "test.cpp" ); std::istringstream istr(code); tokenizer.TokenizeCode(istr, 0); diff --git a/testunusedprivfunc.cpp b/testunusedprivfunc.cpp index 9ad065a24..5f5bad26c 100644 --- a/testunusedprivfunc.cpp +++ b/testunusedprivfunc.cpp @@ -44,7 +44,7 @@ private: void check( const char code[] ) { // Tokenize.. - Tokenizer tokenizer( this ); + Tokenizer tokenizer; tokenizer.getFiles()->push_back( "test.cpp" ); std::istringstream istr(code); tokenizer.TokenizeCode( istr ); diff --git a/testunusedvar.cpp b/testunusedvar.cpp index 72a0623a5..fc9b5d2c2 100644 --- a/testunusedvar.cpp +++ b/testunusedvar.cpp @@ -37,7 +37,7 @@ private: void check( const char code[] ) { // Tokenize.. - Tokenizer tokenizer( this ); + Tokenizer tokenizer; tokenizer.getFiles()->push_back( "test.cpp" ); std::istringstream istr(code); tokenizer.TokenizeCode( istr ); diff --git a/tokenize.cpp b/tokenize.cpp index 2e23a3564..55126b051 100644 --- a/tokenize.cpp +++ b/tokenize.cpp @@ -48,12 +48,11 @@ //--------------------------------------------------------------------------- -Tokenizer::Tokenizer(ErrorLogger *errorLogger) +Tokenizer::Tokenizer() { _tokens = 0; tokens_back = 0; dsymlist = 0; - _errorLogger = errorLogger; } Tokenizer::~Tokenizer() @@ -1155,12 +1154,6 @@ void Tokenizer::FillFunctionList(const unsigned int file_id) { FunctionList.clear(); - std::list _usedfunc; - if ( file_id == 0 ) - { - GlobalFunctions.clear(); - } - bool staticfunc = false; bool classfunc = false; @@ -1173,23 +1166,8 @@ void Tokenizer::FillFunctionList(const unsigned int file_id) else if ( tok->str[0] == '}' ) indentlevel--; - if (indentlevel > 0) { - if ( _settings._checkCodingStyle ) - { - const char *funcname = 0; - - if ( Tokenizer::Match(tok,"%var% (") ) - funcname = tok->str; - else if ( Tokenizer::Match(tok, "= %var% ;") || - Tokenizer::Match(tok, "= %var% ,") ) - funcname = tok->next->str; - - if ( std::find(_usedfunc.begin(), _usedfunc.end(), funcname) == _usedfunc.end() ) - _usedfunc.push_back( funcname ); - } - continue; } @@ -1222,8 +1200,6 @@ void Tokenizer::FillFunctionList(const unsigned int file_id) { if ( Tokenizer::Match(tok2, ") {") ) { - if (_settings._checkCodingStyle && !staticfunc && !classfunc && tok->FileIndex==0) - GlobalFunctions.push_back( GlobalFunction(file_id, tok->str) ); FunctionList.push_back( tok ); tok = tok2; } @@ -1266,87 +1242,8 @@ void Tokenizer::FillFunctionList(const unsigned int file_id) FunctionList.erase( FunctionList.begin() + func1 ); } } - - - for (std::list::const_iterator it = _usedfunc.begin(); it != _usedfunc.end(); ++it) - { - if ( *it != 0 ) - { - UsedGlobalFunctions.push_back( GlobalFunction(file_id, *it) ); - } - } } -//-------------------------------------------------------------------------- - - -void Tokenizer::CheckGlobalFunctionUsage(const std::vector &filenames) -{ - // Iterator for GlobalFunctions - std::list::const_iterator func; - - // Iterator for UsedGlobalFunctions - std::list::const_iterator usedfunc; - - unsigned int i1 = 0; - unsigned int i2 = 1; - - // Check that every function in GlobalFunctions are used - for ( func = GlobalFunctions.begin(); func != GlobalFunctions.end(); func++ ) - { - if ( GlobalFunctions.size() > 100 ) - { - ++i1; - if ( i1 > (i2 * GlobalFunctions.size()) / 100 ) - { - if ( (i2 % 10) == 0 ) - std::cout << i2 << "%"; - else - std::cout << "."; - std::cout.flush(); - ++i2; - } - } - - const std::string &funcname = func->name(); - - if ( funcname == "main" || funcname == "WinMain" ) - continue; - - // Check if this global function is used in any of the other files.. - bool UsedOtherFile = false; - bool UsedAnyFile = false; - for ( usedfunc = UsedGlobalFunctions.begin(); usedfunc != UsedGlobalFunctions.end(); usedfunc++ ) - { - if ( funcname == usedfunc->name() ) - { - UsedAnyFile = true; - if (func->file_id() != usedfunc->file_id()) - { - UsedOtherFile = true; - break; - } - } - } - - if ( ! UsedAnyFile ) - { - std::ostringstream errmsg; - errmsg << "[" << filenames[func->file_id()] << "]: " - << "The function '" << func->name() << "' is never used."; - _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"; - _errorLogger->reportErr( errmsg.str() ); - } - } - - std::cout << "\n"; -} //--------------------------------------------------------------------------- void Tokenizer::settings( const Settings &settings ) diff --git a/tokenize.h b/tokenize.h index e9fdeaf03..868e5e8d1 100644 --- a/tokenize.h +++ b/tokenize.h @@ -61,16 +61,17 @@ public: }; class Tokenizer -{ +{ +private: + // Deallocate lists.. + void DeallocateTokens(); + public: - Tokenizer(ErrorLogger *errorLogger); + Tokenizer(); ~Tokenizer(); void Tokenize(std::istream &code, const char FileName[]); - // Deallocate lists.. - void DeallocateTokens(); - // Simplify tokenlist // ----------------------------- void SimplifyTokenList(); @@ -99,16 +100,12 @@ public: std::vector *getFiles(); - - void FillFunctionList(const unsigned int file_id); const TOKEN *GetFunctionTokenByName( const char funcname[] ) const; - void CheckGlobalFunctionUsage(const std::vector &filenames); void settings( const Settings &settings ); const TOKEN *tokens() const; - #ifndef UNIT_TESTING private: #endif @@ -120,23 +117,6 @@ private: struct DefineSymbol *next; }; - class GlobalFunction - { - private: - unsigned int _FileId; - std::string _FuncName; - - public: - GlobalFunction( const unsigned int FileId, const char FuncName[] ) - { - _FileId = FileId; - _FuncName = FuncName; - } - - unsigned int file_id() const { return _FileId; } - const std::string &name() const { return _FuncName; } - }; - void Define(const char Name[], const char Value[]); void addtoken(const char str[], const unsigned int lineno, const unsigned int fileno); @@ -154,15 +134,12 @@ private: TOKEN *tokens_back; std::map TypeSize; std::vector FunctionList; - std::list< GlobalFunction > GlobalFunctions; - std::list< GlobalFunction > UsedGlobalFunctions; std::vector Files; Settings _settings; struct DefineSymbol * dsymlist; - TOKEN *_tokens; - ErrorLogger *_errorLogger; + TOKEN *_tokens; };