diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp
index 7d7b48b2b..03e407fa4 100644
--- a/gui/mainwindow.cpp
+++ b/gui/mainwindow.cpp
@@ -850,6 +850,21 @@ Settings MainWindow::getCppcheckSettings()
result.buildDir = (prjpath + '/' + buildDir).toStdString();
}
}
+
+ const QString platform = mProjectFile->getPlatform();
+ if (platform.endsWith(".xml")) {
+ const QString applicationFilePath = QCoreApplication::applicationFilePath();
+ const QString appPath = QFileInfo(applicationFilePath).canonicalPath();
+ result.loadPlatformFile(appPath.toStdString().c_str(), platform.toStdString());
+ } else {
+ for (int i = cppcheck::Platform::Native; i <= cppcheck::Platform::Unix64; i++) {
+ const cppcheck::Platform::PlatformType p = (cppcheck::Platform::PlatformType)i;
+ if (platform == cppcheck::Platform::platformString(p)) {
+ result.platform(p);
+ break;
+ }
+ }
+ }
}
// Include directories (and files) are searched in listed order.
@@ -878,7 +893,8 @@ Settings MainWindow::getCppcheckSettings()
result.jobs = mSettings->value(SETTINGS_CHECK_THREADS, 1).toInt();
result.inlineSuppressions = mSettings->value(SETTINGS_INLINE_SUPPRESSIONS, false).toBool();
result.inconclusive = mSettings->value(SETTINGS_INCONCLUSIVE_ERRORS, false).toBool();
- result.platformType = (Settings::PlatformType) mSettings->value(SETTINGS_CHECKED_PLATFORM, 0).toInt();
+ if (result.platformType == cppcheck::Platform::Unspecified)
+ result.platform((cppcheck::Platform::PlatformType) mSettings->value(SETTINGS_CHECKED_PLATFORM, 0).toInt());
if (mSettings->value(SETTINGS_STD_CPP03, false).toBool())
result.standards.cpp = Standards::CPP03;
else if (mSettings->value(SETTINGS_STD_CPP11, false).toBool())
@@ -894,7 +910,7 @@ Settings MainWindow::getCppcheckSettings()
if (result.standards.posix)
posix = tryLoadLibrary(&result.library, "posix.cfg");
bool windows = true;
- if (result.platformType == Settings::Win32A || result.platformType == Settings::Win32W || result.platformType == Settings::Win64)
+ if (result.isWindowsPlatform())
windows = tryLoadLibrary(&result.library, "windows.cfg");
if (!std || !posix || !windows)
diff --git a/gui/projectfile.cpp b/gui/projectfile.cpp
index e90ddc6ac..ff0ed502e 100644
--- a/gui/projectfile.cpp
+++ b/gui/projectfile.cpp
@@ -50,6 +50,7 @@ static const char ExcludePathName[] = "path";
static const char ExcludePathNameAttrib[] = "name";
static const char LibrariesElementName[] = "libraries";
static const char LibraryElementName[] = "library";
+static const char PlatformElementName[] = "platform";
static const char SuppressionsElementName[] = "suppressions";
static const char SuppressionElementName[] = "suppression";
static const char AddonElementName[] = "addon";
@@ -84,6 +85,7 @@ void ProjectFile::clear()
mPaths.clear();
mExcludedPaths.clear();
mLibraries.clear();
+ mPlatform.clear();
mSuppressions.clear();
mAddons.clear();
mClangAnalyzer = mClangTidy = false;
@@ -149,6 +151,9 @@ bool ProjectFile::read(const QString &filename)
if (insideProject && xmlReader.name() == LibrariesElementName)
readStringList(mLibraries, xmlReader,LibraryElementName);
+ if (insideProject && xmlReader.name() == PlatformElementName)
+ readPlatform(xmlReader);
+
// Find suppressions list from inside project element
if (insideProject && xmlReader.name() == SuppressionsElementName)
readStringList(mSuppressions, xmlReader,SuppressionElementName);
@@ -434,6 +439,30 @@ void ProjectFile::readExcludes(QXmlStreamReader &reader)
} while (!allRead);
}
+void ProjectFile::readPlatform(QXmlStreamReader &reader)
+{
+ do {
+ const QXmlStreamReader::TokenType type = reader.readNext();
+ switch (type) {
+ case QXmlStreamReader::Characters:
+ mPlatform = reader.text().toString();
+ case QXmlStreamReader::EndElement:
+ return;
+ // Not handled
+ case QXmlStreamReader::StartElement:
+ case QXmlStreamReader::NoToken:
+ case QXmlStreamReader::Invalid:
+ case QXmlStreamReader::StartDocument:
+ case QXmlStreamReader::EndDocument:
+ case QXmlStreamReader::Comment:
+ case QXmlStreamReader::DTD:
+ case QXmlStreamReader::EntityReference:
+ case QXmlStreamReader::ProcessingInstruction:
+ break;
+ }
+ } while (1);
+}
+
void ProjectFile::readStringList(QStringList &stringlist, QXmlStreamReader &reader, const char elementname[])
{
@@ -498,6 +527,11 @@ void ProjectFile::setLibraries(const QStringList &libraries)
mLibraries = libraries;
}
+void ProjectFile::setPlatform(const QString &platform)
+{
+ mPlatform = platform;
+}
+
void ProjectFile::setSuppressions(const QStringList &suppressions)
{
mSuppressions = suppressions;
@@ -535,6 +569,12 @@ bool ProjectFile::write(const QString &filename)
xmlWriter.writeEndElement();
}
+ if (!mPlatform.isEmpty()) {
+ xmlWriter.writeStartElement(PlatformElementName);
+ xmlWriter.writeCharacters(mPlatform);
+ xmlWriter.writeEndElement();
+ }
+
if (!mImportProject.isEmpty()) {
xmlWriter.writeStartElement(ImportProjectElementName);
xmlWriter.writeCharacters(mImportProject);
diff --git a/gui/projectfile.h b/gui/projectfile.h
index d0ae7aa5b..9bce66bc8 100644
--- a/gui/projectfile.h
+++ b/gui/projectfile.h
@@ -106,6 +106,14 @@ public:
return mLibraries;
}
+ /**
+ * @brief Get platform.
+ * @return Current platform. If it ends with .xml then it is a file. Otherwise it must match one of the return values from @sa cppcheck::Platform::platformString() ("win32A", "unix32", ..)
+ */
+ QString getPlatform() const {
+ return mPlatform;
+ }
+
/**
* @brief Get list suppressions.
* @return list of suppressions.
@@ -206,6 +214,12 @@ public:
*/
void setLibraries(const QStringList &libraries);
+ /**
+ * @brief Set platform.
+ * @param platform platform.
+ */
+ void setPlatform(const QString &platform);
+
/**
* @brief Set list of suppressions.
* @param suppressions List of suppressions.
@@ -282,6 +296,12 @@ protected:
*/
void readExcludes(QXmlStreamReader &reader);
+ /**
+ * @brief Read platform text.
+ * @param reader XML stream reader.
+ */
+ void readPlatform(QXmlStreamReader &reader);
+
/**
* @brief Read string list
* @param stringlist destination string list
@@ -359,6 +379,11 @@ private:
*/
QStringList mLibraries;
+ /**
+ * @brief Platform
+ */
+ QString mPlatform;
+
/**
* @brief List of suppressions.
*/
diff --git a/gui/projectfiledialog.cpp b/gui/projectfiledialog.cpp
index b990f8af6..23c9da4da 100644
--- a/gui/projectfiledialog.cpp
+++ b/gui/projectfiledialog.cpp
@@ -33,6 +33,19 @@
#include "library.h"
#include "cppcheck.h"
#include "errorlogger.h"
+#include "platforms.h"
+
+/** Platforms shown in the platform combobox */
+static const cppcheck::Platform::PlatformType builtinPlatforms[] = {
+ cppcheck::Platform::Native,
+ cppcheck::Platform::Win32A,
+ cppcheck::Platform::Win32W,
+ cppcheck::Platform::Win64,
+ cppcheck::Platform::Unix32,
+ cppcheck::Platform::Unix64
+};
+
+static const int numberOfBuiltinPlatforms = sizeof(builtinPlatforms) / sizeof(builtinPlatforms[0]);
ProjectFileDialog::ProjectFileDialog(ProjectFile *projectFile, QWidget *parent)
: QDialog(parent)
@@ -94,6 +107,32 @@ ProjectFileDialog::ProjectFileDialog(ProjectFile *projectFile, QWidget *parent)
mLibraryCheckboxes << checkbox;
}
+ // Platforms..
+ Platforms p;
+ for (int i = 0; i < numberOfBuiltinPlatforms; i++)
+ mUI.mComboBoxPlatform->addItem(p.get(builtinPlatforms[i]).mTitle);
+ QStringList platformFiles;
+ foreach (QString sp, searchPaths) {
+ if (sp.endsWith("/cfg"))
+ sp = sp.mid(0,sp.length()-3) + "platforms";
+ QDir dir(sp);
+ dir.setSorting(QDir::Name);
+ dir.setNameFilters(QStringList("*.xml"));
+ dir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
+ foreach (QFileInfo item, dir.entryInfoList()) {
+ const QString platformFile = item.fileName();
+
+ cppcheck::Platform p;
+ if (!p.loadPlatformFile(appPath.toStdString().c_str(), platformFile.toStdString()))
+ continue;
+
+ if (platformFiles.indexOf(platformFile) == -1)
+ platformFiles << platformFile;
+ }
+ }
+ qSort(platformFiles);
+ mUI.mComboBoxPlatform->addItems(platformFiles);
+
mUI.mEditTags->setValidator(new QRegExpValidator(QRegExp("[a-zA-Z0-9 ;]*"),this));
connect(mUI.mButtons, &QDialogButtonBox::accepted, this, &ProjectFileDialog::ok);
@@ -156,6 +195,33 @@ void ProjectFileDialog::loadFromProjectFile(const ProjectFile *projectFile)
mUI.mChkAllVsConfigs->setChecked(projectFile->getAnalyzeAllVsConfigs());
setExcludedPaths(projectFile->getExcludedPaths());
setLibraries(projectFile->getLibraries());
+ const QString platform = projectFile->getPlatform();
+ if (platform.endsWith(".xml")) {
+ int i;
+ for (i = numberOfBuiltinPlatforms; i < mUI.mComboBoxPlatform->count(); ++i) {
+ if (mUI.mComboBoxPlatform->itemText(i) == platform)
+ break;
+ }
+ if (i < mUI.mComboBoxPlatform->count())
+ mUI.mComboBoxPlatform->setCurrentIndex(i);
+ else {
+ mUI.mComboBoxPlatform->addItem(platform);
+ mUI.mComboBoxPlatform->setCurrentIndex(i);
+ }
+ } else {
+ int i;
+ for (i = 0; i < numberOfBuiltinPlatforms; ++i) {
+ const cppcheck::Platform::PlatformType p = builtinPlatforms[i];
+ if (platform == cppcheck::Platform::platformString(p))
+ break;
+ }
+ if (i < numberOfBuiltinPlatforms)
+ mUI.mComboBoxPlatform->setCurrentIndex(i);
+ else
+ mUI.mComboBoxPlatform->setCurrentIndex(-1);
+ }
+
+ mUI.mComboBoxPlatform->setCurrentText(projectFile->getPlatform());
setSuppressions(projectFile->getSuppressions());
QSettings settings;
@@ -193,6 +259,15 @@ void ProjectFileDialog::saveToProjectFile(ProjectFile *projectFile) const
projectFile->setCheckPaths(getCheckPaths());
projectFile->setExcludedPaths(getExcludedPaths());
projectFile->setLibraries(getLibraries());
+ if (mUI.mComboBoxPlatform->currentText().endsWith(".xml"))
+ projectFile->setPlatform(mUI.mComboBoxPlatform->currentText());
+ else {
+ int i = mUI.mComboBoxPlatform->currentIndex();
+ if (i < numberOfBuiltinPlatforms)
+ projectFile->setPlatform(cppcheck::Platform::platformString(builtinPlatforms[i]));
+ else
+ projectFile->setPlatform(QString());
+ }
projectFile->setSuppressions(getSuppressions());
QStringList list;
if (mUI.mAddonThreadSafety->isChecked())
diff --git a/gui/projectfiledialog.ui b/gui/projectfiledialog.ui
index 406adb48c..a84ca9a16 100644
--- a/gui/projectfiledialog.ui
+++ b/gui/projectfiledialog.ui
@@ -268,35 +268,11 @@
-
+
- Project
+ Checking
-
- -
-
-
- Root path:
-
-
-
-
-
-
-
-
-
- -
-
-
- Warning tags (separated by semicolon)
-
-
-
-
-
-
-
-
-
+
-
@@ -316,6 +292,18 @@
+ -
+
+
+ Platform
+
+
+
-
+
+
+
+
+
-
@@ -338,6 +326,143 @@
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 96
+
+
+
+
+
+
+
+
+ Warning options
+
+
+ -
+
+
+ Root path:
+
+
+
-
+
+
+
+
+
+ -
+
+
+ Warning tags (separated by semicolon)
+
+
+
-
+
+
+
+
+
+ -
+
+
+ Exclude paths
+
+
+
-
+
+
+ -
+
+
-
+
+
+ Add...
+
+
+
+ -
+
+
+ Edit
+
+
+
+ -
+
+
+ Remove
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+ -
+
+
+ Suppressions
+
+
+
-
+
+
+ -
+
+
-
+
+
+ Add
+
+
+
+ -
+
+
+ Remove
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
-
@@ -353,151 +478,76 @@
-
+
- Exclude
-
-
- -
-
-
- Paths:
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- Add...
-
-
-
- -
-
-
- Edit
-
-
-
- -
-
-
- Remove
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
-
-
-
-
-
-
-
-
- Suppressions
-
-
- -
-
-
- Suppression list:
-
-
-
- -
-
-
- -
-
-
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
- Add
-
-
-
- -
-
-
- Remove
-
-
-
-
-
-
-
-
-
- Addons
+ Addons and tools
-
-
-
- Y2038
+
+
+ Addons
+
+
-
+
+
+ Y2038
+
+
+
+ -
+
+
+ Thread safety
+
+
+
+ -
+
+
+ Coding standards
+
+
+
+ -
+
+
+ Cert
+
+
+
+ -
+
+
+ MISRA C 2012
+
+
+
+
-
-
-
- Thread safety
-
-
-
- -
-
-
- Coding standards
-
-
-
- -
-
-
- Cert
-
-
-
- -
-
-
- MISRA C 2012
+
+
+ External tools
+
+
-
+
+
+ Clang-tidy
+
+
+
+ -
+
+
+ Clang analyzer
+
+
+
+
-
@@ -515,47 +565,6 @@
-
-
- Extra Tools
-
-
- -
-
-
- It is common best practice to use several tools.
-
-
-
- -
-
-
- Clang analyzer
-
-
-
- -
-
-
- Clang-tidy
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 310
-
-
-
-
-
-
-
@@ -572,10 +581,6 @@
mButtons
- mListExcludedPaths
- mBtnAddIgnorePath
- mBtnEditIgnorePath
- mBtnRemoveIgnorePath
diff --git a/lib/platform.h b/lib/platform.h
index 4970f5f58..ddb63bffd 100644
--- a/lib/platform.h
+++ b/lib/platform.h
@@ -122,7 +122,11 @@ namespace cppcheck {
}
const char *platformString() const {
- switch (platformType) {
+ return platformString(platformType);
+ }
+
+ static const char *platformString(PlatformType pt) {
+ switch (pt) {
case Unspecified:
return "Unspecified";
case Native: