cppcheck-py 2.15.0__py3-none-win_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. cppcheck/__init__.py +55 -0
  2. cppcheck/cppcheck-2.15.0.tar.gz +0 -0
  3. cppcheck/data/addons/__init__.py +0 -0
  4. cppcheck/data/addons/cppcheck.py +39 -0
  5. cppcheck/data/addons/cppcheckdata.py +1715 -0
  6. cppcheck/data/addons/findcasts.py +32 -0
  7. cppcheck/data/addons/misc.py +163 -0
  8. cppcheck/data/addons/misra.py +4998 -0
  9. cppcheck/data/addons/misra_9.py +561 -0
  10. cppcheck/data/addons/naming.py +91 -0
  11. cppcheck/data/addons/namingng.py +420 -0
  12. cppcheck/data/addons/runaddon.py +12 -0
  13. cppcheck/data/addons/threadsafety.py +350 -0
  14. cppcheck/data/addons/y2038.py +241 -0
  15. cppcheck/data/cfg/avr.cfg +402 -0
  16. cppcheck/data/cfg/bento4.cfg +142 -0
  17. cppcheck/data/cfg/boost.cfg +1284 -0
  18. cppcheck/data/cfg/bsd.cfg +567 -0
  19. cppcheck/data/cfg/cairo.cfg +89 -0
  20. cppcheck/data/cfg/cppcheck-lib.cfg +72 -0
  21. cppcheck/data/cfg/cppunit.cfg +48 -0
  22. cppcheck/data/cfg/dpdk.cfg +11 -0
  23. cppcheck/data/cfg/embedded_sql.cfg +4 -0
  24. cppcheck/data/cfg/emscripten.cfg +108 -0
  25. cppcheck/data/cfg/ginac.cfg +12848 -0
  26. cppcheck/data/cfg/gnu.cfg +1698 -0
  27. cppcheck/data/cfg/googletest.cfg +60 -0
  28. cppcheck/data/cfg/gtk.cfg +21364 -0
  29. cppcheck/data/cfg/icu.cfg +221 -0
  30. cppcheck/data/cfg/kde.cfg +87 -0
  31. cppcheck/data/cfg/libcerror.cfg +203 -0
  32. cppcheck/data/cfg/libcurl.cfg +487 -0
  33. cppcheck/data/cfg/libsigc++.cfg +36 -0
  34. cppcheck/data/cfg/lua.cfg +316 -0
  35. cppcheck/data/cfg/mfc.cfg +271 -0
  36. cppcheck/data/cfg/microsoft_atl.cfg +40 -0
  37. cppcheck/data/cfg/microsoft_sal.cfg +490 -0
  38. cppcheck/data/cfg/microsoft_unittest.cfg +20 -0
  39. cppcheck/data/cfg/motif.cfg +318 -0
  40. cppcheck/data/cfg/nspr.cfg +38 -0
  41. cppcheck/data/cfg/ntl.cfg +6907 -0
  42. cppcheck/data/cfg/opencv2.cfg +132 -0
  43. cppcheck/data/cfg/opengl.cfg +581 -0
  44. cppcheck/data/cfg/openmp.cfg +157 -0
  45. cppcheck/data/cfg/openssl.cfg +174 -0
  46. cppcheck/data/cfg/pcre.cfg +165 -0
  47. cppcheck/data/cfg/posix.cfg +6438 -0
  48. cppcheck/data/cfg/protobuf.cfg +9 -0
  49. cppcheck/data/cfg/python.cfg +674 -0
  50. cppcheck/data/cfg/qt.cfg +5457 -0
  51. cppcheck/data/cfg/ruby.cfg +142 -0
  52. cppcheck/data/cfg/sdl.cfg +354 -0
  53. cppcheck/data/cfg/selinux.cfg +3621 -0
  54. cppcheck/data/cfg/sfml.cfg +301 -0
  55. cppcheck/data/cfg/sqlite3.cfg +1572 -0
  56. cppcheck/data/cfg/std.cfg +9139 -0
  57. cppcheck/data/cfg/tinyxml2.cfg +37 -0
  58. cppcheck/data/cfg/vcl.cfg +4 -0
  59. cppcheck/data/cfg/windows.cfg +17181 -0
  60. cppcheck/data/cfg/wxsqlite3.cfg +1955 -0
  61. cppcheck/data/cfg/wxsvg.cfg +16905 -0
  62. cppcheck/data/cfg/wxwidgets.cfg +17229 -0
  63. cppcheck/data/cfg/zephyr.cfg +113 -0
  64. cppcheck/data/cfg/zlib.cfg +1450 -0
  65. cppcheck/data/cppcheck-htmlreport +992 -0
  66. cppcheck/data/cppcheck.exe +0 -0
  67. cppcheck/data/platforms/aix_ppc64.xml +18 -0
  68. cppcheck/data/platforms/arm32-wchar_t2.xml +18 -0
  69. cppcheck/data/platforms/arm32-wchar_t4.xml +18 -0
  70. cppcheck/data/platforms/arm64-wchar_t2.xml +18 -0
  71. cppcheck/data/platforms/arm64-wchar_t4.xml +18 -0
  72. cppcheck/data/platforms/avr8.xml +18 -0
  73. cppcheck/data/platforms/cray_sv1.xml +18 -0
  74. cppcheck/data/platforms/elbrus-e1cp.xml +18 -0
  75. cppcheck/data/platforms/mips32.xml +18 -0
  76. cppcheck/data/platforms/msp430_eabi_large_datamodel.xml +18 -0
  77. cppcheck/data/platforms/pic16.xml +18 -0
  78. cppcheck/data/platforms/pic8-enhanced.xml +18 -0
  79. cppcheck/data/platforms/pic8.xml +18 -0
  80. cppcheck/data/platforms/unix32-unsigned.xml +18 -0
  81. cppcheck/data/platforms/unix64-unsigned.xml +18 -0
  82. cppcheck_py-2.15.0.dist-info/METADATA +76 -0
  83. cppcheck_py-2.15.0.dist-info/RECORD +86 -0
  84. cppcheck_py-2.15.0.dist-info/WHEEL +5 -0
  85. cppcheck_py-2.15.0.dist-info/entry_points.txt +4 -0
  86. cppcheck_py-2.15.0.dist-info/licenses/LICENSE.md +191 -0
