summaryrefslogtreecommitdiff
path: root/clang/utils/SummarizeErrors
diff options
context:
space:
mode:
Diffstat (limited to 'clang/utils/SummarizeErrors')
-rwxr-xr-xclang/utils/SummarizeErrors117
1 files changed, 117 insertions, 0 deletions
diff --git a/clang/utils/SummarizeErrors b/clang/utils/SummarizeErrors
new file mode 100755
index 0000000..b6e9122
--- /dev/null
+++ b/clang/utils/SummarizeErrors
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+
+import os, sys, re
+
+class multidict:
+ def __init__(self, elts=()):
+ self.data = {}
+ for key,value in elts:
+ self[key] = value
+
+ def __getitem__(self, item):
+ return self.data[item]
+ def __setitem__(self, key, value):
+ if key in self.data:
+ self.data[key].append(value)
+ else:
+ self.data[key] = [value]
+ def items(self):
+ return self.data.items()
+ def values(self):
+ return self.data.values()
+ def keys(self):
+ return self.data.keys()
+ def __len__(self):
+ return len(self.data)
+
+kDiagnosticRE = re.compile(': (error|warning): (.*)')
+kAssertionRE = re.compile('Assertion failed: (.*, function .*, file .*, line [0-9]+\\.)')
+
+def readInfo(path, opts):
+ lastProgress = [-100,0]
+ def progress(pos):
+ pct = (100. * pos) / (size * 2)
+ if (pct - lastProgress[0]) >= 10:
+ lastProgress[0] = pct
+ print '%d/%d = %.2f%%' % (pos, size*2, pct)
+
+ f = open(path)
+ data = f.read()
+ f.close()
+
+ if opts.truncate != -1:
+ data = data[:opts.truncate]
+
+ size = len(data)
+ warnings = multidict()
+ errors = multidict()
+ for m in kDiagnosticRE.finditer(data):
+ progress(m.end())
+ if m.group(1) == 'error':
+ d = errors
+ else:
+ d = warnings
+ d[m.group(2)] = m
+ warnings = warnings.items()
+ errors = errors.items()
+ assertions = multidict()
+ for m in kAssertionRE.finditer(data):
+ print '%d/%d = %.2f%%' % (size + m.end(), size, (float(m.end()) / (size*2)) * 100.)
+ assertions[m.group(1)] = m
+ assertions = assertions.items()
+
+ # Manual scan for stack traces
+ aborts = multidict()
+ if 0:
+ prevLine = None
+ lnIter = iter(data.split('\n'))
+ for ln in lnIter:
+ m = kStackDumpLineRE.match(ln)
+ if m:
+ stack = [m.group(2)]
+ for ln in lnIter:
+ m = kStackDumpLineRE.match(ln)
+ if not m:
+ break
+ stack.append(m.group(2))
+ if prevLine is None or not kAssertionRE.match(prevLine):
+ aborts[tuple(stack)] = stack
+ prevLine = ln
+
+ sections = [
+ (warnings, 'Warnings'),
+ (errors, 'Errors'),
+ (assertions, 'Assertions'),
+ (aborts.items(), 'Aborts'),
+ ]
+
+ if opts.ascending:
+ sections.reverse()
+
+ for l,title in sections:
+ l.sort(key = lambda (a,b): -len(b))
+ if l:
+ print '-- %d %s (%d kinds) --' % (sum([len(b) for a,b in l]), title, len(l))
+ for name,elts in l:
+ print '%5d:' % len(elts), name
+
+def main():
+ global options
+ from optparse import OptionParser
+ parser = OptionParser("usage: %prog [options] {inputs}")
+ parser.add_option("", "--ascending", dest="ascending",
+ help="Print output in ascending order of severity.",
+ action="store_true", default=False)
+ parser.add_option("", "--truncate", dest="truncate",
+ help="Truncate input file (for testing).",
+ type=int, action="store", default=-1)
+ (opts, args) = parser.parse_args()
+
+ if not args:
+ parser.error('No inputs specified')
+
+ for arg in args:
+ readInfo(arg, opts)
+
+if __name__=='__main__':
+ main()