Skip to content

Commit 6277eec

Browse files
committed
Variable contracts
1 parent 02287d9 commit 6277eec

19 files changed

Lines changed: 624 additions & 23 deletions

gui/gui.pro

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ FORMS = about.ui \
7777
librarydialog.ui \
7878
libraryaddfunctiondialog.ui \
7979
libraryeditargdialog.ui \
80-
newsuppressiondialog.ui
80+
newsuppressiondialog.ui \
81+
variablecontractsdialog.ui
8182

8283
TRANSLATIONS = cppcheck_de.ts \
8384
cppcheck_es.ts \
@@ -134,6 +135,7 @@ HEADERS += aboutdialog.h \
134135
threadresult.h \
135136
translationhandler.h \
136137
txtreport.h \
138+
variablecontractsdialog.h \
137139
xmlreport.h \
138140
xmlreportv2.h \
139141
librarydialog.h \
@@ -176,6 +178,7 @@ SOURCES += aboutdialog.cpp \
176178
threadresult.cpp \
177179
translationhandler.cpp \
178180
txtreport.cpp \
181+
variablecontractsdialog.cpp \
179182
xmlreport.cpp \
180183
xmlreportv2.cpp \
181184
librarydialog.cpp \

gui/mainwindow.cpp

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include "threadhandler.h"
5050
#include "threadresult.h"
5151
#include "translationhandler.h"
52+
#include "variablecontractsdialog.h"
5253

5354
static const QString OnlineHelpURL("http://cppcheck.net/manual.html");
5455
static const QString compile_commands_json("compile_commands.json");
@@ -144,6 +145,9 @@ MainWindow::MainWindow(TranslationHandler* th, QSettings* settings) :
144145
connect(mUI.mResults, &ResultsView::checkSelected, this, &MainWindow::performSelectedFilesCheck);
145146
connect(mUI.mResults, &ResultsView::suppressIds, this, &MainWindow::suppressIds);
146147
connect(mUI.mResults, &ResultsView::editFunctionContract, this, &MainWindow::editFunctionContract);
148+
connect(mUI.mResults, &ResultsView::editVariableContract, this, &MainWindow::editVariableContract);
149+
connect(mUI.mResults, &ResultsView::deleteFunctionContract, this, &MainWindow::deleteFunctionContract);
150+
connect(mUI.mResults, &ResultsView::deleteVariableContract, this, &MainWindow::deleteVariableContract);
147151
connect(mUI.mMenuView, &QMenu::aboutToShow, this, &MainWindow::aboutToShowViewMenu);
148152

149153
// File menu
@@ -351,7 +355,8 @@ void MainWindow::loadSettings()
351355
}
352356
}
353357

354-
updateContractsTab();
358+
updateFunctionContractsTab();
359+
updateVariableContractsTab();
355360
}
356361

357362
void MainWindow::saveSettings() const
@@ -611,15 +616,31 @@ QStringList MainWindow::selectFilesToAnalyze(QFileDialog::FileMode mode)
611616
return selected;
612617
}
613618

614-
void MainWindow::updateContractsTab()
619+
void MainWindow::updateFunctionContractsTab()
615620
{
616621
QStringList addedContracts;
617622
if (mProjectFile) {
618623
for (const auto it: mProjectFile->getFunctionContracts()) {
619624
addedContracts << QString::fromStdString(it.first);
620625
}
621626
}
622-
mUI.mResults->setAddedContracts(addedContracts);
627+
mUI.mResults->setAddedFunctionContracts(addedContracts);
628+
}
629+
630+
void MainWindow::updateVariableContractsTab()
631+
{
632+
QStringList added;
633+
if (mProjectFile) {
634+
for (auto vc: mProjectFile->getVariableContracts()) {
635+
QString line = vc.first;
636+
if (!vc.second.minValue.empty())
637+
line += " min:" + QString::fromStdString(vc.second.minValue);
638+
if (!vc.second.maxValue.empty())
639+
line += " max:" + QString::fromStdString(vc.second.maxValue);
640+
added << line;
641+
}
642+
}
643+
mUI.mResults->setAddedVariableContracts(added);
623644
}
624645

625646
void MainWindow::analyzeFiles()
@@ -865,6 +886,9 @@ Settings MainWindow::getCppcheckSettings()
865886

866887
result.functionContracts = mProjectFile->getFunctionContracts();
867888

