diff --git a/gui/gui.pro b/gui/gui.pro
index f2e54ce7c..b45ed9229 100644
--- a/gui/gui.pro
+++ b/gui/gui.pro
@@ -5,7 +5,7 @@ DEPENDPATH += . \
../lib
INCLUDEPATH += . \
../lib
-
+QT += xml
greaterThan(QT_MAJOR_VERSION, 4) {
QT += widgets # In Qt 5 widgets are in separate module
QT += printsupport # In Qt 5 QPrinter/QPrintDialog are in separate module
@@ -50,7 +50,8 @@ FORMS = about.ui \
resultsview.ui \
scratchpad.ui \
settings.ui \
- stats.ui
+ stats.ui \
+ librarydialog.ui
TRANSLATIONS = cppcheck_de.ts \
cppcheck_es.ts \
@@ -105,7 +106,8 @@ HEADERS += aboutdialog.h \
txtreport.h \
xmlreport.h \
xmlreportv1.h \
- xmlreportv2.h
+ xmlreportv2.h \
+ librarydialog.h
SOURCES += aboutdialog.cpp \
application.cpp \
@@ -139,7 +141,8 @@ SOURCES += aboutdialog.cpp \
txtreport.cpp \
xmlreport.cpp \
xmlreportv1.cpp \
- xmlreportv2.cpp
+ xmlreportv2.cpp \
+ librarydialog.cpp
win32 {
DEFINES += _CRT_SECURE_NO_WARNINGS
diff --git a/gui/librarydialog.cpp b/gui/librarydialog.cpp
new file mode 100644
index 000000000..d8da78a43
--- /dev/null
+++ b/gui/librarydialog.cpp
@@ -0,0 +1,182 @@
+/*
+ * Cppcheck - A tool for static C/C++ code analysis
+ * Copyright (C) 2007-2015 Daniel Marjamäki and Cppcheck team.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "librarydialog.h"
+#include "ui_librarydialog.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+const unsigned int LibraryDialog::Function::Arg::ANY = ~0U;
+
+// TODO: get/compare functions from header
+
+LibraryDialog::LibraryDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::LibraryDialog)
+{
+ ui->setupUi(this);
+}
+
+LibraryDialog::~LibraryDialog()
+{
+ delete ui;
+}
+
+void LibraryDialog::updateui()
+{
+ ui->functions->clear();
+ for (const struct Function &function : functions) {
+ ui->functions->addItem(function.name);
+ }
+}
+
+
+QStringList getFunctions(QFile &file)
+{
+ QStringList ret;
+
+ QDomDocument doc;
+ if (!doc.setContent(&file))
+ return ret;
+
+
+ return ret;
+}
+
+static LibraryDialog::Function::Arg loadFunctionArg(const QDomElement &functionArgElement)
+{
+ LibraryDialog::Function::Arg arg;
+ if (functionArgElement.attribute("nr") == "any")
+ arg.nr = LibraryDialog::Function::Arg::ANY;
+ else
+ arg.nr = functionArgElement.attribute("nr").toUInt();
+ for (QDomElement childElement = functionArgElement.firstChildElement(); !childElement.isNull(); childElement = childElement.nextSiblingElement()) {
+ if (childElement.tagName() == "not-bool")
+ arg.notbool = true;
+ else if (childElement.tagName() == "not-null")
+ arg.notnull = true;
+ else if (childElement.tagName() == "not-uninit")
+ arg.notuninit = true;
+ else if (childElement.tagName() == "strz")
+ arg.strz = true;
+ else if (childElement.tagName() == "formatstr")
+ arg.formatstr = true;
+ else if (childElement.tagName() == "valid")
+ arg.valid = childElement.text();
+ else if (childElement.tagName() == "minsize") {
+ arg.minsize.type = childElement.attribute("type");
+ arg.minsize.arg = childElement.attribute("arg");
+ arg.minsize.arg2 = childElement.attribute("arg2");
+ }
+ }
+ return arg;
+}
+
+static LibraryDialog::Function loadFunction(const QDomElement &functionElement)
+{
+ LibraryDialog::Function function;
+ function.name = functionElement.attribute("name");
+ for (QDomElement childElement = functionElement.firstChildElement(); !childElement.isNull(); childElement = childElement.nextSiblingElement()) {
+ const QString tagName = childElement.tagName();
+ if (childElement.tagName() == "noreturn")
+ function.noreturn = (childElement.text() == "true");
+ else if (childElement.tagName() == "pure")
+ function.gccPure = true;
+ else if (childElement.tagName() == "const")
+ function.gccConst = true;
+ else if (childElement.tagName() == "leak-ignore")
+ function.leakignore = true;
+ else if (childElement.tagName() == "use-retval")
+ function.useretval = true;
+ else if (childElement.tagName() == "formatstr") {
+ function.formatstr.scan = childElement.attribute("scan");
+ function.formatstr.secure = childElement.attribute("secure");
+ } else if (childElement.tagName() == "arg") {
+ const LibraryDialog::Function::Arg fa = loadFunctionArg(childElement);
+ function.args.append(fa);
+ } else {
+ int x = 123;
+ x++;
+
+ }
+ }
+ return function;
+}
+
+bool LibraryDialog::loadFile(QFile &file)
+{
+ QDomDocument doc;
+ if (!doc.setContent(&file))
+ return false;
+
+ QDomElement rootElement = doc.firstChildElement("def");
+ for (QDomElement functionElement = rootElement.firstChildElement("function"); !functionElement.isNull(); functionElement = functionElement.nextSiblingElement("function")) {
+ functions.append(loadFunction(functionElement));
+ }
+
+ return true;
+}
+
+void LibraryDialog::openCfg()
+{
+ const QSettings settings;
+ const QString datadir = settings.value("DATADIR",QString()).toString();
+
+ QString selectedFilter;
+ const QString filter(tr("Library files (*.cfg)"));
+ const QString selectedFile = QFileDialog::getOpenFileName(this,
+ tr("Open library file"),
+ datadir,
+ filter,
+ &selectedFilter);
+
+ if (!selectedFile.isEmpty()) {
+ QFile file(selectedFile);
+ if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ loadFile(file);
+ updateui();
+ }
+ }
+
+}
+
+void LibraryDialog::selectFunction(int row)
+{
+ const Function &function = functions[row];
+ ui->functionreturn->setChecked(!function.noreturn);
+ ui->useretval->setChecked(function.useretval);
+ ui->leakignore->setChecked(function.leakignore);
+ ui->arguments->clear();
+ for (const Function::Arg &arg : function.args) {
+ QString s("arg");
+ if (arg.nr != Function::Arg::ANY)
+ s += QString::number(arg.nr);
+ if (arg.formatstr)
+ s += " formatstr";
+ else if (!arg.strz)
+ s += " strz";
+ else if (!arg.valid.isNull())
+ s += " " + arg.valid;
+ ui->arguments->addItem(s);
+ }
+}
diff --git a/gui/librarydialog.h b/gui/librarydialog.h
new file mode 100644
index 000000000..daa34c3be
--- /dev/null
+++ b/gui/librarydialog.h
@@ -0,0 +1,78 @@
+/*
+ * Cppcheck - A tool for static C/C++ code analysis
+ * Copyright (C) 2007-2015 Daniel Marjamäki and Cppcheck team.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef LIBRARYDIALOG_H
+#define LIBRARYDIALOG_H
+
+#include
+#include
+
+namespace Ui {
+ class LibraryDialog;
+}
+
+class LibraryDialog : public QDialog {
+ Q_OBJECT
+
+public:
+ explicit LibraryDialog(QWidget *parent = 0);
+ ~LibraryDialog();
+
+ struct Function {
+ QString name;
+ bool noreturn = false;
+ bool gccPure = false;
+ bool gccConst = false;
+ bool leakignore = false;
+ bool useretval = false;
+ struct {
+ QString scan;
+ QString secure;
+ } formatstr;
+ struct Arg {
+ QString name;
+ unsigned int nr = 0;
+ static const unsigned int ANY;
+ bool notbool = false;
+ bool notnull = false;
+ bool notuninit = false;
+ bool formatstr = false;
+ bool strz = false;
+ QString valid;
+ struct {
+ QString type;
+ QString arg;
+ QString arg2;
+ } minsize;
+ };
+ QList args;
+ };
+
+private slots:
+ void openCfg();
+ void selectFunction(int row);
+
+private:
+ Ui::LibraryDialog *ui;
+
+ void updateui();
+ bool loadFile(QFile &file);
+ QList functions;
+};
+
+#endif // LIBRARYDIALOG_H
diff --git a/gui/librarydialog.ui b/gui/librarydialog.ui
new file mode 100644
index 000000000..3566d0cc4
--- /dev/null
+++ b/gui/librarydialog.ui
@@ -0,0 +1,165 @@
+
+
+ LibraryDialog
+
+
+
+ 0
+ 0
+ 547
+ 300
+
+
+
+ Library Editor
+
+
+ -
+
+
+ false
+
+
+ QLabel { background-color : red; color : blue; }
+
+
+ EXPERIMENTAL
+
+
+
+ -
+
+
-
+
+
+ Open
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
-
+
+
+ Functions
+
+
+
+ -
+
+
+ QAbstractItemView::SingleSelection
+
+
+
+
+
+ -
+
+
-
+
+
+ function always return
+
+
+
+ -
+
+
+ return value must be used
+
+
+
+ -
+
+
+ ignore function in leaks checking
+
+
+
+ -
+
+
+ Arguments
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+
+
+
+
+ functions
+ currentRowChanged(int)
+ LibraryDialog
+ selectFunction(int)
+
+
+ 155
+ 218
+
+
+ 327
+ 299
+
+
+
+
+ pushButton
+ clicked()
+ LibraryDialog
+ openCfg()
+
+
+ 56
+ 36
+
+
+ 72
+ 21
+
+
+
+
+
+ selectFunction(int)
+ openCfg()
+
+
diff --git a/gui/main.ui b/gui/main.ui
index d579518ab..9f3b2e55f 100644
--- a/gui/main.ui
+++ b/gui/main.ui
@@ -62,7 +62,7 @@
0
0
640
- 21
+ 20
diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp
index b086d82ae..64bb2e949 100644
--- a/gui/mainwindow.cpp
+++ b/gui/mainwindow.cpp
@@ -44,6 +44,7 @@
#include "logview.h"
#include "filelist.h"
#include "showtypes.h"
+#include "librarydialog.h"
static const QString OnlineHelpURL("http://cppcheck.sourceforge.net/manual.html");
@@ -99,6 +100,7 @@ MainWindow::MainWindow(TranslationHandler* th, QSettings* settings) :
connect(mUI.mActionShowHidden, SIGNAL(triggered()), mUI.mResults, SLOT(ShowHiddenResults()));
connect(mUI.mActionViewLog, SIGNAL(triggered()), this, SLOT(ShowLogView()));
connect(mUI.mActionViewStats, SIGNAL(triggered()), this, SLOT(ShowStatistics()));
+ connect(mUI.mActionLibraryEditor, SIGNAL(triggered()), this, SLOT(ShowLibraryEditor()));
connect(mUI.mActionRecheck, SIGNAL(triggered()), this, SLOT(ReCheck()));
@@ -1215,6 +1217,12 @@ void MainWindow::ShowStatistics()
statsDialog.exec();
}
+void MainWindow::ShowLibraryEditor()
+{
+ LibraryDialog libraryDialog(this);
+ libraryDialog.exec();
+}
+
void MainWindow::Log(const QString &logline)
{
if (mLogView) {
diff --git a/gui/mainwindow.h b/gui/mainwindow.h
index b7036331a..587018d86 100644
--- a/gui/mainwindow.h
+++ b/gui/mainwindow.h
@@ -220,6 +220,12 @@ public slots:
*/
void ShowStatistics();
+ /**
+ * @brief Slot for showing the library editor
+ *
+ */
+ void ShowLibraryEditor();
+
protected slots:
/**