#!/usr/bin/env python

import os
import plistlib

def main():
    from optparse import OptionParser, OptionGroup
    parser = OptionParser("""\
Usage: %prog [options] <path>

Utility for dumping Clang-style logged diagnostics.\
""")
    parser.add_option("-a", "--all", action="store_true", dest="all", 
                      default=False, help="dump all messages.")
    parser.add_option("-e", "--error", action="store_true", dest="error", 
                      default=False, help="dump 'error' messages.")
    parser.add_option("-f", "--fatal", action="store_true", dest="fatal", 
                      default=False, help="dump 'fatal error' messages.")
    parser.add_option("-i", "--ignored", action="store_true", dest="ignored", 
                      default=False, help="dump 'ignored' messages.")
    parser.add_option("-n", "--note", action="store_true", dest="note", 
                      default=False, help="dump 'note' messages.")
    parser.add_option("-w", "--warning", action="store_true", dest="warning", 
                      default=False, help="dump 'warning' messages.")
    (opts, args) = parser.parse_args()

    if len(args) != 1:
        parser.error("invalid number of arguments")

    levels = {'error': False, 'fatal error': False, 'ignored': False,
              'note': False, 'warning': False}
    if opts.error:
        levels['error'] = True
    if opts.fatal:
        levels['fatal error'] = True
    if opts.ignored:
        levels['ignored'] = True
    if opts.note:
        levels['note'] = True
    if opts.warning:
        levels['warning'] = True

    path, = args

    # Read the diagnostics log.
    f = open(path)
    try:
        data = f.read()
    finally:
        f.close()

    # Complete the plist (the log itself is just the chunks).
    data = """\
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" \
                       "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
%s
</array>
</plist>""" % data

    # Get the list of files and diagnostics to report.
    to_report = []
    diags = plistlib.readPlistFromString(data)
    for file_diags in diags:
        file = file_diags.get('main-file')

        # Ignore diagnostics for 'conftest.c', which is the file autoconf uses
        # for its tests (which frequently will have warnings).
        if os.path.basename(file) == 'conftest.c':
            continue

        # Get the diagnostics for the selected levels.
        selected_diags = [d
                          for d in file_diags.get('diagnostics', ())
                          if levels[d.get('level')] or opts.all]
        if selected_diags:
            to_report.append((file, selected_diags))

    # If there are no diagnostics to report, show nothing.
    if not to_report:
        return

    # Otherwise, print out the diagnostics.
    print
    print "**** BUILD DIAGNOSTICS ****"
    for file,selected_diags in to_report:
        print "*** %s ***" % file
        for d in selected_diags:
            print " %s:%s:%s: %s: %s" % (
                d.get('filename'), d.get('line'), d.get('column'),
                d.get('level'), d.get('message'))

if __name__ == "__main__":
    main()
