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