]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/utils/SummarizeErrors
Merge from vendor-sys/opensolaris:
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / utils / SummarizeErrors
1 #!/usr/bin/env python
2
3 import os, sys, re
4
5 class multidict:
6     def __init__(self, elts=()):
7         self.data = {}
8         for key,value in elts:
9             self[key] = value
10     
11     def __getitem__(self, item):
12         return self.data[item]
13     def __setitem__(self, key, value):
14         if key in self.data:
15             self.data[key].append(value)
16         else:
17             self.data[key] = [value]
18     def items(self):
19         return self.data.items()
20     def values(self):
21         return self.data.values()
22     def keys(self):
23         return self.data.keys()
24     def __len__(self):
25         return len(self.data)
26
27 kDiagnosticRE = re.compile(': (error|warning): (.*)')
28 kAssertionRE = re.compile('Assertion failed: (.*, function .*, file .*, line [0-9]+\\.)')
29
30 def readInfo(path, opts):
31     lastProgress = [-100,0]
32     def progress(pos):
33         pct = (100. * pos) / (size * 2)
34         if (pct - lastProgress[0]) >= 10:
35             lastProgress[0] = pct
36             print '%d/%d = %.2f%%' % (pos, size*2, pct)
37
38     f = open(path)
39     data = f.read()
40     f.close()
41
42     if opts.truncate != -1:
43         data = data[:opts.truncate]
44
45     size = len(data)
46     warnings = multidict()
47     errors = multidict()
48     for m in kDiagnosticRE.finditer(data):
49         progress(m.end())
50         if m.group(1) == 'error':
51             d = errors
52         else:
53             d = warnings
54         d[m.group(2)] = m
55     warnings = warnings.items()
56     errors = errors.items()
57     assertions = multidict()
58     for m in kAssertionRE.finditer(data):
59         print '%d/%d = %.2f%%' % (size + m.end(), size, (float(m.end()) / (size*2)) * 100.)
60         assertions[m.group(1)] = m
61     assertions = assertions.items()
62
63     # Manual scan for stack traces
64     aborts = multidict()
65     if 0:
66         prevLine = None
67         lnIter = iter(data.split('\n'))
68         for ln in lnIter:
69             m = kStackDumpLineRE.match(ln)
70             if m:
71                 stack = [m.group(2)]
72                 for ln in lnIter:
73                     m = kStackDumpLineRE.match(ln)
74                     if not m:
75                         break
76                     stack.append(m.group(2))
77                 if prevLine is None or not kAssertionRE.match(prevLine):
78                     aborts[tuple(stack)] = stack
79             prevLine = ln
80
81     sections = [
82         (warnings, 'Warnings'),
83         (errors, 'Errors'),
84         (assertions, 'Assertions'),
85         (aborts.items(), 'Aborts'),
86         ]
87
88     if opts.ascending:
89         sections.reverse()
90
91     for l,title in sections:
92         l.sort(key = lambda (a,b): -len(b))
93         if l:
94             print '-- %d %s (%d kinds) --' % (sum([len(b) for a,b in l]), title, len(l))
95             for name,elts in l:
96                 print '%5d:' % len(elts), name
97
98 def main():
99     global options
100     from optparse import OptionParser
101     parser = OptionParser("usage: %prog [options] {inputs}")
102     parser.add_option("", "--ascending", dest="ascending",
103                       help="Print output in ascending order of severity.",
104                       action="store_true", default=False)
105     parser.add_option("", "--truncate", dest="truncate",
106                       help="Truncate input file (for testing).",
107                       type=int, action="store", default=-1)
108     (opts, args) = parser.parse_args()
109     
110     if not args:
111         parser.error('No inputs specified')
112
113     for arg in args:
114         readInfo(arg, opts)
115
116 if __name__=='__main__':
117     main()