cppcheck-py 2.9__py3-none-win_amd64.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 (84) hide show
  1. cppcheck/__init__.py +55 -0
  2. cppcheck/cppcheck-2.9.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 +1529 -0
  6. cppcheck/data/addons/findcasts.py +33 -0
  7. cppcheck/data/addons/misc.py +163 -0
  8. cppcheck/data/addons/misra.py +4728 -0
  9. cppcheck/data/addons/misra_9.py +513 -0
  10. cppcheck/data/addons/naming.py +91 -0
  11. cppcheck/data/addons/namingng.py +253 -0
  12. cppcheck/data/addons/runaddon.py +12 -0
  13. cppcheck/data/addons/threadsafety.py +39 -0
  14. cppcheck/data/addons/y2038.py +252 -0
  15. cppcheck/data/cfg/avr.cfg +431 -0
  16. cppcheck/data/cfg/bento4.cfg +142 -0
  17. cppcheck/data/cfg/boost.cfg +1268 -0
  18. cppcheck/data/cfg/bsd.cfg +546 -0
  19. cppcheck/data/cfg/cairo.cfg +88 -0
  20. cppcheck/data/cfg/cppcheck-lib.cfg +72 -0
  21. cppcheck/data/cfg/cppunit.cfg +48 -0
  22. cppcheck/data/cfg/daca.cfg +31 -0
  23. cppcheck/data/cfg/dpdk.cfg +11 -0
  24. cppcheck/data/cfg/embedded_sql.cfg +4 -0
  25. cppcheck/data/cfg/emscripten.cfg +7 -0
  26. cppcheck/data/cfg/ginac.cfg +12848 -0
  27. cppcheck/data/cfg/gnu.cfg +1626 -0
  28. cppcheck/data/cfg/googletest.cfg +60 -0
  29. cppcheck/data/cfg/gtk.cfg +20584 -0
  30. cppcheck/data/cfg/icu.cfg +6 -0
  31. cppcheck/data/cfg/kde.cfg +51 -0
  32. cppcheck/data/cfg/libcerror.cfg +128 -0
  33. cppcheck/data/cfg/libcurl.cfg +487 -0
  34. cppcheck/data/cfg/libsigc++.cfg +36 -0
  35. cppcheck/data/cfg/lua.cfg +316 -0
  36. cppcheck/data/cfg/mfc.cfg +256 -0
  37. cppcheck/data/cfg/microsoft_atl.cfg +40 -0
  38. cppcheck/data/cfg/microsoft_sal.cfg +491 -0
  39. cppcheck/data/cfg/microsoft_unittest.cfg +20 -0
  40. cppcheck/data/cfg/motif.cfg +318 -0
  41. cppcheck/data/cfg/nspr.cfg +38 -0
  42. cppcheck/data/cfg/ntl.cfg +6907 -0
  43. cppcheck/data/cfg/opencv2.cfg +132 -0
  44. cppcheck/data/cfg/opengl.cfg +580 -0
  45. cppcheck/data/cfg/openmp.cfg +157 -0
  46. cppcheck/data/cfg/openssl.cfg +174 -0
  47. cppcheck/data/cfg/pcre.cfg +165 -0
  48. cppcheck/data/cfg/posix.cfg +6252 -0
  49. cppcheck/data/cfg/python.cfg +674 -0
  50. cppcheck/data/cfg/qt.cfg +5255 -0
  51. cppcheck/data/cfg/ruby.cfg +142 -0
  52. cppcheck/data/cfg/sdl.cfg +354 -0
  53. cppcheck/data/cfg/sfml.cfg +301 -0
  54. cppcheck/data/cfg/sqlite3.cfg +1527 -0
  55. cppcheck/data/cfg/std.cfg +8716 -0
  56. cppcheck/data/cfg/tinyxml2.cfg +56 -0
  57. cppcheck/data/cfg/vcl.cfg +4 -0
  58. cppcheck/data/cfg/windows.cfg +17941 -0
  59. cppcheck/data/cfg/wxsqlite3.cfg +1955 -0
  60. cppcheck/data/cfg/wxsvg.cfg +16905 -0
  61. cppcheck/data/cfg/wxwidgets.cfg +16464 -0
  62. cppcheck/data/cfg/zlib.cfg +1450 -0
  63. cppcheck/data/cppcheck-htmlreport +986 -0
  64. cppcheck/data/cppcheck.exe +0 -0
  65. cppcheck/data/platforms/aix_ppc64.xml +17 -0
  66. cppcheck/data/platforms/arm32-wchar_t2.xml +17 -0
  67. cppcheck/data/platforms/arm32-wchar_t4.xml +17 -0
  68. cppcheck/data/platforms/arm64-wchar_t2.xml +17 -0
  69. cppcheck/data/platforms/arm64-wchar_t4.xml +17 -0
  70. cppcheck/data/platforms/avr8.xml +18 -0
  71. cppcheck/data/platforms/cray_sv1.xml +17 -0
  72. cppcheck/data/platforms/elbrus-e1cp.xml +18 -0
  73. cppcheck/data/platforms/mips32.xml +18 -0
  74. cppcheck/data/platforms/msp430_eabi_large_datamodel.xml +17 -0
  75. cppcheck/data/platforms/pic16.xml +18 -0
  76. cppcheck/data/platforms/pic8-enhanced.xml +18 -0
  77. cppcheck/data/platforms/pic8.xml +18 -0
  78. cppcheck/data/platforms/unix32-unsigned.xml +17 -0
  79. cppcheck/data/platforms/unix64-unsigned.xml +17 -0
  80. cppcheck_py-2.9.dist-info/METADATA +76 -0
  81. cppcheck_py-2.9.dist-info/RECORD +84 -0
  82. cppcheck_py-2.9.dist-info/WHEEL +5 -0
  83. cppcheck_py-2.9.dist-info/entry_points.txt +4 -0
  84. cppcheck_py-2.9.dist-info/licenses/LICENSE.md +191 -0
