GUI: rewrote library dialog xml input/output

This commit is contained in:
Daniel Marjamäki 2015-09-05 11:37:55 +02:00
parent 8ffa96975a
commit 40bd3de9b3
2 changed files with 153 additions and 165 deletions

View File

@ -18,9 +18,8 @@
#include "cppchecklibrarydata.h" #include "cppchecklibrarydata.h"
#include <QDomDocument> #include <QXmlStreamReader>
#include <QDomNode> #include <QXmlStreamWriter>
#include <QDomNodeList>
const unsigned int CppcheckLibraryData::Function::Arg::ANY = ~0U; const unsigned int CppcheckLibraryData::Function::Arg::ANY = ~0U;
@ -28,273 +27,263 @@ CppcheckLibraryData::CppcheckLibraryData()
{ {
} }
static CppcheckLibraryData::Define loadDefine(const QXmlStreamReader &xmlReader)
static CppcheckLibraryData::Define loadDefine(const QDomElement &defineElement)
{ {
CppcheckLibraryData::Define define; CppcheckLibraryData::Define define;
define.name = defineElement.attribute("name"); define.name = xmlReader.attributes().value("name").toString();
define.value = defineElement.attribute("value"); define.value = xmlReader.attributes().value("value").toString();
return define; return define;
} }
static CppcheckLibraryData::Function::Arg loadFunctionArg(const QDomElement &functionArgElement) static CppcheckLibraryData::Function::Arg loadFunctionArg(QXmlStreamReader &xmlReader)
{ {
CppcheckLibraryData::Function::Arg arg; CppcheckLibraryData::Function::Arg arg;
if (functionArgElement.attribute("nr") == "any") QString argnr = xmlReader.attributes().value("nr").toString();
if (argnr == "any")
arg.nr = CppcheckLibraryData::Function::Arg::ANY; arg.nr = CppcheckLibraryData::Function::Arg::ANY;
else else
arg.nr = functionArgElement.attribute("nr").toUInt(); arg.nr = argnr.toUInt();
for (QDomElement childElement = functionArgElement.firstChildElement(); !childElement.isNull(); childElement = childElement.nextSiblingElement()) {
if (childElement.tagName() == "not-bool") QXmlStreamReader::TokenType type;
while ((type = xmlReader.readNext()) != QXmlStreamReader::EndElement ||
xmlReader.name().toString() != "arg") {
if (type != QXmlStreamReader::StartElement)
continue;
const QString elementName = xmlReader.name().toString();
if (elementName == "not-bool")
arg.notbool = true; arg.notbool = true;
else if (childElement.tagName() == "not-null") else if (elementName == "not-null")
arg.notnull = true; arg.notnull = true;
else if (childElement.tagName() == "not-uninit") else if (elementName == "not-uninit")
arg.notuninit = true; arg.notuninit = true;
else if (childElement.tagName() == "strz") else if (elementName == "strz")
arg.strz = true; arg.strz = true;
else if (childElement.tagName() == "formatstr") else if (elementName == "formatstr")
arg.formatstr = true; arg.formatstr = true;
else if (childElement.tagName() == "valid") else if (elementName == "valid")
arg.valid = childElement.text(); arg.valid = xmlReader.readElementText();
else if (childElement.tagName() == "minsize") { else if (elementName == "minsize") {
CppcheckLibraryData::Function::Arg::MinSize minsize; CppcheckLibraryData::Function::Arg::MinSize minsize;
minsize.type = childElement.attribute("type"); minsize.type = xmlReader.attributes().value("type").toString();
minsize.arg = childElement.attribute("arg"); minsize.arg = xmlReader.attributes().value("arg").toString();
minsize.arg2 = childElement.attribute("arg2"); minsize.arg2 = xmlReader.attributes().value("arg2").toString();
arg.minsizes.append(minsize); arg.minsizes.append(minsize);
} }
} }
return arg; return arg;
} }
static CppcheckLibraryData::Function loadFunction(const QDomElement &functionElement, const QStringList &comments) static CppcheckLibraryData::Function loadFunction(QXmlStreamReader &xmlReader, const QStringList &comments)
{ {
CppcheckLibraryData::Function function; CppcheckLibraryData::Function function;
function.comments = comments; function.comments = comments;
function.name = functionElement.attribute("name"); function.name = xmlReader.attributes().value("name").toString();
for (QDomElement childElement = functionElement.firstChildElement(); !childElement.isNull(); childElement = childElement.nextSiblingElement()) { QXmlStreamReader::TokenType type;
if (childElement.tagName() == "noreturn") while ((type = xmlReader.readNext()) != QXmlStreamReader::EndElement ||
function.noreturn = (childElement.text() == "true") ? CppcheckLibraryData::Function::True : CppcheckLibraryData::Function::False; xmlReader.name().toString() != "function") {
else if (childElement.tagName() == "pure") if (type != QXmlStreamReader::StartElement)
continue;
const QString elementName = xmlReader.name().toString();
if (elementName == "noreturn")
function.noreturn = (xmlReader.readElementText() == "true") ? CppcheckLibraryData::Function::True : CppcheckLibraryData::Function::False;
else if (elementName == "pure")
function.gccPure = true; function.gccPure = true;
else if (childElement.tagName() == "const") else if (elementName == "const")
function.gccConst = true; function.gccConst = true;
else if (childElement.tagName() == "leak-ignore") else if (elementName == "leak-ignore")
function.leakignore = true; function.leakignore = true;
else if (childElement.tagName() == "use-retval") else if (elementName == "use-retval")
function.useretval = true; function.useretval = true;
else if (childElement.tagName() == "formatstr") { else if (elementName == "formatstr") {
function.formatstr.scan = childElement.attribute("scan"); function.formatstr.scan = xmlReader.attributes().value("scan").toString();
function.formatstr.secure = childElement.attribute("secure"); function.formatstr.secure = xmlReader.attributes().value("secure").toString();
} else if (childElement.tagName() == "arg") { } else if (elementName == "arg")
const CppcheckLibraryData::Function::Arg fa = loadFunctionArg(childElement); function.args.append(loadFunctionArg(xmlReader));
function.args.append(fa);
} else {
int x = 123;
x++;
}
} }
return function; return function;
} }
static CppcheckLibraryData::MemoryResource loadMemoryResource(const QDomElement &element) static CppcheckLibraryData::MemoryResource loadMemoryResource(QXmlStreamReader &xmlReader)
{ {
CppcheckLibraryData::MemoryResource memoryresource; CppcheckLibraryData::MemoryResource memoryresource;
memoryresource.type = element.tagName(); memoryresource.type = xmlReader.name().toString();
for (QDomElement childElement = element.firstChildElement(); !childElement.isNull(); childElement = childElement.nextSiblingElement()) { QXmlStreamReader::TokenType type;
if (childElement.tagName() == "alloc") { while ((type = xmlReader.readNext()) != QXmlStreamReader::EndElement ||
xmlReader.name().toString() != memoryresource.type) {
if (type != QXmlStreamReader::StartElement)
continue;
const QString elementName = xmlReader.name().toString();
if (elementName == "alloc") {
CppcheckLibraryData::MemoryResource::Alloc alloc; CppcheckLibraryData::MemoryResource::Alloc alloc;
alloc.init = (childElement.attribute("init", "false") == "true"); alloc.init = (xmlReader.attributes().value("init").toString() == "true");
alloc.name = childElement.text(); alloc.name = xmlReader.readElementText();
memoryresource.alloc.append(alloc); memoryresource.alloc.append(alloc);
} else if (childElement.tagName() == "dealloc") } else if (elementName == "dealloc")
memoryresource.dealloc.append(childElement.text()); memoryresource.dealloc.append(xmlReader.readElementText());
else if (childElement.tagName() == "use") else if (elementName == "use")
memoryresource.use.append(childElement.text()); memoryresource.use.append(xmlReader.readElementText());
} }
return memoryresource; return memoryresource;
} }
static CppcheckLibraryData::PodType loadPodType(const QDomElement &element) static CppcheckLibraryData::PodType loadPodType(const QXmlStreamReader &xmlReader)
{ {
CppcheckLibraryData::PodType podtype; CppcheckLibraryData::PodType podtype;
podtype.name = element.attribute("name"); podtype.name = xmlReader.attributes().value("name").toString();
podtype.size = element.attribute("size"); podtype.size = xmlReader.attributes().value("size").toString();
podtype.sign = element.attribute("sign"); podtype.sign = xmlReader.attributes().value("sign").toString();
return podtype; return podtype;
} }
bool CppcheckLibraryData::open(QIODevice &file) bool CppcheckLibraryData::open(QIODevice &file)
{ {
QDomDocument doc;
if (!doc.setContent(&file))
return false;
clear(); clear();
QDomElement rootElement = doc.firstChildElement("def");
QStringList comments; QStringList comments;
for (QDomNode n = rootElement.firstChild(); !n.isNull(); n = n.nextSibling()) { QXmlStreamReader xmlReader(&file);
if (n.isComment()) while (!xmlReader.atEnd()) {
comments.append(n.toComment().data()); const QXmlStreamReader::TokenType t = xmlReader.readNext();
else if (n.isElement()) { switch (t) {
const QDomElement e = n.toElement(); case QXmlStreamReader::Comment:
comments.append(xmlReader.text().toString());
if (e.tagName() == "define") break;
defines.append(loadDefine(e)); case QXmlStreamReader::StartElement:
else if (e.tagName() == "function") if (xmlReader.name() == "define")
functions.append(loadFunction(e, comments)); defines.append(loadDefine(xmlReader));
else if (e.tagName() == "memory" || e.tagName() == "resource") else if (xmlReader.name() == "function")
memoryresource.append(loadMemoryResource(e)); functions.append(loadFunction(xmlReader, comments));
else if (e.tagName() == "podtype") else if (xmlReader.name() == "memory" || xmlReader.name() == "resource")
podtypes.append(loadPodType(e)); memoryresource.append(loadMemoryResource(xmlReader));
else if (xmlReader.name() == "podtype")
podtypes.append(loadPodType(xmlReader));
comments.clear(); comments.clear();
break;
default:
break;
} }
} }
return true; return true;
} }
static QDomElement FunctionElement(QDomDocument &doc, const CppcheckLibraryData::Function &function) static void writeFunction(QXmlStreamWriter &xmlWriter, const CppcheckLibraryData::Function &function)
{ {
QDomElement functionElement = doc.createElement("function"); foreach(const QString &comment, function.comments) {
functionElement.setAttribute("name", function.name); xmlWriter.writeComment(comment);
if (function.useretval)
functionElement.appendChild(doc.createElement("use-retval"));
if (function.gccConst)
functionElement.appendChild(doc.createElement("const"));
if (function.gccPure)
functionElement.appendChild(doc.createElement("pure"));
if (function.noreturn != CppcheckLibraryData::Function::Unknown) {
QDomElement e = doc.createElement("noreturn");
e.appendChild(doc.createTextNode(function.noreturn == CppcheckLibraryData::Function::True ? "true" : "false"));
functionElement.appendChild(e);
} }
xmlWriter.writeStartElement("function");
xmlWriter.writeAttribute("name", function.name);
if (function.useretval)
xmlWriter.writeEmptyElement("use-retval");
if (function.gccConst)
xmlWriter.writeEmptyElement("const");
if (function.gccPure)
xmlWriter.writeEmptyElement("pure");
if (function.noreturn != CppcheckLibraryData::Function::Unknown)
xmlWriter.writeTextElement("noreturn", (function.noreturn == CppcheckLibraryData::Function::True) ? "true" : "false");
if (function.leakignore) if (function.leakignore)
functionElement.appendChild(doc.createElement("leak-ignore")); xmlWriter.writeEmptyElement("leak-ignore");
/*
if (!function.formatstr.scan.isNull()) {
QDomElement e = doc.createElement("formatstr");
e.setAttribute("scan", function.formatstr.scan);
if (!function.formatstr.secure.isNull())
e.setAttribute("secure", function.formatstr.secure);
functionElement.appendChild(e);
}
*/
// Argument info.. // Argument info..
foreach(const CppcheckLibraryData::Function::Arg &arg, function.args) { foreach(const CppcheckLibraryData::Function::Arg &arg, function.args) {
if (arg.formatstr) { if (arg.formatstr) {
QDomElement e = doc.createElement("formatstr"); xmlWriter.writeStartElement("formatstr");
if (!function.formatstr.scan.isNull()) if (!function.formatstr.scan.isNull())
e.setAttribute("scan", function.formatstr.scan); xmlWriter.writeAttribute("scan", function.formatstr.scan);
if (!function.formatstr.secure.isNull()) if (!function.formatstr.secure.isNull())
e.setAttribute("secure", function.formatstr.secure); xmlWriter.writeAttribute("secure", function.formatstr.secure);
functionElement.appendChild(e); xmlWriter.writeEndElement();
} }
QDomElement argElement = doc.createElement("arg"); xmlWriter.writeStartElement("arg");
functionElement.appendChild(argElement);
if (arg.nr == CppcheckLibraryData::Function::Arg::ANY) if (arg.nr == CppcheckLibraryData::Function::Arg::ANY)
argElement.setAttribute("nr", "any"); xmlWriter.writeAttribute("nr", "any");
else else
argElement.setAttribute("nr", arg.nr); xmlWriter.writeAttribute("nr", QString::number(arg.nr));
if (arg.formatstr) if (arg.formatstr)
argElement.appendChild(doc.createElement("formatstr")); xmlWriter.writeEmptyElement("formatstr");
if (arg.notnull) if (arg.notnull)
argElement.appendChild(doc.createElement("not-null")); xmlWriter.writeEmptyElement("not-null");
if (arg.notuninit) if (arg.notuninit)
argElement.appendChild(doc.createElement("not-uninit")); xmlWriter.writeEmptyElement("not-uninit");
if (arg.notbool) if (arg.notbool)
argElement.appendChild(doc.createElement("not-bool")); xmlWriter.writeEmptyElement("not-bool");
if (arg.strz) if (arg.strz)
argElement.appendChild(doc.createElement("strz")); xmlWriter.writeEmptyElement("strz");
if (!arg.valid.isEmpty()) { if (!arg.valid.isEmpty())
QDomElement e = doc.createElement("valid"); xmlWriter.writeTextElement("valid",arg.valid);
e.appendChild(doc.createTextNode(arg.valid));
argElement.appendChild(e); foreach(const CppcheckLibraryData::Function::Arg::MinSize &minsize, arg.minsizes) {
xmlWriter.writeStartElement("minsize");
xmlWriter.writeAttribute("type", minsize.type);
xmlWriter.writeAttribute("arg", minsize.arg);
if (!minsize.arg2.isEmpty())
xmlWriter.writeAttribute("arg2", minsize.arg2);
xmlWriter.writeEndElement();
} }
if (!arg.minsizes.isEmpty()) { xmlWriter.writeEndElement();
foreach(const CppcheckLibraryData::Function::Arg::MinSize &minsize, arg.minsizes) {
QDomElement e = doc.createElement("minsize");
e.setAttribute("type", minsize.type);
e.setAttribute("arg", minsize.arg);
if (!minsize.arg2.isEmpty())
e.setAttribute("arg2", minsize.arg2);
argElement.appendChild(e);
}
}
} }
xmlWriter.writeEndElement();
return functionElement;
} }
static QDomElement MemoryResourceElement(QDomDocument &doc, const CppcheckLibraryData::MemoryResource &mr) static void writeMemoryResource(QXmlStreamWriter &xmlWriter, const CppcheckLibraryData::MemoryResource &mr)
{ {
QDomElement element = doc.createElement(mr.type); xmlWriter.writeStartElement(mr.type);
foreach(const CppcheckLibraryData::MemoryResource::Alloc &alloc, mr.alloc) { foreach(const CppcheckLibraryData::MemoryResource::Alloc &alloc, mr.alloc) {
QDomElement e = doc.createElement("alloc"); xmlWriter.writeStartElement("alloc");
if (alloc.init) if (alloc.init)
e.setAttribute("init", "true"); xmlWriter.writeAttribute("init", "true");
e.appendChild(doc.createTextNode(alloc.name)); xmlWriter.writeCharacters(alloc.name);
element.appendChild(e); xmlWriter.writeEndElement();
} }
foreach(const QString &dealloc, mr.dealloc) { foreach(const QString &dealloc, mr.dealloc) {
QDomElement e = doc.createElement("dealloc"); xmlWriter.writeTextElement("dealloc", dealloc);
e.appendChild(doc.createTextNode(dealloc));
element.appendChild(e);
} }
foreach(const QString &use, mr.use) { foreach(const QString &use, mr.use) {
QDomElement e = doc.createElement("use"); xmlWriter.writeTextElement("use", use);
e.appendChild(doc.createTextNode(use));
element.appendChild(e);
} }
return element; xmlWriter.writeEndElement();
} }
QString CppcheckLibraryData::toString() const QString CppcheckLibraryData::toString() const
{ {
QDomDocument doc; QString outputString;
QDomElement root = doc.createElement("def"); QXmlStreamWriter xmlWriter(&outputString);
doc.appendChild(root); xmlWriter.setAutoFormatting(true);
root.setAttribute("format","2"); xmlWriter.writeStartDocument("1.0");
xmlWriter.writeStartElement("def");
xmlWriter.writeAttribute("format","2");
foreach(const Define &define, defines) { foreach(const Define &define, defines) {
QDomElement defineElement = doc.createElement("define"); xmlWriter.writeStartElement("define");
defineElement.setAttribute("name", define.name); xmlWriter.writeAttribute("name", define.name);
defineElement.setAttribute("value", define.value); xmlWriter.writeAttribute("value", define.value);
root.appendChild(defineElement); xmlWriter.writeEndElement();
} }
foreach(const Function &function, functions) { foreach(const Function &function, functions) {
foreach(const QString &comment, function.comments) { writeFunction(xmlWriter, function);
root.appendChild(doc.createComment(comment));
}
root.appendChild(FunctionElement(doc, function));
} }
foreach(const MemoryResource &mr, memoryresource) { foreach(const MemoryResource &mr, memoryresource) {
root.appendChild(MemoryResourceElement(doc, mr)); writeMemoryResource(xmlWriter, mr);
} }
foreach(const PodType &podtype, podtypes) { foreach(const PodType &podtype, podtypes) {
QDomElement podtypeElement = doc.createElement("podtype"); xmlWriter.writeStartElement("podtype");
podtypeElement.setAttribute("name", podtype.name); xmlWriter.writeAttribute("name", podtype.name);
if (!podtype.size.isEmpty()) if (!podtype.size.isEmpty())
podtypeElement.setAttribute("size", podtype.size); xmlWriter.writeAttribute("size", podtype.size);
if (!podtype.sign.isEmpty()) if (!podtype.sign.isEmpty())
podtypeElement.setAttribute("sign", podtype.sign); xmlWriter.writeAttribute("sign", podtype.sign);
root.appendChild(podtypeElement); xmlWriter.writeEndElement();
} }
return doc.toString(); xmlWriter.writeEndElement();
return outputString;
} }

View File

@ -5,7 +5,6 @@ DEPENDPATH += . \
../lib ../lib
INCLUDEPATH += . \ INCLUDEPATH += . \
../lib ../lib
QT += xml
greaterThan(QT_MAJOR_VERSION, 4) { greaterThan(QT_MAJOR_VERSION, 4) {
QT += widgets # In Qt 5 widgets are in separate module QT += widgets # In Qt 5 widgets are in separate module
QT += printsupport # In Qt 5 QPrinter/QPrintDialog are in separate module QT += printsupport # In Qt 5 QPrinter/QPrintDialog are in separate module