| #!/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() |