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