diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp
new file mode 100644
index 000000000..7104d0981
--- /dev/null
+++ b/cli/cmdlineparser.cpp
@@ -0,0 +1,453 @@
+/*
+ * Cppcheck - A tool for static C/C++ code analysis
+ * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team.
+ *
+ * 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 .
+ */
+
+#include
+#include
+#include
+#include
+#include "cmdlineparser.h"
+#include "cppcheck.h"
+#include "timer.h"
+#include "settings.h"
+
+
+static void AddFilesToList(const std::string& FileList, std::vector& PathNames)
+{
+ // to keep things initially simple, if the file can't be opened, just be
+ // silent and move on
+ // ideas : we could also require this should be an xml file, with the filenames
+ // specified in an xml structure
+ // we could elaborate this then, to also include the I-paths, ...
+ // basically for everything that makes the command line very long
+ // xml is a bonus then, since we can easily extend it
+ // we need a good parser then -> suggestion : TinyXml
+ // drawback : creates a dependency
+ std::ifstream Files(FileList.c_str());
+ if (Files)
+ {
+ std::string FileName;
+ while (std::getline(Files, FileName)) // next line
+ {
+ if (!FileName.empty())
+ {
+ PathNames.push_back(FileName);
+ }
+ }
+ }
+}
+
+CmdLineParser::CmdLineParser(Settings *settings)
+ : _settings(settings)
+ , _showHelp(false)
+ , _showVersion(false)
+ , _showErrorMessages(false)
+{
+}
+
+bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
+{
+ for (int i = 1; i < argc; i++)
+ {
+ if (strcmp(argv[i], "--version") == 0)
+ {
+ _showVersion = true;
+ return true;
+ }
+ // Flag used for various purposes during debugging
+ else if (strcmp(argv[i], "--debug") == 0)
+ _settings->debug = _settings->debugwarnings = true;
+
+ // Show debug warnings
+ else if (strcmp(argv[i], "--debug-warnings") == 0)
+ _settings->debugwarnings = true;
+
+ // Inconclusive checking - keep this for compatibility but don't
+ // handle it
+ else if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "--all") == 0)
+ ;
+
+ // Checking coding style
+ else if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--style") == 0)
+ {
+ const std::string errmsg = _settings->addEnabled("style");
+ if (!errmsg.empty())
+ {
+ std::cout << errmsg;
+ return false;
+ }
+ }
+
+ // Filter errors
+ else if (strcmp(argv[i], "--suppressions") == 0)
+ {
+ ++i;
+
+ if (i >= argc)
+ {
+ std::cout << "cppcheck: No file specified for the --suppressions option";
+ return false;
+ }
+
+ std::ifstream f(argv[i]);
+ if (!f.is_open())
+ {
+ std::cout << "cppcheck: Couldn't open the file \"" << std::string(argv[i]) << "\"";
+ return false;
+ }
+ const std::string errmsg(_settings->nomsg.parseFile(f));
+ if (!errmsg.empty())
+ {
+ std::cout << errmsg;
+ return false;
+ }
+ }
+
+ // Enables inline suppressions.
+ else if (strcmp(argv[i], "--inline-suppr") == 0)
+ _settings->_inlineSuppressions = true;
+
+ // Verbose error messages (configuration info)
+ else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0)
+ _settings->_verbose = true;
+
+ // Force checking of files that have "too many" configurations
+ else if (strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "--force") == 0)
+ _settings->_force = true;
+
+ // Write results in results.xml
+ else if (strcmp(argv[i], "--xml") == 0)
+ _settings->_xml = true;
+
+ // Only print something when there are errors
+ else if (strcmp(argv[i], "-q") == 0 || strcmp(argv[i], "--quiet") == 0)
+ _settings->_errorsOnly = true;
+
+ // Check if there are unused functions
+ else if (strcmp(argv[i], "--unused-functions") == 0)
+ {
+ const std::string errmsg = _settings->addEnabled("unusedFunctions");
+ if (!errmsg.empty())
+ {
+ std::cout << errmsg;
+ return false;
+ }
+ }
+
+ // Append userdefined code to checked source code
+ else if (strncmp(argv[i], "--append=", 9) == 0)
+ _settings->append(9 + argv[i]);
+
+ else if (strncmp(argv[i], "--enable=", 9) == 0)
+ {
+ const std::string errmsg = _settings->addEnabled(argv[i] + 9);
+ if (!errmsg.empty())
+ {
+ std::cout << errmsg;
+ return false;
+ }
+ }
+
+ // --error-exitcode=1
+ else if (strncmp(argv[i], "--error-exitcode=", 17) == 0)
+ {
+ std::string temp = argv[i];
+ temp = temp.substr(17);
+ std::istringstream iss(temp);
+ if (!(iss >> _settings->_exitCode))
+ {
+ _settings->_exitCode = 0;
+ std::cout << "cppcheck: Argument must be an integer. Try something like '--error-exitcode=1'";
+ return false;
+ }
+ }
+
+ // User define
+ else if (strncmp(argv[i], "-D", 2) == 0)
+ {
+ if (!_settings->userDefines.empty())
+ _settings->userDefines += ";";
+ _settings->userDefines += 2 + argv[i];
+ }
+
+ // Include paths
+ else if (strcmp(argv[i], "-I") == 0 || strncmp(argv[i], "-I", 2) == 0)
+ {
+ std::string path;
+
+ // "-I path/"
+ if (strcmp(argv[i], "-I") == 0)
+ {
+ ++i;
+ if (i >= argc)
+ {
+ std::cout << "cppcheck: argument to '-I' is missing";
+ return false;
+ }
+ path = argv[i];
+ }
+
+ // "-Ipath/"
+ else
+ {
+ path = argv[i];
+ path = path.substr(2);
+ }
+
+ // If path doesn't end with / or \, add it
+ if (path[path.length()-1] != '/' && path[path.length()-1] != '\\')
+ path += '/';
+
+ _settings->_includePaths.push_back(path);
+ }
+
+ // file list specified
+ else if (strncmp(argv[i], "--file-list=", 12) == 0)
+ {
+ // open this file and read every input file (1 file name per line)
+ AddFilesToList(12 + argv[i], _pathnames);
+ }
+
+ // Report progress
+ else if (strcmp(argv[i], "--report-progress") == 0)
+ {
+ _settings->reportProgress = true;
+ }
+
+ // Output formatter
+ else if (strcmp(argv[i], "--template") == 0)
+ {
+ // "--template path/"
+ ++i;
+ if (i >= argc)
+ {
+ std::cout << "cppcheck: argument to '--template' is missing";
+ return false;
+ }
+
+ _settings->_outputFormat = argv[i];
+ if (_settings->_outputFormat == "gcc")
+ _settings->_outputFormat = "{file}:{line}: {severity}: {message}";
+ else if (_settings->_outputFormat == "vs")
+ _settings->_outputFormat = "{file}({line}): {severity}: {message}";
+ }
+
+ // Checking threads
+ else if (strcmp(argv[i], "-j") == 0 ||
+ strncmp(argv[i], "-j", 2) == 0)
+ {
+ std::string numberString;
+
+ // "-j 3"
+ if (strcmp(argv[i], "-j") == 0)
+ {
+ ++i;
+ if (i >= argc)
+ {
+ std::cout << "cppcheck: argument to '-j' is missing";
+ return false;
+ }
+
+ numberString = argv[i];
+ }
+
+ // "-j3"
+ else if (strncmp(argv[i], "-j", 2) == 0)
+ {
+ numberString = argv[i];
+ numberString = numberString.substr(2);
+ }
+
+ std::istringstream iss(numberString);
+ if (!(iss >> _settings->_jobs))
+ {
+ std::cout << "cppcheck: argument to '-j' is not a number";
+ return false;
+ }
+
+ if (_settings->_jobs > 1000)
+ {
+ std::cout << "cppcheck: argument for '-j' is allowed to be 1000 at max";
+ return false;
+ }
+ }
+
+ // deprecated: auto deallocated classes..
+ else if (strcmp(argv[i], "--auto-dealloc") == 0)
+ {
+ ++i;
+ }
+
+ // print all possible error messages..
+ else if (strcmp(argv[i], "--errorlist") == 0)
+ {
+ //_cppcheck->getErrorMessages();
+ _showErrorMessages = true;
+ return true;
+ }
+
+ // documentation..
+ else if (strcmp(argv[i], "--doc") == 0)
+ {
+ std::ostringstream doc;
+ // Get documentation..
+ for (std::list::iterator it = Check::instances().begin(); it != Check::instances().end(); ++it)
+ {
+ doc << "===" << (*it)->name() << "===\n"
+ << (*it)->classInfo() << "\n\n";
+ }
+
+ std::string doc2(doc.str());
+ while (doc2.find("\n\n\n") != std::string::npos)
+ doc2.erase(doc2.find("\n\n\n"), 1);
+ std::cout << doc2;
+ return true;
+ }
+
+ // --test-2-pass Experimental 2-pass checking of files
+ // This command line flag will be removed
+ else if (strcmp(argv[i], "--test-2-pass") == 0)
+ {
+ _settings->test_2_pass = true;
+ }
+
+ else if (strncmp(argv[i], "-", 1) == 0 || strncmp(argv[i], "--", 2) == 0)
+ {
+ std::cout << "cppcheck: error: unrecognized command line option \"" << argv[i] << "\"";
+ return false;
+ }
+
+ // show timing information..
+ else if (strncmp(argv[i], "--showtime=", 11) == 0)
+ {
+ const std::string showtimeMode = argv[i] + 11;
+ if (showtimeMode == "file")
+ _settings->_showtime = SHOWTIME_FILE;
+ else if (showtimeMode == "summary")
+ _settings->_showtime = SHOWTIME_SUMMARY;
+ else if (showtimeMode == "top5")
+ _settings->_showtime = SHOWTIME_TOP5;
+ else
+ _settings->_showtime = SHOWTIME_NONE;
+ }
+
+ // Print help
+ else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
+ {
+ _pathnames.clear();
+ _showHelp = true;
+ break;
+ }
+ else
+ _pathnames.push_back(argv[i]);
+ }
+
+ if (_settings->isEnabled("unusedFunctions") && _settings->_jobs > 1)
+ {
+ std::cout << "unusedFunctions check can't be used with -j option, so it was disabled.";
+ }
+
+ // FIXME: Make the _settings.test_2_pass thread safe
+ if (_settings->test_2_pass && _settings->_jobs > 1)
+ {
+ std::cout << "--test-2-pass doesn't work with -j option yet.";
+ }
+
+
+ if (argc <= 1 || _showHelp)
+ PrintHelp();
+ else if (_pathnames.empty())
+ {
+ std::cout << "cppcheck: No C or C++ source files found.";
+ return false;
+ }
+
+ return true;
+}
+
+void CmdLineParser::PrintHelp()
+{
+ std::cout << "Cppcheck - A tool for static C/C++ code analysis\n"
+ "\n"
+ "Syntax:\n"
+ " cppcheck [--append=file] [-D] [--enable=] [--error-exitcode=[n]]\n"
+ " [--exitcode-suppressions file] [--file-list=file.txt] [--force]\n"
+ " [--help] [-Idir] [--inline-suppr] [-j [jobs]] [--quiet]\n"
+ " [--report-progress] [--style] [--suppressions file.txt]\n"
+ " [--verbose] [--version] [--xml] [file or path1] [file or path]\n"
+ "\n"
+ "If path is given instead of filename, *.cpp, *.cxx, *.cc, *.c++ and *.c files\n"
+ "are checked recursively from given directory.\n\n"
+ "Options:\n"
+ " --append=file This allows you to provide information about\n"
+ " functions by providing an implementation for these.\n"
+ " -D By default Cppcheck checks all configurations.\n"
+ " Use -D to limit the checking. When -D is used the\n"
+ " checking is limited to the given configuration.\n"
+ " Example: -DDEBUG=1 -D__cplusplus\n"
+ " --enable=id Enable additional checks. The available ids are:\n"
+ " * all - enable all checks\n"
+ " * style - Check coding style\n"
+ " * unusedFunctions - check for unused functions\n"
+ " Several ids can be given if you separate them with commas\n"
+ " --error-exitcode=[n] If errors are found, integer [n] is returned instead\n"
+ " of default 0. EXIT_FAILURE is returned\n"
+ " if arguments are not valid or if no input files are\n"
+ " provided. Note that your operating system can\n"
+ " modify this value, e.g. 256 can become 0.\n"
+ " --exitcode-suppressions file\n"
+ " Used when certain messages should be displayed but\n"
+ " should not cause a non-zero exitcode.\n"
+ " --file-list=file Specify the files to check in a text file. One Filename per line.\n"
+ " -f, --force Force checking on files that have \"too many\"\n"
+ " configurations\n"
+ " -h, --help Print this help\n"
+ " -I [dir] Give include path. Give several -I parameters to give\n"
+ " several paths. First given path is checked first. If\n"
+ " paths are relative to source files, this is not needed\n"
+ " --inline-suppr Enable inline suppressions. Use them by placing one or\n"
+ " more comments in the form: // cppcheck-suppress memleak\n"
+ " on the lines before the warning to suppress.\n"
+ " -j [jobs] Start [jobs] threads to do the checking simultaneously.\n"
+ " -q, --quiet Only print error messages\n"
+ " --report-progress Report progress messages while checking a file.\n"
+ " -s, --style deprecated, use --enable=style\n"
+ " --suppressions file Suppress warnings listed in the file. Filename and line\n"
+ " are optional. The format of the single line in file is:\n"
+ " [error id]:[filename]:[line]\n"
+ " --template '[text]' Format the error messages. E.g.\n"
+ " '{file}:{line},{severity},{id},{message}' or\n"
+ " '{file}({line}):({severity}) {message}'\n"
+ " Pre-defined templates: gcc, vs\n"
+ " -v, --verbose More detailed error reports\n"
+ " --version Print out version number\n"
+ " --xml Write results in xml to error stream.\n"
+ "\n"
+ "Example usage:\n"
+ " # Recursively check the current folder. Print the progress on the screen and\n"
+ " write errors in a file:\n"
+ " cppcheck . 2> err.txt\n"
+ " # Recursively check ../myproject/ and don't print progress:\n"
+ " cppcheck --quiet ../myproject/\n"
+ " # Check only files one.cpp and two.cpp and give all information there is:\n"
+ " cppcheck -v -s one.cpp two.cpp\n"
+ " # Check f.cpp and search include files from inc1/ and inc2/:\n"
+ " cppcheck -I inc1/ -I inc2/ f.cpp\n"
+ "\n"
+ "For more information:\n"
+ " http://cppcheck.sf.net/manual.pdf\n";
+}
diff --git a/cli/cmdlineparser.h b/cli/cmdlineparser.h
new file mode 100644
index 000000000..ec8898dee
--- /dev/null
+++ b/cli/cmdlineparser.h
@@ -0,0 +1,57 @@
+/*
+ * Cppcheck - A tool for static C/C++ code analysis
+ * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team.
+ *
+ * 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 .
+ */
+
+#ifndef CMDLINE_PARSER_H
+#define CMDLINE_PARSER_H
+
+#include
+#include
+
+class CppCheck;
+class Settings;
+
+class CmdLineParser
+{
+public:
+ CmdLineParser(Settings *settings);
+ bool ParseFromArgs(int argc, const char* const argv[]);
+ bool GetShowVersion() const
+ {
+ return _showVersion;
+ }
+ bool GetShowErrorMessages() const
+ {
+ return _showErrorMessages;
+ }
+ std::vector GetPathNames() const
+ {
+ return _pathnames;
+ }
+
+protected:
+ void PrintHelp();
+
+private:
+ Settings *_settings;
+ bool _showHelp;
+ bool _showVersion;
+ bool _showErrorMessages;
+ std::vector _pathnames;
+};
+
+#endif // CMDLINE_PARSER_H
diff --git a/cli/cppcheck.vcproj b/cli/cppcheck.vcproj
index 48a52d76c..921a22079 100755
--- a/cli/cppcheck.vcproj
+++ b/cli/cppcheck.vcproj
@@ -224,6 +224,10 @@
RelativePath="..\lib\checkunusedfunctions.cpp"
>
+
+
@@ -330,6 +334,10 @@
RelativePath="..\lib\classinfo.h"
>
+
+
diff --git a/cli/cppcheck.vcxproj b/cli/cppcheck.vcxproj
index b68daecd9..17cdc0792 100644
--- a/cli/cppcheck.vcxproj
+++ b/cli/cppcheck.vcxproj
@@ -143,6 +143,7 @@
+
@@ -170,6 +171,7 @@
+
diff --git a/cli/cppcheck.vcxproj.filters b/cli/cppcheck.vcxproj.filters
index 466d3457d..ae2b9ad8b 100644
--- a/cli/cppcheck.vcxproj.filters
+++ b/cli/cppcheck.vcxproj.filters
@@ -80,6 +80,9 @@
Source Files
+
+ Source Files
+
@@ -151,6 +154,9 @@
Header Files
+
+ Header Files
+
diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp
index 113f45b33..df94136db 100644
--- a/cli/cppcheckexecutor.cpp
+++ b/cli/cppcheckexecutor.cpp
@@ -22,6 +22,8 @@
#include
#include
#include // EXIT_SUCCESS and EXIT_FAILURE
+#include "cmdlineparser.h"
+#include "filelister.h"
CppCheckExecutor::CppCheckExecutor()
{
@@ -33,10 +35,47 @@ CppCheckExecutor::~CppCheckExecutor()
}
+bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* const argv[])
+{
+ CmdLineParser parser(&_settings);
+ bool success = parser.ParseFromArgs(argc, argv);
+
+ if (success)
+ {
+ if (parser.GetShowVersion())
+ {
+ std::cout << "Cppcheck " << cppcheck->version();
+ return true;
+ }
+
+ if (parser.GetShowErrorMessages())
+ {
+ cppcheck->getErrorMessages();
+ return true;
+ }
+ }
+
+ std::vector pathnames = parser.GetPathNames();
+ std::vector filenames;
+
+ if (!pathnames.empty())
+ {
+ // Execute recursiveAddFiles() to each given file parameter
+ std::vector::const_iterator iter;
+ for (iter = pathnames.begin(); iter != pathnames.end(); ++iter)
+ getFileLister()->recursiveAddFiles(filenames, iter->c_str(), true);
+
+ for (iter = filenames.begin(); iter != filenames.end(); ++iter)
+ cppcheck->addFile(*iter);
+ }
+
+ return true;
+}
+
int CppCheckExecutor::check(int argc, const char* const argv[])
{
CppCheck cppCheck(*this);
- if (!cppCheck.parseFromArgs(argc, argv))
+ if (!parseFromArgs(&cppCheck, argc, argv))
{
return EXIT_FAILURE;
}
diff --git a/cli/cppcheckexecutor.h b/cli/cppcheckexecutor.h
index 813a2f196..35ab42a31 100644
--- a/cli/cppcheckexecutor.h
+++ b/cli/cppcheckexecutor.h
@@ -23,6 +23,8 @@
#include "settings.h"
#include
+class CppCheck;
+
/**
* This class works as an example of how CppCheck can be used in external
* programs without very little knowledge of the internal parts of the
@@ -79,6 +81,16 @@ protected:
*/
virtual void reportErr(const std::string &errmsg);
+ /**
+ * @brief Parse command line args and get settings and file lists
+ * from there.
+ *
+ * @param argc argc from main()
+ * @param argv argv from main()
+ * @return false when errors are found in the input
+ */
+ bool parseFromArgs(CppCheck *cppcheck, int argc, const char* const argv[]);
+
/**
* check() will setup this in the beginning of check().
*/
diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp
index 624bfd7ae..40ee70e33 100644
--- a/lib/cppcheck.cpp
+++ b/lib/cppcheck.cpp
@@ -101,436 +101,6 @@ static void AddFilesToList(const std::string& FileList, std::vector
}
}
-bool CppCheck::parseFromArgs(int argc, const char* const argv[])
-{
- std::vector pathnames;
- bool showHelp = false;
- for (int i = 1; i < argc; i++)
- {
- if (strcmp(argv[i], "--version") == 0)
- {
- reportOut(std::string("Cppcheck ") + version());
- return true;
- }
-
- // Flag used for various purposes during debugging
- else if (strcmp(argv[i], "--debug") == 0)
- _settings.debug = _settings.debugwarnings = true;
-
- // Show debug warnings
- else if (strcmp(argv[i], "--debug-warnings") == 0)
- _settings.debugwarnings = true;
-
- // Inconclusive checking - keep this for compatibility but don't
- // handle it
- else if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "--all") == 0)
- ;
-
- // Only print something when there are errors
- else if (strcmp(argv[i], "-q") == 0 || strcmp(argv[i], "--quiet") == 0)
- _settings._errorsOnly = true;
-
- // Checking coding style
- else if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--style") == 0)
- {
- const std::string errmsg = _settings.addEnabled("style");
- if (!errmsg.empty())
- {
- reportOut(errmsg);
- return false;
- }
- }
-
- // Filter errors
- else if (strcmp(argv[i], "--suppressions") == 0)
- {
- ++i;
-
- if (i >= argc)
- {
- reportOut("cppcheck: No file specified for the --suppressions option");
- return false;
- }
-
- std::ifstream f(argv[i]);
- if (!f.is_open())
- {
- reportOut("cppcheck: Couldn't open the file \"" + std::string(argv[i]) + "\"");
- return false;
- }
- const std::string errmsg(_settings.nomsg.parseFile(f));
- if (!errmsg.empty())
- {
- reportOut(errmsg);
- return false;
- }
- }
-
- // Filter errors
- else if (strcmp(argv[i], "--exitcode-suppressions") == 0)
- {
- ++i;
-
- if (i >= argc)
- {
- reportOut("cppcheck: No file specified for the --exitcode-suppressions option");
- return false;
- }
-
- std::ifstream f(argv[i]);
- if (!f.is_open())
- {
- reportOut("cppcheck: Couldn't open the file \"" + std::string(argv[i]) + "\"");
- return false;
- }
- const std::string errmsg(_settings.nofail.parseFile(f));
- if (!errmsg.empty())
- {
- reportOut(errmsg);
- return false;
- }
- }
-
- // Enables inline suppressions.
- else if (strcmp(argv[i], "--inline-suppr") == 0)
- _settings._inlineSuppressions = true;
-
- // Verbose error messages (configuration info)
- else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0)
- _settings._verbose = true;
-
- // Force checking of files that have "too many" configurations
- else if (strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "--force") == 0)
- _settings._force = true;
-
- // Write results in results.xml
- else if (strcmp(argv[i], "--xml") == 0)
- _settings._xml = true;
-
- // Check if there are unused functions
- else if (strcmp(argv[i], "--unused-functions") == 0)
- {
- const std::string errmsg = _settings.addEnabled("unusedFunctions");
- if (!errmsg.empty())
- {
- reportOut(errmsg);
- return false;
- }
- }
-
- // Append userdefined code to checked source code
- else if (strncmp(argv[i], "--append=", 9) == 0)
- _settings.append(9 + argv[i]);
-
- // show timing information..
- else if (strncmp(argv[i], "--showtime=", 11) == 0)
- {
- const std::string showtimeMode = argv[i] + 11;
- if (showtimeMode == "file")
- _settings._showtime = SHOWTIME_FILE;
- else if (showtimeMode == "summary")
- _settings._showtime = SHOWTIME_SUMMARY;
- else if (showtimeMode == "top5")
- _settings._showtime = SHOWTIME_TOP5;
- else
- _settings._showtime = SHOWTIME_NONE;
- }
-
- // Print help
- else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
- {
- pathnames.clear();
- _filenames.clear();
- showHelp = true;
- break;
- }
-
-
- else if (strncmp(argv[i], "--enable=", 9) == 0)
- {
- const std::string errmsg = _settings.addEnabled(argv[i] + 9);
- if (!errmsg.empty())
- {
- reportOut(errmsg);
- return false;
- }
- }
-
- // --error-exitcode=1
- else if (strncmp(argv[i], "--error-exitcode=", 17) == 0)
- {
- std::string temp = argv[i];
- temp = temp.substr(17);
- std::istringstream iss(temp);
- if (!(iss >> _settings._exitCode))
- {
- _settings._exitCode = 0;
- reportOut("cppcheck: Argument must be an integer. Try something like '--error-exitcode=1'");
- return false;
- }
- }
-
- // User define
- else if (strncmp(argv[i], "-D", 2) == 0)
- {
- if (!_settings.userDefines.empty())
- _settings.userDefines += ";";
- _settings.userDefines += 2 + argv[i];
- }
-
- // Include paths
- else if (strcmp(argv[i], "-I") == 0 || strncmp(argv[i], "-I", 2) == 0)
- {
- std::string path;
-
- // "-I path/"
- if (strcmp(argv[i], "-I") == 0)
- {
- ++i;
- if (i >= argc)
- {
- reportOut("cppcheck: argument to '-I' is missing");
- return false;
- }
-
- path = argv[i];
- }
-
- // "-Ipath/"
- else
- {
- path = argv[i];
- path = path.substr(2);
- }
-
- // If path doesn't end with / or \, add it
- if (path[path.length()-1] != '/' && path[path.length()-1] != '\\')
- path += '/';
-
- _settings._includePaths.push_back(path);
- }
-
- // file list specified
- else if (strncmp(argv[i], "--file-list=", 12) == 0)
- {
- // open this file and read every input file (1 file name per line)
- AddFilesToList(12 + argv[i], pathnames);
- }
-
- // Report progress
- else if (strcmp(argv[i], "--report-progress") == 0)
- {
- _settings.reportProgress = true;
- }
-
- // Output formatter
- else if (strcmp(argv[i], "--template") == 0)
- {
- // "--template path/"
- ++i;
- if (i >= argc)
- {
- reportOut("cppcheck: argument to '--template' is missing");
- return false;
- }
-
- _settings._outputFormat = argv[i];
- if (_settings._outputFormat == "gcc")
- _settings._outputFormat = "{file}:{line}: {severity}: {message}";
- else if (_settings._outputFormat == "vs")
- _settings._outputFormat = "{file}({line}): {severity}: {message}";
- }
-
- // Checking threads
- else if (strcmp(argv[i], "-j") == 0 ||
- strncmp(argv[i], "-j", 2) == 0)
- {
- std::string numberString;
-
- // "-j 3"
- if (strcmp(argv[i], "-j") == 0)
- {
- ++i;
- if (i >= argc)
- {
- reportOut("cppcheck: argument to '-j' is missing");
- return false;
- }
-
- numberString = argv[i];
- }
-
- // "-j3"
- else if (strncmp(argv[i], "-j", 2) == 0)
- {
- numberString = argv[i];
- numberString = numberString.substr(2);
- }
-
- std::istringstream iss(numberString);
- if (!(iss >> _settings._jobs))
- {
- reportOut("cppcheck: argument to '-j' is not a number");
- return false;
- }
-
- if (_settings._jobs > 1000)
- {
- reportOut("cppcheck: argument for '-j' is allowed to be 1000 at max");
- return false;
- }
- }
-
- // deprecated: auto deallocated classes..
- else if (strcmp(argv[i], "--auto-dealloc") == 0)
- {
- ++i;
- }
-
- // print all possible error messages..
- else if (strcmp(argv[i], "--errorlist") == 0)
- {
- getErrorMessages();
- return true;
- }
-
- // documentation..
- else if (strcmp(argv[i], "--doc") == 0)
- {
- std::ostringstream doc;
- // Get documentation..
- for (std::list::iterator it = Check::instances().begin(); it != Check::instances().end(); ++it)
- {
- doc << "===" << (*it)->name() << "===\n"
- << (*it)->classInfo() << "\n\n";
- }
-
- std::string doc2(doc.str());
- while (doc2.find("\n\n\n") != std::string::npos)
- doc2.erase(doc2.find("\n\n\n"), 1);
- reportOut(doc2);
- return true;
- }
-
- // --test-2-pass Experimental 2-pass checking of files
- // This command line flag will be removed
- else if (strcmp(argv[i], "--test-2-pass") == 0)
- {
- _settings.test_2_pass = true;
- }
-
- else if (strncmp(argv[i], "-", 1) == 0 || strncmp(argv[i], "--", 2) == 0)
- {
- reportOut("cppcheck: error: unrecognized command line option \"" + std::string(argv[i]) + "\"");
- return false;
- }
-
- else
- pathnames.push_back(argv[i]);
- }
-
- if (_settings.isEnabled("unusedFunctions") && _settings._jobs > 1)
- {
- reportOut("unusedFunctions check can't be used with -j option, so it was disabled.");
- }
-
- // FIXME: Make the _settings.test_2_pass thread safe
- if (_settings.test_2_pass && _settings._jobs > 1)
- {
- reportOut("--test-2-pass doesn't work with -j option yet.");
- }
-
- if (!pathnames.empty())
- {
- // Execute recursiveAddFiles() to each given file parameter
- std::vector::const_iterator iter;
- for (iter = pathnames.begin(); iter != pathnames.end(); ++iter)
- getFileLister()->recursiveAddFiles(_filenames, iter->c_str(), true);
- }
-
- if (argc <= 1 || showHelp)
- {
- std::ostringstream oss;
- oss << "Cppcheck - A tool for static C/C++ code analysis\n"
- "\n"
- "Syntax:\n"
- " cppcheck [--append=file] [-D] [--enable=] [--error-exitcode=[n]]\n"
- " [--exitcode-suppressions file] [--file-list=file.txt] [--force]\n"
- " [--help] [-Idir] [--inline-suppr] [-j [jobs]] [--quiet]\n"
- " [--report-progress] [--style] [--suppressions file.txt]\n"
- " [--verbose] [--version] [--xml] [file or path1] [file or path]\n"
- "\n"
- "If path is given instead of filename, *.cpp, *.cxx, *.cc, *.c++ and *.c files\n"
- "are checked recursively from given directory.\n\n"
- "Options:\n"
- " --append=file This allows you to provide information about\n"
- " functions by providing an implementation for these.\n"
- " -D By default Cppcheck checks all configurations.\n"
- " Use -D to limit the checking. When -D is used the\n"
- " checking is limited to the given configuration.\n"
- " Example: -DDEBUG=1 -D__cplusplus\n"
- " --enable=id Enable additional checks. The available ids are:\n"
- " * all - enable all checks\n"
- " * style - Check coding style\n"
- " * unusedFunctions - check for unused functions\n"
- " Several ids can be given if you separate them with commas\n"
- " --error-exitcode=[n] If errors are found, integer [n] is returned instead\n"
- " of default 0. EXIT_FAILURE is returned\n"
- " if arguments are not valid or if no input files are\n"
- " provided. Note that your operating system can\n"
- " modify this value, e.g. 256 can become 0.\n"
- " --exitcode-suppressions file\n"
- " Used when certain messages should be displayed but\n"
- " should not cause a non-zero exitcode.\n"
- " --file-list=file Specify the files to check in a text file. One Filename per line.\n"
- " -f, --force Force checking on files that have \"too many\"\n"
- " configurations\n"
- " -h, --help Print this help\n"
- " -I [dir] Give include path. Give several -I parameters to give\n"
- " several paths. First given path is checked first. If\n"
- " paths are relative to source files, this is not needed\n"
- " --inline-suppr Enable inline suppressions. Use them by placing one or\n"
- " more comments in the form: // cppcheck-suppress memleak\n"
- " on the lines before the warning to suppress.\n"
- " -j [jobs] Start [jobs] threads to do the checking simultaneously.\n"
- " -q, --quiet Only print error messages\n"
- " --report-progress Report progress messages while checking a file.\n"
- " -s, --style deprecated, use --enable=style\n"
- " --suppressions file Suppress warnings listed in the file. Filename and line\n"
- " are optional. The format of the single line in file is:\n"
- " [error id]:[filename]:[line]\n"
- " --template '[text]' Format the error messages. E.g.\n"
- " '{file}:{line},{severity},{id},{message}' or\n"
- " '{file}({line}):({severity}) {message}'\n"
- " Pre-defined templates: gcc, vs\n"
- " -v, --verbose More detailed error reports\n"
- " --version Print out version number\n"
- " --xml Write results in xml to error stream.\n"
- "\n"
- "Example usage:\n"
- " # Recursively check the current folder. Print the progress on the screen and\n"
- " write errors in a file:\n"
- " cppcheck . 2> err.txt\n"
- " # Recursively check ../myproject/ and don't print progress:\n"
- " cppcheck --quiet ../myproject/\n"
- " # Check only files one.cpp and two.cpp and give all information there is:\n"
- " cppcheck -v -s one.cpp two.cpp\n"
- " # Check f.cpp and search include files from inc1/ and inc2/:\n"
- " cppcheck -I inc1/ -I inc2/ f.cpp\n"
- "\n"
- "For more information:\n"
- " http://cppcheck.sf.net/manual.pdf\n";
- reportOut(oss.str());
- }
- else if (_filenames.empty())
- {
- reportOut("cppcheck: No C or C++ source files found.");
- return false;
- }
-
- return true;
-}
-
unsigned int CppCheck::check()
{
exitcode = 0;
diff --git a/lib/cppcheck.h b/lib/cppcheck.h
index 4c48081cd..e24c521b7 100644
--- a/lib/cppcheck.h
+++ b/lib/cppcheck.h
@@ -97,16 +97,6 @@ public:
*/
void clearFiles();
- /**
- * @brief Parse command line args and get settings and file lists
- * from there.
- *
- * @param argc argc from main()
- * @param argv argv from main()
- * @return false when errors are found in the input
- */
- bool parseFromArgs(int argc, const char* const argv[]);
-
/**
* @brief Returns current version number as a string.
* @return version, e.g. "1.38"