Skip to content

Commit ff0f4ce

Browse files
committed
GUI: Add handling of containers to CppcheckLibraryData
1 parent 0d7d1e8 commit ff0f4ce

3 files changed

Lines changed: 170 additions & 46 deletions

File tree

cfg/std.cfg

Lines changed: 42 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2321,9 +2321,9 @@
23212321
<minsize type="argvalue" arg="3"/>
23222322
</arg>
23232323
<arg nr="3">
2324+
<not-uninit/>
23242325
<not-bool/>
23252326
<valid>0:</valid>
2326-
<not-uninit/>
23272327
</arg>
23282328
</function>
23292329
<!-- wchar_t * wmemcpy(wchar_t *ct, const wchar_t *cs, size_t n);-->
@@ -2340,9 +2340,9 @@
23402340
<minsize type="argvalue" arg="3"/>
23412341
</arg>
23422342
<arg nr="3">
2343+
<not-uninit/>
23432344
<not-bool/>
23442345
<valid>0:</valid>
2345-
<not-uninit/>
23462346
</arg>
23472347
</function>
23482348
<!-- void * memmove(void *ct, const void *cs, size_t n); -->
@@ -2359,9 +2359,9 @@
23592359
<minsize type="argvalue" arg="3"/>
23602360
</arg>
23612361
<arg nr="3">
2362+
<not-uninit/>
23622363
<not-bool/>
23632364
<valid>0:</valid>
2364-
<not-uninit/>
23652365
</arg>
23662366
</function>
23672367
<!-- wchar_t * wmemmove(wchar_t *ct, const wchar_t *cs, size_t n); -->
@@ -2378,9 +2378,9 @@
23782378
<minsize type="argvalue" arg="3"/>
23792379
</arg>
23802380
<arg nr="3">
2381+
<not-uninit/>
23812382
<not-bool/>
23822383
<valid>0:</valid>
2383-
<not-uninit/>
23842384
</arg>
23852385
</function>
23862386
<!-- void *memset(void *s, int c, size_t n); -->
@@ -2395,9 +2395,9 @@
23952395
<not-uninit/>
23962396
</arg>
23972397
<arg nr="3">
2398+
<not-uninit/>
23982399
<not-bool/>
23992400
<valid>0:</valid>
2400-
<not-uninit/>
24012401
</arg>
24022402
</function>
24032403
<!-- wchar_t *wmemset(wchar_t *s, wchar_t c, size_t n); -->
@@ -2412,9 +2412,9 @@
24122412
<not-uninit/>
24132413
</arg>
24142414
<arg nr="3">
2415+
<not-uninit/>
24152416
<not-bool/>
24162417
<valid>0:</valid>
2417-
<not-uninit/>
24182418
</arg>
24192419
</function>
24202420
<!-- time_t mktime(struct tm *tp); -->
@@ -2754,40 +2754,40 @@
27542754
<leak-ignore/>
27552755
<formatstr scan="true"/>
27562756
<arg nr="1">
2757-
<not-uninit/>
27582757
<formatstr/>
27592758
<not-null/>
2759+
<not-uninit/>
27602760
</arg>
27612761
</function>
27622762
<!-- int vsscanf(const char *s, const char *format, va_list arg); -->
27632763
<function name="vsscanf,std::vsscanf">
27642764
<noreturn>false</noreturn>
27652765
<leak-ignore/>
2766-
<formatstr scan="true"/>
27672766
<arg nr="1">
2768-
<not-uninit/>
27692767
<not-null/>
2768+
<not-uninit/>
27702769
</arg>
2770+
<formatstr scan="true"/>
27712771
<arg nr="2">
2772-
<not-uninit/>
27732772
<formatstr/>
27742773
<not-null/>
2774+
<not-uninit/>
27752775
</arg>
27762776
<arg nr="3"/>
27772777
</function>
27782778
<!-- int vswscanf(const wchar_t *s, const wchar_t *format, va_list arg); -->
27792779
<function name="vswscanf,std::vswscanf">
27802780
<noreturn>false</noreturn>
27812781
<leak-ignore/>
2782-
<formatstr scan="true"/>
27832782
<arg nr="1">
2784-
<not-uninit/>
27852783
<not-null/>
2784+
<not-uninit/>
27862785
</arg>
2786+
<formatstr scan="true"/>
27872787
<arg nr="2">
2788-
<not-uninit/>
27892788
<formatstr/>
27902789
<not-null/>
2790+
<not-uninit/>
27912791
</arg>
27922792
<arg nr="3"/>
27932793
</function>
@@ -2797,9 +2797,9 @@
27972797
<leak-ignore/>
27982798
<formatstr scan="true"/>
27992799
<arg nr="1">
2800-
<not-uninit/>
28012800
<formatstr/>
28022801
<not-null/>
2802+
<not-uninit/>
28032803
</arg>
28042804
<arg nr="2"/>
28052805
</function>
@@ -2850,16 +2850,6 @@
28502850
<leak-ignore/>
28512851
<arg nr="1"/>
28522852
</function>
2853-
<memory>
2854-
<dealloc>free</dealloc>
2855-
<alloc init="false">malloc</alloc>
2856-
<alloc init="true">calloc</alloc>
2857-
</memory>
2858-
<resource>
2859-
<dealloc>fclose</dealloc>
2860-
<alloc init="true">fopen</alloc>
2861-
<alloc init="true">tmpfile</alloc>
2862-
</resource>
28632853
<!-- char * strcat(char *deststr, const char *srcstr); -->
28642854
<function name="strcat,std::strcat">
28652855
<noreturn>false</noreturn>
@@ -3392,9 +3382,8 @@
33923382
</function>
33933383
<!-- char *strtok(char *s, const char *ct); -->
33943384
<function name="strtok">
3395-
<!-- strtok may modify the first argument, so using the return value is not mandatory -->
3396-
<noreturn>false</noreturn>
33973385
<pure/>
3386+
<noreturn>false</noreturn>
33983387
<leak-ignore/>
33993388
<arg nr="1">
34003389
<not-uninit/>
@@ -3591,13 +3580,13 @@
35913580
<function name="sprintf">
35923581
<noreturn>false</noreturn>
35933582
<leak-ignore/>
3594-
<formatstr/>
35953583
<arg nr="1">
35963584
<minsize type="strlen" arg="2"/>
35973585
</arg>
3586+
<formatstr/>
35983587
<arg nr="2">
3599-
<not-null/>
36003588
<formatstr/>
3589+
<not-null/>
36013590
</arg>
36023591
</function>
36033592
<!-- int swprintf(wchar_t *s, size_t n, const wchar_t *format, ...); -->
@@ -3783,17 +3772,39 @@
37833772
</function>
37843773
<!-- struct tmx *zonetime(const time_t *tp, int zone); -->
37853774
<function name="zonetime">
3775+
<use-retval/>
37863776
<noreturn>false</noreturn>
37873777
<leak-ignore/>
3788-
<use-retval/>
37893778
<arg nr="1">
3790-
<not-uninit/>
37913779
<not-null/>
3780+
<not-uninit/>
37923781
</arg>
37933782
<arg nr="2">
37943783
<not-uninit/>
37953784
</arg>
37963785
</function>
3786+
<!--Not part of standard, but widely supported by runtime libraries-->
3787+
<function name="itoa">
3788+
<noreturn>false</noreturn>
3789+
<leak-ignore/>
3790+
<arg nr="1">
3791+
<not-uninit/>
3792+
</arg>
3793+
<arg nr="2">
3794+
<not-null/>
3795+
</arg>
3796+
<arg nr="3"/>
3797+
</function>
3798+
<memory>
3799+
<alloc>malloc</alloc>
3800+
<alloc init="true">calloc</alloc>
3801+
<dealloc>free</dealloc>
3802+
</memory>
3803+
<resource>
3804+
<alloc init="true">fopen</alloc>
3805+
<alloc init="true">tmpfile</alloc>
3806+
<dealloc>fclose</dealloc>
3807+
</resource>
37973808
<container id="stdContainer" endPattern="&gt; !!::">
37983809
<type templateParameter="0"/>
37993810
<size>
@@ -3867,8 +3878,7 @@
38673878
<container id="stdBasicString" startPattern="std :: basic_string &lt;" inherits="stdAllString">
38683879
<type templateParameter="0"/>
38693880
</container>
3870-
<container id="stdString" startPattern="std :: string|wstring|u16string|u32string" endPattern="" inherits="stdAllString">
3871-
</container>
3881+
<container id="stdString" startPattern="std :: string|wstring|u16string|u32string" inherits="stdAllString"/>
38723882
<podtype name="int8_t" sign="s" size="1"/>
38733883
<podtype name="int16_t" sign="s" size="2"/>
38743884
<podtype name="int32_t" sign="s" size="4"/>
@@ -3919,16 +3929,4 @@
39193929
<podtype name="mbstate_t"/>
39203930
<podtype name="wint_t"/>
39213931
<podtype name="jmp_buf"/>
3922-
<!--Not part of standard, but widely supported by runtime libraries-->
3923-
<function name="itoa">
3924-
<noreturn>false</noreturn>
3925-
<leak-ignore/>
3926-
<arg nr="1">
3927-
<not-uninit/>
3928-
</arg>
3929-
<arg nr="2">
3930-
<not-null/>
3931-
</arg>
3932-
<arg nr="3"/>
3933-
</function>
39343932
</def>