889+
for (const auto vc: mProjectFile->getVariableContracts())
890+
result.variableContracts[vc.first.toStdString()] = vc.second;
891+
868892
const QStringList undefines = mProjectFile->getUndefines();
869893
foreach (QString undefine, undefines)
870894
result.userUndefs.insert(undefine.toStdString());
@@ -1513,7 +1537,9 @@ void MainWindow::loadProjectFile(const QString &filePath)
15131537
delete mProjectFile;
15141538
mProjectFile = new ProjectFile(filePath, this);
15151539
mProjectFile->setActiveProject();
1516-
updateContractsTab();
1540+
mUI.mResults->showContracts(mProjectFile->bugHunting);
1541+
updateFunctionContractsTab();
1542+
updateVariableContractsTab();
15171543
if (!loadLastResults())
15181544
analyzeProject(mProjectFile);
15191545
}
@@ -1639,19 +1665,23 @@ void MainWindow::newProjectFile()
16391665
ProjectFileDialog dlg(mProjectFile, this);
16401666
if (dlg.exec() == QDialog::Accepted) {
16411667
addProjectMRU(filepath);
1668+
mUI.mResults->showContracts(mProjectFile->bugHunting);
16421669
analyzeProject(mProjectFile);
16431670
} else {
16441671
closeProjectFile();
16451672
}
16461673

1647-
updateContractsTab();
1674+
updateFunctionContractsTab();
1675+
updateVariableContractsTab();
16481676
}
16491677

16501678
void MainWindow::closeProjectFile()
16511679
{
16521680
delete mProjectFile;
16531681
mProjectFile = nullptr;
16541682
mUI.mResults->clear(true);
1683+
mUI.mResults->clearContracts();
1684+
mUI.mResults->showContracts(false);
16551685
enableProjectActions(false);
16561686
enableProjectOpenActions(true);
16571687
formatAndSetTitle();
@@ -1672,6 +1702,7 @@ void MainWindow::editProjectFile()
16721702
ProjectFileDialog dlg(mProjectFile, this);
16731703
if (dlg.exec() == QDialog::Accepted) {
16741704
mProjectFile->write();
1705+
mUI.mResults->showContracts(mProjectFile->bugHunting);
16751706
analyzeProject(mProjectFile);
16761707
}
16771708
}
@@ -1858,5 +1889,35 @@ void MainWindow::editFunctionContract(QString function)
18581889
mProjectFile->write();
18591890
}
18601891

1861-
updateContractsTab();
1892+
updateFunctionContractsTab();
1893+
}
1894+
1895+
void MainWindow::editVariableContract(QString var)
1896+
{
1897+
if (!mProjectFile)
1898+
return;
1899+
1900+
VariableContractsDialog dlg(nullptr, var);
1901+
if (dlg.exec() == QDialog::Accepted) {
1902+
mProjectFile->setVariableContracts(dlg.getVarname(), dlg.getMin(), dlg.getMax());
1903+
mProjectFile->write();
1904+
}
1905+
1906+
updateVariableContractsTab();
1907+
}
1908+
1909+
void MainWindow::deleteFunctionContract(QString function)
1910+
{
1911+
if (mProjectFile) {
1912+
mProjectFile->deleteFunctionContract(function);
1913+
mProjectFile->write();
1914+
}
1915+
}
1916+
1917+
void MainWindow::deleteVariableContract(QString var)
1918+
{
1919+
if (mProjectFile) {
1920+
mProjectFile->deleteVariableContract(var);
1921+
mProjectFile->write();
1922+
}
18621923
}

gui/mainwindow.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,11 @@ class MainWindow : public QMainWindow {
7373

7474
public slots:
7575

76-
/** Update "Contracts" tab */
77-
void updateContractsTab();
76+
/** Update "Functions" tab */
77+
void updateFunctionContractsTab();
78+
79+
/** Update "Variables" tab */
80+
void updateVariableContractsTab();
7881

7982
/** @brief Slot for analyze files menu item */
8083
void analyzeFiles();
@@ -227,6 +230,16 @@ protected slots:
227230

228231
/** Edit contract for function */
229232
void editFunctionContract(QString function);
233+
234+
/** Edit constraints for variable */
235+
void editVariableContract(QString var);
236+
237+
/** Delete contract for function */
238+
void deleteFunctionContract(QString function);
239+
240+
/** Edit constraints for variable */
241+
void deleteVariableContract(QString var);
242+
230243
private:
231244

232245
/** Get filename for last results */

gui/projectfile.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ void ProjectFile::clear()
5959
mPaths.clear();
6060
mExcludedPaths.clear();
6161
mFunctionContracts.clear();
62+
mVariableContracts.clear();
6263
mLibraries.clear();
6364
mPlatform.clear();
6465
mSuppressions.clear();
@@ -156,6 +157,10 @@ bool ProjectFile::read(const QString &filename)
156157
if (xmlReader.name() == CppcheckXml::FunctionContracts)
157158
readFunctionContracts(xmlReader);
158159

160+
// Variable constraints
161+
if (xmlReader.name() == CppcheckXml::VariableContractsElementName)
162+
readVariableContracts(xmlReader);
163+
159164
// Find libraries list from inside project element
160165
if (xmlReader.name() == CppcheckXml::LibrariesElementName)
161166
readStringList(mLibraries, xmlReader, CppcheckXml::LibraryElementName);
@@ -531,6 +536,42 @@ void ProjectFile::readFunctionContracts(QXmlStreamReader &reader)
531536
} while (!allRead);
532537
}
533538

