From a794ae6c9d5ea13d3173c65176ebf2242b618b21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 12 Nov 2017 15:07:11 +0100 Subject: [PATCH] GUI: Don't loose information when open/read std.cfg --- gui/cppchecklibrarydata.cpp | 108 ++++++++++++++++++++++++++++-------- gui/cppchecklibrarydata.h | 22 +++++++- 2 files changed, 107 insertions(+), 23 deletions(-) diff --git a/gui/cppchecklibrarydata.cpp b/gui/cppchecklibrarydata.cpp index 3664d2b56..f308edbca 100644 --- a/gui/cppchecklibrarydata.cpp +++ b/gui/cppchecklibrarydata.cpp @@ -22,6 +22,7 @@ #include const unsigned int CppcheckLibraryData::Function::Arg::ANY = ~0U; +const unsigned int CppcheckLibraryData::Function::Arg::VARIADIC = ~1U; CppcheckLibraryData::CppcheckLibraryData() { @@ -30,10 +31,12 @@ CppcheckLibraryData::CppcheckLibraryData() static CppcheckLibraryData::Container loadContainer(QXmlStreamReader &xmlReader) { CppcheckLibraryData::Container container; - container.id = xmlReader.attributes().value("id").toString(); - container.inherits = xmlReader.attributes().value("inherits").toString(); - container.startPattern = xmlReader.attributes().value("startPattern").toString(); - container.endPattern = xmlReader.attributes().value("endPattern").toString(); + container.id = xmlReader.attributes().value("id").toString(); + container.inherits = xmlReader.attributes().value("inherits").toString(); + container.startPattern = xmlReader.attributes().value("startPattern").toString(); + container.endPattern = xmlReader.attributes().value("endPattern").toString(); + container.opLessAllowed = xmlReader.attributes().value("opLessAllowed").toString(); + container.itEndPattern = xmlReader.attributes().value("itEndPattern").toString(); QXmlStreamReader::TokenType type; while ((type = xmlReader.readNext()) != QXmlStreamReader::EndElement || @@ -67,7 +70,9 @@ static CppcheckLibraryData::Container loadContainer(QXmlStreamReader &xmlReader) container.accessFunctions.append(function); else container.otherFunctions.append(function); - }; + } + } else { + throw std::runtime_error("Unhandled element " + elementName.toStdString()); } } return container; @@ -87,8 +92,11 @@ static CppcheckLibraryData::Function::Arg loadFunctionArg(QXmlStreamReader &xmlR QString argnr = xmlReader.attributes().value("nr").toString(); if (argnr == "any") arg.nr = CppcheckLibraryData::Function::Arg::ANY; + else if (argnr == "variadic") + arg.nr = CppcheckLibraryData::Function::Arg::VARIADIC; else arg.nr = argnr.toUInt(); + arg.defaultValue = xmlReader.attributes().value("default").toString(); QXmlStreamReader::TokenType type; while ((type = xmlReader.readNext()) != QXmlStreamReader::EndElement || @@ -114,6 +122,11 @@ static CppcheckLibraryData::Function::Arg loadFunctionArg(QXmlStreamReader &xmlR minsize.arg = xmlReader.attributes().value("arg").toString(); minsize.arg2 = xmlReader.attributes().value("arg2").toString(); arg.minsizes.append(minsize); + } else if (elementName == "iterator") { + arg.iterator.container = xmlReader.attributes().value("container").toInt(); + arg.iterator.type = xmlReader.attributes().value("type").toString(); + } else { + throw std::runtime_error("Unhandled element " + elementName.toStdString()); } } return arg; @@ -140,16 +153,24 @@ static CppcheckLibraryData::Function loadFunction(QXmlStreamReader &xmlReader, c function.leakignore = true; else if (elementName == "use-retval") function.useretval = true; - else if (elementName == "formatstr") { + else if (elementName == "returnValue") { + const QString container = xmlReader.attributes().value("container").toString(); + function.returnValue.container = container.isNull() ? -1 : container.toInt(); + function.returnValue.type = xmlReader.attributes().value("type").toString(); + function.returnValue.value = xmlReader.readElementText(); + } else if (elementName == "formatstr") { function.formatstr.scan = xmlReader.attributes().value("scan").toString(); function.formatstr.secure = xmlReader.attributes().value("secure").toString(); } else if (elementName == "arg") function.args.append(loadFunctionArg(xmlReader)); else if (elementName == "warn") { function.warn.severity = xmlReader.attributes().value("severity").toString(); + function.warn.cstd = xmlReader.attributes().value("cstd").toString(); function.warn.reason = xmlReader.attributes().value("reason").toString(); function.warn.alternatives = xmlReader.attributes().value("alternatives").toString(); function.warn.msg = xmlReader.readElementText(); + } else { + throw std::runtime_error("Unhandled element " + elementName.toStdString()); } } return function; @@ -174,6 +195,8 @@ static CppcheckLibraryData::MemoryResource loadMemoryResource(QXmlStreamReader & memoryresource.dealloc.append(xmlReader.readElementText()); else if (elementName == "use") memoryresource.use.append(xmlReader.readElementText()); + else + throw std::runtime_error("Unhandled element " + elementName.toStdString()); } return memoryresource; } @@ -201,16 +224,26 @@ bool CppcheckLibraryData::open(QIODevice &file) comments += xmlReader.text().toString(); break; case QXmlStreamReader::StartElement: - if (xmlReader.name() == "container") - containers.append(loadContainer(xmlReader)); - if (xmlReader.name() == "define") - defines.append(loadDefine(xmlReader)); - else if (xmlReader.name() == "function") - functions.append(loadFunction(xmlReader, comments)); - else if (xmlReader.name() == "memory" || xmlReader.name() == "resource") - memoryresource.append(loadMemoryResource(xmlReader)); - else if (xmlReader.name() == "podtype") - podtypes.append(loadPodType(xmlReader)); + try { + const QString elementName(xmlReader.name().toString()); + if (elementName == "def") + ; + else if (elementName == "container") + containers.append(loadContainer(xmlReader)); + else if (elementName == "define") + defines.append(loadDefine(xmlReader)); + else if (elementName == "function") + functions.append(loadFunction(xmlReader, comments)); + else if (elementName == "memory" || elementName == "resource") + memoryresource.append(loadMemoryResource(xmlReader)); + else if (elementName == "podtype") + podtypes.append(loadPodType(xmlReader)); + else + return false; + } catch (std::runtime_error &e) { + const QString what(e.what()); + return false; + } comments.clear(); break; default: @@ -223,10 +256,10 @@ bool CppcheckLibraryData::open(QIODevice &file) static void writeContainerFunctions(QXmlStreamWriter &xmlWriter, const QString name, int extra, const QList &functions) { - if (functions.isEmpty() && extra <= 0) + if (functions.isEmpty() && extra < 0) return; xmlWriter.writeStartElement(name); - if (extra > 0) { + if (extra >= 0) { if (name == "access") xmlWriter.writeAttribute("indexOperator", "array-like"); else if (name == "size") @@ -254,6 +287,11 @@ static void writeContainer(QXmlStreamWriter &xmlWriter, const CppcheckLibraryDat xmlWriter.writeAttribute("endPattern", container.endPattern); if (!container.inherits.isEmpty()) xmlWriter.writeAttribute("inherits", container.inherits); + if (!container.opLessAllowed.isEmpty()) + xmlWriter.writeAttribute("opLessAllowed", container.opLessAllowed); + if (!container.itEndPattern.isEmpty()) + xmlWriter.writeAttribute("itEndPattern", container.itEndPattern); + if (!container.type.templateParameter.isEmpty() || !container.type.string.isEmpty()) { xmlWriter.writeStartElement("type"); if (!container.type.templateParameter.isEmpty()) @@ -263,8 +301,8 @@ static void writeContainer(QXmlStreamWriter &xmlWriter, const CppcheckLibraryDat xmlWriter.writeEndElement(); } writeContainerFunctions(xmlWriter, "size", container.size_templateParameter, container.sizeFunctions); - writeContainerFunctions(xmlWriter, "access", container.access_arrayLike, container.accessFunctions); - writeContainerFunctions(xmlWriter, "other", 0, container.otherFunctions); + writeContainerFunctions(xmlWriter, "access", container.access_arrayLike?1:-1, container.accessFunctions); + writeContainerFunctions(xmlWriter, "other", -1, container.otherFunctions); xmlWriter.writeEndElement(); } @@ -291,6 +329,16 @@ static void writeFunction(QXmlStreamWriter &xmlWriter, const CppcheckLibraryData xmlWriter.writeEmptyElement("pure"); if (function.noreturn != CppcheckLibraryData::Function::Unknown) xmlWriter.writeTextElement("noreturn", (function.noreturn == CppcheckLibraryData::Function::True) ? "true" : "false"); + if (!function.returnValue.empty()) { + xmlWriter.writeStartElement("returnValue"); + if (!function.returnValue.type.isNull()) + xmlWriter.writeAttribute("type", function.returnValue.type); + if (function.returnValue.container >= 0) + xmlWriter.writeAttribute("container", QString::number(function.returnValue.container)); + if (!function.returnValue.value.isNull()) + xmlWriter.writeCharacters(function.returnValue.value); + xmlWriter.writeEndElement(); + } if (function.leakignore) xmlWriter.writeEmptyElement("leak-ignore"); // Argument info.. @@ -307,8 +355,12 @@ static void writeFunction(QXmlStreamWriter &xmlWriter, const CppcheckLibraryData xmlWriter.writeStartElement("arg"); if (arg.nr == CppcheckLibraryData::Function::Arg::ANY) xmlWriter.writeAttribute("nr", "any"); + else if (arg.nr == CppcheckLibraryData::Function::Arg::VARIADIC) + xmlWriter.writeAttribute("nr", "variadic"); else xmlWriter.writeAttribute("nr", QString::number(arg.nr)); + if (!arg.defaultValue.isNull()) + xmlWriter.writeAttribute("default", arg.defaultValue); if (arg.formatstr) xmlWriter.writeEmptyElement("formatstr"); if (arg.notnull) @@ -332,6 +384,15 @@ static void writeFunction(QXmlStreamWriter &xmlWriter, const CppcheckLibraryData xmlWriter.writeEndElement(); } + if (arg.iterator.container >= 0 || !arg.iterator.type.isNull()) { + xmlWriter.writeStartElement("iterator"); + if (arg.iterator.container >= 0) + xmlWriter.writeAttribute("container", QString::number(arg.iterator.container)); + if (!arg.iterator.type.isNull()) + xmlWriter.writeAttribute("type", arg.iterator.type); + xmlWriter.writeEndElement(); + } + xmlWriter.writeEndElement(); } @@ -341,12 +402,15 @@ static void writeFunction(QXmlStreamWriter &xmlWriter, const CppcheckLibraryData if (!function.warn.severity.isEmpty()) xmlWriter.writeAttribute("severity", function.warn.severity); - if (!function.warn.reason.isEmpty()) - xmlWriter.writeAttribute("reason", function.warn.reason); + if (!function.warn.cstd.isEmpty()) + xmlWriter.writeAttribute("cstd", function.warn.cstd); if (!function.warn.alternatives.isEmpty()) xmlWriter.writeAttribute("alternatives", function.warn.alternatives); + if (!function.warn.reason.isEmpty()) + xmlWriter.writeAttribute("reason", function.warn.reason); + if (!function.warn.msg.isEmpty()) xmlWriter.writeCharacters(function.warn.msg); diff --git a/gui/cppchecklibrarydata.h b/gui/cppchecklibrarydata.h index bb4686b81..d3426b91c 100644 --- a/gui/cppchecklibrarydata.h +++ b/gui/cppchecklibrarydata.h @@ -35,6 +35,8 @@ public: QString inherits; QString startPattern; QString endPattern; + QString opLessAllowed; + QString itEndPattern; bool access_arrayLike; int size_templateParameter; @@ -71,6 +73,15 @@ public: bool gccConst; bool leakignore; bool useretval; + struct ReturnValue { + ReturnValue() : container(-1) {} + QString type; + QString value; + int container; + bool empty() const { + return type.isNull() && value.isNull() && container < 0; + } + } returnValue; struct { QString scan; QString secure; @@ -83,6 +94,8 @@ public: QString name; unsigned int nr; static const unsigned int ANY; + static const unsigned int VARIADIC; + QString defaultValue; bool notbool; bool notnull; bool notuninit; @@ -95,17 +108,24 @@ public: QString arg2; }; QList minsizes; + struct Iterator { + Iterator() : container(-1) {} + int container; + QString type; + } iterator; }; QList args; struct { QString severity; + QString cstd; QString reason; QString alternatives; QString msg; bool isEmpty() const { - return severity.isEmpty() && + return cstd.isEmpty() && + severity.isEmpty() && reason.isEmpty() && alternatives.isEmpty() && msg.isEmpty();