GUI: Don't loose information when open/read std.cfg

This commit is contained in:
Daniel Marjamäki 2017-11-12 15:07:11 +01:00
parent 63feebc34f
commit a794ae6c9d
2 changed files with 107 additions and 23 deletions

View File

@ -22,6 +22,7 @@
#include <QXmlStreamWriter> #include <QXmlStreamWriter>
const unsigned int CppcheckLibraryData::Function::Arg::ANY = ~0U; const unsigned int CppcheckLibraryData::Function::Arg::ANY = ~0U;
const unsigned int CppcheckLibraryData::Function::Arg::VARIADIC = ~1U;
CppcheckLibraryData::CppcheckLibraryData() CppcheckLibraryData::CppcheckLibraryData()
{ {
@ -30,10 +31,12 @@ CppcheckLibraryData::CppcheckLibraryData()
static CppcheckLibraryData::Container loadContainer(QXmlStreamReader &xmlReader) static CppcheckLibraryData::Container loadContainer(QXmlStreamReader &xmlReader)
{ {
CppcheckLibraryData::Container container; CppcheckLibraryData::Container container;
container.id = xmlReader.attributes().value("id").toString(); container.id = xmlReader.attributes().value("id").toString();
container.inherits = xmlReader.attributes().value("inherits").toString(); container.inherits = xmlReader.attributes().value("inherits").toString();
container.startPattern = xmlReader.attributes().value("startPattern").toString(); container.startPattern = xmlReader.attributes().value("startPattern").toString();
container.endPattern = xmlReader.attributes().value("endPattern").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; QXmlStreamReader::TokenType type;
while ((type = xmlReader.readNext()) != QXmlStreamReader::EndElement || while ((type = xmlReader.readNext()) != QXmlStreamReader::EndElement ||
@ -67,7 +70,9 @@ static CppcheckLibraryData::Container loadContainer(QXmlStreamReader &xmlReader)
container.accessFunctions.append(function); container.accessFunctions.append(function);
else else
container.otherFunctions.append(function); container.otherFunctions.append(function);
}; }
} else {
throw std::runtime_error("Unhandled element " + elementName.toStdString());
} }
} }
return container; return container;
@ -87,8 +92,11 @@ static CppcheckLibraryData::Function::Arg loadFunctionArg(QXmlStreamReader &xmlR
QString argnr = xmlReader.attributes().value("nr").toString(); QString argnr = xmlReader.attributes().value("nr").toString();
if (argnr == "any") if (argnr == "any")
arg.nr = CppcheckLibraryData::Function::Arg::ANY; arg.nr = CppcheckLibraryData::Function::Arg::ANY;
else if (argnr == "variadic")
arg.nr = CppcheckLibraryData::Function::Arg::VARIADIC;
else else
arg.nr = argnr.toUInt(); arg.nr = argnr.toUInt();
arg.defaultValue = xmlReader.attributes().value("default").toString();
QXmlStreamReader::TokenType type; QXmlStreamReader::TokenType type;
while ((type = xmlReader.readNext()) != QXmlStreamReader::EndElement || 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.arg = xmlReader.attributes().value("arg").toString();
minsize.arg2 = xmlReader.attributes().value("arg2").toString(); minsize.arg2 = xmlReader.attributes().value("arg2").toString();
arg.minsizes.append(minsize); 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; return arg;
@ -140,16 +153,24 @@ static CppcheckLibraryData::Function loadFunction(QXmlStreamReader &xmlReader, c
function.leakignore = true; function.leakignore = true;
else if (elementName == "use-retval") else if (elementName == "use-retval")
function.useretval = true; 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.scan = xmlReader.attributes().value("scan").toString();
function.formatstr.secure = xmlReader.attributes().value("secure").toString(); function.formatstr.secure = xmlReader.attributes().value("secure").toString();
} else if (elementName == "arg") } else if (elementName == "arg")
function.args.append(loadFunctionArg(xmlReader)); function.args.append(loadFunctionArg(xmlReader));
else if (elementName == "warn") { else if (elementName == "warn") {
function.warn.severity = xmlReader.attributes().value("severity").toString(); 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.reason = xmlReader.attributes().value("reason").toString();
function.warn.alternatives = xmlReader.attributes().value("alternatives").toString(); function.warn.alternatives = xmlReader.attributes().value("alternatives").toString();
function.warn.msg = xmlReader.readElementText(); function.warn.msg = xmlReader.readElementText();
} else {
throw std::runtime_error("Unhandled element " + elementName.toStdString());
} }
} }
return function; return function;
@ -174,6 +195,8 @@ static CppcheckLibraryData::MemoryResource loadMemoryResource(QXmlStreamReader &
memoryresource.dealloc.append(xmlReader.readElementText()); memoryresource.dealloc.append(xmlReader.readElementText());
else if (elementName == "use") else if (elementName == "use")
memoryresource.use.append(xmlReader.readElementText()); memoryresource.use.append(xmlReader.readElementText());
else
throw std::runtime_error("Unhandled element " + elementName.toStdString());
} }
return memoryresource; return memoryresource;
} }
@ -201,16 +224,26 @@ bool CppcheckLibraryData::open(QIODevice &file)
comments += xmlReader.text().toString(); comments += xmlReader.text().toString();
break; break;
case QXmlStreamReader::StartElement: case QXmlStreamReader::StartElement:
if (xmlReader.name() == "container") try {
containers.append(loadContainer(xmlReader)); const QString elementName(xmlReader.name().toString());
if (xmlReader.name() == "define") if (elementName == "def")
defines.append(loadDefine(xmlReader)); ;
else if (xmlReader.name() == "function") else if (elementName == "container")
functions.append(loadFunction(xmlReader, comments)); containers.append(loadContainer(xmlReader));
else if (xmlReader.name() == "memory" || xmlReader.name() == "resource") else if (elementName == "define")
memoryresource.append(loadMemoryResource(xmlReader)); defines.append(loadDefine(xmlReader));
else if (xmlReader.name() == "podtype") else if (elementName == "function")
podtypes.append(loadPodType(xmlReader)); 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(); comments.clear();
break; break;
default: default:
@ -223,10 +256,10 @@ bool CppcheckLibraryData::open(QIODevice &file)
static void writeContainerFunctions(QXmlStreamWriter &xmlWriter, const QString name, int extra, const QList<struct CppcheckLibraryData::Container::Function> &functions) static void writeContainerFunctions(QXmlStreamWriter &xmlWriter, const QString name, int extra, const QList<struct CppcheckLibraryData::Container::Function> &functions)
{ {
if (functions.isEmpty() && extra <= 0) if (functions.isEmpty() && extra < 0)
return; return;
xmlWriter.writeStartElement(name); xmlWriter.writeStartElement(name);
if (extra > 0) { if (extra >= 0) {
if (name == "access") if (name == "access")
xmlWriter.writeAttribute("indexOperator", "array-like"); xmlWriter.writeAttribute("indexOperator", "array-like");
else if (name == "size") else if (name == "size")
@ -254,6 +287,11 @@ static void writeContainer(QXmlStreamWriter &xmlWriter, const CppcheckLibraryDat
xmlWriter.writeAttribute("endPattern", container.endPattern); xmlWriter.writeAttribute("endPattern", container.endPattern);
if (!container.inherits.isEmpty()) if (!container.inherits.isEmpty())
xmlWriter.writeAttribute("inherits", container.inherits); 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()) { if (!container.type.templateParameter.isEmpty() || !container.type.string.isEmpty()) {
xmlWriter.writeStartElement("type"); xmlWriter.writeStartElement("type");
if (!container.type.templateParameter.isEmpty()) if (!container.type.templateParameter.isEmpty())
@ -263,8 +301,8 @@ static void writeContainer(QXmlStreamWriter &xmlWriter, const CppcheckLibraryDat
xmlWriter.writeEndElement(); xmlWriter.writeEndElement();
} }
writeContainerFunctions(xmlWriter, "size", container.size_templateParameter, container.sizeFunctions); writeContainerFunctions(xmlWriter, "size", container.size_templateParameter, container.sizeFunctions);
writeContainerFunctions(xmlWriter, "access", container.access_arrayLike, container.accessFunctions); writeContainerFunctions(xmlWriter, "access", container.access_arrayLike?1:-1, container.accessFunctions);
writeContainerFunctions(xmlWriter, "other", 0, container.otherFunctions); writeContainerFunctions(xmlWriter, "other", -1, container.otherFunctions);
xmlWriter.writeEndElement(); xmlWriter.writeEndElement();
} }
@ -291,6 +329,16 @@ static void writeFunction(QXmlStreamWriter &xmlWriter, const CppcheckLibraryData
xmlWriter.writeEmptyElement("pure"); xmlWriter.writeEmptyElement("pure");
if (function.noreturn != CppcheckLibraryData::Function::Unknown) if (function.noreturn != CppcheckLibraryData::Function::Unknown)
xmlWriter.writeTextElement("noreturn", (function.noreturn == CppcheckLibraryData::Function::True) ? "true" : "false"); 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) if (function.leakignore)
xmlWriter.writeEmptyElement("leak-ignore"); xmlWriter.writeEmptyElement("leak-ignore");
// Argument info.. // Argument info..
@ -307,8 +355,12 @@ static void writeFunction(QXmlStreamWriter &xmlWriter, const CppcheckLibraryData
xmlWriter.writeStartElement("arg"); xmlWriter.writeStartElement("arg");
if (arg.nr == CppcheckLibraryData::Function::Arg::ANY) if (arg.nr == CppcheckLibraryData::Function::Arg::ANY)
xmlWriter.writeAttribute("nr", "any"); xmlWriter.writeAttribute("nr", "any");
else if (arg.nr == CppcheckLibraryData::Function::Arg::VARIADIC)
xmlWriter.writeAttribute("nr", "variadic");
else else
xmlWriter.writeAttribute("nr", QString::number(arg.nr)); xmlWriter.writeAttribute("nr", QString::number(arg.nr));
if (!arg.defaultValue.isNull())
xmlWriter.writeAttribute("default", arg.defaultValue);
if (arg.formatstr) if (arg.formatstr)
xmlWriter.writeEmptyElement("formatstr"); xmlWriter.writeEmptyElement("formatstr");
if (arg.notnull) if (arg.notnull)
@ -332,6 +384,15 @@ static void writeFunction(QXmlStreamWriter &xmlWriter, const CppcheckLibraryData
xmlWriter.writeEndElement(); 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(); xmlWriter.writeEndElement();
} }
@ -341,12 +402,15 @@ static void writeFunction(QXmlStreamWriter &xmlWriter, const CppcheckLibraryData
if (!function.warn.severity.isEmpty()) if (!function.warn.severity.isEmpty())
xmlWriter.writeAttribute("severity", function.warn.severity); xmlWriter.writeAttribute("severity", function.warn.severity);
if (!function.warn.reason.isEmpty()) if (!function.warn.cstd.isEmpty())
xmlWriter.writeAttribute("reason", function.warn.reason); xmlWriter.writeAttribute("cstd", function.warn.cstd);
if (!function.warn.alternatives.isEmpty()) if (!function.warn.alternatives.isEmpty())
xmlWriter.writeAttribute("alternatives", function.warn.alternatives); xmlWriter.writeAttribute("alternatives", function.warn.alternatives);
if (!function.warn.reason.isEmpty())
xmlWriter.writeAttribute("reason", function.warn.reason);
if (!function.warn.msg.isEmpty()) if (!function.warn.msg.isEmpty())
xmlWriter.writeCharacters(function.warn.msg); xmlWriter.writeCharacters(function.warn.msg);

View File

@ -35,6 +35,8 @@ public:
QString inherits; QString inherits;
QString startPattern; QString startPattern;
QString endPattern; QString endPattern;
QString opLessAllowed;
QString itEndPattern;
bool access_arrayLike; bool access_arrayLike;
int size_templateParameter; int size_templateParameter;
@ -71,6 +73,15 @@ public:
bool gccConst; bool gccConst;
bool leakignore; bool leakignore;
bool useretval; 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 { struct {
QString scan; QString scan;
QString secure; QString secure;
@ -83,6 +94,8 @@ public:
QString name; QString name;
unsigned int nr; unsigned int nr;
static const unsigned int ANY; static const unsigned int ANY;
static const unsigned int VARIADIC;
QString defaultValue;
bool notbool; bool notbool;
bool notnull; bool notnull;
bool notuninit; bool notuninit;
@ -95,17 +108,24 @@ public:
QString arg2; QString arg2;
}; };
QList<struct MinSize> minsizes; QList<struct MinSize> minsizes;
struct Iterator {
Iterator() : container(-1) {}
int container;
QString type;
} iterator;
}; };
QList<struct Arg> args; QList<struct Arg> args;
struct { struct {
QString severity; QString severity;
QString cstd;
QString reason; QString reason;
QString alternatives; QString alternatives;
QString msg; QString msg;
bool isEmpty() const { bool isEmpty() const {
return severity.isEmpty() && return cstd.isEmpty() &&
severity.isEmpty() &&
reason.isEmpty() && reason.isEmpty() &&
alternatives.isEmpty() && alternatives.isEmpty() &&
msg.isEmpty(); msg.isEmpty();