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