#! /usr/bin/python2 import os.path import sys import shlex import re from headerutils import * def pretty_name (name): return name.replace(".","_").replace("-","_").replace("/","_").replace("+","_"); include_files = list() edges = 0 one_c = False clink = list() noterm = False def build_inclist (output, filen): global edges global one_c global clink global noterm inc = build_include_list (filen) if one_c and filen[-2:] == ".c": pn = "all_c" else: pn = pretty_name(filen) for nm in inc: if pn == "all_c": if nm not in clink: if len(build_include_list(nm)) != 0 or not noterm: output.write (pretty_name(nm) + " -> " + pn + ";\n") edges = edges + 1 if nm not in include_files: include_files.append(nm) clink.append (nm) else: output.write (pretty_name(nm) + " -> " + pn + ";\n") edges = edges + 1 if nm not in include_files: include_files.append(nm) return len(inc) == 0 dotname = "graph.dot" graphname = "graph.png" def build_dot_file (file_list): global one_c output = open(dotname, "w") output.write ("digraph incweb {\n"); if one_c: output.write ("all_c [shape=box];\n"); for x in file_list: if x[-2:] == ".h": include_files.append (x) elif os.path.exists (x): build_inclist (output, x) if not one_c: output.write (pretty_name (x) + "[shape=box];\n") for x in include_files: term = build_inclist (output, x) if term: output.write (pretty_name(x) + " [style=filled];\n") output.write ("}\n"); files = list() dohelp = False edge_thresh = 0 for arg in sys.argv[1:]: if arg[0:2] == "-o": dotname = arg[2:]+".dot" graphname = arg[2:]+".png" elif arg[0:2] == "-h": dohelp = True elif arg[0:2] == "-a": one_c = True if arg[0:3] == "-at": noterm = True elif arg[0:2] == "-f": if not os.path.exists (arg[2:]): print "Option " + arg +" doesn't specify a proper file" dohelp = True else: sfile = open (arg[2:], "r") srcdata = sfile.readlines() sfile.close() for x in srcdata: files.append(x.rstrip()) elif arg[0:2] == "-n": edge_thresh = int (arg[2:]) elif arg[0:1] == "-": print "Unrecognized option " + arg dohelp = True else: files.append (arg) if len(sys.argv) == 1: dohelp = True if dohelp: print "Generates a graph of the include web for specified files." print "Usage: [-finput_file] [-h] [-ooutput] [file1 ... [filen]]" print " -finput_file : Input file containing a list of files to process." print " -ooutput : Specifies output to output.dot and output.png." print " defaults to graph.dot and graph.png." print " -nnum : Specifies the # of edges beyond which sfdp is invoked. def=0." print " -a : Aggregate all .c files to 1 file. Shows only include web." print " -at : Aggregate, but don't include terminal.h to .c links." print " -h : Print this help." else: print files build_dot_file (files) if edges > edge_thresh: os.system ("sfdp -Tpng " + dotname + " -o" + graphname) else: os.system ("dot -Tpng " + dotname + " -o" + graphname)