GUI: Refactor report saving.
Refactoring report writing to own classes and using QT's XML classes for XML output. This also fixes the ticket ##408 (GUI generates invalid xml). https://sourceforge.net/apps/trac/cppcheck/ticket/408
This commit is contained in:
parent
df241441dc
commit
678714419c
|
@ -29,6 +29,9 @@ HEADERS += mainwindow.h \
|
|||
common.h \
|
||||
fileviewdialog.h \
|
||||
projectfile.h \
|
||||
report.h \
|
||||
txtreport.h \
|
||||
xmlreport.h \
|
||||
../src/checkautovariables.h \
|
||||
../src/checkdangerousfunctions.h \
|
||||
../src/checkheaders.h \
|
||||
|
@ -65,6 +68,9 @@ SOURCES += main.cpp \
|
|||
aboutdialog.cpp \
|
||||
fileviewdialog.cpp \
|
||||
projectfile.cpp \
|
||||
report.cpp \
|
||||
txtreport.cpp \
|
||||
xmlreport.cpp \
|
||||
../src/checkautovariables.cpp \
|
||||
../src/checkdangerousfunctions.cpp \
|
||||
../src/checkmemoryleak.cpp \
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Cppcheck - A tool for static C/C++ code analysis
|
||||
* Copyright (C) 2007-2009 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 <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
#include <QFile>
|
||||
#include "report.h"
|
||||
|
||||
Report::Report(const QString &filename, QObject * parent) :
|
||||
QObject(parent),
|
||||
mFilename(filename)
|
||||
{
|
||||
}
|
||||
|
||||
Report::~Report()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
bool Report::Create()
|
||||
{
|
||||
bool succeed = false;
|
||||
if (!mFile.isOpen())
|
||||
{
|
||||
mFile.setFileName(mFilename);
|
||||
succeed = mFile.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||
}
|
||||
return succeed;
|
||||
}
|
||||
|
||||
void Report::Close()
|
||||
{
|
||||
if (mFile.isOpen())
|
||||
mFile.close();
|
||||
}
|
||||
|
||||
QFile* Report::GetFile()
|
||||
{
|
||||
return &mFile;
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Cppcheck - A tool for static C/C++ code analysis
|
||||
* Copyright (C) 2007-2009 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 <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
#ifndef _REPORT_H_
|
||||
#define _REPORT_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QFile>
|
||||
|
||||
/**
|
||||
* @brief A base class for reports.
|
||||
*/
|
||||
class Report : public QObject
|
||||
{
|
||||
public:
|
||||
Report(const QString &filename, QObject * parent = 0);
|
||||
virtual ~Report();
|
||||
|
||||
/**
|
||||
* @brief Create the report (file).
|
||||
* @return true if succeeded, false if file could not be created.
|
||||
*/
|
||||
virtual bool Create();
|
||||
|
||||
/**
|
||||
* @brief Close the report (file).
|
||||
*/
|
||||
virtual void Close();
|
||||
|
||||
/**
|
||||
* @brief Write report header.
|
||||
*/
|
||||
virtual void WriteHeader() = 0;
|
||||
|
||||
/**
|
||||
* @brief Write report footer.
|
||||
*/
|
||||
virtual void WriteFooter() = 0;
|
||||
|
||||
/**
|
||||
* @brief Write error to report.
|
||||
*/
|
||||
virtual void WriteError(const QStringList &files, const QStringList &lines,
|
||||
const QString &id, const QString &severity,
|
||||
const QString &msg) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* @brief Get the file object where the report is written to.
|
||||
*/
|
||||
QFile* GetFile();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief Filename of the report.
|
||||
*/
|
||||
QString mFilename;
|
||||
|
||||
/**
|
||||
* @brief Fileobject for the report file.
|
||||
*/
|
||||
QFile mFile;
|
||||
};
|
||||
|
||||
#endif // _REPORT_H_
|
|
@ -16,8 +16,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
|
||||
#include "resultstree.h"
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QMenu>
|
||||
|
@ -27,6 +25,8 @@
|
|||
#include <QMessageBox>
|
||||
#include <QFileInfo>
|
||||
#include <QClipboard>
|
||||
#include "resultstree.h"
|
||||
#include "xmlreport.h"
|
||||
|
||||
ResultsTree::ResultsTree(QSettings &settings, ApplicationList &list) :
|
||||
mSettings(settings),
|
||||
|
@ -533,26 +533,20 @@ QString ResultsTree::SeverityToIcon(const QString &severity)
|
|||
return "";
|
||||
}
|
||||
|
||||
void ResultsTree::SaveResults(QTextStream &out, bool xml)
|
||||
void ResultsTree::SaveResults(Report *report)
|
||||
{
|
||||
if (xml)
|
||||
{
|
||||
out << "<?xml version=\"1.0\"?>" << endl << "<results>" << endl;
|
||||
}
|
||||
report->WriteHeader();
|
||||
|
||||
for (int i = 0;i < mModel.rowCount();i++)
|
||||
{
|
||||
QStandardItem *item = mModel.item(i, 0);
|
||||
SaveErrors(out, item, xml);
|
||||
SaveErrors(report, item);
|
||||
}
|
||||
|
||||
if (xml)
|
||||
{
|
||||
out << "</results>" << endl;
|
||||
}
|
||||
report->WriteFooter();
|
||||
}
|
||||
|
||||
void ResultsTree::SaveErrors(QTextStream &out, QStandardItem *item, bool xml)
|
||||
void ResultsTree::SaveErrors(Report *report, QStandardItem *item)
|
||||
{
|
||||
if (!item)
|
||||
{
|
||||
|
@ -592,47 +586,14 @@ void ResultsTree::SaveErrors(QTextStream &out, QStandardItem *item, bool xml)
|
|||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < files.count(); i++)
|
||||
files[i] = StripPath(files[i], true);
|
||||
|
||||
QStringList linesStr;
|
||||
for (int i = 0; i < lines.count(); i++)
|
||||
linesStr << lines[i].toString();
|
||||
|
||||
if (xml)
|
||||
{
|
||||
/*
|
||||
Error example from the core program in xml
|
||||
<error file="gui/test.cpp" line="14" id="mismatchAllocDealloc" severity="error" msg="Mismatching allocation and deallocation: k"/>
|
||||
The callstack seems to be ignored here aswell, instead last item of the stack is used
|
||||
*/
|
||||
line = QString("<error file=\"%1\" line=\"%2\" id=\"%3\" severity=\"%4\" msg=\"%5\"/>").
|
||||
arg(StripPath(files[files.size()-1], true)). //filename
|
||||
arg(lines[lines.size()-1].toInt()). //line
|
||||
arg(id). //ID
|
||||
arg(severity). //severity
|
||||
arg(message); //Message
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Error example from the core program in text
|
||||
[gui/test.cpp:23] -> [gui/test.cpp:14]: (error) Mismatching allocation and deallocation: k
|
||||
*/
|
||||
for (int i = 0;i < lines.size();i++)
|
||||
{
|
||||
line += QString("[%1:%2]").arg(StripPath(files[i], true)).arg(lines[i].toInt());
|
||||
if (i < lines.size() - 1 && lines.size() > 0)
|
||||
{
|
||||
line += " -> ";
|
||||
}
|
||||
|
||||
if (i == lines.size() - 1)
|
||||
{
|
||||
line += ": ";
|
||||
}
|
||||
}
|
||||
|
||||
line += QString("(%1) %2").arg(severity).arg(message);
|
||||
}
|
||||
|
||||
out << line << endl;
|
||||
report->WriteError(files, linesStr, id, severity, message);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include "applicationlist.h"
|
||||
#include <QTextStream>
|
||||
|
||||
class Report;
|
||||
|
||||
/**
|
||||
* @brief Cppcheck's results are shown in this tree
|
||||
*
|
||||
|
@ -75,7 +77,7 @@ public:
|
|||
* @brief Save results to a text stream
|
||||
*
|
||||
*/
|
||||
void SaveResults(QTextStream &out, bool xml);
|
||||
void SaveResults(Report *report);
|
||||
|
||||
/**
|
||||
* @brief Update tree settings
|
||||
|
@ -162,9 +164,8 @@ protected:
|
|||
* @brief Save all errors under spesified item
|
||||
*
|
||||
* @param item Item whose errors to save
|
||||
* @param xml Should errors be saved as xml (true) or as text (false)
|
||||
*/
|
||||
void SaveErrors(QTextStream &out, QStandardItem *item, bool xml);
|
||||
void SaveErrors(Report *report, QStandardItem *item);
|
||||
|
||||
/**
|
||||
* @brief Convert a severity string to a icon filename
|
||||
|
|
|
@ -16,12 +16,13 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
|
||||
#include "resultsview.h"
|
||||
#include <QDebug>
|
||||
#include <QVBoxLayout>
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
#include "resultsview.h"
|
||||
#include "txtreport.h"
|
||||
#include "xmlreport.h"
|
||||
|
||||
ResultsView::ResultsView(QSettings &settings, ApplicationList &list) :
|
||||
mErrorsFound(false),
|
||||
|
@ -136,17 +137,32 @@ void ResultsView::Save(const QString &filename, bool xml)
|
|||
msgBox.exec();
|
||||
}
|
||||
|
||||
QFile file(filename);
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
|
||||
if (xml)
|
||||
{
|
||||
return;
|
||||
XmlReport report(filename);
|
||||
if (report.Create())
|
||||
mTree->SaveResults(&report);
|
||||
else
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText("Failed to save the report.");
|
||||
msgBox.exec();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TxtReport report(filename);
|
||||
if (report.Create())
|
||||
mTree->SaveResults(&report);
|
||||
else
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText("Failed to save the report.");
|
||||
msgBox.exec();
|
||||
}
|
||||
}
|
||||
|
||||
QTextStream out(&file);
|
||||
mTree->SaveResults(out, xml);
|
||||
}
|
||||
|
||||
|
||||
void ResultsView::UpdateSettings(bool showFullPath,
|
||||
bool saveFullPath,
|
||||
bool saveAllErrors,
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Cppcheck - A tool for static C/C++ code analysis
|
||||
* Copyright (C) 2007-2009 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 <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include "txtreport.h"
|
||||
|
||||
TxtReport::TxtReport(const QString &filename, QObject * parent) :
|
||||
Report(filename, parent)
|
||||
{
|
||||
}
|
||||
|
||||
TxtReport::~TxtReport()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
bool TxtReport::Create()
|
||||
{
|
||||
bool success = false;
|
||||
if (Report::Create())
|
||||
{
|
||||
mTxtWriter.setDevice(Report::GetFile());
|
||||
success = true;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void TxtReport::WriteHeader()
|
||||
{
|
||||
// No header for txt report
|
||||
}
|
||||
|
||||
void TxtReport::WriteFooter()
|
||||
{
|
||||
// No footer for txt report
|
||||
}
|
||||
|
||||
void TxtReport::WriteError(const QStringList &files, const QStringList &lines,
|
||||
const QString &id, const QString &severity, const QString &msg)
|
||||
{
|
||||
Q_UNUSED(id);
|
||||
|
||||
/*
|
||||
Error example from the core program in text
|
||||
[gui/test.cpp:23] -> [gui/test.cpp:14]: (error) Mismatching allocation and deallocation: k
|
||||
*/
|
||||
|
||||
QString line;
|
||||
|
||||
for (int i = 0; i < lines.size(); i++)
|
||||
{
|
||||
line += QString("[%1:%2]").arg(files[i]).arg(lines[i]);
|
||||
if (i < lines.size() - 1 && lines.size() > 0)
|
||||
{
|
||||
line += " -> ";
|
||||
}
|
||||
|
||||
if (i == lines.size() - 1)
|
||||
{
|
||||
line += ": ";
|
||||
}
|
||||
}
|
||||
|
||||
line += QString("(%1) %2").arg(severity).arg(msg);
|
||||
|
||||
mTxtWriter << line << endl;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Cppcheck - A tool for static C/C++ code analysis
|
||||
* Copyright (C) 2007-2009 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 <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
#ifndef _TXT_REPORT_H_
|
||||
#define _TXT_REPORT_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include "Report.h"
|
||||
|
||||
/**
|
||||
* @brief Text file report.
|
||||
* This report mimics the output of the command line cppcheck.
|
||||
*/
|
||||
class TxtReport : public Report
|
||||
{
|
||||
public:
|
||||
TxtReport(const QString &filename, QObject * parent = 0);
|
||||
~TxtReport();
|
||||
|
||||
/**
|
||||
* @brief Create the report (file).
|
||||
* @return true if succeeded, false if file could not be created.
|
||||
*/
|
||||
virtual bool Create();
|
||||
|
||||
/**
|
||||
* @brief Write report header.
|
||||
*/
|
||||
virtual void WriteHeader();
|
||||
|
||||
/**
|
||||
* @brief Write report footer.
|
||||
*/
|
||||
virtual void WriteFooter();
|
||||
|
||||
/**
|
||||
* @brief Write error to report.
|
||||
*/
|
||||
virtual void WriteError(const QStringList &files, const QStringList &lines,
|
||||
const QString &id, const QString &severity,
|
||||
const QString &msg);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief Text stream writer for writing the report in text format.
|
||||
*/
|
||||
QTextStream mTxtWriter;
|
||||
};
|
||||
|
||||
#endif // _TXT_REPORT_H_
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Cppcheck - A tool for static C/C++ code analysis
|
||||
* Copyright (C) 2007-2009 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 <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
#include <QFile>
|
||||
#include <QXmlStreamWriter>
|
||||
#include "xmlreport.h"
|
||||
|
||||
XmlReport::XmlReport(const QString &filename, QObject * parent) :
|
||||
Report(filename, parent)
|
||||
{
|
||||
}
|
||||
|
||||
XmlReport::~XmlReport()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
bool XmlReport::Create()
|
||||
{
|
||||
bool success = false;
|
||||
if (Report::Create())
|
||||
{
|
||||
mXmlWriter.setDevice(Report::GetFile());
|
||||
success = true;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void XmlReport::WriteHeader()
|
||||
{
|
||||
mXmlWriter.setAutoFormatting(true);
|
||||
mXmlWriter.writeStartDocument();
|
||||
mXmlWriter.writeStartElement("results");
|
||||
}
|
||||
|
||||
void XmlReport::WriteFooter()
|
||||
{
|
||||
mXmlWriter.writeEndElement();
|
||||
mXmlWriter.writeEndDocument();
|
||||
}
|
||||
|
||||
void XmlReport::WriteError(const QStringList &files, const QStringList &lines,
|
||||
const QString &id, const QString &severity, const QString &msg)
|
||||
{
|
||||
/*
|
||||
Error example from the core program in xml
|
||||
<error file="gui/test.cpp" line="14" id="mismatchAllocDealloc" severity="error" msg="Mismatching allocation and deallocation: k"/>
|
||||
The callstack seems to be ignored here aswell, instead last item of the stack is used
|
||||
*/
|
||||
|
||||
mXmlWriter.writeStartElement("error");
|
||||
mXmlWriter.writeAttribute("file", files[files.size() - 1]);
|
||||
mXmlWriter.writeAttribute("line", lines[lines.size() - 1]);
|
||||
mXmlWriter.writeAttribute("id", id);
|
||||
mXmlWriter.writeAttribute("severity", severity);
|
||||
mXmlWriter.writeAttribute("msg", msg);
|
||||
mXmlWriter.writeEndElement();
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Cppcheck - A tool for static C/C++ code analysis
|
||||
* Copyright (C) 2007-2009 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 <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
#ifndef _XML_REPORT_H_
|
||||
#define _XML_REPORT_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QFile>
|
||||
#include <QXmlStreamWriter>
|
||||
#include "Report.h"
|
||||
|
||||
/**
|
||||
* @brief XML file report.
|
||||
* This report outputs XML-formatted report. The XML format must match command
|
||||
* line version's XML output.
|
||||
*/
|
||||
class XmlReport : public Report
|
||||
{
|
||||
public:
|
||||
XmlReport(const QString &filename, QObject * parent = 0);
|
||||
~XmlReport();
|
||||
|
||||
/**
|
||||
* @brief Create the report (file).
|
||||
* @return true if succeeded, false if file could not be created.
|
||||
*/
|
||||
virtual bool Create();
|
||||
|
||||
/**
|
||||
* @brief Write report header.
|
||||
*/
|
||||
virtual void WriteHeader();
|
||||
|
||||
/**
|
||||
* @brief Write report footer.
|
||||
*/
|
||||
virtual void WriteFooter();
|
||||
|
||||
/**
|
||||
* @brief Write error to report.
|
||||
*/
|
||||
virtual void WriteError(const QStringList &files, const QStringList &lines,
|
||||
const QString &id, const QString &severity, const QString &msg);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief XML stream writer for writing the report in XML format.
|
||||
*/
|
||||
QXmlStreamWriter mXmlWriter;
|
||||
};
|
||||
|
||||
#endif // _XML_REPORT_H_
|
Loading…
Reference in New Issue