]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/checkDeps.py
Give it a slightly bigger chance to work for non-MUON libs as well
[u/mrichter/AliRoot.git] / MUON / checkDeps.py
CommitLineData
ea1f7807 1#!/usr/bin/python
2
3import sys
4import os
5import re
6import string
7import getopt
8
9"""
10Given a directory, will look into lib*.pkg files to produce a dependency graph
11 of libraries (and DA if there are some)
ea1f7807 12"""
13
14__author__ = "L. Aphecetche aphecetc_at_in2p3_dot_fr"
48739cf2 15__version__ = "$Id$"
ea1f7807 16
17#_______________________________________________________________________________
18def usage():
19 """Describe usage of script
20 """
21 print "Usage: %s [-h | --help] [-d | --debug] [--noda] directory_to_scan" % sys.argv[0]
22 sys.exit(1)
23
24#_______________________________________________________________________________
25def getSourceFiles(lib):
26 """Extract the list of classes from a libXXX.pkg file
27 """
28
29 f = open(lib)
30 sourcefiles = []
31 for line in f:
32 l = line.strip()
33 if re.search('Ali',l) and re.search('.cxx',l):
34 l = re.sub('SRCS',' ',l)
35 l = re.sub(':=',' ',l)
36 l = re.sub('=',' ',l)
37 l = re.sub("\\\\",' ',l)
38 l = re.sub(".cxx",' ',l)
39 for i in l.split():
40 sourcefiles.append(i)
41 f.close()
42 return sourcefiles
43
44#_______________________________________________________________________________
45def getIncludeFiles(srcfile):
46 """Extract the list of included classes from a class
47 """
48
49 includes = []
50
51 try:
52 f = open("%s.cxx" % srcfile)
53 except:
54 print "Could not open file %s.cxx" % srcfile
55 return includes
56
57 for line in f:
58 line = line.strip()
59 if re.search("^#",line) and re.search("#include",line) and re.search('Ali',line):
60 line = re.sub("#include",' ',line)
61 i = line.index(".h")
62 line = line[:i]
63 line = re.sub("\"",' ',line)
64 line = line.strip()
65 includes.append(line)
66 f.close()
67 return includes
68
69#_______________________________________________________________________________
70def unique(list):
71 """Extract a unique list from list
72 """
73 d = {}
74 for l in list:
75 d[l] = 1
76 return d.keys()
77
78#_______________________________________________________________________________
79def findLibrary(file,allfiles):
80 """Find in which library a given class is defined
81 """
82 for k,v in allfiles.items():
83 for f in v:
84 a,f = os.path.split(f)
85 if file == f:
86 return k
87 return "external"
88
89#_______________________________________________________________________________
90def shorten(libname):
8a5956b2 91 """From libYYYxxx.pkg to YYYxxx
ea1f7807 92 """
93 s = libname
8a5956b2 94 if re.search("lib",libname):
95 s = re.sub("lib","",s)
ea1f7807 96 s = re.sub("\.pkg","",s)
97 return s
98
99#_______________________________________________________________________________
100#_______________________________________________________________________________
101#_______________________________________________________________________________
102def main():
103
104 debug = False
105 noda = False
106
107 try:
108 opts, args = getopt.getopt(sys.argv[1:],"hd",["help", "debug","noda"])
109 except getopt.GetoptError:
110 print "Error in options"
111 usage()
112
113 for o, a in opts:
114 if o in ( "-d","--debug" ):
115 debug = True
116 elif o in ( "-h","--help" ):
117 usage()
118 sys.exit()
119 elif o == "--noda":
120 noda = True
121 else:
122 assert False, "unhandled option"
123
124 dir = args[0]
125
126 # find the libraries defined in this directory (looking for libXXXX.pkg files)
127 libraries = []
128
129 for file in os.listdir(dir):
130 if re.search('^lib',file) and re.search('.pkg$',file):
131 libraries.append(file)
132
133 # append fake libraries for DAs
134 if not noda:
135 libraries.append("libMUONTRKda.pkg")
136 libraries.append("libMUONTRGda.pkg")
137
138 # srcfiles is a dictionary :
139 # srcfiles[libXXX.pkg] -> { list of classes (inferred from list of .cxx files) }
140 #
141 srcfiles = {}
142
143 # allfiles is a dictonary :
144 # allfiles[libXXX.pkg] -> { list of all included files of that library }
145 allfiles = {}
146
147 for lib in libraries:
148 if not re.search("da",lib):
149 # handle the special case of DAs which are not part of libs, really
150 srcfiles[lib] = getSourceFiles(lib)
151 else:
152 l = lib
153 l = re.sub("lib","",l)
154 l = re.sub("\.pkg","",l)
155 srcfiles[lib] = [ l ]
156 files = []
157 for src in srcfiles[lib]:
158 files.extend(getIncludeFiles(src))
159 allfiles[lib] = unique(files)
160
161 if debug:
162 for lib in libraries:
163 print lib
164 for f in allfiles[lib]:
165 l = findLibrary(f,srcfiles)
166 print " ",f,"(",l,")"
167 print
168
169 # deps is a dictionary
170 # deps[libXXX.pkg] -> { list of libraries libXXX.pkg directly depends upon }
171
172 deps = {}
173
174 for lib,files in allfiles.items():
175 d = []
176 for f in files:
177 l = findLibrary(f,srcfiles)
178 if l != lib:
179 d.append(l)
180 deps[lib] = unique(d)
181
182 if debug:
183 for lib in deps:
184 print lib, " depends on "
185 for l in deps[lib]:
186 print " ",l
187 print
188
189 ofile = "%s.dot" % os.path.splitext(os.path.basename(sys.argv[0]))[0]
190
191 f = open(ofile,"w")
192
193 f.write("digraph G {")
194 f.write("rankdir=BT;")
195
196 for l,d in deps.items():
197 for dl in d:
198 if re.search("MUON",dl):
199 f.write("node [shape=box,style=filled,fillcolor=yellow];")
200 else:
201 f.write("node [shape=ellipse,style=filled,fillcolor=lightgray];")
202 f.write("%s -> %s;\n" %(shorten(l),shorten(dl)))
203
204 f.write("}")
205
206 print "You should now do :"
207 print "tred %s > %s.bis" % ( ofile, ofile )
208 print "dot -Tpng %s.bis > %s.png" % (ofile,ofile)
209
210if __name__ == "__main__":
211 main()
212