diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 3b6ad7efd..1e528771a 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -882,6 +882,9 @@ Settings MainWindow::getCppcheckSettings() result.maxCtuDepth = mProjectFile->getMaxCtuDepth(); result.checkHeaders = mProjectFile->getCheckHeaders(); result.checkUnusedTemplates = mProjectFile->getCheckUnusedTemplates(); + result.allFunctionsAreSafe = mProjectFile->getCheckAllFunctionParameterValues(); + foreach (QString s, mProjectFile->getCheckUnknownFunctionReturn()) + result.checkUnknownFunctionReturn.insert(s.toStdString()); } // Include directories (and files) are searched in listed order. diff --git a/gui/projectfile.cpp b/gui/projectfile.cpp index 93d2a038a..3ebeea2ec 100644 --- a/gui/projectfile.cpp +++ b/gui/projectfile.cpp @@ -66,6 +66,9 @@ static const char TagElementName[] = "tag"; static const char CheckHeadersElementName[] = "check-headers"; static const char CheckUnusedTemplatesElementName[] = "check-unused-templates"; static const char MaxCtuDepthElementName[] = "max-ctu-depth"; +static const char CheckUnknownFunctionReturn[] = "check-unknown-function-return-values"; +static const char CheckAllFunctionParameterValues[] = "check-all-function-parameter-values"; +static const char Name[] = "name"; ProjectFile::ProjectFile(QObject *parent) : QObject(parent) @@ -101,6 +104,8 @@ void ProjectFile::clear() mCheckHeaders = true; mCheckUnusedTemplates = false; mMaxCtuDepth = 10; + mCheckAllFunctionParameterValues = false; + mCheckUnknownFunctionReturn.clear(); } bool ProjectFile::read(const QString &filename) @@ -180,6 +185,14 @@ bool ProjectFile::read(const QString &filename) if (insideProject && xmlReader.name() == SuppressionsElementName) readSuppressions(xmlReader); + // Unknown function return values + if (insideProject && xmlReader.name() == CheckUnknownFunctionReturn) + readStringList(mCheckUnknownFunctionReturn, xmlReader, Name); + + // check all function parameter values + if (insideProject && xmlReader.name() == CheckAllFunctionParameterValues) + mCheckAllFunctionParameterValues = true; + // Addons if (insideProject && xmlReader.name() == AddonsElementName) readStringList(mAddons, xmlReader, AddonElementName); @@ -778,6 +791,16 @@ bool ProjectFile::write(const QString &filename) xmlWriter.writeEndElement(); } + writeStringList(xmlWriter, + mCheckUnknownFunctionReturn, + CheckUnknownFunctionReturn, + Name); + + if (mCheckAllFunctionParameterValues) { + xmlWriter.writeStartElement(CheckAllFunctionParameterValues); + xmlWriter.writeEndElement(); + } + writeStringList(xmlWriter, mAddons, AddonsElementName, diff --git a/gui/projectfile.h b/gui/projectfile.h index 97ba53df8..24356988a 100644 --- a/gui/projectfile.h +++ b/gui/projectfile.h @@ -300,6 +300,22 @@ public: mFilename = filename; } + /** Experimental: checking all function parameter values */ + bool getCheckAllFunctionParameterValues() const { + return mCheckAllFunctionParameterValues; + } + void setCheckAllFunctionParameterValues(bool b) { + mCheckAllFunctionParameterValues = b; + } + + /** Check unknown function return values */ + QStringList getCheckUnknownFunctionReturn() const { + return mCheckUnknownFunctionReturn; + } + void setCheckUnknownFunctionReturn(QStringList s) { + mCheckUnknownFunctionReturn = s; + } + protected: /** @@ -472,6 +488,11 @@ private: /** Max CTU depth */ int mMaxCtuDepth; + + bool mCheckAllFunctionParameterValues; + + QStringList mCheckUnknownFunctionReturn; + }; /// @} #endif // PROJECT_FILE_H diff --git a/gui/projectfiledialog.cpp b/gui/projectfiledialog.cpp index 03d2a411f..64f278804 100644 --- a/gui/projectfiledialog.cpp +++ b/gui/projectfiledialog.cpp @@ -178,15 +178,6 @@ ProjectFileDialog::ProjectFileDialog(ProjectFile *projectFile, QWidget *parent) const QRegExp undefRegExp("\\s*([a-zA-Z_][a-zA-Z0-9_]*[; ]*)*"); mUI.mEditUndefines->setValidator(new QRegExpValidator(undefRegExp, this)); - // Human knowledge.. - mUI.mListUnknownFunctionReturn->clear(); - mUI.mListUnknownFunctionReturn->addItem("rand()"); - for (int row = 0; row < mUI.mListUnknownFunctionReturn->count(); ++row) { - QListWidgetItem *item = mUI.mListUnknownFunctionReturn->item(row); - item->setFlags(item->flags() | Qt::ItemIsUserCheckable); // set checkable flag - item->setCheckState(item->text() == "rand()" ? Qt::Checked : Qt::Unchecked); // AND initialize check state - } - connect(mUI.mButtons, &QDialogButtonBox::accepted, this, &ProjectFileDialog::ok); connect(mUI.mBtnBrowseBuildDir, &QPushButton::clicked, this, &ProjectFileDialog::browseBuildDir); connect(mUI.mBtnClearImportProject, &QPushButton::clicked, this, &ProjectFileDialog::clearImportProject); @@ -283,6 +274,18 @@ void ProjectFileDialog::loadFromProjectFile(const ProjectFile *projectFile) mUI.mComboBoxPlatform->setCurrentText(projectFile->getPlatform()); setSuppressions(projectFile->getSuppressions()); + // Human knowledge.. + mUI.mListUnknownFunctionReturn->clear(); + mUI.mListUnknownFunctionReturn->addItem("rand()"); + for (int row = 0; row < mUI.mListUnknownFunctionReturn->count(); ++row) { + QListWidgetItem *item = mUI.mListUnknownFunctionReturn->item(row); + item->setFlags(item->flags() | Qt::ItemIsUserCheckable); // set checkable flag + const bool unknownValues = projectFile->getCheckUnknownFunctionReturn().contains(item->text()); + item->setCheckState(unknownValues ? Qt::Checked : Qt::Unchecked); // AND initialize check state + } + mUI.mAllFunctionsAreSafe->setChecked(projectFile->getCheckAllFunctionParameterValues()); + + // Addons.. QSettings settings; const QString dataDir = settings.value("DATADIR", QString()).toString(); updateAddonCheckBox(mUI.mAddonThreadSafety, projectFile, dataDir, "threadsafety"); @@ -335,6 +338,16 @@ void ProjectFileDialog::saveToProjectFile(ProjectFile *projectFile) const projectFile->setPlatform(QString()); } projectFile->setSuppressions(getSuppressions()); + // Human knowledge + QStringList unknownReturnValues; + for (int row = 0; row < mUI.mListUnknownFunctionReturn->count(); ++row) { + QListWidgetItem *item = mUI.mListUnknownFunctionReturn->item(row); + if (item->checkState() == Qt::Checked) + unknownReturnValues << item->text(); + } + projectFile->setCheckUnknownFunctionReturn(unknownReturnValues); + projectFile->setCheckAllFunctionParameterValues(mUI.mAllFunctionsAreSafe->isChecked()); + // Addons QStringList list; if (mUI.mAddonThreadSafety->isChecked()) list << "threadsafety"; diff --git a/gui/projectfiledialog.ui b/gui/projectfiledialog.ui index bba5386f0..050f958ba 100644 --- a/gui/projectfiledialog.ui +++ b/gui/projectfiledialog.ui @@ -481,28 +481,14 @@ - - - - TODO: Configure possible values of function parameters - - - - - - - Note: It must be possible to define parameter values in the code using annotations in the code (SAL , code contracts, etc) - - - true - - - + + false + All classes must have a "safe" public interface