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>
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<struct CppcheckLibraryData::Container::Function> &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);

View File

@ -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<struct MinSize> minsizes;
struct Iterator {
Iterator() : container(-1) {}
int container;
QString type;
} iterator;
};
QList<struct Arg> 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();