gui/cppchecklibrarydata.cpp

Lines changed: 101 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,52 @@ CppcheckLibraryData::CppcheckLibraryData()
2727
{
2828
}
2929

30+
static CppcheckLibraryData::Container loadContainer(QXmlStreamReader &xmlReader)
31+
{
32+
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();
37+
38+
QXmlStreamReader::TokenType type;
39+
while ((type = xmlReader.readNext()) != QXmlStreamReader::EndElement ||
40+
xmlReader.name().toString() != "container") {
41+
if (type != QXmlStreamReader::StartElement)
42+
continue;
43+
const QString elementName = xmlReader.name().toString();
44+
if (elementName == "type") {
45+
container.type.templateParameter = xmlReader.attributes().value("templateParameter").toString();
46+
container.type.string = xmlReader.attributes().value("string").toString();
47+
} else if (elementName == "size" || elementName == "access" || elementName == "other") {
48+
const QString indexOperator = xmlReader.attributes().value("indexOperator").toString();
49+
if (elementName == "access" && indexOperator == "array-like")
50+
container.access_arrayLike = true;
51+
const QString templateParameter = xmlReader.attributes().value("templateParameter").toString();
52+
if (elementName == "size" && !templateParameter.isEmpty())
53+
container.size_templateParameter = templateParameter.toInt();
54+
for (;;) {
55+
type = xmlReader.readNext();
56+
if (xmlReader.name().toString() == elementName)
57+
break;
58+
if (type != QXmlStreamReader::StartElement)
59+
continue;
60+
struct CppcheckLibraryData::Container::Function function;
61+
function.name = xmlReader.attributes().value("name").toString();
62+
function.action = xmlReader.attributes().value("action").toString();
63+
function.yields = xmlReader.attributes().value("yields").toString();
64+
if (elementName == "size")
65+
container.sizeFunctions.append(function);
66+
else if (elementName == "access")
67+
container.accessFunctions.append(function);
68+
else
69+
container.otherFunctions.append(function);
70+
};
71+
}
72+
}
73+
return container;
74+
}
75+
3076
static CppcheckLibraryData::Define loadDefine(const QXmlStreamReader &xmlReader)
3177
{
3278
CppcheckLibraryData::Define define;
@@ -148,6 +194,8 @@ bool CppcheckLibraryData::open(QIODevice &file)
148194
comments.append(xmlReader.text().toString());
149195
break;
150196
case QXmlStreamReader::StartElement:
197+
if (xmlReader.name() == "container")
198+
containers.append(loadContainer(xmlReader));
151199
if (xmlReader.name() == "define")
152200
defines.append(loadDefine(xmlReader));
153201
else if (xmlReader.name() == "function")
@@ -166,6 +214,53 @@ bool CppcheckLibraryData::open(QIODevice &file)
166214
return true;
167215
}
168216

