1#! /usr/bin/python2 2import os.path 3import sys 4import shlex 5import re 6 7from headerutils import * 8 9def pretty_name (name): 10 return name.replace(".","_").replace("-","_").replace("/","_").replace("+","_"); 11 12 13include_files = list() 14edges = 0 15one_c = False 16clink = list() 17noterm = False 18 19def build_inclist (output, filen): 20 global edges 21 global one_c 22 global clink 23 global noterm 24 inc = build_include_list (filen) 25 if one_c and filen[-2:] == ".c": 26 pn = "all_c" 27 else: 28 pn = pretty_name(filen) 29 for nm in inc: 30 if pn == "all_c": 31 if nm not in clink: 32 if len(build_include_list(nm)) != 0 or not noterm: 33 output.write (pretty_name(nm) + " -> " + pn + ";\n") 34 edges = edges + 1 35 if nm not in include_files: 36 include_files.append(nm) 37 clink.append (nm) 38 else: 39 output.write (pretty_name(nm) + " -> " + pn + ";\n") 40 edges = edges + 1 41 if nm not in include_files: 42 include_files.append(nm) 43 return len(inc) == 0 44 45dotname = "graph.dot" 46graphname = "graph.png" 47 48def build_dot_file (file_list): 49 global one_c 50 output = open(dotname, "w") 51 output.write ("digraph incweb {\n"); 52 if one_c: 53 output.write ("all_c [shape=box];\n"); 54 for x in file_list: 55 if x[-2:] == ".h": 56 include_files.append (x) 57 elif os.path.exists (x): 58 build_inclist (output, x) 59 if not one_c: 60 output.write (pretty_name (x) + "[shape=box];\n") 61 62 for x in include_files: 63 term = build_inclist (output, x) 64 if term: 65 output.write (pretty_name(x) + " [style=filled];\n") 66 67 output.write ("}\n"); 68 69 70files = list() 71dohelp = False 72edge_thresh = 0 73for arg in sys.argv[1:]: 74 if arg[0:2] == "-o": 75 dotname = arg[2:]+".dot" 76 graphname = arg[2:]+".png" 77 elif arg[0:2] == "-h": 78 dohelp = True 79 elif arg[0:2] == "-a": 80 one_c = True 81 if arg[0:3] == "-at": 82 noterm = True 83 elif arg[0:2] == "-f": 84 if not os.path.exists (arg[2:]): 85 print "Option " + arg +" doesn't specify a proper file" 86 dohelp = True 87 else: 88 sfile = open (arg[2:], "r") 89 srcdata = sfile.readlines() 90 sfile.close() 91 for x in srcdata: 92 files.append(x.rstrip()) 93 elif arg[0:2] == "-n": 94 edge_thresh = int (arg[2:]) 95 elif arg[0:1] == "-": 96 print "Unrecognized option " + arg 97 dohelp = True 98 else: 99 files.append (arg) 100 101if len(sys.argv) == 1: 102 dohelp = True 103 104if dohelp: 105 print "Generates a graph of the include web for specified files." 106 print "Usage: [-finput_file] [-h] [-ooutput] [file1 ... [filen]]" 107 print " -finput_file : Input file containing a list of files to process." 108 print " -ooutput : Specifies output to output.dot and output.png." 109 print " defaults to graph.dot and graph.png." 110 print " -nnum : Specifies the # of edges beyond which sfdp is invoked. def=0." 111 print " -a : Aggregate all .c files to 1 file. Shows only include web." 112 print " -at : Aggregate, but don't include terminal.h to .c links." 113 print " -h : Print this help." 114else: 115 print files 116 build_dot_file (files) 117 if edges > edge_thresh: 118 os.system ("sfdp -Tpng " + dotname + " -o" + graphname) 119 else: 120 os.system ("dot -Tpng " + dotname + " -o" + graphname) 121 122 123