@@ -0,0 +1,561 @@
1
+ # Holds information about an array, struct or union's element definition.
2
+ class ElementDef:
3
+ def __init__(self, elementType, name, valueType, dimensions = None):
4
+ self.elementType = elementType # 'array', 'record' or 'value'
5
+ self.name = str(name)
6
+ self.valueType = valueType
7
+ self.children = []
8
+ self.dimensions = dimensions
9
+ self.parent = None
10
+
11
+ self.isDesignated = False
12
+ self.isPositional = False
13
+ self.numInits = 0
14
+ self.childIndex = -1
15
+
16
+ self.flexibleToken = None
17
+ self.isFlexible = False
18
+ self.structureViolationToken = None
19
+
20
+ def __repr__(self):
21
+ inits = ""
22
+ if self.isPositional:
23
+ inits += 'P'
24
+ if self.isDesignated:
25
+ inits += 'D'
26
+ if not (self.isPositional or self.isDesignated) and self.numInits == 0:
27
+ inits += '_'
28
+ if self.numInits > 1:
29
+ inits += str(self.numInits)
30
+
31
+ attrs = ["childIndex", "elementType", "valueType"]
32
+ return "{}({}, {}, {})".format(
33
+ "ElementDef",
34
+ self.getLongName(),
35
+ inits,
36
+ ", ".join(("{}={}".format(a, repr(getattr(self, a))) for a in attrs))
37
+ )
38
+
39
+ @property
40
+ def isArray(self):
41
+ return self.elementType == 'array'
42
+
43
+ @property
44
+ def isRecord(self):
45
+ return self.elementType == 'record'
46
+
47
+ @property
48
+ def isValue(self):
49
+ return self.elementType == 'value'
50
+
51
+
52
+ def getLongName(self):
53
+ return self.parent.getLongName() + "." + self.name if self.parent else self.name
54
+
55
+ def getInitDump(self):
56
+ t = []
57
+ if self.isPositional:
58
+ t.append('P')
59
+ if self.isDesignated:
60
+ t.append('D')
61
+ if self.numInits == 0:
62
+ t.append('_')
63
+ if self.numInits > 1:
64
+ t.append(str(self.numInits))
65
+
66
+ myDump = "".join(t)
67
+
68
+ if len(self.children):
69
+ childDumps = []
70
+ for c in self.children:
71
+ childDumps.append(c.getInitDump())
72
+ if self.structureViolationToken is not None:
73
+ myDump += "!"
74
+ myDump += "{ " + ", ".join(childDumps) + " }"
75
+
76
+ return myDump
77
+
78
+ def addChild(self, child):
79
+ self.children.append(child)
80
+ child.parent = self
81
+
82
+ def getNextChild(self):
83
+ self.childIndex += 1
84
+ return self.getChildByIndex(self.childIndex)
85
+
86
+ def getChildByIndex(self, index):
87
+ if self.isFlexible:
88
+ while len(self.children) <= index:
89
+ createChild(self, self.flexibleToken, len(self.children), None)
90
+ return self.children[index] if 0 <= index < len(self.children) else None
91
+
92
+ def getChildByName(self, name):
93
+ for c in self.children:
94
+ if c.name == name:
95
+ return c
96
+ return None
97
+
98
+ def getNextValueElement(self, root):
99
+ current = self
100
+ while current != root:
101
+ if not current.parent:
102
+ return None
103
+ # Get next index of parent
104
+ i = current.parent.children.index(current) + 1
105
+ # Next index of parent exists
106
+ if i < len(current.parent.children):
107
+ current = current.parent.children[i]
108
+ return current.getFirstValueElement()
109
+
110
+ # Next index of parent doesn't exist. Move up
111
+ current = current.parent
112
+ return None
113
+
114
+ def getFirstValueElement(self):
115
+ current = self
116
+
117
+ # Move to first child as long as children exists
118
+ next_child = current.getChildByIndex(0)
119
+ while next_child:
120
+ current = next_child
121
+ next_child = current.getChildByIndex(0)
122
+ return current
123
+
124
+ def getLastValueElement(self):
125
+ current = self
126
+ # Move to last child as long as children exists
127
+ while len(current.children) > 0:
128
+ current = current.children[-1]
129
+ return current
130
+
131
+ def getChildByValueElement(self, ed):
132
+ potentialChild = ed
133
+ while potentialChild and potentialChild not in self.children:
134
+ potentialChild = potentialChild.parent
135
+
136
+ return self.children[self.children.index(potentialChild)] if potentialChild else None
137
+
138
+ def getEffectiveLevel(self):
139
+ if self.parent and self.parent.elementType == "array":
140
+ return self.parent.getEffectiveLevel() + 1
141
+ else:
142
+ return 0
143
+
144
+ def setInitialized(self, designated=False, positional=False):
145
+ if designated:
146
+ self.isDesignated = True
147
+ if positional or not designated:
148
+ self.isPositional = True
149
+ self.numInits += 1
150
+
151
+ def initializeChildren(self):
152
+ for child in self.children:
153
+ child.setInitialized(positional=True)
154
+ child.initializeChildren()
155
+
156
+ def unset(self):
157
+ self.isDesignated = False
158
+ self.isPositional = False
159
+
160
+ # Unset is always recursive
161
+ for child in self.children:
162
+ child.unset()
163
+
164
+ def markStuctureViolation(self, token):
165
+ if self.name == '->':
166
+ self.children[0].markStuctureViolation(token)
167
+ elif not self.structureViolationToken:
168
+ self.structureViolationToken = token
169
+
170
+ def markAsFlexibleArray(self, token):
171
+ self.flexibleToken = token
172
+ self.isFlexible = True
173
+
174
+ def markAsCurrent(self):
175
+ if self.parent:
176
+ if self.name == '<-':
177
+ self.parent.childIndex = self.parent.children.index(self.children[0])
178
+ else:
179
+ self.parent.childIndex = self.parent.children.index(self)
180
+
181
+ self.parent.markAsCurrent()
182
+
183
+ def isAllChildrenSet(self):
184
+ myself = len(self.children) == 0 and (self.isDesignated or self.isPositional)
185
+ mychildren = len(self.children) > 0 and all([child.isAllChildrenSet() for child in self.children])
186
+ return myself or mychildren
187
+
188
+ def isAllSet(self):
189
+ return all([child.isPositional or child.isDesignated for child in self.children])
190
+
191
+ def isOnlyDesignated(self):
192
+ return all([not child.isPositional for child in self.children])
193
+
194
+ def isMisra92Compliant(self):
195
+ return self.structureViolationToken is None and all([child.isMisra92Compliant() for child in self.children])
196
+
197
+ def isMisra93Compliant(self):
198
+ if self.elementType == 'array':
199
+ result = self.isAllChildrenSet() or \
200
+ ((self.isAllSet() or
201
+ self.isOnlyDesignated()) and
202
+ all([not (child.isDesignated or child.isPositional) or child.isMisra93Compliant() for child in self.children]))
203
+ return result
204
+ elif self.elementType == 'record':
205
+ result = all([child.isMisra93Compliant() for child in self.children])
206
+ return result
207
+ else:
208
+ return True
209
+
210
+ def isMisra94Compliant(self):
211
+ return self.numInits <= 1 and all([child.isMisra94Compliant() for child in self.children])
212
+
213
+ def isMisra95Compliant(self):
214
+ return not self.isFlexible or all([not child.isDesignated for child in self.children])
215
+
216
+ # Parses the initializers and update the ElementDefs status accordingly
217
+ class InitializerParser:
218
+ def __init__(self):
219
+ self.token = None
220
+ self.root = None
221
+ self.ed = None
222
+ self.rootStack = []
223
+
224
+ def parseInitializer(self, root, token):
225
+ self.root = root
226
+ self.token = token
227
+ dummyRoot = ElementDef('array', '->', self.root.valueType)
228
+ dummyRoot.children = [self.root]
229
+
230
+ self.rootStack = []
231
+ self.root = dummyRoot
232
+ self.ed = self.root.getFirstValueElement()
233
+ isFirstElement = False
234
+ isDesignated = False
235
+
236
+ while self.token:
237
+ if self.token.str == ',':
238
+ self.token = self.token.astOperand1
239
+ isFirstElement = False
240
+
241
+ # Designated initializer ( [2]=... or .name=... )
242
+ elif self.token.isAssignmentOp and not self.token.valueType:
243
+ self.popFromStackIfExitElement()
244
+
245
+ self.ed = getElementByDesignator(self.root, self.token.astOperand1)
246
+ if self.ed:
247
+ # Update root
248
+ self.pushToRootStackAndMarkAsDesignated()
249
+ # Make sure ed points to valueElement
250
+ self.ed = self.ed.getFirstValueElement()
251
+
252
+ self.token = self.token.astOperand2
253
+ isFirstElement = False
254
+ isDesignated = True
255
+
256
+ elif self.token.isString and self.ed and self.ed.isArray:
257
+ self.ed.setInitialized(isDesignated)
258
+ if self.token == self.token.astParent.astOperand1 and self.token.astParent.astOperand2:
259
+ self.token = self.token.astParent.astOperand2
260
+ self.ed.markAsCurrent()
261
+ self.ed = self.root.getNextChild()
262
+ else:
263
+ self.unwindAndContinue()
264
+ continue
265
+
266
+ elif self.token.str == '{':
267
+ nextChild = self.root.getNextChild() if self.root is not None else None
268
+
269
+ if nextChild:
270
+ if nextChild.isArray or nextChild.isRecord:
271
+ nextChild.unset()
272
+ nextChild.setInitialized(isDesignated)
273
+ self.ed = nextChild.getFirstValueElement()
274
+ isDesignated = False
275
+ elif nextChild.valueType is None:
276
+ # No type information available - unable to check structure - assume correct initialization
277
+ nextChild.setInitialized(isDesignated)
278
+ self.unwindAndContinue()
279
+ continue
280
+
281
+ elif self.token.astOperand1:
282
+ # Create dummy nextChild to represent excess levels in initializer
283
+ dummyRoot = ElementDef('array', '<-', self.root.valueType)
284
+ dummyRoot.parent = self.root
285
+ dummyRoot.childIndex = 0
286
+ dummyRoot.children = [nextChild]
287
+ nextChild.parent = dummyRoot
288
+
289
+ self.root.markStuctureViolation(self.token)
290
+
291
+ # Fake dummy as nextChild (of current root)
292
+ nextChild = dummyRoot
293
+
294
+ if nextChild and self.token.astOperand1:
295
+ self.root = nextChild
296
+ self.token = self.token.astOperand1
297
+ isFirstElement = True
298
+ else:
299
+ if self.root:
300
+ # {}
301
+ if self.root.name == '<-':
302
+ self.root.parent.markStuctureViolation(self.token)
303
+ else:
304
+ self.root.markStuctureViolation(self.token)
305
+ self.ed = None
306
+ self.unwindAndContinue()
307
+
308
+ else:
309
+ if self.ed and self.ed.isValue:
310
+ if not isDesignated and len(self.rootStack) > 0 and self.rootStack[-1][1] == self.root:
311
+ self.rootStack[-1][0].markStuctureViolation(self.token)
312
+ if isFirstElement and self.token.str == '0' and self.token.next.str == '}':
313
+ # Zero initializer causes recursive initialization
314
+ self.root.initializeChildren()
315
+ elif self.token.isString and self.ed.valueType and self.ed.valueType.pointer > 0:
316
+ if self.ed.valueType.pointer - self.ed.getEffectiveLevel() == 1:
317
+ if self.ed.parent != self.root:
318
+ self.root.markStuctureViolation(self.token)
319
+ self.ed.setInitialized(isDesignated)
320
+ elif self.ed.valueType.pointer == self.ed.getEffectiveLevel():
321
+ if(self.root.name != '->' and self.ed.parent.parent != self.root) or (self.root.name == '->' and self.root.children[0] != self.ed.parent):
322
+ self.root.markStuctureViolation(self.token)
323
+ else:
324
+ self.ed.parent.setInitialized(isDesignated)
325
+ self.ed.parent.initializeChildren()
326
+
327
+ else:
328
+ if self.root is not None and self.ed.parent != self.root:
329
+ # Check if token is correct value type for self.root.children[?]
330
+ child = self.root.getChildByValueElement(self.ed)
331
+ if self.token.valueType:
332
+ if child.elementType != 'record' or self.token.valueType.type != 'record' or child.valueType.typeScope != self.token.valueType.typeScope:
333
+ self.root.markStuctureViolation(self.token)
334
+
335
+ self.ed.setInitialized(isDesignated)
336
+
337
+ # Mark all elements up to root with positional or designated
338
+ # (for complex designators, or missing structure)
339
+ parent = self.ed.parent
340
+ while parent and parent != self.root:
341
+ parent.isDesignated = isDesignated if isDesignated and not parent.isPositional else parent.isDesignated
342
+ parent.isPositional = not isDesignated if not isDesignated and not parent.isDesignated else parent.isPositional
343
+ parent = parent.parent
344
+ isDesignated = False
345
+
346
+ if self.token.isString and self.ed.parent.isArray:
347
+ self.ed = self.ed.parent
348
+ self.unwindAndContinue()
349
+
350
+ def pushToRootStackAndMarkAsDesignated(self):
351
+ new = self.ed.parent
352
+ if new != self.root:
353
+ # Mark all elements up to self.root root as designated
354
+ parent = new
355
+ while parent and parent != self.root:
356
+ parent.isDesignated = True
357
+ parent = parent.parent
358
+ self.rootStack.append((self.root, new))
359
+ new.markAsCurrent()
360
+ new.childIndex = new.children.index(self.ed) - 1
361
+ self.root = new
362
+
363
+ def popFromStackIfExitElement(self):
364
+ if len(self.rootStack) > 0 and self.rootStack[-1][1] == self.root:
365
+ old = self.rootStack.pop()[0]
366
+ old.markAsCurrent()
367
+ self.root = old
368
+
369
+ def unwindAndContinue(self):
370
+ while self.token:
371
+ if self.token.astParent.astOperand1 == self.token and self.token.astParent.astOperand2:
372
+ if self.ed:
373
+ if self.token.astParent.astOperand2.str == "{" and self.ed.isDesignated:
374
+ self.popFromStackIfExitElement()
375
+ else:
376
+ self.ed.markAsCurrent()
377
+ self.ed = self.ed.getNextValueElement(self.root)
378
+
379
+ self.token = self.token.astParent.astOperand2
380
+ break
381
+ else:
382
+ self.token = self.token.astParent
383
+ if self.token.str == '{':
384
+ if self.root:
385
+ self.ed = self.root.getLastValueElement()
386
+ self.ed.markAsCurrent()
387
+
388
+ # Cleanup if root is dummy node representing excess levels in initializer
389
+ if self.root.name == '<-':
390
+ self.root.children[0].parent = self.root.parent
391
+
392
+ self.root = self.root.parent
393
+
394
+ if self.token.astParent is None:
395
+ self.token = None
396
+ break
397
+
398
+ def misra_9_x(self, data, rule, rawTokens = None):
399
+
400
+ parser = InitializerParser()
401
+
402
+ for variable in data.variables:
403
+ if variable.nameToken is None:
404
+ continue
405
+
406
+ nameToken = variable.nameToken
407
+
408
+ # Check if declaration and initialization is
409
+ # split into two separate statements in ast.
410
+ if nameToken.next and nameToken.next.isSplittedVarDeclEq:
411
+ nameToken = nameToken.next.next
412
+
413
+ # Find declarations with initializer assignment
414
+ eq = nameToken
415
+ while not eq.isAssignmentOp and eq.astParent:
416
+ eq = eq.astParent
417
+
418
+ # We are only looking for initializers
419
+ if not eq.isAssignmentOp or eq.astOperand2.isName:
420
+ continue
421
+
422
+ if variable.isArray or variable.isClass:
423
+ ed = getElementDef(nameToken, rawTokens)
424
+ # No need to check non-arrays if valueType is missing,
425
+ # since we can't say anything useful about the structure
426
+ # without it.
427
+ if ed.valueType is None and not variable.isArray:
428
+ continue
429
+ parser.parseInitializer(ed, eq.astOperand2)
430
+ # print(rule, nameToken.str + '=', ed.getInitDump())
431
+ if rule == 902 and not ed.isMisra92Compliant():
432
+ self.reportError(nameToken, 9, 2)
433
+ if rule == 903 and not ed.isMisra93Compliant():
434
+ # Do not check when variable is pointer type
435
+ type_token = variable.nameToken
436
+ while type_token and type_token.isName:
437
+ type_token = type_token.previous
438
+ if type_token and type_token.str == '*':
439
+ continue
440
+
441
+ self.reportError(nameToken, 9, 3)
442
+ if rule == 904 and not ed.isMisra94Compliant():
443
+ self.reportError(nameToken, 9, 4)
444
+ if rule == 905 and not ed.isMisra95Compliant():
445
+ self.reportError(nameToken, 9, 5)
446
+
447
+ def getElementDef(nameToken, rawTokens = None):
448
+ if nameToken.variable.isArray:
449
+ ed = ElementDef("array", nameToken.str, nameToken.valueType)
450
+ createArrayChildrenDefs(ed, nameToken.astParent, nameToken.variable, rawTokens)
451
+ elif nameToken.variable.isClass:
452
+ ed = ElementDef("record", nameToken.str, nameToken.valueType)
453
+ createRecordChildrenDefs(ed, nameToken.variable)
454
+ else:
455
+ ed = ElementDef("value", nameToken.str, nameToken.valueType)
456
+ return ed
457
+
458
+ def createArrayChildrenDefs(ed, token, var, rawTokens = None):
459
+ if token and token.str == '[':
460
+ if rawTokens is not None:
461
+ foundToken = next((rawToken for rawToken in rawTokens
462
+ if rawToken.file == token.file
463
+ and rawToken.linenr == token.linenr
464
+ and rawToken.column == token.column
465
+ ), None)
466
+
467
+ if foundToken and foundToken.next and foundToken.next.str == ']':
468
+ ed.markAsFlexibleArray(token)
469
+
470
+ if (token.astOperand2 is not None) and (token.astOperand2.getKnownIntValue() is not None):
471
+ for i in range(token.astOperand2.getKnownIntValue()):
472
+ createChild(ed, token, i, var)
473
+ else:
474
+ ed.markAsFlexibleArray(token)
475
+
476
+
477
+ def createChild(ed, token, name, var):
478
+ if token.astParent and token.astParent.str == '[':
479
+ child = ElementDef("array", name, ed.valueType)
480
+ createArrayChildrenDefs(child, token.astParent, var)
481
+ else:
482
+ if ed.valueType and ed.valueType.type == "record":
483
+ child = ElementDef("record", name, ed.valueType)
484
+ createRecordChildrenDefs(child, var)
485
+ else:
486
+ child = ElementDef("value", name, ed.valueType)
487
+
488
+ ed.addChild(child)
489
+
490
+ def createRecordChildrenDefs(ed, var):
491
+ valueType = ed.valueType
492
+ if not valueType or not valueType.typeScope:
493
+ return
494
+ if var is None:
495
+ return
496
+ typeToken = var.typeEndToken
497
+ while typeToken and typeToken.isName:
498
+ typeToken = typeToken.previous
499
+ if typeToken and typeToken.str == '*':
500
+ child = ElementDef("pointer", var.nameToken, var.nameToken.valueType)
501
+ ed.addChild(child)
502
+ return
503
+ child_dict = {}
504
+ for variable in valueType.typeScope.varlist:
505
+ if variable is var:
506
+ continue
507
+ child = getElementDef(variable.nameToken)
508
+ child_dict[variable.nameToken] = child
509
+ for scopes in valueType.typeScope.nestedList:
510
+ varscope = False
511
+ if scopes.nestedIn == valueType.typeScope:
512
+ for variable in valueType.typeScope.varlist:
513
+ if variable.nameToken and variable.nameToken.valueType and variable.nameToken.valueType.typeScope == scopes:
514
+ varscope = True
515
+ break
516
+ if not varscope:
517
+ ed1 = ElementDef("record", scopes.Id, valueType)
518
+ for variable in scopes.varlist:
519
+ child = getElementDef(variable.nameToken)
520
+ ed1.addChild(child)
521
+ child_dict[scopes.bodyStart] = ed1
522
+ sorted_keys = sorted(list(child_dict.keys()), key=lambda k: "%s %s %s" % (k.file, k.linenr, k.column))
523
+ for _key in sorted_keys:
524
+ ed.addChild(child_dict[_key])
525
+
526
+
527
+ def getElementByDesignator(ed, token):
528
+ if not token.str in [ '.', '[' ]:
529
+ return None
530
+
531
+ while token.str in [ '.', '[' ]:
532
+ token = token.astOperand1
533
+
534
+ while ed and not token.isAssignmentOp:
535
+ token = token.astParent
536
+
537
+ if token.str == '[':
538
+ if not ed.isArray:
539
+ ed.markStuctureViolation(token)
540
+
541
+ chIndex = -1
542
+ if token.astOperand2 is not None:
543
+ chIndex = token.astOperand2.getKnownIntValue()
544
+ elif token.astOperand1 is not None:
545
+ chIndex = token.astOperand1.getKnownIntValue()
546
+
547
+ ed = ed.getChildByIndex(chIndex) if chIndex is not None else None
548
+
549
+ elif token.str == '.':
550
+ if not ed.isRecord:
551
+ ed.markStuctureViolation(token)
552
+
553
+ name = ""
554
+ if token.astOperand2 is not None:
555
+ name = token.astOperand2.str
556
+ elif token.astOperand1 is not None:
557
+ name = token.astOperand1.str
558
+
559
+ ed = ed.getChildByName(name)
560
+
561
+ return ed
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env python3
2
+ #
3
+ # cppcheck addon for naming conventions
4
+ #
5
+ # Example usage (variable name must start with lowercase, function name must start with uppercase):
6
+ # $ cppcheck --dump path-to-src/
7
+ # $ python addons/naming.py --var='[a-z].*' --function='[A-Z].*' path-to-src/*.dump
8
+ #
9
+
10
+ import cppcheckdata
11
+ import sys
12
+ import re
13
+
14
+
15
+ def validate_regex(expr):
16
+ try:
17
+ re.compile(expr)
18
+ except re.error:
19
+ print('Error: "{}" is not a valid regular expression.'.format(expr))
20
+ exit(1)
21
+
22
+
23
+ RE_VARNAME = None
24
+ RE_CONSTNAME = None
25
+ RE_PRIVATE_MEMBER_VARIABLE = None
26
+ RE_FUNCTIONNAME = None
27
+ for arg in sys.argv[1:]:
28
+ if arg[:6] == '--var=':
29
+ RE_VARNAME = arg[6:]
30
+ validate_regex(RE_VARNAME)
31
+ elif arg.startswith('--const='):
32
+ RE_CONSTNAME = arg[arg.find('=')+1:]
33
+ validate_regex(RE_CONSTNAME)
34
+ elif arg.startswith('--private-member-variable='):
35
+ RE_PRIVATE_MEMBER_VARIABLE = arg[arg.find('=')+1:]
36
+ validate_regex(RE_PRIVATE_MEMBER_VARIABLE)
37
+ elif arg[:11] == '--function=':
38
+ RE_FUNCTIONNAME = arg[11:]
39
+ validate_regex(RE_FUNCTIONNAME)
40
+
41
+
42
+ def reportError(token, severity, msg, errorId):
43
+ cppcheckdata.reportError(token, severity, msg, 'naming', errorId)
44
+
45
+
46
+ for arg in sys.argv[1:]:
47
+ if not arg.endswith('.dump'):
48
+ continue
49
+ print('Checking ' + arg + '...')
50
+ data = cppcheckdata.CppcheckData(arg)
51
+
52
+ for cfg in data.iterconfigurations():
53
+ print('Checking %s, config %s...' % (arg, cfg.name))
54
+ if RE_VARNAME:
55
+ for var in cfg.variables:
56
+ if var.access == 'Private':
57
+ continue
58
+ if var.nameToken and not var.isConst:
59
+ res = re.match(RE_VARNAME, var.nameToken.str)
60
+ if not res:
61
+ reportError(var.typeStartToken, 'style', 'Variable ' +
62
+ var.nameToken.str + ' violates naming convention', 'varname')
63
+ if RE_CONSTNAME:
64
+ for var in cfg.variables:
65
+ if var.access == 'Private':
66
+ continue
67
+ if var.nameToken and var.isConst:
68
+ res = re.match(RE_CONSTNAME, var.nameToken.str)
69
+ if not res:
70
+ reportError(var.typeStartToken, 'style', 'Constant ' +
71
+ var.nameToken.str + ' violates naming convention', 'constname')
72
+ if RE_PRIVATE_MEMBER_VARIABLE:
73
+ for var in cfg.variables:
74
+ if (var.access is None) or var.access != 'Private':
75
+ continue
76
+ res = re.match(RE_PRIVATE_MEMBER_VARIABLE, var.nameToken.str)
77
+ if not res:
78
+ reportError(var.typeStartToken, 'style', 'Private member variable ' +
79
+ var.nameToken.str + ' violates naming convention', 'privateMemberVariable')
80
+ if RE_FUNCTIONNAME:
81
+ for scope in cfg.scopes:
82
+ if scope.type == 'Function':
83
+ function = scope.function
84
+ if function is not None and function.type in ('Constructor', 'Destructor', 'CopyConstructor', 'MoveConstructor'):
85
+ continue
86
+ res = re.match(RE_FUNCTIONNAME, scope.className)
87
+ if not res:
88
+ reportError(
89
+ scope.bodyStart, 'style', 'Function ' + scope.className + ' violates naming convention', 'functionName')
90
+
91
+ sys.exit(cppcheckdata.EXIT_CODE)