2222#include < QXmlStreamWriter>
2323
2424const unsigned int CppcheckLibraryData::Function::Arg::ANY = ~0U ;
25+ const unsigned int CppcheckLibraryData::Function::Arg::VARIADIC = ~1U ;
2526
2627CppcheckLibraryData::CppcheckLibraryData ()
2728{
@@ -30,10 +31,12 @@ CppcheckLibraryData::CppcheckLibraryData()
3031static 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
224257static 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
0 commit comments