From 895b1d5561c1cdb1ba34799199743ddec9bc215e Mon Sep 17 00:00:00 2001 From: Reijo Tomperi Date: Sun, 23 Nov 2008 22:01:09 +0000 Subject: [PATCH] Refactoring: Started making CppCheck class more generally usable (e.g. as a part of IDE). --- cppcheck.cpp | 89 +++++++++++++++++++++++++++++----------------------- cppcheck.h | 53 ++++++++++++++++++++++++++++--- main.cpp | 10 ++++-- settings.cpp | 1 + settings.h | 1 + 5 files changed, 109 insertions(+), 45 deletions(-) diff --git a/cppcheck.cpp b/cppcheck.cpp index a3b420da4..9b2654b49 100644 --- a/cppcheck.cpp +++ b/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 pathnames; bool Recursive = false; - Settings _settings; - for (int i = 1; i < argc; i++) { if (strcmp(argv[i],"--debug") == 0) @@ -77,14 +85,13 @@ void CppCheck::check(int argc, char* argv[]) pathnames.push_back( argv[i] ); } - std::vector filenames; // --recursive was used if ( Recursive ) { if( pathnames.size() == 0 ) { // Handle situation: cppcheck --recursive - FileLister::RecursiveAddFiles( filenames, "", true ); + FileLister::RecursiveAddFiles( _filenames, "", true ); } else { @@ -93,47 +100,52 @@ void CppCheck::check(int argc, char* argv[]) // Execute RecursiveAddFiles() to each given file parameter std::vector::const_iterator iter; for(iter=pathnames.begin(); iter!=pathnames.end(); iter++) - FileLister::RecursiveAddFiles( filenames, iter->c_str(), true ); + FileLister::RecursiveAddFiles( _filenames, iter->c_str(), true ); } } else { std::vector::const_iterator 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" - "\n" - "Syntax:\n" - " cppcheck [--all] [--style] [--errorsonly] [--recursive] [filename1] [filename2]\n" - "\n" - "Options:\n" - " --all Normally a message is only shown if cppcheck is sure\n" - " it has found a bug.\n" - " When this option is given, all messages are shown.\n" - "\n" - " --style Check coding style.\n" - " --errorsonly Only print something when there is an error\n" - " --recursive Recursively check all *.cpp, *.cc and *.c files\n"; - return; + std::ostringstream oss; + oss << "C/C++ code checking.\n" + "\n" + "Syntax:\n" + " cppcheck [--all] [--style] [--errorsonly] [--recursive] [filename1] [filename2]\n" + "\n" + "Options:\n" + " --all Normally a message is only shown if cppcheck is sure\n" + " it has found a bug.\n" + " When this option is given, all messages are shown.\n" + "\n" + " --style Check coding style.\n" + " --errorsonly Only print something when there is an error\n" + " --recursive Recursively check all *.cpp, *.cc and *.c files\n"; + 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. - CheckFunctionUsage *checkFunctionUsage = NULL; - if ( Recursive && _settings._showAll && _settings._checkCodingStyle ) - checkFunctionUsage = new CheckFunctionUsage( this ); + return ""; +} - 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(""); - std::string fname = filenames[c]; + std::string fname = _filenames[c]; // If only errors are printed, print filename after the check if (!_settings._errorsOnly) @@ -144,7 +156,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(), _settings, checkFunctionUsage); + checkFile(it->second, _filenames[c].c_str()); if (_settings._errorsOnly) { @@ -164,11 +176,11 @@ void CppCheck::check(int argc, char* argv[]) } // This generates false positives - especially for libraries - if ( checkFunctionUsage ) + if ( _settings._checkFunctionUsage ) { _errout.str(""); std::cout << "Checking usage of global functions (this may take several minutes)..\n"; - checkFunctionUsage->check(); + _checkFunctionUsage.check(); if ( ! _errout.str().empty() ) { 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 //--------------------------------------------------------------------------- -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.settings( _settings ); @@ -227,8 +238,8 @@ void CppCheck::checkFile(const std::string &code, const char FileName[], Setting _tokenizer.SimplifyTokenList(); - if ( checkFunctionUsage ) - checkFunctionUsage->parseTokens(_tokenizer); + if ( _settings._checkFunctionUsage ) + _checkFunctionUsage.parseTokens(_tokenizer); // Memory leak CheckMemoryLeakClass checkMemoryLeak( &_tokenizer, _settings, this ); diff --git a/cppcheck.h b/cppcheck.h index d61b74fcb..b46b1118d 100644 --- a/cppcheck.h +++ b/cppcheck.h @@ -22,30 +22,75 @@ #include #include #include +#include #include "settings.h" #include "errorlogger.h" - -class CheckFunctionUsage; +#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 * errors or places that could be improved. + * Usage: See check() for more info. */ class CppCheck : public ErrorLogger { public: + /** + * Constructor. + */ CppCheck(); + + /** + * Destructor. + */ 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: - 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 TOKEN *token, const std::string &errmsg); std::list _errorList; std::ostringstream _errout; + Settings _settings; + std::vector _filenames; + CheckFunctionUsage _checkFunctionUsage; }; #endif // CPPCHECK_H diff --git a/main.cpp b/main.cpp index ea51c5cfa..010cf52b5 100644 --- a/main.cpp +++ b/main.cpp @@ -17,7 +17,8 @@ */ -#include "cppcheck.h" +#include "cppcheck.h" +#include //--------------------------------------------------------------------------- // Main function of cppcheck @@ -26,7 +27,12 @@ int main(int argc, char* argv[]) { 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; } diff --git a/settings.cpp b/settings.cpp index 689502e9c..5af961ac7 100644 --- a/settings.cpp +++ b/settings.cpp @@ -24,6 +24,7 @@ Settings::Settings() _showAll = false; _checkCodingStyle = false; _errorsOnly = false; + _checkFunctionUsage = false; } Settings::~Settings() diff --git a/settings.h b/settings.h index 31a94b164..877d515b4 100644 --- a/settings.h +++ b/settings.h @@ -34,6 +34,7 @@ public: bool _showAll; bool _checkCodingStyle; bool _errorsOnly; + bool _checkFunctionUsage; }; #endif // SETTINGS_H