Skip to content

Commit a794ae6

Browse files
committed
GUI: Don't loose information when open/read std.cfg
1 parent 63feebc commit a794ae6

2 files changed

Lines changed: 107 additions & 23 deletions

File tree

gui/cppchecklibrarydata.cpp

Lines changed: 86 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <QXmlStreamWriter>
2323

2424
const unsigned int CppcheckLibraryData::Function::Arg::ANY = ~0U;
25+
const unsigned int CppcheckLibraryData::Function::Arg::VARIADIC = ~1U;
2526

2627
CppcheckLibraryData::CppcheckLibraryData()
2728
{
@@ -30,10 +31,12 @@ CppcheckLibraryData::CppcheckLibraryData()
3031
static CppcheckLibraryData::Container loadContainer(QXmlStreamReader &xmlReader)
3132
{
3233
CppcheckLibraryData::Container container;
33-
container.id = xmlReader.attributes().value("id").toString();
34-
container.inherits = xmlReader.attributes().value("inherits").toString();
35-
container.startPattern = xmlReader.attributes().value("startPattern").toString();
36-
container.endPattern = xmlReader.attributes().value("endPattern").toString();
34+
container.id = xmlReader.attributes().value("id").toString();
35+
container.inherits = xmlReader.attributes().value("inherits").toString();
36+
container.startPattern = xmlReader.attributes().value("startPattern").toString();
37+
container.endPattern = xmlReader.attributes().value("endPattern").toString();
38+
container.opLessAllowed = xmlReader.attributes().value("opLessAllowed").toString();
39+
container.itEndPattern = xmlReader.attributes().value("itEndPattern").toString();
3740

3841
QXmlStreamReader::TokenType type;
3942
while ((type = xmlReader.readNext()) != QXmlStreamReader::EndElement ||
@@ -67,7 +70,9 @@ static CppcheckLibraryData::Container loadContainer(QXmlStreamReader &xmlReader)
6770
container.accessFunctions.append(function);
6871
else
6972
container.otherFunctions.append(function);
70-
};
73+
}
74+
} else {
75+
throw std::runtime_error("Unhandled element " + elementName.toStdString());
7176
}
7277
}
7378
return container;
@@ -87,8 +92,11 @@ static CppcheckLibraryData::Function::Arg loadFunctionArg(QXmlStreamReader &xmlR
8792
QString argnr = xmlReader.attributes().value("nr").toString();
8893
if (argnr == "any")
8994
arg.nr = CppcheckLibraryData::Function::Arg::ANY;
95+
else if (argnr == "variadic")
96+
arg.nr = CppcheckLibraryData::Function::Arg::VARIADIC;
9097
else
9198
arg.nr = argnr.toUInt();
99+
arg.defaultValue = xmlReader.attributes().value("default").toString();
92100

93101
QXmlStreamReader::TokenType type;
94102
while ((type = xmlReader.readNext()) != QXmlStreamReader::EndElement ||
@@ -114,6 +122,11 @@ static CppcheckLibraryData::Function::Arg loadFunctionArg(QXmlStreamReader &xmlR
114122
minsize.arg = xmlReader.attributes().value("arg").toString();
115123
minsize.arg2 = xmlReader.attributes().value("arg2").toString();
116124
arg.minsizes.append(minsize);
125+
} else if (elementName == "iterator") {
126+
arg.iterator.container = xmlReader.attributes().value("container").toInt();
127+
arg.iterator.type = xmlReader.attributes().value("type").toString();
128+
} else {
129+
throw std::runtime_error("Unhandled element " + elementName.toStdString());
117130
}
118131
}
119132
return arg;
@@ -140,16 +153,24 @@ static CppcheckLibraryData::Function loadFunction(QXmlStreamReader &xmlReader, c
140153
function.leakignore = true;
141154
else if (elementName == "use-retval")
142155
function.useretval = true;
143-
else if (elementName == "formatstr") {
156+
else if (elementName == "returnValue") {
157+
const QString container = xmlReader.attributes().value("container").toString();
158+
function.returnValue.container = container.isNull() ? -1 : container.toInt();
159+
function.returnValue.type = xmlReader.attributes().value("type").toString();
160+
function.returnValue.value = xmlReader.readElementText();
161+
} else if (elementName == "formatstr") {
144162
function.formatstr.scan = xmlReader.attributes().value("scan").toString();
145163
function.formatstr.secure = xmlReader.attributes().value("secure").toString();
146164
} else if (elementName == "arg")
147165
function.args.append(loadFunctionArg(xmlReader));
148166
else if (elementName == "warn") {
149167
function.warn.severity = xmlReader.attributes().value("severity").toString();
168+
function.warn.cstd = xmlReader.attributes().value("cstd").toString();
150169
function.warn.reason = xmlReader.attributes().value("reason").toString();
151170
function.warn.alternatives = xmlReader.attributes().value("alternatives").toString();
152171
function.warn.msg = xmlReader.readElementText();
172+
} else {
173+
throw std::runtime_error("Unhandled element " + elementName.toStdString());
153174
}
154175
}
155176
return function;
@@ -174,6 +195,8 @@ static CppcheckLibraryData::MemoryResource loadMemoryResource(QXmlStreamReader &
174195
memoryresource.dealloc.append(xmlReader.readElementText());
175196
else if (elementName == "use")
176197
memoryresource.use.append(xmlReader.readElementText());
198+
else
199+
throw std::runtime_error("Unhandled element " + elementName.toStdString());
177200
}
178201
return memoryresource;
179202
}
@@ -201,16 +224,26 @@ bool CppcheckLibraryData::open(QIODevice &file)
201224
comments += xmlReader.text().toString();
202225
break;
203226
case QXmlStreamReader::StartElement:
204-
if (xmlReader.name() == "container")
205-
containers.append(loadContainer(xmlReader));
206-
if (xmlReader.name() == "define")
207-
defines.append(loadDefine(xmlReader));
208-
else if (xmlReader.name() == "function")
209-
functions.append(loadFunction(xmlReader, comments));
210-
else if (xmlReader.name() == "memory" || xmlReader.name() == "resource")
211-
memoryresource.append(loadMemoryResource(xmlReader));
212-
else if (xmlReader.name() == "podtype")
213-
podtypes.append(loadPodType(xmlReader));
227+
try {
228+
const QString elementName(xmlReader.name().toString());
229+
if (elementName == "def")
230+
;
231+
else if (elementName == "container")
232+
containers.append(loadContainer(xmlReader));
233+
else if (elementName == "define")
234+
defines.append(loadDefine(xmlReader));
235+
else if (elementName == "function")
236+
functions.append(loadFunction(xmlReader, comments));
237+
else if (elementName == "memory" || elementName == "resource")
238+
memoryresource.append(loadMemoryResource(xmlReader));
239+
else if (elementName == "podtype")
240+
podtypes.append(loadPodType(xmlReader));
241+
else
242+
return false;
243+
} catch (std::runtime_error &e) {
244+
const QString what(e.what());
245+
return false;
246+
}
214247
comments.clear();
215248
break;
216249
default:
@@ -223,10 +256,10 @@ bool CppcheckLibraryData::open(QIODevice &file)
223256

224257
static void writeContainerFunctions(QXmlStreamWriter &xmlWriter, const QString name, int extra, const QList<struct CppcheckLibraryData::Container::Function> &functions)
225258
{
226-
if (functions.isEmpty() && extra <= 0)
259+
if (functions.isEmpty() && extra < 0)
227260
return;
228261
xmlWriter.writeStartElement(name);
229-
if (extra > 0) {
262+
if (extra >= 0) {
230263
if (name == "access")
231264
xmlWriter.writeAttribute("indexOperator", "array-like");
232265
else if (name == "size")
@@ -254,6 +287,11 @@ static void writeContainer(QXmlStreamWriter &xmlWriter, const CppcheckLibraryDat
254287
xmlWriter.writeAttribute("endPattern", container.endPattern);
255288
if (!container.inherits.isEmpty())
256289
xmlWriter.writeAttribute("inherits", container.inherits);
290+
if (!container.opLessAllowed.isEmpty())
291+
xmlWriter.writeAttribute("opLessAllowed", container.opLessAllowed);
292+
if (!container.itEndPattern.isEmpty())
293+
xmlWriter.writeAttribute("itEndPattern", container.itEndPattern);
294+
257295
if (!container.type.templateParameter.isEmpty() || !container.type.string.isEmpty()) {
258296
xmlWriter.writeStartElement("type");
259297
if (!container.type.templateParameter.isEmpty())
@@ -263,8 +301,8 @@ static void writeContainer(QXmlStreamWriter &xmlWriter, const CppcheckLibraryDat
263301
xmlWriter.writeEndElement();
264302
}
265303
writeContainerFunctions(xmlWriter, "size", container.size_templateParameter, container.sizeFunctions);
266-
writeContainerFunctions(xmlWriter, "access", container.access_arrayLike, container.accessFunctions);
267-
writeContainerFunctions(xmlWriter, "other", 0, container.otherFunctions);
304+
writeContainerFunctions(xmlWriter, "access", container.access_arrayLike?1:-1, container.accessFunctions);
305+
writeContainerFunctions(xmlWriter, "other", -1, container.otherFunctions);
268306
xmlWriter.writeEndElement();
269307
}
270308

@@ -291,6 +329,16 @@ static void writeFunction(QXmlStreamWriter &xmlWriter, const CppcheckLibraryData
291329
xmlWriter.writeEmptyElement("pure");
292330
if (function.noreturn != CppcheckLibraryData::Function::Unknown)
293331
xmlWriter.writeTextElement("noreturn", (function.noreturn == CppcheckLibraryData::Function::True) ? "true" : "false");
332+
if (!function.returnValue.empty()) {
333+
xmlWriter.writeStartElement("returnValue");
334+
if (!function.returnValue.type.isNull())
335+
xmlWriter.writeAttribute("type", function.returnValue.type);
336+
if (function.returnValue.container >= 0)
337+
xmlWriter.writeAttribute("container", QString::number(function.returnValue.container));
338+
if (!function.returnValue.value.isNull())
339+
xmlWriter.writeCharacters(function.returnValue.value);
340+
xmlWriter.writeEndElement();
341+
}
294342
if (function.leakignore)
295343
xmlWriter.writeEmptyElement("leak-ignore");
296344
// Argument info..
@@ -307,8 +355,12 @@ static void writeFunction(QXmlStreamWriter &xmlWriter, const CppcheckLibraryData
307355
xmlWriter.writeStartElement("arg");
308356
if (arg.nr == CppcheckLibraryData::Function::Arg::ANY)
309357
xmlWriter.writeAttribute("nr", "any");
358+
else if (arg.nr == CppcheckLibraryData::Function::Arg::VARIADIC)
359+
xmlWriter.writeAttribute("nr", "variadic");
310360
else
311361
xmlWriter.writeAttribute("nr", QString::number(arg.nr));
362+
if (!arg.defaultValue.isNull())
363+
xmlWriter.writeAttribute("default", arg.defaultValue);
312364
if (arg.formatstr)
313365
xmlWriter.writeEmptyElement("formatstr");
314366
if (arg.notnull)
@@ -332,6 +384,15 @@ static void writeFunction(QXmlStreamWriter &xmlWriter, const CppcheckLibraryData
332384
xmlWriter.writeEndElement();
333385
}
334386

387+
if (arg.iterator.container >= 0 || !arg.iterator.type.isNull()) {
388+
xmlWriter.writeStartElement("iterator");
389+
if (arg.iterator.container >= 0)
390+
xmlWriter.writeAttribute("container", QString::number(arg.iterator.container));
391+
if (!arg.iterator.type.isNull())
392+
xmlWriter.writeAttribute("type", arg.iterator.type);
393+
xmlWriter.writeEndElement();
394+
}
395+
335396
xmlWriter.writeEndElement();
336397
}
337398

@@ -341,12 +402,15 @@ static void writeFunction(QXmlStreamWriter &xmlWriter, const CppcheckLibraryData
341402
if (!function.warn.severity.isEmpty())
342403
xmlWriter.writeAttribute("severity", function.warn.severity);
343404

344-
if (!function.warn.reason.isEmpty())
345-
xmlWriter.writeAttribute("reason", function.warn.reason);
405+
if (!function.warn.cstd.isEmpty())
406+
xmlWriter.writeAttribute("cstd", function.warn.cstd);
346407

347408
if (!function.warn.alternatives.isEmpty())
348409
xmlWriter.writeAttribute("alternatives", function.warn.alternatives);
349410

411+
if (!function.warn.reason.isEmpty())
412+
xmlWriter.writeAttribute("reason", function.warn.reason);
413+
350414
if (!function.warn.msg.isEmpty())
351415
xmlWriter.writeCharacters(function.warn.msg);
352416

gui/cppchecklibrarydata.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ class CppcheckLibraryData {
3535
QString inherits;
3636
QString startPattern;
3737
QString endPattern;
38+
QString opLessAllowed;
39+
QString itEndPattern;
3840

3941
bool access_arrayLike;
4042
int size_templateParameter;
@@ -71,6 +73,15 @@ class CppcheckLibraryData {
7173
bool gccConst;
7274
bool leakignore;
7375
bool useretval;
76+
struct ReturnValue {
77+
ReturnValue() : container(-1) {}
78+
QString type;
79+
QString value;
80+
int container;
81+
bool empty() const {
82+
return type.isNull() && value.isNull() && container < 0;
83+
}
84+
} returnValue;
7485
struct {
7586
QString scan;
7687
QString secure;
@@ -83,6 +94,8 @@ class CppcheckLibraryData {
8394
QString name;
8495
unsigned int nr;
8596
static const unsigned int ANY;
97+
static const unsigned int VARIADIC;
98+
QString defaultValue;
8699
bool notbool;
87100
bool notnull;
88101
bool notuninit;
@@ -95,17 +108,24 @@ class CppcheckLibraryData {
95108
QString arg2;
96109
};
97110
QList<struct MinSize> minsizes;
111+
struct Iterator {
112+
Iterator() : container(-1) {}
113+
int container;
114+
QString type;
115+
} iterator;
98116
};
99117
QList<struct Arg> args;
100118

101119
struct {
102120
QString severity;
121+
QString cstd;
103122
QString reason;
104123
QString alternatives;
105124
QString msg;
106125

107126
bool isEmpty() const {
108-
return severity.isEmpty() &&
127+
return cstd.isEmpty() &&
128+
severity.isEmpty() &&
109129
reason.isEmpty() &&
110130
alternatives.isEmpty() &&
111131
msg.isEmpty();

0 commit comments

Comments
 (0)