diff --git a/man/cppcheck.1.xml b/man/cppcheck.1.xml
index 7302b06ee..0aee5a760 100644
--- a/man/cppcheck.1.xml
+++ b/man/cppcheck.1.xml
@@ -105,11 +105,12 @@ man(1), man(7), http://www.tldp.org/HOWTO/Man-Page/
-
+
+
@@ -153,7 +154,7 @@ default.
-
+
Give include path. Give several -I parameters to give several paths. First given path is checked first. If paths are relative to source
files, this is not needed.
@@ -186,6 +187,12 @@ files, this is not needed.
More detailed error reports
+
+
+
+ Start [workers] threads to do the checking work.
+
+
diff --git a/src/cppcheck.cpp b/src/cppcheck.cpp
index 4acddb0e0..e2d4ed68b 100644
--- a/src/cppcheck.cpp
+++ b/src/cppcheck.cpp
@@ -146,6 +146,39 @@ std::string CppCheck::parseFromArgs(int argc, const char* const argv[])
_includePaths.push_back(path);
}
+// Include paths
+ else if (strcmp(argv[i], "-w") == 0 ||
+ strncmp(argv[i], "-w", 2) == 0)
+ {
+ std::string numberString;
+
+ // "-w 3"
+ if (strcmp(argv[i], "-w") == 0)
+ {
+ ++i;
+ if (i >= argc)
+ return "cppcheck: argument to '-w' is missing\n";
+
+ numberString = argv[i];
+ }
+
+ // "-w3"
+ else if (strncmp(argv[i], "-w", 2) == 0)
+ {
+ numberString = argv[i];
+ numberString = numberString.substr(2);
+ }
+
+ std::istringstream iss(numberString);
+ if (!(iss >> _settings._workers))
+ return "cppcheck: argument to '-w' is not a number\n";
+
+ if (_settings._workers > 1000)
+ {
+ return "cppcheck: argument for '-w' is allowed to be 1000 at max\n";
+ }
+ }
+
else if (strncmp(argv[i], "-", 1) == 0 || strncmp(argv[i], "--", 2) == 0)
{
return "cppcheck: error: unrecognized command line option \"" + std::string(argv[i]) + "\"\n";
@@ -184,7 +217,7 @@ std::string CppCheck::parseFromArgs(int argc, const char* const argv[])
" -f, --force Force checking on files that have \"too many\"\n"
" configurations\n"
" -h, --help Print this help\n"
- " -I Give include path. Give several -I parameters to give\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"
" -q, --quiet Only print error messages\n"
@@ -192,6 +225,7 @@ std::string CppCheck::parseFromArgs(int argc, const char* const argv[])
" --unused-functions Check if there are unused functions\n"
" --vcl Suppress messages about memory leaks when using VCL classes\n"
" -v, --verbose More detailed error reports\n"
+ " -w [workers] Start [workers] threads to do the checking work.\n"
" --xml Write results in xml to error stream.\n"
"\n"
"Example usage:\n"
diff --git a/src/cppcheckexecutor.cpp b/src/cppcheckexecutor.cpp
index 4cdd2e1b7..aae21865d 100644
--- a/src/cppcheckexecutor.cpp
+++ b/src/cppcheckexecutor.cpp
@@ -47,11 +47,15 @@ unsigned int CppCheckExecutor::check(int argc, const char* const argv[])
}
unsigned int returnValue = 0;
- if (1)
+ if (_settings._workers == 1)
{
// Single process
returnValue = cppCheck.check();
}
+ else if (!ThreadExecutor::isEnabled())
+ {
+ std::cout << "No thread support yet implemented for this platform." << std::endl;
+ }
else
{
// Multiple processes
diff --git a/src/settings.cpp b/src/settings.cpp
index dc6282af4..77830c56b 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -31,6 +31,7 @@ Settings::Settings()
_unusedFunctions = false;
_security = false;
_vcl = false;
+ _workers = 1;
}
Settings::~Settings()
diff --git a/src/settings.h b/src/settings.h
index b73d5cfa6..6d88054b2 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -51,6 +51,10 @@ public:
/** Disable warnings for VCL classes */
bool _vcl;
+
+ /** How many processes/threads should do checking at the same
+ time. Default is 1. */
+ unsigned int _workers;
};
#endif // SETTINGS_H
diff --git a/src/threadexecutor.cpp b/src/threadexecutor.cpp
index a87c44418..efcd2b5b6 100644
--- a/src/threadexecutor.cpp
+++ b/src/threadexecutor.cpp
@@ -19,18 +19,12 @@
#include "threadexecutor.h"
#include "cppcheck.h"
-
-#if 0
-
-/**
-This implementation is currently for Linux only and disabled with #if 0 until
-proper way is invented.
- */
-
-#include
#include
+#if defined(__GNUC__) && !defined(__MINGW32__)
+#include
#include
#include
+#endif
ThreadExecutor::ThreadExecutor(const std::vector &filenames, const Settings &settings, ErrorLogger &errorLogger)
: _filenames(filenames), _settings(settings), _errorLogger(errorLogger), _fileCount(0)
@@ -43,6 +37,12 @@ ThreadExecutor::~ThreadExecutor()
//dtor
}
+///////////////////////////////////////////////////////////////////////////////
+////// This code is for __GNUC__ only /////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+#if defined(__GNUC__) && !defined(__MINGW32__)
+
bool ThreadExecutor::handleRead(unsigned int &result)
{
char type = 0;
@@ -53,7 +53,7 @@ bool ThreadExecutor::handleRead(unsigned int &result)
if (type != '1' && type != '2' && type != '3')
{
- std::cerr << "#### ThreadExecutor::handleRead error, type was:" << type << std::endl;
+ std::cerr << "#### You found a bug from cppcheck.\nThreadExecutor::handleRead error, type was:" << type << std::endl;
exit(0);
}
@@ -112,7 +112,7 @@ unsigned int ThreadExecutor::check()
for (unsigned int i = 0; i < _filenames.size(); i++)
{
// Keep only wanted amount of child processes running at a time.
- if (childCount >= 2)
+ if (childCount >= _settings._workers)
{
while (handleRead(result))
{
@@ -187,5 +187,22 @@ void ThreadExecutor::reportStatus(unsigned int /*index*/, unsigned int /*max*/)
}
#else
+unsigned int ThreadExecutor::check()
+{
+ return 0;
+}
+void ThreadExecutor::reportOut(const std::string &/*outmsg*/)
+{
+
+}
+void ThreadExecutor::reportErr(const ErrorLogger::ErrorMessage &/*msg*/)
+{
+
+}
+
+void ThreadExecutor::reportStatus(unsigned int /*index*/, unsigned int /*max*/)
+{
+
+}
#endif
diff --git a/src/threadexecutor.h b/src/threadexecutor.h
index b4f28cc0c..53f79d04d 100644
--- a/src/threadexecutor.h
+++ b/src/threadexecutor.h
@@ -31,7 +31,6 @@
*/
class ThreadExecutor : public ErrorLogger
{
-#if 0
public:
ThreadExecutor(const std::vector &filenames, const Settings &settings, ErrorLogger &_errorLogger);
virtual ~ThreadExecutor();
@@ -39,28 +38,37 @@ public:
virtual void reportOut(const std::string &outmsg);
virtual void reportErr(const ErrorLogger::ErrorMessage &msg);
virtual void reportStatus(unsigned int index, unsigned int max);
-protected:
-private:
- bool handleRead(unsigned int &result);
- void writeToPipe(char type, const std::string &data);
+private:
const std::vector &_filenames;
const Settings &_settings;
ErrorLogger &_errorLogger;
- int _pipe[2];
unsigned int _fileCount;
+
+#if defined(__GNUC__) && !defined(__MINGW32__)
+private:
+ bool handleRead(unsigned int &result);
+ void writeToPipe(char type, const std::string &data);
+ int _pipe[2];
+public:
+ /**
+ * @return true if support for threads exist.
+ */
+ static bool isEnabled()
+ {
+ return true;
+ }
#else
public:
- ThreadExecutor(const std::vector &filenames, const Settings &settings, ErrorLogger &_errorLogger) {};
- virtual ~ThreadExecutor() {};
- unsigned int check()
+ /**
+ * @return true if support for threads exist.
+ */
+ static bool isEnabled()
{
- return 0;
+ return false;
}
- virtual void reportOut(const std::string &outmsg) {}
- virtual void reportErr(const ErrorLogger::ErrorMessage &msg) {}
- virtual void reportStatus(unsigned int index, unsigned int max) {}
#endif
+
};
#endif // THREADEXECUTOR_H
diff --git a/tools/errmsg.cpp b/tools/errmsg.cpp
index 0cde3e108..a9a59e6ea 100644
--- a/tools/errmsg.cpp
+++ b/tools/errmsg.cpp
@@ -181,7 +181,7 @@ int main()
fout << " std::string toXML() const;\n";
fout << " std::string toText() const;\n";
fout << " std::string serialize() const;\n";
- fout << " bool deserialize( const std::string &data );\n";
+ fout << " bool deserialize(const std::string &data);\n";
fout << " private:\n";
fout << " std::list _callStack;\n";
fout << " std::string _severity;\n";