539+
void ProjectFile::readVariableContracts(QXmlStreamReader &reader)
540+
{
541+
QXmlStreamReader::TokenType type;
542+
while (true) {
543+
type = reader.readNext();
544+
switch (type) {
545+
case QXmlStreamReader::StartElement:
546+
if (reader.name().toString() == CppcheckXml::VariableContractItemElementName) {
547+
QXmlStreamAttributes attribs = reader.attributes();
548+
QString varname = attribs.value(QString(), CppcheckXml::VariableContractVarName).toString();
549+
QString minValue = attribs.value(QString(), CppcheckXml::VariableContractMin).toString();
550+
QString maxValue = attribs.value(QString(), CppcheckXml::VariableContractMax).toString();
551+
setVariableContracts(varname, minValue, maxValue);
552+
}
553+
break;
554+
555+
case QXmlStreamReader::EndElement:
556+
if (reader.name().toString() == CppcheckXml::VariableContractsElementName)
557+
return;
558+
break;
559+
560+
// Not handled
561+
case QXmlStreamReader::NoToken:
562+
case QXmlStreamReader::Invalid:
563+
case QXmlStreamReader::StartDocument:
564+
case QXmlStreamReader::EndDocument:
565+
case QXmlStreamReader::Characters:
566+
case QXmlStreamReader::Comment:
567+
case QXmlStreamReader::DTD:
568+
case QXmlStreamReader::EntityReference:
569+
case QXmlStreamReader::ProcessingInstruction:
570+
break;
571+
}
572+
}
573+
}
574+
534575
void ProjectFile::readVsConfigurations(QXmlStreamReader &reader)
535576
{
536577
QXmlStreamReader::TokenType type;
@@ -926,6 +967,20 @@ bool ProjectFile::write(const QString &filename)
926967
xmlWriter.writeEndElement();
927968
}
928969

970+
if (!mVariableContracts.empty()) {
971+
xmlWriter.writeStartElement(CppcheckXml::VariableContractsElementName);
972+
973+
for (auto vc: mVariableContracts) {
974+
xmlWriter.writeStartElement(CppcheckXml::VariableContractItemElementName);
975+
xmlWriter.writeAttribute(CppcheckXml::VariableContractVarName, vc.first);
976+
xmlWriter.writeAttribute(CppcheckXml::VariableContractMin, QString::fromStdString(vc.second.minValue));
977+
xmlWriter.writeAttribute(CppcheckXml::VariableContractMax, QString::fromStdString(vc.second.maxValue));
978+
xmlWriter.writeEndElement();
979+
}
980+
981+
xmlWriter.writeEndElement();
982+
}
983+
929984
if (!mSuppressions.isEmpty()) {
930985
xmlWriter.writeStartElement(CppcheckXml::SuppressionsElementName);
931986
foreach (const Suppressions::Suppression &suppression, mSuppressions) {

gui/projectfile.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,24 @@ class ProjectFile : public QObject {
230230
return mFunctionContracts;
231231
}
232232

233+
const std::map<QString, Settings::VariableContracts>& getVariableContracts() const {
234+
return mVariableContracts;
235+
}
236+
237+
void setVariableContracts(QString var, QString min, QString max) {
238+
mVariableContracts[var] = Settings::VariableContracts{min.toStdString(), max.toStdString()};
239+
}
240+
241+
void deleteFunctionContract(QString function)
242+
{
243+
mFunctionContracts.erase(function.toStdString());
244+
}
245+
246+
void deleteVariableContract(QString var)
247+
{
248+
mVariableContracts.erase(var);
249+
}
250+
233251
/**
234252
* @brief Get filename for the project file.
235253
* @return file name.
@@ -425,6 +443,12 @@ class ProjectFile : public QObject {
425443
*/
426444
void readFunctionContracts(QXmlStreamReader &reader);
427445

446+
/**
447+
* @brief Read variable constraints.
448+
* @param reader XML stream reader.
449+
*/
450+
void readVariableContracts(QXmlStreamReader &reader);
451+
428452
/**
429453
* @brief Read lists of Visual Studio configurations
430454
* @param reader XML stream reader.
@@ -542,6 +566,8 @@ class ProjectFile : public QObject {
542566

543567
std::map<std::string, std::string> mFunctionContracts;
544568

569+
std::map<QString, Settings::VariableContracts> mVariableContracts;
570+
545571
/**
546572
* @brief Platform
547573
*/

0 commit comments

Comments
 (0)