GUI: add clang-tidy

This commit is contained in:
Daniel Marjamäki 2017-08-04 15:10:27 +02:00
parent 7468b40a5e
commit c2bb9890e9
3 changed files with 146 additions and 96 deletions

View File

@ -25,6 +25,9 @@
#include "threadresult.h" #include "threadresult.h"
#include "cppcheck.h" #include "cppcheck.h"
static const char CLANG[] = "clang";
static const char CLANGTIDY[] = "clang-tidy";
CheckThread::CheckThread(ThreadResult &result) : CheckThread::CheckThread(ThreadResult &result) :
mState(Ready), mState(Ready),
mResult(result), mResult(result),
@ -110,26 +113,35 @@ void CheckThread::runAddons(const QString &addonPath, const ImportProject::FileS
QString dumpFile; QString dumpFile;
foreach (const QString addon, mAddons) { foreach (const QString addon, mAddons) {
if (addon == "clang") { if (addon == CLANG || addon == CLANGTIDY) {
if (!fileSettings) if (!fileSettings)
continue; continue;
QString cmd("clang --analyze");
QString args;
for (std::list<std::string>::const_iterator I = fileSettings->includePaths.begin(); I != fileSettings->includePaths.end(); ++I) for (std::list<std::string>::const_iterator I = fileSettings->includePaths.begin(); I != fileSettings->includePaths.end(); ++I)
cmd += " -I" + QString::fromStdString(*I); args += " -I" + QString::fromStdString(*I);
for (std::list<std::string>::const_iterator i = fileSettings->systemIncludePaths.begin(); i != fileSettings->systemIncludePaths.end(); ++i) for (std::list<std::string>::const_iterator i = fileSettings->systemIncludePaths.begin(); i != fileSettings->systemIncludePaths.end(); ++i)
cmd += " -isystem " + QString::fromStdString(*i); args += " -isystem " + QString::fromStdString(*i);
foreach (QString D, QString::fromStdString(fileSettings->defines).split(";")) { foreach (QString D, QString::fromStdString(fileSettings->defines).split(";")) {
cmd += " -D" + D; args += " -D" + D;
} }
if (!fileSettings->standard.empty()) if (!fileSettings->standard.empty())
cmd += " -std=" + QString::fromStdString(fileSettings->standard); args += " -std=" + QString::fromStdString(fileSettings->standard);
cmd += ' ' + fileName;
QString cmd;
if (addon == CLANG)
cmd = addon + " --analyze" + args + ' ' + fileName;
else
cmd = addon + " -checks=*,-clang*,-llvm* " + fileName + " -- " + args;
qDebug() << cmd; qDebug() << cmd;
QProcess process; QProcess process;
process.start(cmd); process.start(cmd);
process.waitForFinished(600*1000); process.waitForFinished(600*1000);
parseClangErrors(process.readAllStandardError()); if (addon == CLANG)
parseClangErrors(process.readAllStandardError());
else
parseClangErrors(process.readAllStandardOutput());
} else { } else {
QString a; QString a;
if (QFileInfo(addonPath + '/' + addon + ".py").exists()) if (QFileInfo(addonPath + '/' + addon + ".py").exists())
@ -225,8 +237,16 @@ void CheckThread::parseClangErrors(QString err)
const std::string filename = r.cap(1).toStdString(); const std::string filename = r.cap(1).toStdString();
const int lineNumber = r.cap(2).toInt(); const int lineNumber = r.cap(2).toInt();
Severity::SeverityType severity = (r.cap(3) == "warning") ? Severity::warning : Severity::error; Severity::SeverityType severity = (r.cap(3) == "warning") ? Severity::warning : Severity::error;
const std::string message = r.cap(4).toStdString(); std::string message, id;
const std::string id = "clang"; QRegExp r2("(.*)\\[([a-zA-Z0-9\\-_\\.]+)\\]");
if (r2.exactMatch(r.cap(4))) {
message = r2.cap(1).toStdString();
id = r2.cap(2).toStdString();
} else {
message = r.cap(4).toStdString();
id = CLANG;
}
std::list<ErrorLogger::ErrorMessage::FileLocation> callstack; std::list<ErrorLogger::ErrorMessage::FileLocation> callstack;
callstack.push_back(ErrorLogger::ErrorMessage::FileLocation(filename, lineNumber)); callstack.push_back(ErrorLogger::ErrorMessage::FileLocation(filename, lineNumber));
ErrorLogger::ErrorMessage errmsg(callstack, filename, severity, message, id, false); ErrorLogger::ErrorMessage errmsg(callstack, filename, severity, message, id, false);

View File

@ -132,6 +132,8 @@ void ProjectFileDialog::saveSettings() const
void ProjectFileDialog::loadFromProjectFile(const ProjectFile *projectFile) void ProjectFileDialog::loadFromProjectFile(const ProjectFile *projectFile)
{ {
mUI.mToolClang->setChecked(projectFile->getAddons().contains("clang"));
mUI.mToolClangTidy->setChecked(projectFile->getAddons().contains("clang-tidy"));
setRootPath(projectFile->getRootPath()); setRootPath(projectFile->getRootPath());
setBuildDir(projectFile->getBuildDir()); setBuildDir(projectFile->getBuildDir());
setIncludepaths(projectFile->getIncludeDirs()); setIncludepaths(projectFile->getIncludeDirs());
@ -145,7 +147,6 @@ void ProjectFileDialog::loadFromProjectFile(const ProjectFile *projectFile)
mUI.mAddonY2038->setChecked(projectFile->getAddons().contains("y2038")); mUI.mAddonY2038->setChecked(projectFile->getAddons().contains("y2038"));
mUI.mAddonCert->setChecked(projectFile->getAddons().contains("cert")); mUI.mAddonCert->setChecked(projectFile->getAddons().contains("cert"));
mUI.mAddonMisra->setChecked(projectFile->getAddons().contains("misra")); mUI.mAddonMisra->setChecked(projectFile->getAddons().contains("misra"));
mUI.mClang->setChecked(projectFile->getAddons().contains("clang"));
updatePathsAndDefines(); updatePathsAndDefines();
} }
@ -161,6 +162,10 @@ void ProjectFileDialog::saveToProjectFile(ProjectFile *projectFile) const
projectFile->setLibraries(getLibraries()); projectFile->setLibraries(getLibraries());
projectFile->setSuppressions(getSuppressions()); projectFile->setSuppressions(getSuppressions());
QStringList list; QStringList list;
if (mUI.mToolClang->isChecked())
list << "clang";
if (mUI.mToolClangTidy->isChecked())
list << "clang-tidy";
if (mUI.mAddonThreadSafety->isChecked()) if (mUI.mAddonThreadSafety->isChecked())
list << "threadsafety"; list << "threadsafety";
if (mUI.mAddonY2038->isChecked()) if (mUI.mAddonY2038->isChecked())
@ -169,8 +174,6 @@ void ProjectFileDialog::saveToProjectFile(ProjectFile *projectFile) const
list << "cert"; list << "cert";
if (mUI.mAddonMisra->isChecked()) if (mUI.mAddonMisra->isChecked())
list << "misra"; list << "misra";
if (mUI.mClang->isChecked())
list << "clang";
projectFile->setAddons(list); projectFile->setAddons(list);
} }

View File

@ -19,93 +19,48 @@
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="mTabProject"> <widget class="QWidget" name="mTabTools">
<attribute name="title"> <attribute name="title">
<string>Project</string> <string>Tools</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout_7"> <layout class="QVBoxLayout" name="verticalLayout_12">
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout_4"> <widget class="QLabel" name="label_3">
<item>
<widget class="QLabel" name="mLabelProjectRoot">
<property name="text">
<string>&amp;Root:</string>
</property>
<property name="buddy">
<cstring>mEditProjectRoot</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="mEditProjectRoot"/>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="mLabelBuildDir">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;In the build dir, cppcheck stores data about each translation unit.&lt;/p&gt;&lt;p&gt;With a build dir you get whole program analysis.&lt;/p&gt;&lt;p&gt;Unchanged files will be analyzed much faster; Cppcheck skip the analysis of these files and reuse their old data.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Cppcheck build dir (whole program analysis, faster analysis for unchanged files)</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="mEditBuildDir"/>
</item>
<item>
<widget class="QPushButton" name="mBtnBrowseBuildDir">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="mLayoutLibraries">
<item>
<widget class="QLabel" name="mLabelLibraries">
<property name="text">
<string>Libraries:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="mLabelLibrariesNote">
<property name="text"> <property name="text">
<string>Note: Put your own custom .cfg files in the same folder as the project file. You should see them above.</string> <string>It is common best practice to use several tools.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="verticalSpacer_9"> <widget class="QCheckBox" name="mToolClang">
<property name="text">
<string>Clang</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="mToolClangTidy">
<property name="text">
<string>Clang-tidy</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_7">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
<height>96</height> <height>310</height>
</size> </size>
</property> </property>
</spacer> </spacer>
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="mTabOther"> <widget class="QWidget" name="mTabPathsAndDefines">
<attribute name="title"> <attribute name="title">
<string>Paths and Defines</string> <string>Paths and Defines</string>
</attribute> </attribute>
@ -356,6 +311,92 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="mTabProject">
<attribute name="title">
<string>Project</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="mLabelProjectRoot">
<property name="text">
<string>&amp;Root:</string>
</property>
<property name="buddy">
<cstring>mEditProjectRoot</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="mEditProjectRoot"/>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="mLabelBuildDir">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;In the build dir, cppcheck stores data about each translation unit.&lt;/p&gt;&lt;p&gt;With a build dir you get whole program analysis.&lt;/p&gt;&lt;p&gt;Unchanged files will be analyzed much faster; Cppcheck skip the analysis of these files and reuse their old data.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Cppcheck build dir (whole program analysis, faster analysis for unchanged files)</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="mEditBuildDir"/>
</item>
<item>
<widget class="QPushButton" name="mBtnBrowseBuildDir">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="mLayoutLibraries">
<item>
<widget class="QLabel" name="mLabelLibraries">
<property name="text">
<string>Libraries:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="mLabelLibrariesNote">
<property name="text">
<string>Note: Put your own custom .cfg files in the same folder as the project file. You should see them above.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_9">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>96</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="mTabExclude"> <widget class="QWidget" name="mTabExclude">
<attribute name="title"> <attribute name="title">
<string>Exclude</string> <string>Exclude</string>
@ -415,7 +456,7 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tabSuppressions"> <widget class="QWidget" name="mTabSuppressions">
<attribute name="title"> <attribute name="title">
<string>Suppressions</string> <string>Suppressions</string>
</attribute> </attribute>
@ -463,7 +504,7 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tab"> <widget class="QWidget" name="mTabAddons">
<attribute name="title"> <attribute name="title">
<string>Addons</string> <string>Addons</string>
</attribute> </attribute>
@ -503,20 +544,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Other</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="mClang">
<property name="text">
<string>clang (experimental)</string>
</property>
</widget>
</item>
<item> <item>
<spacer name="verticalSpacer_5"> <spacer name="verticalSpacer_5">
<property name="orientation"> <property name="orientation">