158194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar#!/usr/bin/env python 258194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar 370d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbarimport os 458194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbarimport plistlib 558194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar 658194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbardef main(): 758194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar from optparse import OptionParser, OptionGroup 858194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar parser = OptionParser("""\ 97f53d592ffbef0225a95cbd97d653307f546a347Chad RosierUsage: %prog [options] <path> 1058194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar 1158194307c1a45f6a20f5ed421c97309a9e007e46Daniel DunbarUtility for dumping Clang-style logged diagnostics.\ 1258194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar""") 137f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier parser.add_option("-a", "--all", action="store_true", dest="all", 147f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier default=False, help="dump all messages.") 157f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier parser.add_option("-e", "--error", action="store_true", dest="error", 167f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier default=False, help="dump 'error' messages.") 177f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier parser.add_option("-f", "--fatal", action="store_true", dest="fatal", 187f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier default=False, help="dump 'fatal error' messages.") 197f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier parser.add_option("-i", "--ignored", action="store_true", dest="ignored", 207f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier default=False, help="dump 'ignored' messages.") 217f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier parser.add_option("-n", "--note", action="store_true", dest="note", 227f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier default=False, help="dump 'note' messages.") 237f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier parser.add_option("-w", "--warning", action="store_true", dest="warning", 247f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier default=False, help="dump 'warning' messages.") 2558194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar (opts, args) = parser.parse_args() 2658194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar 2758194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar if len(args) != 1: 2858194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar parser.error("invalid number of arguments") 2958194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar 307f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier levels = {'error': False, 'fatal error': False, 'ignored': False, 317f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier 'note': False, 'warning': False} 327f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier if opts.error: 337f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier levels['error'] = True 347f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier if opts.fatal: 357f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier levels['fatal error'] = True 367f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier if opts.ignored: 377f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier levels['ignored'] = True 387f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier if opts.note: 397f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier levels['note'] = True 407f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier if opts.warning: 417f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier levels['warning'] = True 427f53d592ffbef0225a95cbd97d653307f546a347Chad Rosier 4358194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar path, = args 4458194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar 4558194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar # Read the diagnostics log. 4658194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar f = open(path) 4758194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar try: 4858194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar data = f.read() 4958194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar finally: 5058194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar f.close() 5158194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar 5258194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar # Complete the plist (the log itself is just the chunks). 5358194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar data = """\ 5458194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar<?xml version="1.0" encoding="UTF-8"?> 5558194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" \ 5658194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 5758194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar<plist version="1.0"> 5858194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar<array> 5958194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar%s 6058194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar</array> 6158194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar</plist>""" % data 6258194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar 6370d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar # Get the list of files and diagnostics to report. 6470d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar to_report = [] 6558194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar diags = plistlib.readPlistFromString(data) 6670d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar for file_diags in diags: 6770d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar file = file_diags.get('main-file') 6870d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar 6970d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar # Ignore diagnostics for 'conftest.c', which is the file autoconf uses 7070d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar # for its tests (which frequently will have warnings). 7170d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar if os.path.basename(file) == 'conftest.c': 7270d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar continue 7370d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar 7470d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar # Get the diagnostics for the selected levels. 7570d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar selected_diags = [d 7670d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar for d in file_diags.get('diagnostics', ()) 7770d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar if levels[d.get('level')] or opts.all] 7870d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar if selected_diags: 7970d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar to_report.append((file, selected_diags)) 8058194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar 8170d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar # If there are no diagnostics to report, show nothing. 8270d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar if not to_report: 8370d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar return 8470d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar 8570d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar # Otherwise, print out the diagnostics. 8658194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar print 8758194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar print "**** BUILD DIAGNOSTICS ****" 8870d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar for file,selected_diags in to_report: 8958194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar print "*** %s ***" % file 9070d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar for d in selected_diags: 9170d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar print " %s:%s:%s: %s: %s" % ( 9270d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar d.get('filename'), d.get('line'), d.get('column'), 9370d4e75a37fcd98e9a29073ef6d84fad6663bb02Daniel Dunbar d.get('level'), d.get('message')) 9458194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar 9558194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbarif __name__ == "__main__": 9658194307c1a45f6a20f5ed421c97309a9e007e46Daniel Dunbar main() 97