GUI: Suppress cppcheck-id
This commit is contained in:
parent
260c53ba6f
commit
6ab4f39f52
|
@ -341,6 +341,7 @@ void MainWindow::loadSettings()
|
||||||
if (inf.exists() && inf.isReadable()) {
|
if (inf.exists() && inf.isReadable()) {
|
||||||
setPath(SETTINGS_LAST_PROJECT_PATH, projectFile);
|
setPath(SETTINGS_LAST_PROJECT_PATH, projectFile);
|
||||||
mProjectFile = new ProjectFile(this);
|
mProjectFile = new ProjectFile(this);
|
||||||
|
mProjectFile->setActiveProject();
|
||||||
mProjectFile->read(projectFile);
|
mProjectFile->read(projectFile);
|
||||||
loadLastResults();
|
loadLastResults();
|
||||||
QDir::setCurrent(inf.absolutePath());
|
QDir::setCurrent(inf.absolutePath());
|
||||||
|
@ -1508,6 +1509,7 @@ void MainWindow::loadProjectFile(const QString &filePath)
|
||||||
mUI.mActionEditProjectFile->setEnabled(true);
|
mUI.mActionEditProjectFile->setEnabled(true);
|
||||||
delete mProjectFile;
|
delete mProjectFile;
|
||||||
mProjectFile = new ProjectFile(filePath, this);
|
mProjectFile = new ProjectFile(filePath, this);
|
||||||
|
mProjectFile->setActiveProject();
|
||||||
updateContractsTab();
|
updateContractsTab();
|
||||||
if (!loadLastResults())
|
if (!loadLastResults())
|
||||||
analyzeProject(mProjectFile);
|
analyzeProject(mProjectFile);
|
||||||
|
@ -1630,6 +1632,7 @@ void MainWindow::newProjectFile()
|
||||||
|
|
||||||
delete mProjectFile;
|
delete mProjectFile;
|
||||||
mProjectFile = new ProjectFile(this);
|
mProjectFile = new ProjectFile(this);
|
||||||
|
mProjectFile->setActiveProject();
|
||||||
mProjectFile->setFilename(filepath);
|
mProjectFile->setFilename(filepath);
|
||||||
mProjectFile->setBuildDir(filename.left(filename.indexOf(".")) + "-cppcheck-build-dir");
|
mProjectFile->setBuildDir(filename.left(filename.indexOf(".")) + "-cppcheck-build-dir");
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
|
ProjectFile *ProjectFile::mActiveProject;
|
||||||
|
|
||||||
ProjectFile::ProjectFile(QObject *parent) :
|
ProjectFile::ProjectFile(QObject *parent) :
|
||||||
QObject(parent)
|
QObject(parent)
|
||||||
{
|
{
|
||||||
|
@ -603,6 +605,8 @@ void ProjectFile::readSuppressions(QXmlStreamReader &reader)
|
||||||
suppression.lineNumber = reader.attributes().value(QString(),"lineNumber").toInt();
|
suppression.lineNumber = reader.attributes().value(QString(),"lineNumber").toInt();
|
||||||
if (reader.attributes().hasAttribute(QString(),"symbolName"))
|
if (reader.attributes().hasAttribute(QString(),"symbolName"))
|
||||||
suppression.symbolName = reader.attributes().value(QString(),"symbolName").toString().toStdString();
|
suppression.symbolName = reader.attributes().value(QString(),"symbolName").toString().toStdString();
|
||||||
|
if (reader.attributes().hasAttribute(QString(),"cppcheck-id"))
|
||||||
|
suppression.cppcheckId = reader.attributes().value(QString(),"cppcheck-id").toULongLong();
|
||||||
type = reader.readNext();
|
type = reader.readNext();
|
||||||
if (type == QXmlStreamReader::Characters) {
|
if (type == QXmlStreamReader::Characters) {
|
||||||
suppression.errorId = reader.text().toString().toStdString();
|
suppression.errorId = reader.text().toString().toStdString();
|
||||||
|
@ -873,6 +877,8 @@ bool ProjectFile::write(const QString &filename)
|
||||||
xmlWriter.writeAttribute("lineNumber", QString::number(suppression.lineNumber));
|
xmlWriter.writeAttribute("lineNumber", QString::number(suppression.lineNumber));
|
||||||
if (!suppression.symbolName.empty())
|
if (!suppression.symbolName.empty())
|
||||||
xmlWriter.writeAttribute("symbolName", QString::fromStdString(suppression.symbolName));
|
xmlWriter.writeAttribute("symbolName", QString::fromStdString(suppression.symbolName));
|
||||||
|
if (suppression.cppcheckId > 0)
|
||||||
|
xmlWriter.writeAttribute("cppcheck-id", QString::number(suppression.cppcheckId));
|
||||||
if (!suppression.errorId.empty())
|
if (!suppression.errorId.empty())
|
||||||
xmlWriter.writeCharacters(QString::fromStdString(suppression.errorId));
|
xmlWriter.writeCharacters(QString::fromStdString(suppression.errorId));
|
||||||
xmlWriter.writeEndElement();
|
xmlWriter.writeEndElement();
|
||||||
|
@ -1022,3 +1028,12 @@ QString ProjectFile::getAddonFilePath(QString filesDir, const QString &addon)
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProjectFile::suppressCppcheckId(std::size_t cppcheckId)
|
||||||
|
{
|
||||||
|
if (cppcheckId > 0) {
|
||||||
|
Suppressions::Suppression s;
|
||||||
|
s.cppcheckId = cppcheckId;
|
||||||
|
mSuppressions.append(s);
|
||||||
|
write();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -44,6 +44,19 @@ class ProjectFile : public QObject {
|
||||||
public:
|
public:
|
||||||
explicit ProjectFile(QObject *parent = nullptr);
|
explicit ProjectFile(QObject *parent = nullptr);
|
||||||
explicit ProjectFile(const QString &filename, QObject *parent = nullptr);
|
explicit ProjectFile(const QString &filename, QObject *parent = nullptr);
|
||||||
|
~ProjectFile() {
|
||||||
|
if (this == mActiveProject) mActiveProject = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ProjectFile* getActiveProject() {
|
||||||
|
return mActiveProject;
|
||||||
|
}
|
||||||
|
void setActiveProject() {
|
||||||
|
mActiveProject = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Suppress warning with Cppcheck-ID */
|
||||||
|
void suppressCppcheckId(std::size_t cppcheckId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the project file.
|
* @brief Read the project file.
|
||||||
|
@ -551,6 +564,7 @@ private:
|
||||||
|
|
||||||
QStringList mCheckUnknownFunctionReturn;
|
QStringList mCheckUnknownFunctionReturn;
|
||||||
|
|
||||||
|
static ProjectFile *mActiveProject;
|
||||||
};
|
};
|
||||||
/// @}
|
/// @}
|
||||||
#endif // PROJECT_FILE_H
|
#endif // PROJECT_FILE_H
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "resultstree.h"
|
#include "resultstree.h"
|
||||||
#include "report.h"
|
#include "report.h"
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
|
#include "projectfile.h"
|
||||||
#include "showtypes.h"
|
#include "showtypes.h"
|
||||||
#include "threadhandler.h"
|
#include "threadhandler.h"
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
|
@ -638,6 +639,7 @@ void ResultsTree::contextMenuEvent(QContextMenuEvent * e)
|
||||||
QAction *copy = new QAction(tr("Copy"), &menu);
|
QAction *copy = new QAction(tr("Copy"), &menu);
|
||||||
QAction *hide = new QAction(tr("Hide"), &menu);
|
QAction *hide = new QAction(tr("Hide"), &menu);
|
||||||
QAction *hideallid = new QAction(tr("Hide all with id"), &menu);
|
QAction *hideallid = new QAction(tr("Hide all with id"), &menu);
|
||||||
|
QAction *suppressCppcheckID = new QAction(tr("Suppress cppcheck-id"), &menu);
|
||||||
QAction *opencontainingfolder = new QAction(tr("Open containing folder"), &menu);
|
QAction *opencontainingfolder = new QAction(tr("Open containing folder"), &menu);
|
||||||
|
|
||||||
if (multipleSelection) {
|
if (multipleSelection) {
|
||||||
|
@ -655,6 +657,7 @@ void ResultsTree::contextMenuEvent(QContextMenuEvent * e)
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
menu.addAction(hide);
|
menu.addAction(hide);
|
||||||
menu.addAction(hideallid);
|
menu.addAction(hideallid);
|
||||||
|
menu.addAction(suppressCppcheckID);
|
||||||
if (!bughunting) {
|
if (!bughunting) {
|
||||||
QAction *suppress = new QAction(tr("Suppress selected id(s)"), &menu);
|
QAction *suppress = new QAction(tr("Suppress selected id(s)"), &menu);
|
||||||
menu.addAction(suppress);
|
menu.addAction(suppress);
|
||||||
|
@ -667,6 +670,7 @@ void ResultsTree::contextMenuEvent(QContextMenuEvent * e)
|
||||||
connect(copy, SIGNAL(triggered()), this, SLOT(copy()));
|
connect(copy, SIGNAL(triggered()), this, SLOT(copy()));
|
||||||
connect(hide, SIGNAL(triggered()), this, SLOT(hideResult()));
|
connect(hide, SIGNAL(triggered()), this, SLOT(hideResult()));
|
||||||
connect(hideallid, SIGNAL(triggered()), this, SLOT(hideAllIdResult()));
|
connect(hideallid, SIGNAL(triggered()), this, SLOT(hideAllIdResult()));
|
||||||
|
connect(suppressCppcheckID, &QAction::triggered, this, &ResultsTree::suppressCppcheckID);
|
||||||
connect(opencontainingfolder, SIGNAL(triggered()), this, SLOT(openContainingFolder()));
|
connect(opencontainingfolder, SIGNAL(triggered()), this, SLOT(openContainingFolder()));
|
||||||
|
|
||||||
if (!mTags.isEmpty()) {
|
if (!mTags.isEmpty()) {
|
||||||
|
@ -1031,12 +1035,35 @@ void ResultsTree::suppressSelectedIds()
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (file->rowCount() == 0)
|
||||||
|
mModel.removeRow(file->row());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
emit suppressIds(selectedIds.toList());
|
emit suppressIds(selectedIds.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResultsTree::suppressCppcheckID()
|
||||||
|
{
|
||||||
|
if (!mSelectionModel)
|
||||||
|
return;
|
||||||
|
ProjectFile *projectFile = ProjectFile::getActiveProject();
|
||||||
|
foreach (QModelIndex index, mSelectionModel->selectedRows()) {
|
||||||
|
QStandardItem *item = mModel.itemFromIndex(index);
|
||||||
|
if (!item->parent())
|
||||||
|
continue;
|
||||||
|
while (item->parent()->parent())
|
||||||
|
item = item->parent();
|
||||||
|
const QVariantMap data = item->data().toMap();
|
||||||
|
if (projectFile && data.contains("cppcheckId"))
|
||||||
|
projectFile->suppressCppcheckId(data["cppcheckId"].toULongLong());
|
||||||
|
QStandardItem *fileItem = item->parent();
|
||||||
|
fileItem->removeRow(item->row());
|
||||||
|
if (fileItem->rowCount() == 0)
|
||||||
|
mModel.removeRow(fileItem->row());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ResultsTree::openContainingFolder()
|
void ResultsTree::openContainingFolder()
|
||||||
{
|
{
|
||||||
QString filePath = getFilePath(mContextItem, true);
|
QString filePath = getFilePath(mContextItem, true);
|
||||||
|
|
|
@ -285,6 +285,9 @@ protected slots:
|
||||||
/** Slot for context menu item to suppress all messages with the current message id */
|
/** Slot for context menu item to suppress all messages with the current message id */
|
||||||
void suppressSelectedIds();
|
void suppressSelectedIds();
|
||||||
|
|
||||||
|
/** Slot for context menu item to suppress message with cppcheck ID */
|
||||||
|
void suppressCppcheckID();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Slot for context menu item to open the folder containing the current file.
|
* @brief Slot for context menu item to open the folder containing the current file.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -219,7 +219,7 @@ ErrorItem XmlReportV2::readError(QXmlStreamReader *reader)
|
||||||
if (attribs.hasAttribute(QString(), CWEAttribute))
|
if (attribs.hasAttribute(QString(), CWEAttribute))
|
||||||
item.cwe = attribs.value(QString(), CWEAttribute).toInt();
|
item.cwe = attribs.value(QString(), CWEAttribute).toInt();
|
||||||
if (attribs.hasAttribute(QString(), CppcheckIdAttribute))
|
if (attribs.hasAttribute(QString(), CppcheckIdAttribute))
|
||||||
item.cppcheckId = attribs.value(QString(), CWEAttribute).toULongLong();
|
item.cppcheckId = attribs.value(QString(), CppcheckIdAttribute).toULongLong();
|
||||||
if (attribs.hasAttribute(QString(), SinceDateAttribute))
|
if (attribs.hasAttribute(QString(), SinceDateAttribute))
|
||||||
item.sinceDate = attribs.value(QString(), SinceDateAttribute).toString();
|
item.sinceDate = attribs.value(QString(), SinceDateAttribute).toString();
|
||||||
if (attribs.hasAttribute(QString(), TagsAttribute))
|
if (attribs.hasAttribute(QString(), TagsAttribute))
|
||||||
|
|
|
@ -235,6 +235,7 @@ void ErrorMessage::setmsg(const std::string &msg)
|
||||||
Suppressions::ErrorMessage ErrorMessage::toSuppressionsErrorMessage() const
|
Suppressions::ErrorMessage ErrorMessage::toSuppressionsErrorMessage() const
|
||||||
{
|
{
|
||||||
Suppressions::ErrorMessage ret;
|
Suppressions::ErrorMessage ret;
|
||||||
|
ret.cppcheckId = cppcheckId;
|
||||||
ret.errorId = id;
|
ret.errorId = id;
|
||||||
if (!callStack.empty()) {
|
if (!callStack.empty()) {
|
||||||
ret.setFileName(callStack.back().getfile(false));
|
ret.setFileName(callStack.back().getfile(false));
|
||||||
|
|
|
@ -204,9 +204,9 @@ std::string Suppressions::addSuppressionLine(const std::string &line)
|
||||||
std::string Suppressions::addSuppression(const Suppressions::Suppression &suppression)
|
std::string Suppressions::addSuppression(const Suppressions::Suppression &suppression)
|
||||||
{
|
{
|
||||||
// Check that errorId is valid..
|
// Check that errorId is valid..
|
||||||
if (suppression.errorId.empty()) {
|
if (suppression.errorId.empty() && suppression.cppcheckId == 0)
|
||||||
return "Failed to add suppression. No id.";
|
return "Failed to add suppression. No id.";
|
||||||
}
|
|
||||||
if (suppression.errorId != "*") {
|
if (suppression.errorId != "*") {
|
||||||
for (std::string::size_type pos = 0; pos < suppression.errorId.length(); ++pos) {
|
for (std::string::size_type pos = 0; pos < suppression.errorId.length(); ++pos) {
|
||||||
if (suppression.errorId[pos] < 0 || !isAcceptedErrorIdChar(suppression.errorId[pos])) {
|
if (suppression.errorId[pos] < 0 || !isAcceptedErrorIdChar(suppression.errorId[pos])) {
|
||||||
|
@ -271,6 +271,8 @@ bool Suppressions::Suppression::parseComment(std::string comment, std::string *e
|
||||||
|
|
||||||
bool Suppressions::Suppression::isSuppressed(const Suppressions::ErrorMessage &errmsg) const
|
bool Suppressions::Suppression::isSuppressed(const Suppressions::ErrorMessage &errmsg) const
|
||||||
{
|
{
|
||||||
|
if (cppcheckId > 0 && cppcheckId != errmsg.cppcheckId)
|
||||||
|
return false;
|
||||||
if (!errorId.empty() && !matchglob(errorId, errmsg.errorId))
|
if (!errorId.empty() && !matchglob(errorId, errmsg.errorId))
|
||||||
return false;
|
return false;
|
||||||
if (!fileName.empty() && !matchglob(fileName, errmsg.getFileName()))
|
if (!fileName.empty() && !matchglob(fileName, errmsg.getFileName()))
|
||||||
|
@ -371,6 +373,8 @@ std::list<Suppressions::Suppression> Suppressions::getUnmatchedLocalSuppressions
|
||||||
for (const Suppression &s : mSuppressions) {
|
for (const Suppression &s : mSuppressions) {
|
||||||
if (s.matched)
|
if (s.matched)
|
||||||
continue;
|
continue;
|
||||||
|
if (s.cppcheckId > 0)
|
||||||
|
continue;
|
||||||
if (!unusedFunctionChecking && s.errorId == "unusedFunction")
|
if (!unusedFunctionChecking && s.errorId == "unusedFunction")
|
||||||
continue;
|
continue;
|
||||||
if (file.empty() || !s.isLocal() || s.fileName != file)
|
if (file.empty() || !s.isLocal() || s.fileName != file)
|
||||||
|
@ -386,6 +390,8 @@ std::list<Suppressions::Suppression> Suppressions::getUnmatchedGlobalSuppression
|
||||||
for (const Suppression &s : mSuppressions) {
|
for (const Suppression &s : mSuppressions) {
|
||||||
if (s.matched)
|
if (s.matched)
|
||||||
continue;
|
continue;
|
||||||
|
if (s.cppcheckId > 0)
|
||||||
|
continue;
|
||||||
if (!unusedFunctionChecking && s.errorId == "unusedFunction")
|
if (!unusedFunctionChecking && s.errorId == "unusedFunction")
|
||||||
continue;
|
continue;
|
||||||
if (s.isLocal())
|
if (s.isLocal())
|
||||||
|
|
|
@ -35,6 +35,7 @@ class CPPCHECKLIB Suppressions {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct CPPCHECKLIB ErrorMessage {
|
struct CPPCHECKLIB ErrorMessage {
|
||||||
|
std::size_t cppcheckId;
|
||||||
std::string errorId;
|
std::string errorId;
|
||||||
void setFileName(const std::string &s);
|
void setFileName(const std::string &s);
|
||||||
const std::string &getFileName() const {
|
const std::string &getFileName() const {
|
||||||
|
@ -48,17 +49,18 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CPPCHECKLIB Suppression {
|
struct CPPCHECKLIB Suppression {
|
||||||
Suppression() : lineNumber(NO_LINE), matched(false) {}
|
Suppression() : lineNumber(NO_LINE), cppcheckId(0), matched(false) {}
|
||||||
Suppression(const Suppression &other) {
|
Suppression(const Suppression &other) {
|
||||||
*this = other;
|
*this = other;
|
||||||
}
|
}
|
||||||
Suppression(const std::string &id, const std::string &file, int line=NO_LINE) : errorId(id), fileName(file), lineNumber(line), matched(false) {}
|
Suppression(const std::string &id, const std::string &file, int line=NO_LINE) : errorId(id), fileName(file), lineNumber(line), cppcheckId(0), matched(false) {}
|
||||||
|
|
||||||
Suppression & operator=(const Suppression &other) {
|
Suppression & operator=(const Suppression &other) {
|
||||||
errorId = other.errorId;
|
errorId = other.errorId;
|
||||||
fileName = other.fileName;
|
fileName = other.fileName;
|
||||||
lineNumber = other.lineNumber;
|
lineNumber = other.lineNumber;
|
||||||
symbolName = other.symbolName;
|
symbolName = other.symbolName;
|
||||||
|
cppcheckId = other.cppcheckId;
|
||||||
matched = other.matched;
|
matched = other.matched;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -72,6 +74,8 @@ public:
|
||||||
return fileName < other.fileName;
|
return fileName < other.fileName;
|
||||||
if (symbolName != other.symbolName)
|
if (symbolName != other.symbolName)
|
||||||
return symbolName < other.symbolName;
|
return symbolName < other.symbolName;
|
||||||
|
if (cppcheckId != other.cppcheckId)
|
||||||
|
return cppcheckId < other.cppcheckId;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,6 +100,7 @@ public:
|
||||||
std::string fileName;
|
std::string fileName;
|
||||||
int lineNumber;
|
int lineNumber;
|
||||||
std::string symbolName;
|
std::string symbolName;
|
||||||
|
std::size_t cppcheckId;
|
||||||
bool matched;
|
bool matched;
|
||||||
|
|
||||||
enum { NO_LINE = -1 };
|
enum { NO_LINE = -1 };
|
||||||
|
|
Loading…
Reference in New Issue