217+
static void writeContainerFunctions(QXmlStreamWriter &xmlWriter, const QString name, int extra, const QList<struct CppcheckLibraryData::Container::Function> &functions)
218+
{
219+
if (functions.isEmpty() && extra <= 0)
220+
return;
221+
xmlWriter.writeStartElement(name);
222+
if (extra > 0) {
223+
if (name == "access")
224+
xmlWriter.writeAttribute("indexOperator", "array-like");
225+
else if (name == "size")
226+
xmlWriter.writeAttribute("templateParameter", QString::number(extra));
227+
}
228+
foreach(const CppcheckLibraryData::Container::Function &function, functions) {
229+
xmlWriter.writeStartElement("function");
230+
xmlWriter.writeAttribute("name", function.name);
231+
if (!function.action.isEmpty())
232+
xmlWriter.writeAttribute("action", function.action);
233+
if (!function.yields.isEmpty())
234+
xmlWriter.writeAttribute("yields", function.yields);
235+
xmlWriter.writeEndElement();
236+
}
237+
xmlWriter.writeEndElement();
238+
}
239+
240+
static void writeContainer(QXmlStreamWriter &xmlWriter, const CppcheckLibraryData::Container &container)
241+
{
242+
xmlWriter.writeStartElement("container");
243+
xmlWriter.writeAttribute("id", container.id);
244+
if (!container.startPattern.isEmpty())
245+
xmlWriter.writeAttribute("startPattern", container.startPattern);
246+
if (!container.endPattern.isEmpty())
247+
xmlWriter.writeAttribute("endPattern", container.endPattern);
248+
if (!container.inherits.isEmpty())
249+
xmlWriter.writeAttribute("inherits", container.inherits);
250+
if (!container.type.templateParameter.isEmpty() || !container.type.string.isEmpty()) {
251+
xmlWriter.writeStartElement("type");
252+
if (!container.type.templateParameter.isEmpty())
253+
xmlWriter.writeAttribute("templateParameter", container.type.templateParameter);
254+
if (!container.type.string.isEmpty())
255+
xmlWriter.writeAttribute("string", container.type.string);
256+
xmlWriter.writeEndElement();
257+
}
258+
writeContainerFunctions(xmlWriter, "size", container.size_templateParameter, container.sizeFunctions);
259+
writeContainerFunctions(xmlWriter, "access", container.access_arrayLike, container.accessFunctions);
260+
writeContainerFunctions(xmlWriter, "other", 0, container.otherFunctions);
261+
xmlWriter.writeEndElement();
262+
}
263+
169264
static void writeFunction(QXmlStreamWriter &xmlWriter, const CppcheckLibraryData::Function &function)
170265
{
171266
foreach(const QString &comment, function.comments) {
@@ -273,13 +368,17 @@ QString CppcheckLibraryData::toString() const
273368
writeMemoryResource(xmlWriter, mr);
274369
}
275370

371+
foreach(const Container &container, containers) {
372+
writeContainer(xmlWriter, container);
373+
}
374+
276375
foreach(const PodType &podtype, podtypes) {
277376
xmlWriter.writeStartElement("podtype");
278377
xmlWriter.writeAttribute("name", podtype.name);
279-
if (!podtype.size.isEmpty())
280-
xmlWriter.writeAttribute("size", podtype.size);
281378
if (!podtype.sign.isEmpty())
282379
xmlWriter.writeAttribute("sign", podtype.sign);
380+
if (!podtype.size.isEmpty())
381+
xmlWriter.writeAttribute("size", podtype.size);
283382
xmlWriter.writeEndElement();
284383
}
285384

0 commit comments

Comments
 (0)