xref: /aosp_15_r20/external/clang/bindings/python/examples/cindex/cindex-includes.py (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li#!/usr/bin/env python
2*67e74705SXin Li
3*67e74705SXin Li#===- cindex-includes.py - cindex/Python Inclusion Graph -----*- python -*--===#
4*67e74705SXin Li#
5*67e74705SXin Li#                     The LLVM Compiler Infrastructure
6*67e74705SXin Li#
7*67e74705SXin Li# This file is distributed under the University of Illinois Open Source
8*67e74705SXin Li# License. See LICENSE.TXT for details.
9*67e74705SXin Li#
10*67e74705SXin Li#===------------------------------------------------------------------------===#
11*67e74705SXin Li
12*67e74705SXin Li"""
13*67e74705SXin LiA simple command line tool for dumping a Graphviz description (dot) that
14*67e74705SXin Lidescribes include dependencies.
15*67e74705SXin Li"""
16*67e74705SXin Li
17*67e74705SXin Lidef main():
18*67e74705SXin Li    import sys
19*67e74705SXin Li    from clang.cindex import Index
20*67e74705SXin Li
21*67e74705SXin Li    from optparse import OptionParser, OptionGroup
22*67e74705SXin Li
23*67e74705SXin Li    parser = OptionParser("usage: %prog [options] {filename} [clang-args*]")
24*67e74705SXin Li    parser.disable_interspersed_args()
25*67e74705SXin Li    (opts, args) = parser.parse_args()
26*67e74705SXin Li    if len(args) == 0:
27*67e74705SXin Li        parser.error('invalid number arguments')
28*67e74705SXin Li
29*67e74705SXin Li    # FIXME: Add an output file option
30*67e74705SXin Li    out = sys.stdout
31*67e74705SXin Li
32*67e74705SXin Li    index = Index.create()
33*67e74705SXin Li    tu = index.parse(None, args)
34*67e74705SXin Li    if not tu:
35*67e74705SXin Li        parser.error("unable to load input")
36*67e74705SXin Li
37*67e74705SXin Li    # A helper function for generating the node name.
38*67e74705SXin Li    def name(f):
39*67e74705SXin Li        if f:
40*67e74705SXin Li            return "\"" + f.name + "\""
41*67e74705SXin Li
42*67e74705SXin Li    # Generate the include graph
43*67e74705SXin Li    out.write("digraph G {\n")
44*67e74705SXin Li    for i in tu.get_includes():
45*67e74705SXin Li        line = "  ";
46*67e74705SXin Li        if i.is_input_file:
47*67e74705SXin Li            # Always write the input file as a node just in case it doesn't
48*67e74705SXin Li            # actually include anything. This would generate a 1 node graph.
49*67e74705SXin Li            line += name(i.include)
50*67e74705SXin Li        else:
51*67e74705SXin Li            line += '%s->%s' % (name(i.source), name(i.include))
52*67e74705SXin Li        line += "\n";
53*67e74705SXin Li        out.write(line)
54*67e74705SXin Li    out.write("}\n")
55*67e74705SXin Li
56*67e74705SXin Liif __name__ == '__main__':
57*67e74705SXin Li    main()
58*67e74705SXin Li
59