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