18b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato#!/usr/bin/env python
28b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato# vim: ts=2 sw=2 nocindent
38b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato
48b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onoratoimport re
58b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onoratoimport sys
68b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato
78b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onoratodef choose_regex(regs, line):
88b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  for func,reg in regs:
98b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato    m = reg.match(line)
108b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato    if m:
118b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato      return (func,m)
128b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  return (None,None)
138b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato
148b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onoratodef gather(included, deps):
158b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  result = set()
168b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  for inc in included:
178b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato    result.add(inc)
188b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato    for d in deps:
198b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato      if inc == d[1]:
208b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato        result.add(d[0])
218b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  return result
228b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato
238b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onoratodef main():
248b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  deps = []
258b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  infos = []
268b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  def dependency(m):
278b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato    deps.append((m.group(1), m.group(2)))
288b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  def info(m):
298b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato    infos.append((m.group(1), m.group(2)))
308b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato
318b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  REGS = [
328b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato      (dependency, re.compile(r'"(.*)"\s*->\s*"(.*)"')),
338b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato      (info, re.compile(r'"(.*)"(\s*\[.*\])')),
348b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato    ]
358b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato
368b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  lines = sys.stdin.readlines()
378b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  lines = [line.strip() for line in lines]
388b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato
398b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  for line in lines:
408b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato    func,m = choose_regex(REGS, line)
418b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato    if func:
428b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato      func(m)
438b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato
448b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  # filter
458b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  sys.stderr.write("argv: " + str(sys.argv) + "\n")
468b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  if not (len(sys.argv) == 2 and sys.argv[1] == "--all"):
478b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato    targets = sys.argv[1:]
488b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato
498b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato    included = set(targets)
508b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato    prevLen = -1
518b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato    while prevLen != len(included):
528b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato      prevLen = len(included)
538b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato      included = gather(included, deps)
548b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato
558b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato    deps = [dep for dep in deps if dep[1] in included]
568b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato    infos = [info for info in infos if info[0] in included]
578b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato
588b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  print "digraph {"
598b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  print "graph [ ratio=.5 ];"
608b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  for dep in deps:
618b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato    print '"%s" -> "%s"' % dep
628b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  for info in infos:
638b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato    print '"%s"%s' % info
648b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  print "}"
658b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato
668b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato
678b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onoratoif __name__ == "__main__":
688b46e302e6ed30e72ece1680767d00fc4241f2d5Joe Onorato  main()
69