1818
1919#include < QString>
2020#include < QDebug>
21+ #include < QDir>
22+ #include < QFileInfo>
23+ #include < QProcess>
2124#include " checkthread.h"
2225#include " threadresult.h"
2326#include " cppcheck.h"
@@ -69,10 +72,47 @@ void CheckThread::run()
6972 return ;
7073 }
7174
75+ QString addonPath;
76+ if (QFileInfo (mDataDir + " /threadsafety.py" ).exists ())
77+ addonPath = mDataDir ;
78+ else if (QDir (mDataDir + " /addons" ).exists ())
79+ addonPath = mDataDir + " /addons" ;
80+ else if (mDataDir .endsWith (" /cfg" )) {
81+ if (QDir (mDataDir .mid (0 ,mDataDir .size ()-3 ) + " addons" ).exists ())
82+ addonPath = mDataDir .mid (0 ,mDataDir .size ()-3 ) + " addons" ;
83+ }
84+
85+ bool needDump = mAddons .contains (" y2038" ) || mAddons .contains (" threadsafety" ) || mAddons .contains (" cert" ) || mAddons .contains (" misra" );
7286 QString file = mResult .getNextFile ();
7387 while (!file.isEmpty () && mState == Running) {
7488 qDebug () << " Checking file" << file;
7589 mCppcheck .check (file.toStdString ());
90+ if (!mAddons .isEmpty ()) {
91+ if (needDump) {
92+ mCppcheck .settings ().dump = true ;
93+ mCppcheck .check (file.toStdString ());
94+ mCppcheck .settings ().dump = false ;
95+ }
96+ foreach (const QString addon, mAddons ) {
97+ if (addon == " clang" )
98+ continue ;
99+ QProcess process;
100+ QString a;
101+ if (QFileInfo (addonPath + ' /' + addon + " .py" ).exists ())
102+ a = addonPath + ' /' + addon + " .py" ;
103+ else if (QFileInfo (addonPath + ' /' + addon + ' /' + addon + " .py" ).exists ())
104+ a = addonPath + ' /' + addon + ' /' + addon + " .py" ;
105+ else
106+ continue ;
107+ QString dumpFile = QString::fromStdString (file + " .dump" );
108+ QString cmd = " python " + a + ' ' + dumpFile;
109+ qDebug () << cmd;
110+ process.start (cmd);
111+ process.waitForFinished ();
112+ QString err (process.readAllStandardError ());
113+ parseErrors (err, addon);
114+ }
115+ }
76116 emit fileChecked (file);
77117
78118 if (mState == Running)
@@ -84,6 +124,45 @@ void CheckThread::run()
84124 file = QString::fromStdString (fileSettings.filename );
85125 qDebug () << " Checking file" << file;
86126 mCppcheck .check (fileSettings);
127+ if (!mAddons .isEmpty ()) {
128+ if (needDump) {
129+ mCppcheck .settings ().dump = true ;
130+ mCppcheck .check (fileSettings);
131+ mCppcheck .settings ().dump = false ;
132+ }
133+ foreach (const QString addon, mAddons ) {
134+ QProcess process;
135+ if (addon == " clang" ) {
136+ QString cmd (" clang --analyze" );
137+ for (std::list<std::string>::const_iterator I = fileSettings.includePaths .begin (); I != fileSettings.includePaths .end (); ++I)
138+ cmd += " -I" + QString::fromStdString (*I);
139+ foreach (QString D, QString::fromStdString (fileSettings.defines ).split (" ;" ))
140+ cmd += " -D" + D;
141+ QString fileName = QString::fromStdString (fileSettings.filename );
142+ if (fileName.endsWith (" .cpp" ))
143+ cmd += " -std=c++11" ;
144+ cmd += ' ' + fileName;
145+ qDebug () << cmd;
146+ process.start (cmd);
147+ process.waitForFinished (600 *1000 );
148+ } else {
149+ QString a;
150+ if (QFileInfo (addonPath + ' /' + addon + " .py" ).exists ())
151+ a = addonPath + ' /' + addon + " .py" ;
152+ else if (QFileInfo (addonPath + ' /' + addon + ' /' + addon + " .py" ).exists ())
153+ a = addonPath + ' /' + addon + ' /' + addon + " .py" ;
154+ else
155+ continue ;
156+ QString dumpFile = QString::fromStdString (fileSettings.filename + " .dump" );
157+ QString cmd = " python " + a + ' ' + dumpFile;
158+ qDebug () << cmd;
159+ process.start (cmd);
160+ process.waitForFinished ();
161+ }
162+ QString err (process.readAllStandardError ());
163+ parseErrors (err, addon);
164+ }
165+ }
87166 emit fileChecked (file);
88167
89168 if (mState == Running)
@@ -103,3 +182,46 @@ void CheckThread::stop()
103182 mState = Stopping;
104183 mCppcheck .terminate ();
105184}
185+
186+ void CheckThread::parseErrors (QString err, QString tool)
187+ {
188+ QTextStream in (&err, QIODevice::ReadOnly);
189+ while (!in.atEnd ()) {
190+ QString line = in.readLine ();
191+
192+ if (tool == " clang" ) {
193+ QRegExp r (" ([^:]+):([0-9]+):[0-9]+: (warning|error): (.*)" );
194+ if (!r.exactMatch (line))
195+ continue ;
196+ const std::string filename = r.cap (1 ).toStdString ();
197+ const int lineNumber = r.cap (2 ).toInt ();
198+ Severity::SeverityType severity = (r.cap (3 ) == " error" ) ? Severity::error : Severity::warning;
199+ const std::string message = r.cap (4 ).toStdString ();
200+ const std::string id = tool.toStdString ();
201+ std::list<ErrorLogger::ErrorMessage::FileLocation> callstack;
202+ callstack.push_back (ErrorLogger::ErrorMessage::FileLocation (filename, lineNumber));
203+ ErrorLogger::ErrorMessage errmsg (callstack, filename, severity, message, id, false );
204+ mResult .reportErr (errmsg);
205+ } else {
206+ QRegExp r1 (" \\ [([^:]+):([0-9]+)\\ ](.*)" );
207+ if (!r1.exactMatch (line))
208+ continue ;
209+ const std::string &filename = r1.cap (1 ).toStdString ();
210+ const int lineNumber = r1.cap (2 ).toInt ();
211+
212+ std::string message, id;
213+ QRegExp r2 (" (.*)\\ [([a-zA-Z0-9\\ -\\ ._]+)\\ ]" );
214+ if (r2.exactMatch (r1.cap (3 ))) {
215+ message = r2.cap (1 ).toStdString ();
216+ id = tool.toStdString () + ' -' + r2.cap (2 ).toStdString ();
217+ } else {
218+ message = r1.cap (3 ).toStdString ();
219+ id = tool.toStdString ();
220+ }
221+ std::list<ErrorLogger::ErrorMessage::FileLocation> callstack;
222+ callstack.push_back (ErrorLogger::ErrorMessage::FileLocation (filename, lineNumber));
223+ ErrorLogger::ErrorMessage errmsg (callstack, filename, Severity::style, message, id, false );
224+ mResult .reportErr (errmsg);
225+ }
226+ }
227+ }
0 commit comments