diff --git a/gui/checkthread.cpp b/gui/checkthread.cpp index 2592567d490..522f4d380be 100644 --- a/gui/checkthread.cpp +++ b/gui/checkthread.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include "checkthread.h" #include "erroritem.h" #include "threadresult.h" @@ -127,8 +128,9 @@ void CheckThread::runAddonsAndTools(const ImportProject::FileSettings *fileSetti args << ("-D" + D); } - if (!mClangPath.isEmpty()) { - QDir dir(mClangPath + "/../lib/clang"); + const QString clangPath = CheckThread::clangTidyCmd(); + if (!clangPath.isEmpty()) { + QDir dir(clangPath + "/../lib/clang"); foreach (QString ver, dir.entryList()) { QString includePath = dir.absolutePath() + '/' + ver + "/include"; if (ver[0] != '.' && QDir(includePath).exists()) { @@ -174,12 +176,11 @@ void CheckThread::runAddonsAndTools(const ImportProject::FileSettings *fileSetti if (!buildDir.empty()) { analyzerInfoFile = QString::fromStdString(AnalyzerInformation::getAnalyzerInfoFile(buildDir, fileSettings->filename, fileSettings->cfg)); - const QString cmd(mClangPath.isEmpty() ? QString("clang") : (mClangPath + "/clang.exe")); QStringList args2(args); args2.insert(0,"-E"); args2 << fileName; QProcess process; - process.start(cmd,args2); + process.start(clangCmd(),args2); process.waitForFinished(); const QByteArray &ba = process.readAllStandardOutput(); const quint16 chksum = qChecksum(ba.data(), ba.length()); @@ -223,13 +224,8 @@ void CheckThread::runAddonsAndTools(const ImportProject::FileSettings *fileSetti args.insert(2, "--"); } -#ifdef Q_OS_WIN - const QString ext = ".exe"; -#else - const QString ext = ""; -#endif - const QString cmd(mClangPath.isEmpty() ? ("clang-tidy" + ext) : (mClangPath + "/clang-tidy" + ext)); { + const QString cmd(clangTidyCmd()); QString debug(cmd.contains(" ") ? ('\"' + cmd + '\"') : cmd); foreach (QString arg, args) { if (arg.contains(" ")) @@ -249,7 +245,7 @@ void CheckThread::runAddonsAndTools(const ImportProject::FileSettings *fileSetti } QProcess process; - process.start(cmd, args); + process.start(clangTidyCmd(), args); process.waitForFinished(600*1000); const QString errout(process.readAllStandardOutput() + "\n\n\n" + process.readAllStandardError()); if (!analyzerInfoFile.isEmpty()) { @@ -262,12 +258,9 @@ void CheckThread::runAddonsAndTools(const ImportProject::FileSettings *fileSetti parseClangErrors(addon, fileName, errout); } else { - QString a = CheckThread::getAddonFilePath(mDataDir, addon + ".py"); - if (a.isEmpty()) { - a = CheckThread::getAddonFilePath(QApplication::applicationDirPath(), addon + ".py"); - if (a.isEmpty()) - continue; - } + const QString a = CheckThread::getAddonFilePath(mDataDir, addon + ".py"); + if (a.isEmpty()) + continue; if (dumpFile.isEmpty()) { const std::string buildDir = mCppcheck.settings().buildDir; @@ -431,15 +424,72 @@ void CheckThread::parseClangErrors(const QString &tool, const QString &file0, QS } } +QString CheckThread::clangCmd() +{ + QString path = QSettings().value(SETTINGS_CLANG_PATH,QString()).toString(); + if (!path.isEmpty()) + path += '/'; + path += "clang"; +#ifdef Q_OS_WIN + path += ".exe"; +#endif + + QProcess process; + process.start(path, QStringList() << "--version"); + process.waitForFinished(); + if (process.exitCode() == 0) + return path; + +#ifdef Q_OS_WIN + // Try to autodetect clang + if (QFileInfo("C:/Program Files/LLVM/bin/clang.exe").exists()) + return "C:/Program Files/LLVM/bin/clang.exe"; +#endif + + return QString(); +} + +QString CheckThread::clangTidyCmd() +{ + QString path = QSettings().value(SETTINGS_CLANG_PATH,QString()).toString(); + if (!path.isEmpty()) + path += '/'; + path += "clang-tidy"; +#ifdef Q_OS_WIN + path += ".exe"; +#endif + + QProcess process; + process.start(path, QStringList() << "--version"); + process.waitForFinished(); + if (process.exitCode() == 0) + return path; + +#ifdef Q_OS_WIN + // Try to autodetect clang-tidy + if (QFileInfo("C:/Program Files/LLVM/bin/clang-tidy.exe").exists()) + return "C:/Program Files/LLVM/bin/clang-tidy.exe"; +#endif + + return QString(); +} + QString CheckThread::getAddonFilePath(const QString &dataDir, const QString &addonFile) { - if (dataDir.isEmpty()) - return QString(); - if (QFileInfo(dataDir + '/' + addonFile).exists()) - return dataDir + '/' + addonFile; - if (QFileInfo(dataDir + "/addons/" + addonFile).exists()) - return dataDir + "/addons/" + addonFile; - if (QFileInfo(dataDir + "/../addons/" + addonFile).exists()) - return dataDir + "/../addons/" + addonFile; + const QStringList paths = QStringList() << "/" << "/addons/" << "/../addons/"; + + if (!dataDir.isEmpty()) { + foreach (const QString p, paths) { + if (QFileInfo(dataDir + p + addonFile).exists()) + return dataDir + p + addonFile; + } + } + + const QString appPath = QApplication::applicationDirPath(); + foreach (const QString p, paths) { + if (QFileInfo(dataDir + p + addonFile).exists()) + return appPath + p + addonFile; + } + return QString(); } diff --git a/gui/checkthread.h b/gui/checkthread.h index b01dac7c9a8..482e2913100 100644 --- a/gui/checkthread.h +++ b/gui/checkthread.h @@ -64,10 +64,6 @@ class CheckThread : public QThread { mDataDir = dataDir; } - void setClangPath(const QString &p) { - mClangPath = p; - } - void setClangIncludePaths(const QStringList &s) { mClangIncludePaths = s; } @@ -84,6 +80,22 @@ class CheckThread : public QThread { void stop(); + /** + * Loop for clang and return path + * \return path to clang if found, empty if it is not found + */ + static QString clangCmd(); + + /** + * Loop for clang-tidy and return path + * \return path to clang-tidy if found, empty if it is not found + */ + static QString clangTidyCmd(); + + /** + * Look for addon and return path + * \return path to addon if found, empty if it is not found + */ static QString getAddonFilePath(const QString &dataDir, const QString &addonFile); signals: @@ -133,7 +145,6 @@ class CheckThread : public QThread { QStringList mAddonsAndTools; QString mPythonPath; QString mDataDir; - QString mClangPath; QStringList mClangIncludePaths; QStringList mSuppressions; }; diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index eeff96359d4..6fe285d8fc9 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -460,15 +460,6 @@ void MainWindow::doAnalyzeProject(ImportProject p) mThread->setPythonPath(mSettings->value(SETTINGS_PYTHON_PATH).toString()); QString clangHeaders = mSettings->value(SETTINGS_VS_INCLUDE_PATHS).toString(); mThread->setClangIncludePaths(clangHeaders.split(";")); - QString clangPath = mSettings->value(SETTINGS_CLANG_PATH,QString()).toString(); -#ifdef Q_OS_WIN - if (clangPath.isEmpty()) { - // Try to autodetect clang - if (QFileInfo("C:/Program Files/LLVM/bin/clang.exe").exists()) - clangPath = "C:/Program Files/LLVM/bin"; - } -#endif - mThread->setClangPath(clangPath); mThread->setSuppressions(mProjectFile->getSuppressions()); } mThread->setProject(p); diff --git a/gui/projectfiledialog.cpp b/gui/projectfiledialog.cpp index b9fd277eb05..4af30de1f2f 100644 --- a/gui/projectfiledialog.cpp +++ b/gui/projectfiledialog.cpp @@ -34,31 +34,6 @@ #include "cppcheck.h" #include "errorlogger.h" -static QString clangTidyCmd() -{ - QString path = QSettings().value(SETTINGS_CLANG_PATH,QString()).toString(); - if (!path.isEmpty()) - path += '/'; - path += "clang-tidy"; -#ifdef Q_OS_WIN - path += ".exe"; -#endif - - QProcess process; - process.start(path, QStringList() << "--version"); - process.waitForFinished(); - if (process.exitCode() == 0) - return path; - -#ifdef Q_OS_WIN - // Try to autodetect clang-tidy - if (QFileInfo("C:/Program Files/LLVM/bin/clang-tidy.exe").exists()) - return "C:/Program Files/LLVM/bin/clang-tidy.exe"; -#endif - - return QString(); -} - ProjectFileDialog::ProjectFileDialog(ProjectFile *projectFile, QWidget *parent) : QDialog(parent) , mProjectFile(projectFile) @@ -164,8 +139,7 @@ void ProjectFileDialog::saveSettings() const static void updateAddonCheckBox(QCheckBox *cb, const ProjectFile *projectFile, const QString &dataDir, const QString &addon) { cb->setChecked(projectFile->getAddons().contains(addon)); - const QString appPath = QApplication::applicationDirPath(); - if (CheckThread::getAddonFilePath(dataDir, addon + ".py").isEmpty() && CheckThread::getAddonFilePath(appPath, addon + ".py").isEmpty()) { + if (CheckThread::getAddonFilePath(dataDir, addon + ".py").isEmpty()) { cb->setEnabled(false); cb->setText(cb->text() + QObject::tr(" (Not found)")); } @@ -194,7 +168,7 @@ void ProjectFileDialog::loadFromProjectFile(const ProjectFile *projectFile) mUI.mAddonCert->setChecked(projectFile->getAddons().contains("cert")); mUI.mToolClangAnalyzer->setChecked(projectFile->getClangAnalyzer()); mUI.mToolClangTidy->setChecked(projectFile->getClangTidy()); - if (clangTidyCmd().isEmpty()) { + if (CheckThread::clangTidyCmd().isEmpty()) { mUI.mToolClangTidy->setText(tr("Clang-tidy (not found)")); mUI.mToolClangTidy->setEnabled(false); } diff --git a/gui/threadhandler.cpp b/gui/threadhandler.cpp index cc2146c70f0..3b631c19d9a 100644 --- a/gui/threadhandler.cpp +++ b/gui/threadhandler.cpp @@ -96,7 +96,6 @@ void ThreadHandler::check(const Settings &settings) mThreads[i]->setAddonsAndTools(mAddonsAndTools); mThreads[i]->setPythonPath(mPythonPath); mThreads[i]->setSuppressions(mSuppressions); - mThreads[i]->setClangPath(mClangPath); mThreads[i]->setClangIncludePaths(mClangIncludePaths); mThreads[i]->setDataDir(mDataDir); mThreads[i]->check(settings); diff --git a/gui/threadhandler.h b/gui/threadhandler.h index c647620a572..7e43894138c 100644 --- a/gui/threadhandler.h +++ b/gui/threadhandler.h @@ -83,10 +83,6 @@ class ThreadHandler : public QObject { mPythonPath = p; } - void setClangPath(const QString &p) { - mClangPath = p; - } - void setClangIncludePaths(const QStringList &s) { mClangIncludePaths = s; } @@ -264,7 +260,6 @@ protected slots: QStringList mAddonsAndTools; QStringList mSuppressions; QString mPythonPath; - QString mClangPath; QStringList mClangIncludePaths; QString mDataDir;