Refactoring: The Tokenizer::FillFunctionList has no use of its parameter. Enabled the CheckFunctionUsage

This commit is contained in:
Daniel Marjamäki 2008-11-23 06:21:44 +00:00
parent b8c7543149
commit 0c9784fc0c
12 changed files with 179 additions and 171 deletions

View File

@ -30,9 +30,8 @@
// FUNCTION USAGE - Check for unused functions etc // FUNCTION USAGE - Check for unused functions etc
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
CheckFunctionUsage::CheckFunctionUsage( const Tokenizer *tokenizer, ErrorLogger *errorLogger ) CheckFunctionUsage::CheckFunctionUsage( ErrorLogger *errorLogger )
{ {
_tokenizer = tokenizer;
_errorLogger = errorLogger; _errorLogger = errorLogger;
functions.clear(); functions.clear();
} }
@ -43,10 +42,10 @@ CheckFunctionUsage::~CheckFunctionUsage()
} }
void CheckFunctionUsage::parseTokens( const std::string &filename ) void CheckFunctionUsage::parseTokens( const Tokenizer &tokenizer )
{ {
// Function declarations.. // Function declarations..
for ( const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next ) for ( const TOKEN *tok = tokenizer.tokens(); tok; tok = tok->next )
{ {
if ( tok->FileIndex != 0 ) if ( tok->FileIndex != 0 )
continue; continue;
@ -58,16 +57,27 @@ void CheckFunctionUsage::parseTokens( const std::string &filename )
else if ( TOKEN::Match(tok, "%type% * %var% (") ) else if ( TOKEN::Match(tok, "%type% * %var% (") )
funcname = tok->at(2); funcname = tok->at(2);
// Check that ") {" is found..
for (const TOKEN *tok2 = funcname; tok2; tok2 = tok2->next)
{
if ( TOKEN::Match(tok2, ")") )
{
if ( ! TOKEN::Match(tok2, ") {") )
funcname = NULL;
break;
}
}
if ( TOKEN::Match(funcname, "%var% ( )") || TOKEN::Match(funcname, "%var% ( %type%") ) if ( TOKEN::Match(funcname, "%var% ( )") || TOKEN::Match(funcname, "%var% ( %type%") )
{ {
FunctionUsage &func = functions[ funcname->str ]; FunctionUsage &func = functions[ funcname->str ];
// No filename set yet.. // No filename set yet..
if (func.filename.empty()) if (func.filename.empty())
func.filename = filename; func.filename = tokenizer.getFiles()->at(0);
// Multiple files => filename = "+" // Multiple files => filename = "+"
else if (func.filename != filename) else if (func.filename != tokenizer.getFiles()->at(0))
{ {
func.filename = "+"; func.filename = "+";
func.usedOtherFile |= func.usedSameFile; func.usedOtherFile |= func.usedSameFile;
@ -76,14 +86,11 @@ void CheckFunctionUsage::parseTokens( const std::string &filename )
} }
// Function usage.. // Function usage..
for ( const TOKEN *tok = _tokenizer->tokens(); tok; tok = tok->next ) for ( const TOKEN *tok = tokenizer.tokens(); tok; tok = tok->next )
{ {
const TOKEN *funcname = 0; const TOKEN *funcname = 0;
if ( TOKEN::Match( tok, "[;{}.)[=] %var% (" ) ) if ( TOKEN::Match( tok, "[;{}.,()[=] %var% [(),;]" ) )
funcname = tok;
else if ( TOKEN::Match(tok, "= %var% ;") )
funcname = tok->next; funcname = tok->next;
if ( funcname ) if ( funcname )

View File

@ -28,19 +28,18 @@
class CheckFunctionUsage class CheckFunctionUsage
{ {
public: public:
CheckFunctionUsage( const Tokenizer *tokenizer, ErrorLogger *errorLogger ); CheckFunctionUsage( ErrorLogger *errorLogger );
~CheckFunctionUsage(); ~CheckFunctionUsage();
// Parse current tokens and determine.. // Parse current tokens and determine..
// * Check what functions are used // * Check what functions are used
// * What functions are declared // * What functions are declared
void parseTokens( const std::string &filename ); void parseTokens( const Tokenizer &tokenizer );
void check(); void check();
private: private:
const Tokenizer *_tokenizer;
ErrorLogger *_errorLogger; ErrorLogger *_errorLogger;

View File

@ -25,6 +25,7 @@
#include "CheckClass.h" #include "CheckClass.h"
#include "CheckHeaders.h" #include "CheckHeaders.h"
#include "CheckOther.h" #include "CheckOther.h"
#include "CheckFunctionUsage.h"
#include "FileLister.h" #include "FileLister.h"
#include <algorithm> #include <algorithm>
@ -124,6 +125,11 @@ void CppCheck::check(int argc, char* argv[])
std::sort( filenames.begin(), filenames.end() ); std::sort( filenames.begin(), filenames.end() );
// Check function usage if "--recursive", "--style" and "--all" was given.
CheckFunctionUsage *checkFunctionUsage = NULL;
if ( Recursive && _settings._showAll && _settings._checkCodingStyle )
checkFunctionUsage = new CheckFunctionUsage( this );
for (unsigned int c = 0; c < filenames.size(); c++) for (unsigned int c = 0; c < filenames.size(); c++)
{ {
errout.str(""); errout.str("");
@ -138,7 +144,7 @@ void CppCheck::check(int argc, char* argv[])
Preprocessor preprocessor( this ); Preprocessor preprocessor( this );
preprocessor.preprocess(fin, code, fname); preprocessor.preprocess(fin, code, fname);
for ( std::map<std::string,std::string>::const_iterator it = code.begin(); it != code.end(); ++it ) for ( std::map<std::string,std::string>::const_iterator it = code.begin(); it != code.end(); ++it )
checkFile(it->second, filenames[c].c_str(), c, _settings); checkFile(it->second, filenames[c].c_str(), _settings, checkFunctionUsage);
if (_settings._errorsOnly) if (_settings._errorsOnly)
{ {
@ -158,11 +164,11 @@ void CppCheck::check(int argc, char* argv[])
} }
// This generates false positives - especially for libraries // This generates false positives - especially for libraries
if ( _settings._showAll && _settings._checkCodingStyle && filenames.size() > 1 ) if ( checkFunctionUsage )
{ {
errout.str(""); errout.str("");
std::cout << "Checking usage of global functions (this may take several minutes)..\n"; std::cout << "Checking usage of global functions (this may take several minutes)..\n";
//_tokenizer.CheckGlobalFunctionUsage(filenames); checkFunctionUsage->check();
if ( ! errout.str().empty() ) if ( ! errout.str().empty() )
{ {
std::cerr << "\n"; std::cerr << "\n";
@ -170,6 +176,7 @@ void CppCheck::check(int argc, char* argv[])
} }
} }
delete checkFunctionUsage;
} }
@ -177,7 +184,7 @@ void CppCheck::check(int argc, char* argv[])
// CppCheck - A function that checks a specified file // CppCheck - A function that checks a specified file
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CppCheck::checkFile(const std::string &code, const char FileName[], unsigned int FileId, Settings &_settings) void CppCheck::checkFile(const std::string &code, const char FileName[], Settings &_settings, CheckFunctionUsage *checkFunctionUsage)
{ {
Tokenizer _tokenizer; Tokenizer _tokenizer;
_tokenizer.settings( _settings ); _tokenizer.settings( _settings );
@ -188,7 +195,7 @@ void CppCheck::checkFile(const std::string &code, const char FileName[], unsigne
_tokenizer.Tokenize(istr, FileName); _tokenizer.Tokenize(istr, FileName);
} }
_tokenizer.FillFunctionList(FileId); _tokenizer.FillFunctionList();
// Check that the memsets are valid. // Check that the memsets are valid.
// The 'memset' function can do dangerous things if used wrong. // The 'memset' function can do dangerous things if used wrong.
@ -219,6 +226,10 @@ void CppCheck::checkFile(const std::string &code, const char FileName[], unsigne
_tokenizer.SimplifyTokenList(); _tokenizer.SimplifyTokenList();
if ( checkFunctionUsage )
checkFunctionUsage->parseTokens(_tokenizer);
// Memory leak // Memory leak
CheckMemoryLeakClass checkMemoryLeak( &_tokenizer, _settings, this ); CheckMemoryLeakClass checkMemoryLeak( &_tokenizer, _settings, this );
checkMemoryLeak.CheckMemoryLeak(); checkMemoryLeak.CheckMemoryLeak();

View File

@ -25,6 +25,8 @@
#include "settings.h" #include "settings.h"
#include "errorlogger.h" #include "errorlogger.h"
class CheckFunctionUsage;
/** /**
* This is the base class which will use other classes to do * This is the base class which will use other classes to do
* static code analysis for C and C++ code to find possible * static code analysis for C and C++ code to find possible
@ -38,7 +40,7 @@ class CppCheck : public ErrorLogger
void check(int argc, char* argv[]); void check(int argc, char* argv[]);
private: private:
void checkFile(const std::string &code, const char FileName[], unsigned int FileId, Settings &_settings); void checkFile(const std::string &code, const char FileName[], Settings &_settings, CheckFunctionUsage *checkFunctionUsage);
std::list<std::string> _errorList; std::list<std::string> _errorList;
std::ostringstream errout; std::ostringstream errout;

View File

@ -49,7 +49,7 @@ private:
Settings settings; Settings settings;
settings._checkCodingStyle = true; settings._checkCodingStyle = true;
tokenizer.settings( settings ); tokenizer.settings( settings );
tokenizer.FillFunctionList(0); tokenizer.FillFunctionList();
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");

View File

@ -53,7 +53,7 @@ private:
Settings settings; Settings settings;
settings._checkCodingStyle = true; settings._checkCodingStyle = true;
tokenizer.settings( settings ); tokenizer.settings( settings );
tokenizer.FillFunctionList(0); tokenizer.FillFunctionList();
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");

View File

@ -52,7 +52,7 @@ private:
settings._checkCodingStyle = true; settings._checkCodingStyle = true;
settings._showAll = false; settings._showAll = false;
tokenizer.settings( settings ); tokenizer.settings( settings );
tokenizer.FillFunctionList(0); tokenizer.FillFunctionList();
CheckMemoryLeakClass checkMemoryLeak( &tokenizer, settings, this ); CheckMemoryLeakClass checkMemoryLeak( &tokenizer, settings, this );
checkMemoryLeak.CheckMemoryLeak(); checkMemoryLeak.CheckMemoryLeak();
} }

View File

@ -31,8 +31,6 @@
<Unit filename="CheckMemoryLeak.h" /> <Unit filename="CheckMemoryLeak.h" />
<Unit filename="CheckOther.cpp" /> <Unit filename="CheckOther.cpp" />
<Unit filename="CheckOther.h" /> <Unit filename="CheckOther.h" />
<Unit filename="CommonCheck.cpp" />
<Unit filename="CommonCheck.h" />
<Unit filename="FileLister.cpp" /> <Unit filename="FileLister.cpp" />
<Unit filename="FileLister.h" /> <Unit filename="FileLister.h" />
<Unit filename="cppcheck.cpp" /> <Unit filename="cppcheck.cpp" />
@ -56,6 +54,8 @@
<Unit filename="testtokenize.cpp" /> <Unit filename="testtokenize.cpp" />
<Unit filename="testunusedprivfunc.cpp" /> <Unit filename="testunusedprivfunc.cpp" />
<Unit filename="testunusedvar.cpp" /> <Unit filename="testunusedvar.cpp" />
<Unit filename="token.cpp" />
<Unit filename="token.h" />
<Unit filename="tokenize.cpp" /> <Unit filename="tokenize.cpp" />
<Unit filename="tokenize.h" /> <Unit filename="tokenize.h" />
<Extensions> <Extensions>

View File

@ -48,11 +48,6 @@ public:
_tests.push_back( t ); _tests.push_back( t );
} }
void removeTest( TestFixture *t )
{
_tests.remove( t );
}
const std::list<TestFixture *> &tests() const const std::list<TestFixture *> &tests() const
{ {
return _tests; return _tests;
@ -74,12 +69,6 @@ TestFixture::TestFixture(const std::string &_name) : classname(_name)
TestRegistry::theInstance().addTest(this); TestRegistry::theInstance().addTest(this);
} }
/*
TestFixture::~TestFixture()
{
TestRegistry::theInstance().removeTest(this);
}
*/
bool TestFixture::runTest(const char testname[]) bool TestFixture::runTest(const char testname[])
{ {

View File

@ -146,7 +146,7 @@ private:
std::istringstream istr(code); std::istringstream istr(code);
tokenizer.TokenizeCode(istr, 0); tokenizer.TokenizeCode(istr, 0);
tokenizer.FillFunctionList(0); tokenizer.FillFunctionList();
ASSERT_EQUALS( 1, tokenizer.FunctionList.size() ); ASSERT_EQUALS( 1, tokenizer.FunctionList.size() );
ASSERT_EQUALS( std::string("b"), tokenizer.FunctionList[0]->str ); ASSERT_EQUALS( std::string("b"), tokenizer.FunctionList[0]->str );

View File

@ -1032,7 +1032,7 @@ const TOKEN *Tokenizer::GetFunctionTokenByName( const char funcname[] ) const
} }
void Tokenizer::FillFunctionList(const unsigned int file_id) void Tokenizer::FillFunctionList()
{ {
FunctionList.clear(); FunctionList.clear();

View File

@ -64,7 +64,7 @@ public:
const std::vector<std::string> *getFiles() const; const std::vector<std::string> *getFiles() const;
void FillFunctionList(const unsigned int file_id); void FillFunctionList();
const TOKEN *GetFunctionTokenByName( const char funcname[] ) const; const TOKEN *GetFunctionTokenByName( const char funcname[] ) const;
void settings( const Settings &settings ); void settings( const Settings &settings );
const TOKEN *tokens() const; const TOKEN *tokens() const;