|
Cppcheck
|
00001 /* 00002 * Cppcheck - A tool for static C/C++ code analysis 00003 * Copyright (C) 2007-2013 Daniel Marjamäki and Cppcheck team. 00004 * 00005 * This program is free software: you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation, either version 3 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 */ 00018 00019 #include <QObject> 00020 #include <QString> 00021 #include <QList> 00022 #include <QDir> 00023 #include <QXmlStreamWriter> 00024 #include <QDebug> 00025 #include "report.h" 00026 #include "erroritem.h" 00027 #include "xmlreport.h" 00028 #include "xmlreportv1.h" 00029 00030 static const char ResultElementName[] = "results"; 00031 static const char ErrorElementName[] = "error"; 00032 static const char FilenameAttribute[] = "file"; 00033 static const char LineAttribute[] = "line"; 00034 static const char IdAttribute[] = "id"; 00035 static const char SeverityAttribute[] = "severity"; 00036 static const char MsgAttribute[] = "msg"; 00037 00038 XmlReportV1::XmlReportV1(const QString &filename) : 00039 XmlReport(filename), 00040 mXmlReader(NULL), 00041 mXmlWriter(NULL) 00042 { 00043 } 00044 00045 XmlReportV1::~XmlReportV1() 00046 { 00047 delete mXmlReader; 00048 delete mXmlWriter; 00049 } 00050 00051 bool XmlReportV1::Create() 00052 { 00053 if (Report::Create()) { 00054 mXmlWriter = new QXmlStreamWriter(Report::GetFile()); 00055 return true; 00056 } 00057 return false; 00058 } 00059 00060 bool XmlReportV1::Open() 00061 { 00062 if (Report::Open()) { 00063 mXmlReader = new QXmlStreamReader(Report::GetFile()); 00064 return true; 00065 } 00066 return false; 00067 } 00068 00069 void XmlReportV1::WriteHeader() 00070 { 00071 mXmlWriter->setAutoFormatting(true); 00072 mXmlWriter->writeStartDocument(); 00073 mXmlWriter->writeStartElement(ResultElementName); 00074 } 00075 00076 void XmlReportV1::WriteFooter() 00077 { 00078 mXmlWriter->writeEndElement(); 00079 mXmlWriter->writeEndDocument(); 00080 } 00081 00082 void XmlReportV1::WriteError(const ErrorItem &error) 00083 { 00084 /* 00085 Error example from the core program in xml 00086 <error file="gui/test.cpp" line="14" id="mismatchAllocDealloc" severity="error" msg="Mismatching allocation and deallocation: k"/> 00087 The callstack seems to be ignored here as well, instead last item of the stack is used 00088 */ 00089 00090 // Don't write inconclusive errors to XML V1 00091 if (error.inconclusive) 00092 return; 00093 00094 mXmlWriter->writeStartElement(ErrorElementName); 00095 QString file = QDir::toNativeSeparators(error.files[error.files.size() - 1]); 00096 file = XmlReport::quoteMessage(file); 00097 mXmlWriter->writeAttribute(FilenameAttribute, file); 00098 const QString line = QString::number(error.lines[error.lines.size() - 1]); 00099 mXmlWriter->writeAttribute(LineAttribute, line); 00100 mXmlWriter->writeAttribute(IdAttribute, error.errorId); 00101 00102 // Don't localize severity so we can read these files 00103 mXmlWriter->writeAttribute(SeverityAttribute, GuiSeverity::toString(error.severity)); 00104 const QString message = XmlReport::quoteMessage(error.message); 00105 mXmlWriter->writeAttribute(MsgAttribute, message); 00106 mXmlWriter->writeEndElement(); 00107 } 00108 00109 QList<ErrorItem> XmlReportV1::Read() 00110 { 00111 QList<ErrorItem> errors; 00112 bool insideResults = false; 00113 if (!mXmlReader) { 00114 qDebug() << "You must Open() the file before reading it!"; 00115 return errors; 00116 } 00117 while (!mXmlReader->atEnd()) { 00118 switch (mXmlReader->readNext()) { 00119 case QXmlStreamReader::StartElement: 00120 if (mXmlReader->name() == ResultElementName) 00121 insideResults = true; 00122 00123 // Read error element from inside result element 00124 if (insideResults && mXmlReader->name() == ErrorElementName) { 00125 ErrorItem item = ReadError(mXmlReader); 00126 errors.append(item); 00127 } 00128 break; 00129 00130 case QXmlStreamReader::EndElement: 00131 if (mXmlReader->name() == ResultElementName) 00132 insideResults = false; 00133 break; 00134 00135 // Not handled 00136 case QXmlStreamReader::NoToken: 00137 case QXmlStreamReader::Invalid: 00138 case QXmlStreamReader::StartDocument: 00139 case QXmlStreamReader::EndDocument: 00140 case QXmlStreamReader::Characters: 00141 case QXmlStreamReader::Comment: 00142 case QXmlStreamReader::DTD: 00143 case QXmlStreamReader::EntityReference: 00144 case QXmlStreamReader::ProcessingInstruction: 00145 break; 00146 } 00147 } 00148 return errors; 00149 } 00150 00151 ErrorItem XmlReportV1::ReadError(QXmlStreamReader *reader) 00152 { 00153 ErrorItem item; 00154 if (reader->name().toString() == ErrorElementName) { 00155 QXmlStreamAttributes attribs = reader->attributes(); 00156 QString file = attribs.value("", FilenameAttribute).toString(); 00157 file = XmlReport::unquoteMessage(file); 00158 item.file = file; 00159 item.files.push_back(file); 00160 const int line = attribs.value("", LineAttribute).toString().toUInt(); 00161 item.lines.push_back(line); 00162 item.errorId = attribs.value("", IdAttribute).toString(); 00163 item.severity = GuiSeverity::fromString(attribs.value("", SeverityAttribute).toString()); 00164 00165 // NOTE: This duplicates the message to Summary-field. But since 00166 // old XML format doesn't have separate summary and verbose messages 00167 // we must add same message to both data so it shows up in GUI. 00168 // Check if there is full stop and cut the summary to it. 00169 QString summary = attribs.value("", MsgAttribute).toString(); 00170 const int ind = summary.indexOf('.'); 00171 if (ind != -1) 00172 summary = summary.left(ind + 1); 00173 item.summary = XmlReport::unquoteMessage(summary); 00174 QString message = attribs.value("", MsgAttribute).toString(); 00175 item.message = XmlReport::unquoteMessage(message); 00176 } 00177 return item; 00178 }
1.7.6.1