@@ -0,0 +1,513 @@
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
+ "ED",
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.str == '{':
257
+ nextChild = self.root.getNextChild() if self.root is not None else None
258
+
259
+ if nextChild:
260
+ if nextChild.isArray or nextChild.isRecord:
261
+ nextChild.unset()
262
+ nextChild.setInitialized(isDesignated)
263
+ self.ed = nextChild.getFirstValueElement()
264
+ isDesignated = False
265
+ elif nextChild.valueType is None:
266
+ # No type information available - unable to check structure - assume correct initialization
267
+ nextChild.setInitialized(isDesignated)
268
+ self.unwindAndContinue()
269
+ continue
270
+
271
+ elif self.token.astOperand1:
272
+ # Create dummy nextChild to represent excess levels in initializer
273
+ dummyRoot = ElementDef('array', '<-', self.root.valueType)
274
+ dummyRoot.parent = self.root
275
+ dummyRoot.childIndex = 0
276
+ dummyRoot.children = [nextChild]
277
+ nextChild.parent = dummyRoot
278
+
279
+ self.root.markStuctureViolation(self.token)
280
+
281
+ # Fake dummy as nextChild (of current root)
282
+ nextChild = dummyRoot
283
+
284
+ if self.token.astOperand1:
285
+ self.root = nextChild
286
+ self.token = self.token.astOperand1
287
+ isFirstElement = True
288
+ else:
289
+ if self.root:
290
+ # {}
291
+ if self.root.name == '<-':
292
+ self.root.parent.markStuctureViolation(self.token)
293
+ else:
294
+ self.root.markStuctureViolation(self.token)
295
+ self.ed = None
296
+ self.unwindAndContinue()
297
+
298
+ else:
299
+ if self.ed and self.ed.isValue:
300
+ if not isDesignated and len(self.rootStack) > 0 and self.rootStack[-1][1] == self.root:
301
+ self.rootStack[-1][0].markStuctureViolation(self.token)
302
+
303
+ if isFirstElement and self.token.str == '0' and self.token.next.str == '}':
304
+ # Zero initializer causes recursive initialization
305
+ self.root.initializeChildren()
306
+ elif self.token.isString and self.ed.valueType and self.ed.valueType.pointer > 0:
307
+ if self.ed.valueType.pointer - self.ed.getEffectiveLevel() == 1:
308
+ if self.ed.parent != self.root:
309
+ self.root.markStuctureViolation(self.token)
310
+ self.ed.setInitialized(isDesignated)
311
+ elif self.ed.valueType.pointer == self.ed.getEffectiveLevel():
312
+ if(self.root.name != '->' and self.ed.parent.parent != self.root) or (self.root.name == '->' and self.root.children[0] != self.ed.parent):
313
+ self.root.markStuctureViolation(self.token)
314
+ else:
315
+ self.ed.parent.setInitialized(isDesignated)
316
+ self.ed.parent.initializeChildren()
317
+ else:
318
+ if self.ed.parent != self.root:
319
+ # Check if token is correct value type for self.root.children[?]
320
+ child = self.root.getChildByValueElement(self.ed)
321
+ if self.token.valueType:
322
+ if child.elementType != 'record' or self.token.valueType.type != 'record' or child.valueType.typeScope != self.token.valueType.typeScope:
323
+ self.root.markStuctureViolation(self.token)
324
+
325
+ self.ed.setInitialized(isDesignated)
326
+
327
+ # Mark all elements up to root with positional or designated
328
+ # (for complex designators, or missing structure)
329
+ parent = self.ed.parent
330
+ while parent and parent != self.root:
331
+ parent.isDesignated = isDesignated if isDesignated and not parent.isPositional else parent.isDesignated
332
+ parent.isPositional = not isDesignated if not isDesignated and not parent.isDesignated else parent.isPositional
333
+ parent = parent.parent
334
+ isDesignated = False
335
+
336
+ self.unwindAndContinue()
337
+
338
+ def pushToRootStackAndMarkAsDesignated(self):
339
+ new = self.ed.parent
340
+ if new != self.root:
341
+ # Mark all elements up to self.root root as designated
342
+ parent = new
343
+ while parent and parent != self.root:
344
+ parent.isDesignated = True
345
+ parent = parent.parent
346
+ self.rootStack.append((self.root, new))
347
+ new.markAsCurrent()
348
+ new.childIndex = new.children.index(self.ed) - 1
349
+ self.root = new
350
+
351
+ def popFromStackIfExitElement(self):
352
+ if len(self.rootStack) > 0 and self.rootStack[-1][1] == self.root:
353
+ old = self.rootStack.pop()[0]
354
+ old.markAsCurrent()
355
+ self.root = old
356
+
357
+ def unwindAndContinue(self):
358
+ while self.token:
359
+ if self.token.astParent.astOperand1 == self.token and self.token.astParent.astOperand2:
360
+ if self.ed:
361
+ self.ed.markAsCurrent()
362
+ self.ed = self.ed.getNextValueElement(self.root)
363
+
364
+ self.token = self.token.astParent.astOperand2
365
+ break
366
+ else:
367
+ self.token = self.token.astParent
368
+ if self.token.str == '{':
369
+ if self.root:
370
+ self.ed = self.root.getLastValueElement()
371
+ self.ed.markAsCurrent()
372
+
373
+ # Cleanup if root is dummy node representing excess levels in initializer
374
+ if self.root.name == '<-':
375
+ self.root.children[0].parent = self.root.parent
376
+
377
+ self.root = self.root.parent
378
+
379
+ if self.token.astParent is None:
380
+ self.token = None
381
+ break
382
+
383
+ def misra_9_x(self, data, rule, rawTokens = None):
384
+ parser = InitializerParser()
385
+
386
+ for variable in data.variables:
387
+ if variable.nameToken is None:
388
+ continue
389
+
390
+ nameToken = variable.nameToken
391
+
392
+ # Check if declaration and initialization is
393
+ # split into two separate statements in ast.
394
+ if nameToken.next and nameToken.next.isSplittedVarDeclEq:
395
+ nameToken = nameToken.next.next
396
+
397
+ # Find declarations with initializer assignment
398
+ eq = nameToken
399
+ while not eq.isAssignmentOp and eq.astParent:
400
+ eq = eq.astParent
401
+
402
+ # We are only looking for initializers
403
+ if not eq.isAssignmentOp or eq.astOperand2.isName:
404
+ continue
405
+
406
+ if variable.isArray or variable.isClass:
407
+ ed = getElementDef(nameToken, rawTokens)
408
+ # No need to check non-arrays if valueType is missing,
409
+ # since we can't say anything useful about the structure
410
+ # without it.
411
+ if ed.valueType is None and not variable.isArray:
412
+ continue
413
+
414
+ parser.parseInitializer(ed, eq.astOperand2)
415
+ # print(rule, nameToken.str + '=', ed.getInitDump())
416
+ if rule == 902 and not ed.isMisra92Compliant():
417
+ self.reportError(nameToken, 9, 2)
418
+ if rule == 903 and not ed.isMisra93Compliant():
419
+ self.reportError(nameToken, 9, 3)
420
+ if rule == 904 and not ed.isMisra94Compliant():
421
+ self.reportError(nameToken, 9, 4)
422
+ if rule == 905 and not ed.isMisra95Compliant():
423
+ self.reportError(nameToken, 9, 5)
424
+
425
+ def getElementDef(nameToken, rawTokens = None):
426
+ if nameToken.variable.isArray:
427
+ ed = ElementDef("array", nameToken.str, nameToken.valueType)
428
+ createArrayChildrenDefs(ed, nameToken.astParent, nameToken.variable, rawTokens)
429
+ elif nameToken.variable.isClass:
430
+ ed = ElementDef("record", nameToken.str, nameToken.valueType)
431
+ createRecordChildrenDefs(ed, nameToken.variable)
432
+ else:
433
+ ed = ElementDef("value", nameToken.str, nameToken.valueType)
434
+ return ed
435
+
436
+ def createArrayChildrenDefs(ed, token, var, rawTokens = None):
437
+ if token.str == '[':
438
+ if rawTokens is not None:
439
+ foundToken = next((rawToken for rawToken in rawTokens
440
+ if rawToken.file == token.file
441
+ and rawToken.linenr == token.linenr
442
+ and rawToken.column == token.column
443
+ ), None)
444
+
445
+ if foundToken and foundToken.next and foundToken.next.str == ']':
446
+ ed.markAsFlexibleArray(token)
447
+
448
+ if (token.astOperand2 is not None) and (token.astOperand2.getKnownIntValue() is not None):
449
+ for i in range(token.astOperand2.getKnownIntValue()):
450
+ createChild(ed, token, i, var)
451
+ else:
452
+ ed.markAsFlexibleArray(token)
453
+
454
+
455
+ def createChild(ed, token, name, var):
456
+ if token.astParent and token.astParent.str == '[':
457
+ child = ElementDef("array", name, ed.valueType)
458
+ createArrayChildrenDefs(child, token.astParent, var)
459
+ else:
460
+ if ed.valueType and ed.valueType.type == "record":
461
+ child = ElementDef("record", name, ed.valueType)
462
+ createRecordChildrenDefs(child, var)
463
+ else:
464
+ child = ElementDef("value", name, ed.valueType)
465
+
466
+ ed.addChild(child)
467
+
468
+ def createRecordChildrenDefs(ed, var):
469
+ valueType = ed.valueType
470
+ if not valueType or not valueType.typeScope:
471
+ return
472
+
473
+ for variable in valueType.typeScope.varlist:
474
+ if variable is var:
475
+ continue
476
+ child = getElementDef(variable.nameToken)
477
+ ed.addChild(child)
478
+
479
+ def getElementByDesignator(ed, token):
480
+ if not token.str in [ '.', '[' ]:
481
+ return None
482
+
483
+ while token.str in [ '.', '[' ]:
484
+ token = token.astOperand1
485
+
486
+ while ed and not token.isAssignmentOp:
487
+ token = token.astParent
488
+
489
+ if token.str == '[':
490
+ if not ed.isArray:
491
+ ed.markStuctureViolation(token)
492
+
493
+ chIndex = -1
494
+ if token.astOperand2 is not None:
495
+ chIndex = token.astOperand2.getKnownIntValue()
496
+ elif token.astOperand1 is not None:
497
+ chIndex = token.astOperand1.getKnownIntValue()
498
+
499
+ ed = ed.getChildByIndex(chIndex) if chIndex is not None else None
500
+
501
+ elif token.str == '.':
502
+ if not ed.isRecord:
503
+ ed.markStuctureViolation(token)
504
+
505
+ name = ""
506
+ if token.astOperand2 is not None:
507
+ name = token.astOperand2.str
508
+ elif token.astOperand1 is not None:
509
+ name = token.astOperand1.str
510
+
511
+ ed = ed.getChildByName(name)
512
+
513
+ 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)