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