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