xref: /netbsd-src/external/gpl3/gcc/dist/contrib/header-tools/show-headers (revision f9a78e0e885f664fa1b5fd1637673b39c1aa53b3)
1*f9a78e0eSmrg#! /usr/bin/python2
2*f9a78e0eSmrgimport os.path
3*f9a78e0eSmrgimport sys
4*f9a78e0eSmrgimport shlex
5*f9a78e0eSmrgimport re
6*f9a78e0eSmrg
7*f9a78e0eSmrgfrom headerutils import *
8*f9a78e0eSmrg
9*f9a78e0eSmrg
10*f9a78e0eSmrgtabstop = 2
11*f9a78e0eSmrgpadding = "                                                                  "
12*f9a78e0eSmrgseen = { }
13*f9a78e0eSmrgoutput = list()
14*f9a78e0eSmrgsummary = list()
15*f9a78e0eSmrgsawcore = False
16*f9a78e0eSmrg
17*f9a78e0eSmrg# list of headers to emphasize
18*f9a78e0eSmrghighlight = list ()
19*f9a78e0eSmrg
20*f9a78e0eSmrgbld_dir = ""
21*f9a78e0eSmrg# search path for headers
22*f9a78e0eSmrgincl_dirs = ["../include", "../libcpp/include", "common", "c-family", "c", "cp", "config" ]
23*f9a78e0eSmrg# extra search paths to look in *after* the directory the source file is in.
24*f9a78e0eSmrg
25*f9a78e0eSmrg# append (1) to the end of the first line which includes INC in list INC.
26*f9a78e0eSmrgdef append_1 (output, inc):
27*f9a78e0eSmrg  for n,t in enumerate (output):
28*f9a78e0eSmrg    idx = t.find(inc)
29*f9a78e0eSmrg    if idx != -1:
30*f9a78e0eSmrg      eos = idx + len (inc)
31*f9a78e0eSmrg      t = t[:eos] + "  (1)" + t[eos+1:]
32*f9a78e0eSmrg      output[n] = t
33*f9a78e0eSmrg      return
34*f9a78e0eSmrg
35*f9a78e0eSmrg# These headers show up as duplicates in rtl.h due to conditional code arund the includes
36*f9a78e0eSmrgrtl_core = [ "machmode.h" , "signop.h" , "wide-int.h" , "double-int.h" , "real.h" , "fixed-value.h" , "statistics.h" , "vec.h" , "hash-table.h" , "hash-set.h" , "input.h" , "is-a.h" ]
37*f9a78e0eSmrg
38*f9a78e0eSmrgdef find_include_data (inc):
39*f9a78e0eSmrg  global sawcore
40*f9a78e0eSmrg  for x in incl_dirs:
41*f9a78e0eSmrg    nm = x+"/"+inc
42*f9a78e0eSmrg    if os.path.exists (nm):
43*f9a78e0eSmrg      info = find_unique_include_list (nm)
44*f9a78e0eSmrg      # rtl.h mimics coretypes for GENERATOR FILES, remove if coretypes.h seen.
45*f9a78e0eSmrg      if inc == "coretypes.h":
46*f9a78e0eSmrg        sawcore = True
47*f9a78e0eSmrg      elif inc  == "rtl.h" and sawcore:
48*f9a78e0eSmrg        for i in rtl_core:
49*f9a78e0eSmrg          if i in info:
50*f9a78e0eSmrg            info.remove (i)
51*f9a78e0eSmrg      return info
52*f9a78e0eSmrg  return list()
53*f9a78e0eSmrg
54*f9a78e0eSmrgdef process_include (inc, indent):
55*f9a78e0eSmrg  if inc[-2:] != ".h":
56*f9a78e0eSmrg    return
57*f9a78e0eSmrg  bname  = os.path.basename (inc)
58*f9a78e0eSmrg  if bname in highlight:
59*f9a78e0eSmrg    arrow = "                <<-------"
60*f9a78e0eSmrg    if bname not in summary:
61*f9a78e0eSmrg      summary.append (bname)
62*f9a78e0eSmrg  else:
63*f9a78e0eSmrg    arrow = ""
64*f9a78e0eSmrg  if seen.get(inc) == None:
65*f9a78e0eSmrg    seen[inc] = 1
66*f9a78e0eSmrg    output.append (padding[:indent*tabstop] + bname + arrow)
67*f9a78e0eSmrg    info = find_include_data (inc)
68*f9a78e0eSmrg    for y in info:
69*f9a78e0eSmrg      process_include (y, indent+1)
70*f9a78e0eSmrg  else:
71*f9a78e0eSmrg    seen[inc] += 1
72*f9a78e0eSmrg    if (seen[inc] == 2):
73*f9a78e0eSmrg      append_1(output, inc)
74*f9a78e0eSmrg    output.append (padding[:indent*tabstop] + bname + "  ("+str(seen[inc])+")" + arrow)
75*f9a78e0eSmrg
76*f9a78e0eSmrg
77*f9a78e0eSmrg
78*f9a78e0eSmrgextradir = list()
79*f9a78e0eSmrgusage = False
80*f9a78e0eSmrgsrc = list()
81*f9a78e0eSmrg
82*f9a78e0eSmrgfor x in sys.argv[1:]:
83*f9a78e0eSmrg  if x[0:2] == "-i":
84*f9a78e0eSmrg    bld = x[2:]
85*f9a78e0eSmrg    extradir.append (bld)
86*f9a78e0eSmrg  elif x[0:2] == "-s":
87*f9a78e0eSmrg    highlight.append (os.path.basename (x[2:]))
88*f9a78e0eSmrg  elif x[0:2] == "-h":
89*f9a78e0eSmrg    usage = True
90*f9a78e0eSmrg  else:
91*f9a78e0eSmrg    src.append (x)
92*f9a78e0eSmrg
93*f9a78e0eSmrgif len(src) != 1:
94*f9a78e0eSmrg  usage = True
95*f9a78e0eSmrgelif not os.path.exists (src[0]):
96*f9a78e0eSmrg  print src[0] + ": Requested source file does not exist.\n"
97*f9a78e0eSmrg  usage = True
98*f9a78e0eSmrg
99*f9a78e0eSmrgif usage:
100*f9a78e0eSmrg  print "show-headers [-idir] [-sfilen] file1 "
101*f9a78e0eSmrg  print " "
102*f9a78e0eSmrg  print " Show a hierarchical visual format how many times each header file"
103*f9a78e0eSmrg  print " is included in a source file.  Should be run from the source directory"
104*f9a78e0eSmrg  print " files from find-include-depends"
105*f9a78e0eSmrg  print "      -s : search for a header, and point it out."
106*f9a78e0eSmrg  print "      -i : Specifies additonal directories to search for includes."
107*f9a78e0eSmrg  sys.exit(0)
108*f9a78e0eSmrg
109*f9a78e0eSmrg
110*f9a78e0eSmrg
111*f9a78e0eSmrgif extradir:
112*f9a78e0eSmrg  incl_dirs = extradir + incl_dirs;
113*f9a78e0eSmrg
114*f9a78e0eSmrgblddir = find_gcc_bld_dir ("../..")
115*f9a78e0eSmrg
116*f9a78e0eSmrgif blddir:
117*f9a78e0eSmrg  print "Using build directory: " + blddir
118*f9a78e0eSmrg  incl_dirs.insert (0, blddir)
119*f9a78e0eSmrgelse:
120*f9a78e0eSmrg  print "Could not find a build directory, better results if you specify one with -i"
121*f9a78e0eSmrg
122*f9a78e0eSmrg# search path is now ".", blddir, extradirs_from_-i, built_in_incl_dirs
123*f9a78e0eSmrgincl_dirs.insert (0, ".")
124*f9a78e0eSmrg
125*f9a78e0eSmrg# if source is in a subdirectory, prepend the subdirectory to the search list
126*f9a78e0eSmrgx = src[0]
127*f9a78e0eSmrgsrcpath = os.path.dirname(x)
128*f9a78e0eSmrgif srcpath:
129*f9a78e0eSmrg  incl_dirs.insert (0, srcpath)
130*f9a78e0eSmrg
131*f9a78e0eSmrgoutput = list()
132*f9a78e0eSmrgsawcore = False
133*f9a78e0eSmrg
134*f9a78e0eSmrgdata = open (x).read().splitlines()
135*f9a78e0eSmrgfor line in data:
136*f9a78e0eSmrg  d = find_pound_include (line, True, True)
137*f9a78e0eSmrg  if d and d[-2:] == ".h":
138*f9a78e0eSmrg    process_include (d, 1)
139*f9a78e0eSmrg
140*f9a78e0eSmrgprint "\n" + x
141*f9a78e0eSmrgfor line in output:
142*f9a78e0eSmrg  print line
143*f9a78e0eSmrg
144*f9a78e0eSmrgif highlight:
145*f9a78e0eSmrg  print " "
146*f9a78e0eSmrg  for h in summary:
147*f9a78e0eSmrg    print h + " is included by source file."
148*f9a78e0eSmrg  for h in highlight:
149*f9a78e0eSmrg    if h not in summary:
150*f9a78e0eSmrg      print h + " is not included by source file."
151*f9a78e0eSmrg
152