Home | History | Annotate | Line # | Download | only in header-tools
      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