diff --git a/gui/checkthread.cpp b/gui/checkthread.cpp index 198bb5930..c804330fe 100644 --- a/gui/checkthread.cpp +++ b/gui/checkthread.cpp @@ -25,9 +25,7 @@ #include "erroritem.h" #include "threadresult.h" #include "cppcheck.h" - -static const char CLANG[] = "clang"; -static const char CLANGTIDY[] = "clang-tidy"; +#include "common.h" CheckThread::CheckThread(ThreadResult &result) : mState(Ready), @@ -82,7 +80,7 @@ void CheckThread::run() while (!file.isEmpty() && mState == Running) { qDebug() << "Checking file" << file; mCppcheck.check(file.toStdString()); - runAddons(addonPath, nullptr, file); + runAddonsAndTools(addonPath, nullptr, file); emit fileChecked(file); if (mState == Running) @@ -94,7 +92,7 @@ void CheckThread::run() file = QString::fromStdString(fileSettings.filename); qDebug() << "Checking file" << file; mCppcheck.check(fileSettings); - runAddons(addonPath, &fileSettings, QString::fromStdString(fileSettings.filename)); + runAddonsAndTools(addonPath, &fileSettings, QString::fromStdString(fileSettings.filename)); emit fileChecked(file); if (mState == Running) @@ -109,12 +107,12 @@ void CheckThread::run() emit done(); } -void CheckThread::runAddons(const QString &addonPath, const ImportProject::FileSettings *fileSettings, const QString &fileName) +void CheckThread::runAddonsAndTools(const QString &addonPath, const ImportProject::FileSettings *fileSettings, const QString &fileName) { QString dumpFile; - foreach (const QString addon, mAddons) { - if (addon == CLANG || addon == CLANGTIDY) { + foreach (const QString addon, mAddonsAndTools) { + if (addon == CLANG_ANALYZER || addon == CLANG_TIDY) { if (!fileSettings) continue; @@ -195,7 +193,7 @@ void CheckThread::runAddons(const QString &addonPath, const ImportProject::FileS QFile::remove(analyzerInfoFile + '.' + addon + "-results"); } - if (addon == CLANG) { + if (addon == CLANG_ANALYZER) { args.insert(0,"--analyze"); args.insert(1, "-Xanalyzer"); args.insert(2, "-analyzer-output=text"); @@ -206,7 +204,13 @@ void CheckThread::runAddons(const QString &addonPath, const ImportProject::FileS args.insert(2, "--"); } - const QString cmd(mClangPath.isEmpty() ? addon : (mClangPath + '/' + addon + ".exe")); +#ifdef Q_OS_WIN + const QString ext = ".exe"; +#else + const QString ext = ""; +#endif + const QString exename(addon == CLANG_ANALYZER ? ("clang" + ext) : ("clang-tidy" + ext)); + const QString cmd(mClangPath.isEmpty() ? exename : (mClangPath + '/' + exename)); { QString debug(cmd.contains(" ") ? ('\"' + cmd + '\"') : cmd); foreach (QString arg, args) { @@ -383,7 +387,7 @@ void CheckThread::parseClangErrors(const QString &tool, const QString &file0, QS errorItem.severity = Severity::SeverityType::style; } else { message = r1.cap(5); - id = CLANG; + id = CLANG_ANALYZER; } if (errorItem.errorPath.size() == 1) { diff --git a/gui/checkthread.h b/gui/checkthread.h index c453031a7..5605e4fa8 100644 --- a/gui/checkthread.h +++ b/gui/checkthread.h @@ -52,8 +52,8 @@ public: */ void analyseWholeProgram(const QStringList &files); - void setAddons(const QStringList &addons) { - mAddons = addons; + void setAddonsAndTools(const QStringList &addonsAndTools) { + mAddonsAndTools = addonsAndTools; } void setPythonPath(const QString &p) { @@ -124,14 +124,14 @@ protected: private: QString getAddonPath() const; - void runAddons(const QString &addonPath, const ImportProject::FileSettings *fileSettings, const QString &fileName); + void runAddonsAndTools(const QString &addonPath, const ImportProject::FileSettings *fileSettings, const QString &fileName); void parseAddonErrors(QString err, QString tool); void parseClangErrors(const QString &tool, const QString &file0, QString err); QStringList mFiles; bool mAnalyseWholeProgram; - QStringList mAddons; + QStringList mAddonsAndTools; QString mPythonPath; QString mDataDir; QString mClangPath; diff --git a/gui/common.h b/gui/common.h index 7d57114ba..1de0fb306 100644 --- a/gui/common.h +++ b/gui/common.h @@ -24,6 +24,8 @@ /// @addtogroup GUI /// @{ +#define CLANG_ANALYZER "clang-analyzer" +#define CLANG_TIDY "clang-tidy" /** * QSetting value names diff --git a/gui/erroritem.cpp b/gui/erroritem.cpp index cfe3c6351..714a6b4f8 100644 --- a/gui/erroritem.cpp +++ b/gui/erroritem.cpp @@ -17,6 +17,7 @@ */ #include "erroritem.h" +#include "common.h" QErrorPathItem::QErrorPathItem(const ErrorLogger::ErrorMessage::FileLocation &loc) : file(QString::fromStdString(loc.getfile(false))) @@ -55,10 +56,10 @@ ErrorItem::ErrorItem(const ErrorLogger::ErrorMessage &errmsg) QString ErrorItem::tool() const { - if (errorId == "clang") - return "clang"; - if (errorId.startsWith("clang-tidy")) - return "clang-tidy"; + if (errorId == CLANG_ANALYZER) + return CLANG_ANALYZER; + if (errorId.startsWith(CLANG_TIDY)) + return CLANG_TIDY; if (errorId.startsWith("clang-")) return "clang"; return "cppcheck"; diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 04a5812cb..15e5283ae 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -445,7 +445,7 @@ void MainWindow::doAnalyzeProject(ImportProject p) //mThread->SetanalyzeProject(true); if (mProjectFile) { - mThread->setAddons(mProjectFile->getAddons()); + mThread->setAddonsAndTools(mProjectFile->getAddonsAndTools()); mThread->setPythonPath(mSettings->value(SETTINGS_PYTHON_PATH).toString()); QString clangHeaders = mSettings->value(SETTINGS_VS_INCLUDE_PATHS).toString(); mThread->setClangIncludePaths(clangHeaders.split(";")); @@ -1417,7 +1417,7 @@ void MainWindow::analyzeProject(const ProjectFile *projectFile) QFileInfo inf(projectFile->getFilename()); const QString rootpath = projectFile->getRootPath(); - mThread->setAddons(projectFile->getAddons()); + mThread->setAddonsAndTools(projectFile->getAddonsAndTools()); mUI.mResults->setTags(projectFile->getTags()); // If the root path is not given or is not "current dir", use project diff --git a/gui/projectfile.cpp b/gui/projectfile.cpp index aeab628bd..6b8723e72 100644 --- a/gui/projectfile.cpp +++ b/gui/projectfile.cpp @@ -23,6 +23,7 @@ #include #include #include "projectfile.h" +#include "common.h" static const char ProjectElementName[] = "project"; static const char ProjectVersionAttrib[] = "version"; @@ -53,6 +54,8 @@ static const char SuppressionsElementName[] = "suppressions"; static const char SuppressionElementName[] = "suppression"; static const char AddonElementName[] = "addon"; static const char AddonsElementName[] = "addons"; +static const char ToolElementName[] = "tool"; +static const char ToolsElementName[] = "tools"; static const char TagsElementName[] = "tags"; static const char TagElementName[] = "tag"; @@ -83,6 +86,7 @@ void ProjectFile::clear() mLibraries.clear(); mSuppressions.clear(); mAddons.clear(); + mClangAnalyzer = mClangTidy = false; } bool ProjectFile::read(const QString &filename) @@ -153,6 +157,14 @@ bool ProjectFile::read(const QString &filename) if (insideProject && xmlReader.name() == AddonsElementName) readStringList(mAddons, xmlReader, AddonElementName); + // Tools + if (insideProject && xmlReader.name() == ToolsElementName) { + QStringList tools; + readStringList(tools, xmlReader, ToolElementName); + mClangAnalyzer = tools.contains(CLANG_ANALYZER); + mClangTidy = tools.contains(CLANG_TIDY); + } + if (insideProject && xmlReader.name() == TagsElementName) readStringList(mTags, xmlReader, TagElementName); @@ -588,6 +600,16 @@ bool ProjectFile::write(const QString &filename) AddonsElementName, AddonElementName); + QStringList tools; + if (mClangAnalyzer) + tools << CLANG_ANALYZER; + if (mClangTidy) + tools << CLANG_TIDY; + writeStringList(xmlWriter, + tools, + ToolsElementName, + ToolElementName); + writeStringList(xmlWriter, mTags, TagsElementName, TagElementName); xmlWriter.writeEndDocument(); @@ -616,3 +638,12 @@ QStringList ProjectFile::fromNativeSeparators(const QStringList &paths) ret << QDir::fromNativeSeparators(path); return ret; } + +QStringList ProjectFile::getAddonsAndTools() const { + QStringList ret(mAddons); + if (mClangAnalyzer) + ret << CLANG_ANALYZER; + if (mClangTidy) + ret << CLANG_TIDY; + return ret; + } diff --git a/gui/projectfile.h b/gui/projectfile.h index 7a2eb3269..b0808f0ba 100644 --- a/gui/projectfile.h +++ b/gui/projectfile.h @@ -122,12 +122,26 @@ public: return mAddons; } + /** + * @brief Get list of addons and tools. + * @return list of addons and tools. + */ + QStringList getAddonsAndTools() const; + bool getClangAnalyzer() const { - return mAddons.contains("clang-analyzer"); + return mClangAnalyzer; + } + + void setClangAnalyzer(bool c) { + mClangAnalyzer = c; } bool getClangTidy() const { - return mAddons.contains("clang-tidy"); + return mClangTidy; + } + + void setClangTidy(bool c) { + mClangTidy = c; } QStringList getTags() const { @@ -355,6 +369,12 @@ private: */ QStringList mAddons; + /** @brief Execute clang analyzer? */ + bool mClangAnalyzer; + + /** @brief Execute clang-tidy? */ + bool mClangTidy; + /** * @brief Warning tags */ diff --git a/gui/projectfiledialog.cpp b/gui/projectfiledialog.cpp index 107adf94b..a4a33f656 100644 --- a/gui/projectfiledialog.cpp +++ b/gui/projectfiledialog.cpp @@ -134,7 +134,6 @@ void ProjectFileDialog::saveSettings() const void ProjectFileDialog::loadFromProjectFile(const ProjectFile *projectFile) { - mUI.mToolClangTidy->setChecked(projectFile->getAddons().contains("clang-tidy")); setRootPath(projectFile->getRootPath()); setBuildDir(projectFile->getBuildDir()); setIncludepaths(projectFile->getIncludeDirs()); @@ -148,6 +147,8 @@ void ProjectFileDialog::loadFromProjectFile(const ProjectFile *projectFile) mUI.mAddonThreadSafety->setChecked(projectFile->getAddons().contains("threadsafety")); mUI.mAddonY2038->setChecked(projectFile->getAddons().contains("y2038")); mUI.mAddonCert->setChecked(projectFile->getAddons().contains("cert")); + //mUI.mToolClangAnalyzer->setChecked(projectFile->getClangAnalyzer()); + mUI.mToolClangTidy->setChecked(projectFile->getClangTidy()); QString tags; foreach (const QString tag, projectFile->getTags()) { if (tags.isEmpty()) @@ -172,8 +173,6 @@ void ProjectFileDialog::saveToProjectFile(ProjectFile *projectFile) const projectFile->setLibraries(getLibraries()); projectFile->setSuppressions(getSuppressions()); QStringList list; - if (mUI.mToolClangTidy->isChecked()) - list << "clang-tidy"; if (mUI.mAddonThreadSafety->isChecked()) list << "threadsafety"; if (mUI.mAddonY2038->isChecked()) @@ -181,6 +180,8 @@ void ProjectFileDialog::saveToProjectFile(ProjectFile *projectFile) const if (mUI.mAddonCert->isChecked()) list << "cert"; projectFile->setAddons(list); + //projectFile->setClangAnalyzer(mUI.mToolClangAnalyzer->isChecked()); + projectFile->setClangTidy(mUI.mToolClangTidy->isChecked()); QStringList tags(mUI.mEditTags->text().split(";")); tags.removeAll(QString()); projectFile->setTags(tags); diff --git a/gui/statsdialog.cpp b/gui/statsdialog.cpp index 67733fb91..75ceb414f 100755 --- a/gui/statsdialog.cpp +++ b/gui/statsdialog.cpp @@ -65,8 +65,12 @@ void StatsDialog::setProject(const ProjectFile* projectFile) QChartView *chartView; chartView = createChart(statsFile, "cppcheck"); mUI.mTabHistory->layout()->addWidget(chartView); - if (projectFile->getAddons().contains("clang-tidy")) { - chartView = createChart(statsFile, "clang-tidy"); + if (projectFile->getClangAnalyzer()) { + chartView = createChart(statsFile, CLANG_ANALYZER); + mUI.mTabHistory->layout()->addWidget(chartView); + } + if (projectFile->getClangTidy()) { + chartView = createChart(statsFile, CLANG_TIDY); mUI.mTabHistory->layout()->addWidget(chartView); } } diff --git a/gui/threadhandler.cpp b/gui/threadhandler.cpp index 2a8d5bd5b..cc2146c70 100644 --- a/gui/threadhandler.cpp +++ b/gui/threadhandler.cpp @@ -46,7 +46,7 @@ void ThreadHandler::clearFiles() mLastFiles.clear(); mResults.clearFiles(); mAnalyseWholeProgram = false; - mAddons.clear(); + mAddonsAndTools.clear(); mSuppressions.clear(); } @@ -93,7 +93,7 @@ void ThreadHandler::check(const Settings &settings) } for (int i = 0; i < mRunningThreadCount; i++) { - mThreads[i]->setAddons(mAddons); + mThreads[i]->setAddonsAndTools(mAddonsAndTools); mThreads[i]->setPythonPath(mPythonPath); mThreads[i]->setSuppressions(mSuppressions); mThreads[i]->setClangPath(mClangPath); diff --git a/gui/threadhandler.h b/gui/threadhandler.h index 7354fb9d4..c647620a5 100644 --- a/gui/threadhandler.h +++ b/gui/threadhandler.h @@ -71,8 +71,8 @@ public: */ void saveSettings(QSettings &settings) const; - void setAddons(const QStringList &addons) { - mAddons = addons; + void setAddonsAndTools(const QStringList &addonsAndTools) { + mAddonsAndTools = addonsAndTools; } void setSuppressions(const QStringList &s) { @@ -261,7 +261,7 @@ protected: bool mAnalyseWholeProgram; - QStringList mAddons; + QStringList mAddonsAndTools; QStringList mSuppressions; QString mPythonPath; QString mClangPath;