172952Srwatson#!/usr/bin/env python 224143Sjoerg 324143Sjoergimport os 4164784Skeramidaimport plistlib 524143Sjoerg 6164784Skeramidadef main(): 7164784Skeramida from optparse import OptionParser, OptionGroup 8164784Skeramida parser = OptionParser("""\ 9164784SkeramidaUsage: %prog [options] <path> 10164784Skeramida 11164784SkeramidaUtility for dumping Clang-style logged diagnostics.\ 1224143Sjoerg""") 13201386Sed parser.add_option("-a", "--all", action="store_true", dest="all", 14201386Sed default=False, help="dump all messages.") 1524143Sjoerg parser.add_option("-e", "--error", action="store_true", dest="error", 1624143Sjoerg default=False, help="dump 'error' messages.") 1724143Sjoerg parser.add_option("-f", "--fatal", action="store_true", dest="fatal", 18164784Skeramida default=False, help="dump 'fatal error' messages.") 1924143Sjoerg parser.add_option("-i", "--ignored", action="store_true", dest="ignored", 2024143Sjoerg default=False, help="dump 'ignored' messages.") 2124143Sjoerg parser.add_option("-n", "--note", action="store_true", dest="note", 2224143Sjoerg default=False, help="dump 'note' messages.") 2324143Sjoerg parser.add_option("-w", "--warning", action="store_true", dest="warning", 24266280Sbdrewery default=False, help="dump 'warning' messages.") 25266280Sbdrewery (opts, args) = parser.parse_args() 2624143Sjoerg 27164784Skeramida if len(args) != 1: 28164784Skeramida parser.error("invalid number of arguments") 29164784Skeramida 30164784Skeramida levels = {'error': False, 'fatal error': False, 'ignored': False, 31164784Skeramida 'note': False, 'warning': False} 3224143Sjoerg if opts.error: 33164784Skeramida levels['error'] = True 34284484Smarcel if opts.fatal: 35284484Smarcel levels['fatal error'] = True 3679636Sru if opts.ignored: 3779636Sru levels['ignored'] = True 3879636Sru if opts.note: 3979636Sru levels['note'] = True 4079636Sru if opts.warning: 4179636Sru levels['warning'] = True 4279636Sru 4379636Sru path, = args 4479636Sru 45164784Skeramida # Read the diagnostics log. 46164784Skeramida f = open(path) 47164784Skeramida try: 48164784Skeramida data = f.read() 4924143Sjoerg finally: 50 f.close() 51 52 # Complete the plist (the log itself is just the chunks). 53 data = """\ 54<?xml version="1.0" encoding="UTF-8"?> 55<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" \ 56 "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 57<plist version="1.0"> 58<array> 59%s 60</array> 61</plist>""" % data 62 63 # Get the list of files and diagnostics to report. 64 to_report = [] 65 diags = plistlib.readPlistFromString(data) 66 for file_diags in diags: 67 file = file_diags.get('main-file') 68 69 # Diagnostics from modules don't have a main-file listed. 70 if not file: 71 file = '<module-includes>' 72 73 # Ignore diagnostics for 'conftest.c', which is the file autoconf uses 74 # for its tests (which frequently will have warnings). 75 if os.path.basename(file) == 'conftest.c': 76 continue 77 78 # Get the diagnostics for the selected levels. 79 selected_diags = [d 80 for d in file_diags.get('diagnostics', ()) 81 if levels[d.get('level')] or opts.all] 82 if selected_diags: 83 to_report.append((file, selected_diags)) 84 85 # If there are no diagnostics to report, show nothing. 86 if not to_report: 87 return 88 89 # Otherwise, print out the diagnostics. 90 print 91 print "**** BUILD DIAGNOSTICS ****" 92 for file,selected_diags in to_report: 93 print "*** %s ***" % file 94 for d in selected_diags: 95 print " %s:%s:%s: %s: %s" % ( 96 d.get('filename'), d.get('line'), d.get('column'), 97 d.get('level'), d.get('message')) 98 99if __name__ == "__main__": 100 main() 101