diff --git a/gui/common.h b/gui/common.h index 6f98ac2ac..8d42648e6 100644 --- a/gui/common.h +++ b/gui/common.h @@ -80,6 +80,7 @@ #define SETTINGS_LANGUAGE "Application language" #define SETTINGS_GLOBAL_INCLUDE_PATHS "Global include paths" #define SETTINGS_PYTHON_PATH "Python path" +#define SETTINGS_MISRA_FILE "MISRA C 2012 file" #define SETTINGS_CLANG_PATH "Clang path" #define SETTINGS_VS_INCLUDE_PATHS "VS include paths" #define SETTINGS_INLINE_SUPPRESSIONS "Inline suppressions" diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 14984a7e0..97f6a4d4b 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -971,6 +971,15 @@ Settings MainWindow::getCppcheckSettings() json += "{ \"script\":\"" + addonFilePath + "\""; if (!pythonCmd.isEmpty()) json += ", \"python\":\"" + pythonCmd + "\""; + const QString misraFile = fromNativePath(mSettings->value(SETTINGS_MISRA_FILE).toString()); + if (addon == "misra" && !misraFile.isEmpty()) { + QString arg; + if (misraFile.endsWith(".pdf", Qt::CaseInsensitive)) + arg = "--misra-pdf=" + misraFile; + else + arg = "--rule-texts=" + misraFile; + json += ", \"args\":[\"" + arg + "\"]"; + } json += " }"; result.addons.emplace(json.toStdString()); } diff --git a/gui/projectfile.ui b/gui/projectfile.ui index 26ca08a45..a2e47484e 100644 --- a/gui/projectfile.ui +++ b/gui/projectfile.ui @@ -779,7 +779,7 @@ - Coding standards (Premium) + Coding standards @@ -789,6 +789,31 @@ + + + + + + MISRA rule texts + + + + + + + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + + + + + + + ... + + + + + diff --git a/gui/projectfiledialog.cpp b/gui/projectfiledialog.cpp index 0979840ca..d422a74a7 100644 --- a/gui/projectfiledialog.cpp +++ b/gui/projectfiledialog.cpp @@ -225,6 +225,7 @@ ProjectFileDialog::ProjectFileDialog(ProjectFile *projectFile, bool premium, QWi connect(mUI->mBtnAddSuppression, &QPushButton::clicked, this, &ProjectFileDialog::addSuppression); connect(mUI->mBtnRemoveSuppression, &QPushButton::clicked, this, &ProjectFileDialog::removeSuppression); connect(mUI->mListSuppressions, &QListWidget::doubleClicked, this, &ProjectFileDialog::editSuppression); + connect(mUI->mBtnBrowseMisraFile, &QPushButton::clicked, this, &ProjectFileDialog::browseMisraFile); connect(mUI->mChkAllVsConfigs, &QCheckBox::clicked, this, &ProjectFileDialog::checkAllVSConfigs); loadFromProjectFile(projectFile); } @@ -349,11 +350,19 @@ void ProjectFileDialog::loadFromProjectFile(const ProjectFile *projectFile) const QString dataDir = getDataDir(); updateAddonCheckBox(mUI->mAddonThreadSafety, projectFile, dataDir, "threadsafety"); updateAddonCheckBox(mUI->mAddonY2038, projectFile, dataDir, "y2038"); + updateAddonCheckBox(mUI->mMisraC2012, projectFile, dataDir, ADDON_MISRA); + + const QString &misraFile = settings.value(SETTINGS_MISRA_FILE, QString()).toString(); + mUI->mEditMisraFile->setText(misraFile); + if (mPremium) { + mUI->mLabelMisraFile->setVisible(false); + mUI->mEditMisraFile->setVisible(false); + mUI->mBtnBrowseMisraFile->setVisible(false); + } else if (!mUI->mMisraC2012->isEnabled()) { + mUI->mEditMisraFile->setEnabled(false); + mUI->mBtnBrowseMisraFile->setEnabled(false); + } - if (mPremium) - updateAddonCheckBox(mUI->mMisraC2012, projectFile, dataDir, ADDON_MISRA); - else - mUI->mMisraC2012->setChecked(false); mUI->mCertC2016->setChecked(mPremium && projectFile->getCodingStandards().contains(CODING_STANDARD_CERT_C)); mUI->mCertCpp2016->setChecked(mPremium && projectFile->getCodingStandards().contains(CODING_STANDARD_CERT_CPP)); mUI->mMisraCpp2008->setChecked(mPremium && projectFile->getCodingStandards().contains(CODING_STANDARD_MISRA_CPP_2008)); @@ -364,7 +373,6 @@ void ProjectFileDialog::loadFromProjectFile(const ProjectFile *projectFile) else mUI->mEditCertIntPrecision->setText(QString::number(projectFile->getCertIntPrecision())); - mUI->mMisraC2012->setEnabled(mPremium); mUI->mMisraCpp2008->setEnabled(mPremium); mUI->mCertC2016->setEnabled(mPremium); mUI->mCertCpp2016->setEnabled(mPremium); @@ -899,3 +907,20 @@ int ProjectFileDialog::getSuppressionIndex(const QString &shortText) const } return -1; } + +void ProjectFileDialog::browseMisraFile() +{ + const QString fileName = QFileDialog::getOpenFileName(this, + tr("Select MISRA rule texts file"), + QDir::homePath(), + tr("MISRA rule texts file (%1)").arg("*.txt")); + if (!fileName.isEmpty()) { + QSettings settings; + mUI->mEditMisraFile->setText(fileName); + settings.setValue(SETTINGS_MISRA_FILE, fileName); + + mUI->mMisraC2012->setText("MISRA C 2012"); + mUI->mMisraC2012->setEnabled(true); + updateAddonCheckBox(mUI->mMisraC2012, nullptr, getDataDir(), ADDON_MISRA); + } +} diff --git a/gui/projectfiledialog.h b/gui/projectfiledialog.h index 9f5a00bc6..d7f803e8a 100644 --- a/gui/projectfiledialog.h +++ b/gui/projectfiledialog.h @@ -267,6 +267,11 @@ protected slots: */ void editSuppression(const QModelIndex &index); + /** + * @brief Browse for misra file + */ + void browseMisraFile(); + /** * @brief Check for all VS configurations */ diff --git a/gui/settings.ui b/gui/settings.ui index 58a20da08..3ead9bad0 100644 --- a/gui/settings.ui +++ b/gui/settings.ui @@ -324,6 +324,40 @@ + + + + MISRA addon + + + + + + + + MISRA rule texts file + + + + + + + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + + + + + + + ... + + + + + + + + diff --git a/gui/settingsdialog.cpp b/gui/settingsdialog.cpp index be04a0a54..b2776935e 100644 --- a/gui/settingsdialog.cpp +++ b/gui/settingsdialog.cpp @@ -65,6 +65,9 @@ SettingsDialog::SettingsDialog(ApplicationList *list, mUI->mCheckForUpdates->setCheckState(boolToCheckState(settings.value(SETTINGS_CHECK_FOR_UPDATES, false).toBool())); mUI->mEditPythonPath->setText(settings.value(SETTINGS_PYTHON_PATH, QString()).toString()); validateEditPythonPath(); + if (premium) + mUI->mGroupBoxMisra->setVisible(false); + mUI->mEditMisraFile->setText(settings.value(SETTINGS_MISRA_FILE, QString()).toString()); #ifdef Q_OS_WIN //mUI->mTabClang->setVisible(true); @@ -94,6 +97,7 @@ SettingsDialog::SettingsDialog(ApplicationList *list, this, SLOT(editApplication())); connect(mUI->mBtnBrowsePythonPath, &QPushButton::clicked, this, &SettingsDialog::browsePythonPath); + connect(mUI->mBtnBrowseMisraFile, &QPushButton::clicked, this, &SettingsDialog::browseMisraFile); connect(mUI->mBtnEditTheme, SIGNAL(clicked()), this, SLOT(editCodeEditorStyle())); connect(mUI->mThemeSystem, SIGNAL(released()), this, SLOT(setCodeEditorStyleDefault())); connect(mUI->mThemeDark, SIGNAL(released()), this, SLOT(setCodeEditorStyleDefault())); @@ -185,6 +189,8 @@ void SettingsDialog::saveSettingValues() const saveCheckboxValue(&settings, mUI->mShowErrorId, SETTINGS_SHOW_ERROR_ID); saveCheckboxValue(&settings, mUI->mCheckForUpdates, SETTINGS_CHECK_FOR_UPDATES); settings.setValue(SETTINGS_PYTHON_PATH, mUI->mEditPythonPath->text()); + if (!mPremium) + settings.setValue(SETTINGS_MISRA_FILE, mUI->mEditMisraFile->text()); #ifdef Q_OS_WIN settings.setValue(SETTINGS_CLANG_PATH, mUI->mEditClangPath->text()); @@ -350,6 +356,13 @@ void SettingsDialog::browsePythonPath() mUI->mEditPythonPath->setText(fileName); } +void SettingsDialog::browseMisraFile() +{ + const QString fileName = QFileDialog::getOpenFileName(this, tr("Select MISRA File"), QDir::homePath(), "Misra File (*.pdf *.txt)"); + if (!fileName.isEmpty()) + mUI->mEditMisraFile->setText(fileName); +} + // Slot to set default light style void SettingsDialog::setCodeEditorStyleDefault() { diff --git a/gui/settingsdialog.h b/gui/settingsdialog.h index 2c4e30cd8..d1caab630 100644 --- a/gui/settingsdialog.h +++ b/gui/settingsdialog.h @@ -141,6 +141,11 @@ protected slots: /** @brief Slot for browsing for the clang binary */ void browseClangPath(); + /** + * @brief Browse for MISRA file + */ + void browseMisraFile(); + /** * @brief Set Code Editor Style to Default */