forked from se-sic/cppstats
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdmacros.py
executable file
·688 lines (581 loc) · 27.3 KB
/
dmacros.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
#!/usr/bin/python
# -*- coding: utf-8 -*-
# modules from the std-library
import os
import re
import sys
from optparse import OptionParser, OptionGroup
# external libs
# python-lxml module
try:
from lxml import etree
except ImportError:
print("python-lxml module not found! (python-lxml)")
print("see http://codespeak.net/lxml/")
print("programm terminating ...!")
sys.exit(-1)
__cppnscpp = 'http://www.sdml.info/srcML/cpp'
__cpprens = re.compile('{(.+)}(.+)')
def returnFileNames(folder, extfilt = ['.xml']):
'''This function returns all files of the input folder <folder>
and its subfolders.'''
filesfound = list()
if os.path.isdir(folder):
wqueue = [os.path.abspath(folder)]
while wqueue:
currentfolder = wqueue[0]
wqueue = wqueue[1:]
foldercontent = os.listdir(currentfolder)
tmpfiles = filter(lambda n: os.path.isfile(
os.path.join(currentfolder, n)), foldercontent)
tmpfiles = filter(lambda n: os.path.splitext(n)[1] in extfilt,
tmpfiles)
tmpfiles = map(lambda n: os.path.join(currentfolder, n),
tmpfiles)
filesfound += tmpfiles
tmpfolders = filter(lambda n: os.path.isdir(
os.path.join(currentfolder, n)), foldercontent)
tmpfolders = map(lambda n: os.path.join(currentfolder, n),
tmpfolders)
wqueue += tmpfolders
return filesfound
class DisciplinedAnnotations:
##################################################
# constants:
__cppnscpp = 'http://www.sdml.info/srcML/cpp'
__cppnsdef = 'http://www.sdml.info/srcML/src'
__cpprens = re.compile('{(.+)}(.+)')
__conditionals = ['if', 'ifdef', 'ifndef', 'else', 'elif', 'endif']
__conditions = ['if', 'ifdef', 'ifndef']
##################################################
def __init__(self):
oparser = OptionParser()
oparser.add_option('-d', '--dir', dest='dir',
help='input directory (mandatory)')
oparser.add_option('-l', '--log', dest='log',
default=True, help='log to stdout (default=True)')
oparser.add_option('-c', '--check', dest='check', type='int',
default=1, help='pattern check (default=1)')
oparser.add_option('-v', '--verbose', dest='verbose', type='int',
default=0, help='verbose output (default=0)')
oparser.add_option('-a', '--all', dest='all', type='int',
default=0, help='check all patterns (default=0)')
groupc = OptionGroup(oparser, 'Check',
'This option allows to set the patterns, that are '
'checked during the program run: '
'(1) check top level siblings (compilation unit) '
'(2) check sibling (excludes check top level siblings; NOT CLASSIFIED) '
'(4) check if-then enframement (wrapper) '
'(8) check case enframement (conditional) '
'(16) check else-if enframement (conditional) '
'(32) check param/argument enframement (parameter) '
'(64) check expression enframement (expression) '
'(128) check else enframement (NOT CLASSIFIED) '
)
oparser.add_option_group(groupc)
groupr = OptionGroup(oparser, 'Result',
'This program counts the number of the disciplined '
'cpp usage in software projects. To this end, it '
'checks xml representations of header and source '
'files and returns the number of disciplined ifdefs '
'in those. Disciplined annotations are: '
)
oparser.add_option_group(groupr)
(self.opts, self.args) = oparser.parse_args()
if not self.opts.dir:
oparser.print_help()
sys.exit(-1)
self.overallblocks = 0
self.disciplined = 0
self.undisciplinedknown = 0
self.undisciplinedunknown = 0
self.compilationunit = 0
self.functiontype = 0
self.siblings = 0
self.wrapperif = 0
self.wrapperfor = 0
self.wrapperwhile = 0
self.conditionalcase = 0
self.conditionalelif = 0
self.parameter = 0
self.expression = 0
self.loc = 0
self.checkFiles()
def __getIfdefAnnotations__(self, root):
'''This method returns all nodes of the xml which are ifdef
annotations in the source code.'''
treeifdefs = list()
for _, elem in etree.iterwalk(root):
ns, tag = DisciplinedAnnotations.__cpprens.match(elem.tag).\
groups()
if ns == DisciplinedAnnotations.__cppnscpp \
and tag in DisciplinedAnnotations.__conditionals:
treeifdefs.append(elem)
return treeifdefs
def __createListFromTreeifdefs__(self, treeifdefs):
'''This method returns a list representation for the input treeifdefs
(xml-objects). Corresponding #ifdef elements are in one sublist.'''
if not treeifdefs: return []
listifdefs = list()
workerlist = list()
for nifdef in treeifdefs:
tag = nifdef.tag.split('}')[1]
if tag in ['if', 'ifdef', 'ifndef']:
workerlist.append(list())
workerlist[-1].append(nifdef)
elif tag in ['elif', 'else']:
workerlist[-1].append(nifdef)
elif tag in ['endif']:
if not workerlist:
return -1
workerlist[-1].append(nifdef)
last = workerlist[-1]
getpairs = zip(last,last[1:])
map(lambda i: listifdefs.append(list(i)), getpairs)
workerlist = workerlist[:-1]
else:
print('[ERROR] ill-formed tag (%s) occured in line (%4s).' % (tag, nifdef.sourceline))
if workerlist:
return -2
return listifdefs
def __filterConditionalPreprocessorDirectives(self, listifdefs):
'''This method filters out all ifdef-endif pairs that annotate only preprocessor directives.'''
# iterate annotated blocks by determining all siblings of the #ifdef and filter out preprocessor
# annotated elements
resultlist = filter(lambda (ifdef, endif): ifdef.getnext() != endif, listifdefs)
print('[INFO] before after: %s <-> %s' % (str(len(listifdefs)), str(len(resultlist))))
return resultlist
PATTLS = 0 # 1 << 0 => 1
def __checkStrictTLSFDPattern__(self, listifdefs):
'''like sibling pattern, but only top level and statement elements are
considered disciplined'''
listundisciplinedknown = list()
listundisciplinedunknown = list()
for listcorifdef in listifdefs:
nodeifdef = listcorifdef[0]
nodeifdefsibs = [sib for sib in nodeifdef.itersiblings()]
error=0
for corifdef in listcorifdef[1:]:
if not corifdef in nodeifdefsibs:
error=1
if error==0:
parenttag = self.__getParentTag__(nodeifdef)
if not parenttag in ['block','public']:
error=1
if error==1:
listundisciplinedunknown.append(listcorifdef)
else:
listundisciplinedknown.append(listcorifdef)
return (listundisciplinedknown, listundisciplinedunknown)
def __checkStrictTLSCUPattern__(self, listifdefs):
'''This method checks all patterns, if they occur right under the root element
of the grammer, here unit.'''
listundisciplinedknown = list()
listundisciplinedunknown = list()
for listcorifdef in listifdefs:
nodeifdef = listcorifdef[0]
nodeifdefsibs = [sib for sib in nodeifdef.itersiblings()]
error=0
for corifdef in listcorifdef[1:]:
if not corifdef in nodeifdefsibs:
error=1
if error==0:
parenttag = self.__getParentTag__(nodeifdef)
if not parenttag in ['unit']:
error=1
if error==1:
listundisciplinedunknown.append(listcorifdef)
else:
listundisciplinedknown.append(listcorifdef)
assert len(listifdefs) == len(listundisciplinedknown)+len(listundisciplinedunknown)
return (listundisciplinedknown, listundisciplinedunknown)
def __checkStrictPattern__(self, listifdefs):
'''This pattern checks the annotation of functions, where the XML markup
of src2srcml is ill-formed. TODO might be fixed in future versions of
src2srcml. Example is:
void foo(k)
int k;
{
// some lines of code
}
'''
listundisciplinedknown = list()
listundisciplinedunknown = list()
for listcorifdef in listifdefs:
if len(listcorifdef) != 2:
listundisciplinedunknown.append(listcorifdef)
continue
nodeifdef = listcorifdef[0]
nodeendif = listcorifdef[1]
func = nodeendif.getparent()
if func != None and func.tag.split('}')[1] == 'function':
nodefuncsibs = [sib for sib in func.itersiblings(preceding=True)]
if nodeifdef == nodefuncsibs[0]:
if self.opts.verbose:
print('[INFO] ill-formed compilation unit pattern occured in line (%4s).' % nodeifdef.sourceline)
listundisciplinedknown.append(listcorifdef)
continue
listundisciplinedunknown.append(listcorifdef)
assert len(listifdefs) == len(listundisciplinedknown)+len(listundisciplinedunknown)
return (listundisciplinedknown, listundisciplinedunknown)
PATSIB = 1 # 1 << 1 => 2
def __checkSiblingPattern__(self, listifdefs):
'''This method returns a tuple with (listdisciplined,
listundisciplined) #ifdef elements. The pattern works on the basis
of the sibling pattern. If the xml elements of #if-#elif-#else-#endif
are siblings, we determine them as disciplined.'''
listundisciplinedknown = list()
listundisciplinedunknown = list()
for listcorifdef in listifdefs:
nodeifdef = listcorifdef[0]
nodeifdefsibs = [sib for sib in nodeifdef.itersiblings()]
error=0;
for corifdef in listcorifdef[1:]:
if not corifdef in nodeifdefsibs:
error=1
if error==1:
listundisciplinedunknown.append(listcorifdef)
else:
listundisciplinedknown.append(listcorifdef)
assert len(listifdefs) == len(listundisciplinedknown)+len(listundisciplinedunknown)
return (listundisciplinedknown, listundisciplinedunknown)
def __getParentTag__(self, tag):
parent = tag.getparent()
return parent.tag.split('}')[1]
PATIFTHEN = 2 # 1 << 2 => 4
def __checkIfThenPattern__(self, listifdefs):
'''This method returns a tuple with (listdisciplined,
listundisciplined) #ifdef elements. The pattern matches the following
situation. The if-then in C is enframed by #if-#endif. The else part of
the if-then in C is not enframed. The sibling pattern does not work here
since the annatation cannot work properly here.'''
listundisciplinedknown = list()
listundisciplinedunknown = list()
for listcorifdef in listifdefs:
if len(listcorifdef) != 2:
listundisciplinedunknown.append(listcorifdef)
continue
# check that the endif is the first child of its parent and the parent
# is an else
ifdef = listcorifdef[0]
ifdefsibs = [sib for sib in ifdef.itersiblings()]
# first sibling of starting ifdef must be an if
if len(ifdefsibs) == 0 or ifdefsibs[0].tag.split('}')[1] != 'if':
listundisciplinedunknown.append(listcorifdef)
continue
# parent of endif must be either an else or an then (if)
endif = listcorifdef[1]
poselse = endif.getparent()
poselsetag = poselse.tag.split('}')[1]
if poselsetag in ['else', 'then']:
if self.opts.verbose:
print('[INFO] if-then pattern occured in line (%4s).' % poselse.sourceline)
listundisciplinedknown.append(listcorifdef)
else:
listundisciplinedunknown.append(listcorifdef)
assert len(listifdefs) == len(listundisciplinedknown)+len(listundisciplinedunknown)
return (listundisciplinedknown, listundisciplinedunknown)
#TODO
def __checkForWrapperPattern__(self, listifdefs):
'''This method returns a tuple with (listdisciplined,
listundisciplined) #ifdef elements. The pattern matches the following
situation. The for in C is enframed by #if-#endif.'''
listundisciplinedknown = list()
listundisciplinedunknown = list()
for listcorifdef in listifdefs:
if len(listcorifdef) != 2:
listundisciplinedunknown.append(listcorifdef)
continue
# check that the endif is the first child of its parent and the parent
# is an else
ifdef = listcorifdef[0]
ifdefsibs = [sib for sib in ifdef.itersiblings()]
# first sibling of starting ifdef must be an for
if len(ifdefsibs) == 0 or ifdefsibs[0].tag.split('}')[1] != 'for':
listundisciplinedunknown.append(listcorifdef)
continue
# parent of endif must be either an else or an then (if)
endif = listcorifdef[1]
poselse = endif.getparent()
poselsetag = poselse.tag.split('}')[1]
if poselsetag in ['else', 'then']:
if self.opts.verbose:
print('[INFO] if-then pattern occured in line (%4s).' % poselse.sourceline)
listundisciplinedknown.append(listcorifdef)
else:
listundisciplinedunknown.append(listcorifdef)
assert len(listifdefs) == len(listundisciplinedknown)+len(listundisciplinedunknown)
return (listundisciplinedknown, listundisciplinedunknown)
PATCASE = 3 # 1 << 3 => 8
def __checkCasePattern__(self, listifdefs):
'''The method checks the case-block pattern; the #ifdef enframes a case block
of a switch case.'''
listundisciplinedknown = list()
listundisciplinedunknown = list()
for listcorifdef in listifdefs:
# pattern works only for #if-#endif combinations
if len(listcorifdef) > 2:
listundisciplinedunknown.append(listcorifdef)
continue
# get endif and check whether parent is a case
nodeendif = listcorifdef[-1]
parenttag = self.__getParentTag__(nodeendif)
if parenttag in ['case']:
if self.opts.verbose:
print('[INFO] case pattern occured in line (%4s).' % nodeendif.sourceline)
listundisciplinedknown.append(listcorifdef)
else:
listundisciplinedunknown.append(listcorifdef)
assert len(listifdefs) == len(listundisciplinedknown)+len(listundisciplinedunknown)
return (listundisciplinedknown, listundisciplinedunknown)
PATELSEIF = 4 # 1 << 4 => 16
def __checkElseIfPattern__(self, listifdefs):
'''The method check the elseif-block pattern; the #ifdef enframes an elseif
block in an if-then-else.'''
listundisciplinedknown = list()
listundisciplinedunknown = list()
for listcorifdef in listifdefs:
# pattern works only for #if-#endif combinations
if len(listcorifdef) > 2:
listundisciplinedunknown.append(listcorifdef)
continue
# get the endif
# endif parent -> then
# then parent -> if
# if parent -> else
# else parent -> #ifdef
nodeendif = listcorifdef[-1]
thensib = nodeendif.getprevious()
if thensib == None:
listundisciplinedunknown.append(listcorifdef)
continue
if thensib.tag.split('}')[1] not in ['then']:
listundisciplinedunknown.append(listcorifdef)
continue
ifparent = thensib.getparent()
if ifparent.tag.split('}')[1] not in ['if']:
listundisciplinedunknown.append(listcorifdef)
continue
elseparent = ifparent.getparent()
if elseparent.tag.split('}')[1] not in ['else']:
listundisciplinedunknown.append(listcorifdef)
continue
ifdefsib = elseparent.getprevious()
if ifdefsib != listcorifdef[0]:
if self.opts.verbose:
print('[INFO] else-if pattern occured in line (%4s).' % ifdefsib.sourceline)
listundisciplinedunknown.append(listcorifdef)
else:
listundisciplinedknown.append(listcorifdef)
assert len(listifdefs) == len(listundisciplinedknown)+len(listundisciplinedunknown)
return (listundisciplinedknown, listundisciplinedunknown)
PATPARAM = 5 # 1 << 5 => 32
def __checkParameter__(self, listifdefs):
'''The method checks whether an #ifdef enframes a parameter of a function;
includes function definitions and function calls.'''
listundisciplinedknown = list()
listundisciplinedunknown = list()
for listcorifdef in listifdefs:
# pattern works only for #if-#endif combinations
if len(listcorifdef) > 2:
listundisciplinedunknown.append(listcorifdef)
continue
nodeifdef = listcorifdef[0]
nodeifdefsibs = [sib for sib in nodeifdef.itersiblings()]
error = 0
for corifdef in listcorifdef[1:]:
if not corifdef in nodeifdefsibs:
error = 1
if error == 0:
# check whether node is an argument or parameter
parenttag = self.__getParentTag__(nodeifdef)
if not parenttag in ['argument_list','parameter_list']:
error = 1
firstsib = nodeifdefsibs[0]
if firstsib.tag.split('}')[1] not in ['argument', 'param']:
error = 1
if error == 1:
listundisciplinedunknown.append(listcorifdef)
else:
if self.opts.verbose:
print('[INFO] param/argument pattern occured in line (%4s).' % nodeifdef.sourceline)
listundisciplinedknown.append(listcorifdef)
assert len(listifdefs) == len(listundisciplinedknown)+len(listundisciplinedunknown)
return (listundisciplinedknown, listundisciplinedunknown)
PATEXP = 6 # 1 << 5 => 64
def __checkExpression__(self, listifdefs):
'''The method checks whether an #ifdef enframes an expression of a condition.'''
listundisciplinedknown = list()
listundisciplinedunknown = list()
for listcorifdef in listifdefs:
# pattern works only for #if-#endif combinations
if len(listcorifdef) > 2:
listundisciplinedunknown.append(listcorifdef)
continue
error = 0
nodeifdef = listcorifdef[0]
# get parent and check whether its tag is expr
exppar = nodeifdef.getparent()
exppartag = exppar.tag.split('}')[1]
if not exppartag == 'expr':
error = 1
if error == 0:
conpar = exppar.getparent()
conpartag = conpar.tag.split('}')[1]
if not conpartag == 'condition':
error = 1
if error == 1:
listundisciplinedunknown.append(listcorifdef)
else:
if self.opts.verbose:
print('[INFO] expression pattern occured in line (%4s).' % nodeifdef.sourceline)
listundisciplinedknown.append(listcorifdef)
assert len(listifdefs) == len(listundisciplinedknown)+len(listundisciplinedunknown)
return (listundisciplinedknown, listundisciplinedunknown)
def __iterateUnknownPatterns__(self, listifdefs, file):
'''This method iterates of the unknown patterns and prints out information
about the pattern: file and line.'''
for ifdef in listifdefs:
if self.opts.log:
print('[INFO] Unknown pattern in file (%s) and line (%s)' % \
(file, ifdef[0].sourceline))
def __checkDiscipline__(self, treeifdefs, file):
'''This method checks a number of patterns in the given treeifdefs.
The checks are in that order, that ifdef patterns not recognized
are passed to the next pattern.'''
listundisciplined = self.__createListFromTreeifdefs__(treeifdefs)
listundisciplined = self.__filterConditionalPreprocessorDirectives(listundisciplined)
if (listundisciplined == -1):
print('[ERROR] Too many #endifs in file (%s)' % file)
return
if (listundisciplined == -2):
print('[ERROR] Not enough #endifs in file (%s)' % file)
return
self.overallblocks += len(listundisciplined)
# check TLS pattern, subset of sibling pattern
if (self.opts.all or self.opts.check & (1 << DisciplinedAnnotations.PATTLS)):
listifdefs = list(listundisciplined)
(listdisciplined, listundisciplined) = \
self.__checkStrictTLSCUPattern__(listifdefs)
self.compilationunit += len(listdisciplined)
self.disciplined += len(listdisciplined)
# checking fd pattern (part of tls)
listifdefs = list(listundisciplined)
(listdisciplined, listundisciplined) = \
self.__checkStrictTLSFDPattern__(listifdefs)
self.functiontype += len(listdisciplined)
self.disciplined += len(listdisciplined)
# checking ill-formed compilation unit pattern
listifdefs = list(listundisciplined)
(listdisciplined, listundisciplined) = \
self.__checkStrictPattern__(listifdefs)
self.compilationunit += len(listdisciplined)
self.disciplined += len(listdisciplined)
# check if-then pattern
if (self.opts.all or self.opts.check & (1 << DisciplinedAnnotations.PATIFTHEN)):
listifdefs = list(listundisciplined)
(listdisciplined, listundisciplined) = \
self.__checkIfThenPattern__(listifdefs)
self.wrapperif += len(listdisciplined)
self.undisciplinedknown += len(listdisciplined)
# check case pattern
if (self.opts.all or self.opts.check & (1 << DisciplinedAnnotations.PATCASE)):
listifdefs = list(listundisciplined)
(listdisciplined, listundisciplined) = \
self.__checkCasePattern__(listifdefs)
self.conditionalcase += len(listdisciplined)
self.undisciplinedknown += len(listdisciplined)
# check else-if pattern
if (self.opts.all or self.opts.check & (1 << DisciplinedAnnotations.PATELSEIF)):
listifdefs = list(listundisciplined)
(listdisciplined, listundisciplined) = \
self.__checkElseIfPattern__(listifdefs)
self.conditionalelif += len(listdisciplined)
self.undisciplinedknown += len(listdisciplined)
# check param pattern
if (self.opts.all or self.opts.check & (1 << DisciplinedAnnotations.PATPARAM)):
listifdefs = list(listundisciplined)
(listdisciplined, listundisciplined) = \
self.__checkParameter__(listifdefs)
self.parameter += len(listdisciplined)
self.undisciplinedknown += len(listdisciplined)
# check expression pattern
if (self.opts.all or self.opts.check & (1 << DisciplinedAnnotations.PATEXP)):
listifdefs = list(listundisciplined)
(listdisciplined, listundisciplined) = \
self.__checkExpression__(listifdefs)
self.expression += len(listdisciplined)
self.undisciplinedknown += len(listdisciplined)
# check sibling pattern; check this late because pattern might match for others as well
if (self.opts.all or self.opts.check & (1 << DisciplinedAnnotations.PATSIB)):
listifdefs = list(listundisciplined)
(listdisciplined, listundisciplined) = \
self.__checkSiblingPattern__(listifdefs)
self.siblings += len(listdisciplined)
self.disciplined += len(listdisciplined)
# wrap up listundisciplined
self.__iterateUnknownPatterns__(listundisciplined, file)
self.undisciplinedunknown += len(listundisciplined)
def checkFile(self, file):
try:
tree = etree.parse(file)
f = open(file, 'r')
except etree.XMLSyntaxError:
print('ERROR: file (%s) is not valid. Skipping it.' % file)
return
# get LOC
self.loc += len(f.readlines())-2;
# get root of the xml and iterate over it
root = tree.getroot()
treeifdefs = self.__getIfdefAnnotations__(root)
try:
self.__checkDiscipline__(treeifdefs, file)
except:
print('[ERROR]: file (%s) is not valid. Skipping it.' % file)
return
def checkFiles(self):
xmlfiles = returnFileNames(self.opts.dir, ['.xml'])
for xmlfile in xmlfiles:
print('[INFO] checking file %s' % xmlfile)
self.checkFile(xmlfile)
projectpath = os.path.dirname(self.opts.dir)
projectname = os.path.basename(projectpath)
fd = open(
os.path.join(
projectpath,
'dmacros.csv'
), 'w')
ratio = 0
if (self.overallblocks > 0):
ratio = self.disciplined/(0.0 + self.overallblocks)
fd.write("projectname"
+";"+"loc"
+";"+"compilationunit"
+";"+"functiontype"
+";"+"siblings"
+";"+"wrapperif"
+";"+"conditionalcase"
+";"+"conditionalelif"
+";"+"parameter"
+";"+"expression"
+";"+"undisciplinedknown"
+";"+"undisciplinedunknown"
+";"+"disciplined/overallblocks"
+";"+"overallblocks"+"\n")
fd.write(projectname
+";"+str(self.loc)
+";"+str(self.compilationunit)
+";"+str(self.functiontype)
+";"+str(self.siblings)
+";"+str(self.wrapperif)
+";"+str(self.conditionalcase)
+";"+str(self.conditionalelif)
+";"+str(self.parameter)
+";"+str(self.expression)
+";"+str(self.undisciplinedknown)
+";"+str(self.undisciplinedunknown)
+";"+str(ratio)
+";"+str(self.overallblocks)+"\n")
##################################################
if __name__ == '__main__':
DisciplinedAnnotations()