forked from jon-jacky/PyModel
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDot.py
75 lines (67 loc) · 2.68 KB
/
Dot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
"""
Dot - generate graphics in dot language
"""
import os.path
def node(n, fsm):
try: # FSM modules written by PyModel Analyzer have frontier attribute etc.
unsafe = fsm.unsafe
frontier = fsm.frontier
finished = fsm.finished
deadend = fsm.deadend
runstarts = fsm.runstarts
except AttributeError: # FSM modules written by hand may not have these
unsafe = list()
frontier = list()
finished = list()
deadend = list()
runstarts = list()
return '%s [ style=filled, shape=ellipse, peripheries=%s, fillcolor=%s' % \
(n, 2 if n in fsm.accepting else 1, # peripheries
'red' if n in unsafe else
'orange' if n in frontier else # high priority, analysis inconclusive
'yellow' if n in deadend else
'lightgreen' if n in finished else
'lightgray' if n == fsm.initial or n in runstarts else #lowest priority
'white') # other states
def state(n, fsm, noStateTooltip):
if noStateTooltip:
return '%s ]' % node(n,fsm)
else:
return '%s,\n tooltip="%s" ]' % (node(n,fsm), fsm.states[n])
def quote_string(x): # also appears in Analyzer
if isinstance(x,tuple):
return str(x)
else:
return "'%s'" % x if isinstance(x, str) else "%s" % x
def rlabel(result):
return '/%s' % quote_string(result) if result != None else ''
def transition(t, style, noTransitionTooltip):
current, (a, args, result), next = t
action = '%s%s%s' % (a.__name__, args, rlabel(result))
if style == 'name':
label = '%s' % a.__name__
elif style == 'none':
label = ''
else: # 'action'
label = action
if noTransitionTooltip:
return '%s -> %s [ label="%s" ]' % \
(current, next, label)
else:
return '%s -> %s [ label="%s", tooltip="%s" ]' % \
(current, next, label, action)
def dotfile(fname, fsm, style, noStateTooltip, noTransitionTooltip):
f = open(fname, 'w')
f.write('digraph %s {\n' % os.path.basename(fname).partition('.')[0])
f.write('\n // Nodes\n')
try: # FSM modules written by PyModel Analyzer have states attribute
f.writelines([ ' %s\n' % state(n,fsm,noStateTooltip) for n in fsm.states ])
except: # FSM modules written by hand may not have states attribute
nodes = set([current for (current,trans,next) in fsm.graph]
+ [next for (current,trans,next) in fsm.graph])
f.writelines([ ' %s ]\n' % node(n,fsm) for n in nodes ])
f.write('\n // Transitions\n')
f.writelines([ ' %s\n' % transition(t, style,noTransitionTooltip)
for t in fsm.graph ])
f.write('}\n')
f.close()