Refactoring: Started making CppCheck class more generally usable (e.g. as a part of IDE).
This commit is contained in:
parent
beee37c86b
commit
895b1d5561
65
cppcheck.cpp
65
cppcheck.cpp
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
CppCheck::CppCheck()
|
CppCheck::CppCheck() : _checkFunctionUsage( this )
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -47,13 +47,21 @@ CppCheck::~CppCheck()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppCheck::check(int argc, char* argv[])
|
void CppCheck::settings( const Settings &settings )
|
||||||
|
{
|
||||||
|
_settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CppCheck::addFile( const std::string &path )
|
||||||
|
{
|
||||||
|
_filenames.push_back( path );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CppCheck::parseFromArgs( int argc, char* argv[] )
|
||||||
{
|
{
|
||||||
std::vector<std::string> pathnames;
|
std::vector<std::string> pathnames;
|
||||||
bool Recursive = false;
|
bool Recursive = false;
|
||||||
|
|
||||||
Settings _settings;
|
|
||||||
|
|
||||||
for (int i = 1; i < argc; i++)
|
for (int i = 1; i < argc; i++)
|
||||||
{
|
{
|
||||||
if (strcmp(argv[i],"--debug") == 0)
|
if (strcmp(argv[i],"--debug") == 0)
|
||||||
|
@ -77,14 +85,13 @@ void CppCheck::check(int argc, char* argv[])
|
||||||
pathnames.push_back( argv[i] );
|
pathnames.push_back( argv[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> filenames;
|
|
||||||
// --recursive was used
|
// --recursive was used
|
||||||
if ( Recursive )
|
if ( Recursive )
|
||||||
{
|
{
|
||||||
if( pathnames.size() == 0 )
|
if( pathnames.size() == 0 )
|
||||||
{
|
{
|
||||||
// Handle situation: cppcheck --recursive
|
// Handle situation: cppcheck --recursive
|
||||||
FileLister::RecursiveAddFiles( filenames, "", true );
|
FileLister::RecursiveAddFiles( _filenames, "", true );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -93,21 +100,20 @@ void CppCheck::check(int argc, char* argv[])
|
||||||
// Execute RecursiveAddFiles() to each given file parameter
|
// Execute RecursiveAddFiles() to each given file parameter
|
||||||
std::vector<std::string>::const_iterator iter;
|
std::vector<std::string>::const_iterator iter;
|
||||||
for(iter=pathnames.begin(); iter!=pathnames.end(); iter++)
|
for(iter=pathnames.begin(); iter!=pathnames.end(); iter++)
|
||||||
FileLister::RecursiveAddFiles( filenames, iter->c_str(), true );
|
FileLister::RecursiveAddFiles( _filenames, iter->c_str(), true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::vector<std::string>::const_iterator iter;
|
std::vector<std::string>::const_iterator iter;
|
||||||
for(iter=pathnames.begin(); iter!=pathnames.end(); iter++)
|
for(iter=pathnames.begin(); iter!=pathnames.end(); iter++)
|
||||||
FileLister::RecursiveAddFiles( filenames, iter->c_str(), false );
|
FileLister::RecursiveAddFiles( _filenames, iter->c_str(), false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_filenames.empty())
|
||||||
|
|
||||||
if (filenames.empty())
|
|
||||||
{
|
{
|
||||||
std::cout << "C/C++ code checking.\n"
|
std::ostringstream oss;
|
||||||
|
oss << "C/C++ code checking.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Syntax:\n"
|
"Syntax:\n"
|
||||||
" cppcheck [--all] [--style] [--errorsonly] [--recursive] [filename1] [filename2]\n"
|
" cppcheck [--all] [--style] [--errorsonly] [--recursive] [filename1] [filename2]\n"
|
||||||
|
@ -120,20 +126,26 @@ void CppCheck::check(int argc, char* argv[])
|
||||||
" --style Check coding style.\n"
|
" --style Check coding style.\n"
|
||||||
" --errorsonly Only print something when there is an error\n"
|
" --errorsonly Only print something when there is an error\n"
|
||||||
" --recursive Recursively check all *.cpp, *.cc and *.c files\n";
|
" --recursive Recursively check all *.cpp, *.cc and *.c files\n";
|
||||||
return;
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort( filenames.begin(), filenames.end() );
|
if ( _settings._showAll && _settings._checkCodingStyle )
|
||||||
|
_settings._checkFunctionUsage = true;
|
||||||
|
|
||||||
// Check function usage if "--recursive", "--style" and "--all" was given.
|
return "";
|
||||||
CheckFunctionUsage *checkFunctionUsage = NULL;
|
}
|
||||||
if ( Recursive && _settings._showAll && _settings._checkCodingStyle )
|
|
||||||
checkFunctionUsage = new CheckFunctionUsage( this );
|
|
||||||
|
|
||||||
for (unsigned int c = 0; c < filenames.size(); c++)
|
void CppCheck::check()
|
||||||
|
{
|
||||||
|
std::sort( _filenames.begin(), _filenames.end() );
|
||||||
|
|
||||||
|
// Check function usage if "--style" and "--all" was given.
|
||||||
|
|
||||||
|
|
||||||
|
for (unsigned int c = 0; c < _filenames.size(); c++)
|
||||||
{
|
{
|
||||||
_errout.str("");
|
_errout.str("");
|
||||||
std::string fname = filenames[c];
|
std::string fname = _filenames[c];
|
||||||
|
|
||||||
// If only errors are printed, print filename after the check
|
// If only errors are printed, print filename after the check
|
||||||
if (!_settings._errorsOnly)
|
if (!_settings._errorsOnly)
|
||||||
|
@ -144,7 +156,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(), _settings, checkFunctionUsage);
|
checkFile(it->second, _filenames[c].c_str());
|
||||||
|
|
||||||
if (_settings._errorsOnly)
|
if (_settings._errorsOnly)
|
||||||
{
|
{
|
||||||
|
@ -164,11 +176,11 @@ void CppCheck::check(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
// This generates false positives - especially for libraries
|
// This generates false positives - especially for libraries
|
||||||
if ( checkFunctionUsage )
|
if ( _settings._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";
|
||||||
checkFunctionUsage->check();
|
_checkFunctionUsage.check();
|
||||||
if ( ! _errout.str().empty() )
|
if ( ! _errout.str().empty() )
|
||||||
{
|
{
|
||||||
std::cerr << "\n";
|
std::cerr << "\n";
|
||||||
|
@ -176,7 +188,6 @@ void CppCheck::check(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete checkFunctionUsage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -184,7 +195,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[], Settings &_settings, CheckFunctionUsage *checkFunctionUsage)
|
void CppCheck::checkFile(const std::string &code, const char FileName[])
|
||||||
{
|
{
|
||||||
Tokenizer _tokenizer;
|
Tokenizer _tokenizer;
|
||||||
_tokenizer.settings( _settings );
|
_tokenizer.settings( _settings );
|
||||||
|
@ -227,8 +238,8 @@ void CppCheck::checkFile(const std::string &code, const char FileName[], Setting
|
||||||
_tokenizer.SimplifyTokenList();
|
_tokenizer.SimplifyTokenList();
|
||||||
|
|
||||||
|
|
||||||
if ( checkFunctionUsage )
|
if ( _settings._checkFunctionUsage )
|
||||||
checkFunctionUsage->parseTokens(_tokenizer);
|
_checkFunctionUsage.parseTokens(_tokenizer);
|
||||||
|
|
||||||
// Memory leak
|
// Memory leak
|
||||||
CheckMemoryLeakClass checkMemoryLeak( &_tokenizer, _settings, this );
|
CheckMemoryLeakClass checkMemoryLeak( &_tokenizer, _settings, this );
|
||||||
|
|
53
cppcheck.h
53
cppcheck.h
|
@ -22,30 +22,75 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "errorlogger.h"
|
#include "errorlogger.h"
|
||||||
|
#include "CheckFunctionUsage.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
|
||||||
* errors or places that could be improved.
|
* errors or places that could be improved.
|
||||||
|
* Usage: See check() for more info.
|
||||||
*/
|
*/
|
||||||
class CppCheck : public ErrorLogger
|
class CppCheck : public ErrorLogger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
CppCheck();
|
CppCheck();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor.
|
||||||
|
*/
|
||||||
virtual ~CppCheck();
|
virtual ~CppCheck();
|
||||||
void check(int argc, char* argv[]);
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @param settings New settings which will overwrite the old.
|
||||||
|
*/
|
||||||
|
void settings( const Settings &settings );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add new file to be checked.
|
||||||
|
*
|
||||||
|
* @param path Relative or absolute path to the file to be checked,
|
||||||
|
* e.g. "cppcheck.cpp". Note that only source files (.c, .cc or .cpp)
|
||||||
|
* should be added to the list. Include filese are gathered automatically.
|
||||||
|
*/
|
||||||
|
void addFile( const std::string &path );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse command line args and get settings and file lists
|
||||||
|
* from there.
|
||||||
|
*
|
||||||
|
* @param argc argc from main()
|
||||||
|
* @param argv argv from main()
|
||||||
|
* @return Empty string if parameters were accepted, or
|
||||||
|
* string containing "help" text if no files were found to be
|
||||||
|
* checked.
|
||||||
|
*/
|
||||||
|
std::string parseFromArgs( int argc, char* argv[] );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void checkFile(const std::string &code, const char FileName[], Settings &_settings, CheckFunctionUsage *checkFunctionUsage);
|
void checkFile(const std::string &code, const char FileName[]);
|
||||||
void reportErr( const std::string &errmsg);
|
void reportErr( const std::string &errmsg);
|
||||||
void reportErr( const TOKEN *token, const std::string &errmsg);
|
void reportErr( const TOKEN *token, const std::string &errmsg);
|
||||||
|
|
||||||
std::list<std::string> _errorList;
|
std::list<std::string> _errorList;
|
||||||
std::ostringstream _errout;
|
std::ostringstream _errout;
|
||||||
|
Settings _settings;
|
||||||
|
std::vector<std::string> _filenames;
|
||||||
|
CheckFunctionUsage _checkFunctionUsage;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CPPCHECK_H
|
#endif // CPPCHECK_H
|
||||||
|
|
8
main.cpp
8
main.cpp
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
|
|
||||||
#include "cppcheck.h"
|
#include "cppcheck.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// Main function of cppcheck
|
// Main function of cppcheck
|
||||||
|
@ -26,7 +27,12 @@
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
CppCheck cppCheck;
|
CppCheck cppCheck;
|
||||||
cppCheck.check( argc, argv );
|
std::string result = cppCheck.parseFromArgs( argc, argv );
|
||||||
|
if( result.length() == 0 )
|
||||||
|
cppCheck.check();
|
||||||
|
else
|
||||||
|
std::cout << result;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ Settings::Settings()
|
||||||
_showAll = false;
|
_showAll = false;
|
||||||
_checkCodingStyle = false;
|
_checkCodingStyle = false;
|
||||||
_errorsOnly = false;
|
_errorsOnly = false;
|
||||||
|
_checkFunctionUsage = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings::~Settings()
|
Settings::~Settings()
|
||||||
|
|
|
@ -34,6 +34,7 @@ public:
|
||||||
bool _showAll;
|
bool _showAll;
|
||||||
bool _checkCodingStyle;
|
bool _checkCodingStyle;
|
||||||
bool _errorsOnly;
|
bool _errorsOnly;
|
||||||
|
bool _checkFunctionUsage;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SETTINGS_H
|
#endif // SETTINGS_H
|
||||||
|
|
Loading…
Reference in New Issue