1 |
#!/usr/bin/python |
2 |
|
3 |
# convert 'dot' format graph file to term representation readable by uDraw(Graph) |
4 |
# note, this version only deals with the subset of 'dot' that is output by quattor |
5 |
# 'panc-call-tree.pl' utility. |
6 |
|
7 |
# J Templon NIKHEF 2010. |
8 |
|
9 |
import getopt, sys, os |
10 |
import re |
11 |
|
12 |
def usage(): |
13 |
print "Usage: dot2term [-r root_template ] file.dot" |
14 |
print "Converts <file.dot> from dot format to udg format readable by uDrawGraph" |
15 |
print "option -r means to display only that part of the include tree stemming from the"+\ |
16 |
" specified template" |
17 |
|
18 |
# note : in order to avoid having to 'install' this program, I have |
19 |
# included the relevant pieces of treedefs.py and dvtree.py in this file. Don't edit here, |
20 |
# edit the originals. |
21 |
# BEGIN code included via m4 macro processor |
22 |
include(treedefs.py) |
23 |
include(dvtree.py) |
24 |
# END code included via m4 macro processor |
25 |
|
26 |
dprefix = " " |
27 |
|
28 |
def main(): |
29 |
try: |
30 |
opts, args = getopt.getopt(sys.argv[1:], "hr:", ["help","root="]) |
31 |
except getopt.GetoptError: |
32 |
usage() |
33 |
sys.exit(2) |
34 |
|
35 |
root = None # default to printing entire graph |
36 |
|
37 |
for o, a in opts: |
38 |
if o in ("-h", "--help"): |
39 |
usage() |
40 |
sys.exit() |
41 |
if o in ("-r", "--root"): |
42 |
root = a |
43 |
|
44 |
dotlines = open(args[0]).readlines() |
45 |
if dotlines[0].find('digraph') < 0 : |
46 |
print "Expected digraph as first line, found", dotlines[0] |
47 |
print "Bailing out" |
48 |
sys.exit(1) |
49 |
li = dotlines[0].find('"') + 1 |
50 |
ri = dotlines[0].rfind('"') |
51 |
nodename=dotlines[0][li:ri] |
52 |
shape='ellipse' |
53 |
tnode = Node(nodename,shape) |
54 |
Ltreenode.append(tnode) |
55 |
Dnode[tnode.name] = tnode |
56 |
|
57 |
for dl in dotlines[1:]: |
58 |
l = dl[:-1].strip() # get rid of trailing newline and any preceding whitespace |
59 |
if l.find('node') == 0: |
60 |
li=l.find('shape=')+6 |
61 |
ri=l.rfind(']') |
62 |
shape=l[li:ri] |
63 |
elif l.find(' -> ') > 0: # edge definition |
64 |
fields=l.split('"') # nodes are between quotes, so split on that |
65 |
par = fields[1] |
66 |
child = fields[3] |
67 |
if par not in Dnode.keys(): |
68 |
tnode = Node(par, shape) |
69 |
Dnode[tnode.name] = tnode |
70 |
pn = tnode |
71 |
else: |
72 |
pn = Dnode[par] |
73 |
if not pn.shape : pn.shape = shape |
74 |
if child not in Dnode.keys(): |
75 |
tnode = Node(child) |
76 |
Dnode[tnode.name] = tnode |
77 |
cn = tnode |
78 |
else: |
79 |
cn = Dnode[child] |
80 |
if not pn.children: pn.children = [] |
81 |
pn.children.append(cn) |
82 |
elif l.find('}') == 0: |
83 |
break |
84 |
else: |
85 |
print 'found some incomprehensible line', l |
86 |
sys.exit(1) |
87 |
|
88 |
|
89 |
dvFmt = Formathandler(dvnode, dvref, dvb4child, dvb4next, |
90 |
dvafterchild, dvafterchildren, |
91 |
filename='aap.daVinci') |
92 |
|
93 |
init_traverse() # initialize data structures for tree traversal |
94 |
|
95 |
if not root: |
96 |
n = Ltreenode[0] # the root of the entire graph |
97 |
else: |
98 |
if root not in Dnode.keys(): |
99 |
print 'template ' + root + ' not found in call graph, bailing out' |
100 |
sys.exit(2) |
101 |
else: |
102 |
n = Dnode[root] |
103 |
|
104 |
dvFmt.of.write('[\n') # open the term representation |
105 |
fmt_applyunique(n, dvFmt) # traverse the tree, outputting daVinci file |
106 |
dvFmt.of.write(']\n') # close the term representation |
107 |
|
108 |
main() |