Home | History | Annotate | Download | only in tools
      1 #!/usr/bin/env python
      2 # vim: ts=2 sw=2
      3 
      4 import optparse
      5 import re
      6 import sys
      7 
      8 
      9 class Dependency:
     10   def __init__(self, tgt):
     11     self.tgt = tgt
     12     self.pos = ""
     13     self.prereqs = set()
     14     self.visit = 0
     15 
     16   def add(self, prereq):
     17     self.prereqs.add(prereq)
     18 
     19 
     20 class Dependencies:
     21   def __init__(self):
     22     self.lines = {}
     23     self.__visit = 0
     24     self.count = 0
     25 
     26   def add(self, tgt, prereq):
     27     t = self.lines.get(tgt)
     28     if not t:
     29       t = Dependency(tgt)
     30       self.lines[tgt] = t
     31     p = self.lines.get(prereq)
     32     if not p:
     33       p = Dependency(prereq)
     34       self.lines[prereq] = p
     35     t.add(p)
     36     self.count = self.count + 1
     37 
     38   def setPos(self, tgt, pos):
     39     t = self.lines.get(tgt)
     40     if not t:
     41       t = Dependency(tgt)
     42       self.lines[tgt] = t
     43     t.pos = pos
     44 
     45   def get(self, tgt):
     46     if self.lines.has_key(tgt):
     47       return self.lines[tgt]
     48     else:
     49       return None
     50 
     51   def __iter__(self):
     52     return self.lines.iteritems()
     53 
     54   def trace(self, tgt, prereq):
     55     self.__visit = self.__visit + 1
     56     d = self.lines.get(tgt)
     57     if not d:
     58       return
     59     return self.__trace(d, prereq)
     60 
     61   def __trace(self, d, prereq):
     62     if d.visit == self.__visit:
     63       return d.trace
     64     if d.tgt == prereq:
     65       return [ [ d ], ]
     66     d.visit = self.__visit
     67     result = []
     68     for pre in d.prereqs:
     69       recursed = self.__trace(pre, prereq)
     70       for r in recursed:
     71         result.append([ d ] + r)
     72     d.trace = result
     73     return result
     74 
     75 def help():
     76   print "Commands:"
     77   print "  dep TARGET             Print the prerequisites for TARGET"
     78   print "  trace TARGET PREREQ    Print the paths from TARGET to PREREQ"
     79 
     80 
     81 def main(argv):
     82   opts = optparse.OptionParser()
     83   opts.add_option("-i", "--interactive", action="store_true", dest="interactive",
     84                     help="Interactive mode")
     85   (options, args) = opts.parse_args()
     86 
     87   deps = Dependencies()
     88 
     89   filename = args[0]
     90   print "Reading %s" % filename
     91 
     92   if True:
     93     f = open(filename)
     94     for line in f:
     95       line = line.strip()
     96       if len(line) > 0:
     97         if line[0] == '#':
     98           pos,tgt = line.rsplit(":", 1)
     99           pos = pos[1:].strip()
    100           tgt = tgt.strip()
    101           deps.setPos(tgt, pos)
    102         else:
    103           (tgt,prereq) = line.split(':', 1)
    104           tgt = tgt.strip()
    105           prereq = prereq.strip()
    106           deps.add(tgt, prereq)
    107     f.close()
    108 
    109   print "Read %d dependencies. %d targets." % (deps.count, len(deps.lines))
    110   while True:
    111     line = raw_input("target> ")
    112     if not line.strip():
    113       continue
    114     split = line.split()
    115     cmd = split[0]
    116     if len(split) == 2 and cmd == "dep":
    117       tgt = split[1]
    118       d = deps.get(tgt)
    119       if d:
    120         for prereq in d.prereqs:
    121           print prereq.tgt
    122     elif len(split) == 3 and cmd == "trace":
    123       tgt = split[1]
    124       prereq = split[2]
    125       if False:
    126         print "from %s to %s" % (tgt, prereq)
    127       trace = deps.trace(tgt, prereq)
    128       if trace:
    129         width = 0
    130         for g in trace:
    131           for t in g:
    132             if len(t.tgt) > width:
    133               width = len(t.tgt)
    134         for g in trace:
    135           for t in g:
    136             if t.pos:
    137               print t.tgt, " " * (width-len(t.tgt)), "  #", t.pos
    138             else:
    139               print t.tgt
    140           print
    141     else:
    142       help()
    143 
    144 if __name__ == "__main__":
    145   try:
    146     main(sys.argv)
    147   except KeyboardInterrupt:
    148     print
    149   except EOFError:
    150     print
    151 
    152