xref: /aosp_15_r20/external/llvm/utils/clang-parse-diagnostics-file (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker#!/usr/bin/env python
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Workerimport os
4*9880d681SAndroid Build Coastguard Workerimport plistlib
5*9880d681SAndroid Build Coastguard Worker
6*9880d681SAndroid Build Coastguard Workerdef main():
7*9880d681SAndroid Build Coastguard Worker    from optparse import OptionParser, OptionGroup
8*9880d681SAndroid Build Coastguard Worker    parser = OptionParser("""\
9*9880d681SAndroid Build Coastguard WorkerUsage: %prog [options] <path>
10*9880d681SAndroid Build Coastguard Worker
11*9880d681SAndroid Build Coastguard WorkerUtility for dumping Clang-style logged diagnostics.\
12*9880d681SAndroid Build Coastguard Worker""")
13*9880d681SAndroid Build Coastguard Worker    parser.add_option("-a", "--all", action="store_true", dest="all",
14*9880d681SAndroid Build Coastguard Worker                      default=False, help="dump all messages.")
15*9880d681SAndroid Build Coastguard Worker    parser.add_option("-e", "--error", action="store_true", dest="error",
16*9880d681SAndroid Build Coastguard Worker                      default=False, help="dump 'error' messages.")
17*9880d681SAndroid Build Coastguard Worker    parser.add_option("-f", "--fatal", action="store_true", dest="fatal",
18*9880d681SAndroid Build Coastguard Worker                      default=False, help="dump 'fatal error' messages.")
19*9880d681SAndroid Build Coastguard Worker    parser.add_option("-i", "--ignored", action="store_true", dest="ignored",
20*9880d681SAndroid Build Coastguard Worker                      default=False, help="dump 'ignored' messages.")
21*9880d681SAndroid Build Coastguard Worker    parser.add_option("-n", "--note", action="store_true", dest="note",
22*9880d681SAndroid Build Coastguard Worker                      default=False, help="dump 'note' messages.")
23*9880d681SAndroid Build Coastguard Worker    parser.add_option("-w", "--warning", action="store_true", dest="warning",
24*9880d681SAndroid Build Coastguard Worker                      default=False, help="dump 'warning' messages.")
25*9880d681SAndroid Build Coastguard Worker    (opts, args) = parser.parse_args()
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Worker    if len(args) != 1:
28*9880d681SAndroid Build Coastguard Worker        parser.error("invalid number of arguments")
29*9880d681SAndroid Build Coastguard Worker
30*9880d681SAndroid Build Coastguard Worker    levels = {'error': False, 'fatal error': False, 'ignored': False,
31*9880d681SAndroid Build Coastguard Worker              'note': False, 'warning': False}
32*9880d681SAndroid Build Coastguard Worker    if opts.error:
33*9880d681SAndroid Build Coastguard Worker        levels['error'] = True
34*9880d681SAndroid Build Coastguard Worker    if opts.fatal:
35*9880d681SAndroid Build Coastguard Worker        levels['fatal error'] = True
36*9880d681SAndroid Build Coastguard Worker    if opts.ignored:
37*9880d681SAndroid Build Coastguard Worker        levels['ignored'] = True
38*9880d681SAndroid Build Coastguard Worker    if opts.note:
39*9880d681SAndroid Build Coastguard Worker        levels['note'] = True
40*9880d681SAndroid Build Coastguard Worker    if opts.warning:
41*9880d681SAndroid Build Coastguard Worker        levels['warning'] = True
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Worker    path, = args
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Worker    # Read the diagnostics log.
46*9880d681SAndroid Build Coastguard Worker    f = open(path)
47*9880d681SAndroid Build Coastguard Worker    try:
48*9880d681SAndroid Build Coastguard Worker        data = f.read()
49*9880d681SAndroid Build Coastguard Worker    finally:
50*9880d681SAndroid Build Coastguard Worker        f.close()
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Worker    # Complete the plist (the log itself is just the chunks).
53*9880d681SAndroid Build Coastguard Worker    data = """\
54*9880d681SAndroid Build Coastguard Worker<?xml version="1.0" encoding="UTF-8"?>
55*9880d681SAndroid Build Coastguard Worker<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" \
56*9880d681SAndroid Build Coastguard Worker                       "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
57*9880d681SAndroid Build Coastguard Worker<plist version="1.0">
58*9880d681SAndroid Build Coastguard Worker<array>
59*9880d681SAndroid Build Coastguard Worker%s
60*9880d681SAndroid Build Coastguard Worker</array>
61*9880d681SAndroid Build Coastguard Worker</plist>""" % data
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Worker    # Get the list of files and diagnostics to report.
64*9880d681SAndroid Build Coastguard Worker    to_report = []
65*9880d681SAndroid Build Coastguard Worker    diags = plistlib.readPlistFromString(data)
66*9880d681SAndroid Build Coastguard Worker    for file_diags in diags:
67*9880d681SAndroid Build Coastguard Worker        file = file_diags.get('main-file')
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker        # Ignore diagnostics for 'conftest.c', which is the file autoconf uses
70*9880d681SAndroid Build Coastguard Worker        # for its tests (which frequently will have warnings).
71*9880d681SAndroid Build Coastguard Worker        if os.path.basename(file) == 'conftest.c':
72*9880d681SAndroid Build Coastguard Worker            continue
73*9880d681SAndroid Build Coastguard Worker
74*9880d681SAndroid Build Coastguard Worker        # Get the diagnostics for the selected levels.
75*9880d681SAndroid Build Coastguard Worker        selected_diags = [d
76*9880d681SAndroid Build Coastguard Worker                          for d in file_diags.get('diagnostics', ())
77*9880d681SAndroid Build Coastguard Worker                          if levels[d.get('level')] or opts.all]
78*9880d681SAndroid Build Coastguard Worker        if selected_diags:
79*9880d681SAndroid Build Coastguard Worker            to_report.append((file, selected_diags))
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker    # If there are no diagnostics to report, show nothing.
82*9880d681SAndroid Build Coastguard Worker    if not to_report:
83*9880d681SAndroid Build Coastguard Worker        return
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker    # Otherwise, print out the diagnostics.
86*9880d681SAndroid Build Coastguard Worker    print
87*9880d681SAndroid Build Coastguard Worker    print "**** BUILD DIAGNOSTICS ****"
88*9880d681SAndroid Build Coastguard Worker    for file,selected_diags in to_report:
89*9880d681SAndroid Build Coastguard Worker        print "*** %s ***" % file
90*9880d681SAndroid Build Coastguard Worker        for d in selected_diags:
91*9880d681SAndroid Build Coastguard Worker            print " %s:%s:%s: %s: %s" % (
92*9880d681SAndroid Build Coastguard Worker                d.get('filename'), d.get('line'), d.get('column'),
93*9880d681SAndroid Build Coastguard Worker                d.get('level'), d.get('message'))
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Workerif __name__ == "__main__":
96*9880d681SAndroid Build Coastguard Worker    main()
97