blob: f4016f41e8a2d4e9f9996104f884aa0878dc291b [file] [log] [blame]
A R Karthicka2e53d62016-02-19 17:38:30 -08001#!/usr/bin/env python
2
3import yaml, pprint, sys, pdb
A R Karthicka2e53d62016-02-19 17:38:30 -08004
5stateHash = {}
A R Karthick85ed65e2016-02-22 09:49:57 -08006header = '''#!/usr/bin/env python
A R Karthicka2e53d62016-02-19 17:38:30 -08007'''
A R Karthicka2e53d62016-02-19 17:38:30 -08008# ---------------------------- DOT -----------------------------------
9colorList = ['aquamarine4', 'crimson', 'chartreuse4', 'darkolivegreen', 'darkgoldenrod', 'dodgerblue3', 'blue4', 'cyan4']
10rankdict = {}
11# ---------------------------- DOT -----------------------------------
12
A R Karthicka2e53d62016-02-19 17:38:30 -080013if __name__ == '__main__':
14
15 usage = ''
A R Karthicka2e53d62016-02-19 17:38:30 -080016 from optparse import OptionParser
A R Karthicka2e53d62016-02-19 17:38:30 -080017 parser = OptionParser(usage)
A R Karthicka2e53d62016-02-19 17:38:30 -080018 parser.add_option('-p', '--prefix', dest='prefix', type='string', action='store', help='prefix for state table')
19 parser.add_option('-f', '--file', dest='file', type='string', action='store', help='input yaml filename')
20 parser.add_option('-d', '--dot', dest='dot', default=False, action='store_true', help='output DOT')
A R Karthicka2e53d62016-02-19 17:38:30 -080021 (opts, args) = parser.parse_args()
A R Karthicka2e53d62016-02-19 17:38:30 -080022 prefix = opts.prefix
A R Karthicka2e53d62016-02-19 17:38:30 -080023 f = open(opts.file, 'r')
24 y = yaml.load(f)
25 f.close()
A R Karthicka2e53d62016-02-19 17:38:30 -080026 stateHash = y['States']
A R Karthicka2e53d62016-02-19 17:38:30 -080027 eventHash = {}
A R Karthicka2e53d62016-02-19 17:38:30 -080028 # GLOBAL DOT DIRECTIVES
29 stateRadiate = y.get('DOT_StateRadiate')
30 ignoredIntensity = abs(int(y.get('DOT_IgnoredIntensity', 100)) - 100)
31 eventGroups = y.get('DOT_EventGroups')
A R Karthicka2e53d62016-02-19 17:38:30 -080032 if stateRadiate is not None:
33 stateRadiate = str(stateRadiate)
34
35 actionStrLen = [0]
36 stateColorIdx = 0
37 for k, v in stateHash.iteritems():
38 events = v.get('Events')
39 if events:
40 for event in events.keys():
41 eventHash[event] = {}
A R Karthicka2e53d62016-02-19 17:38:30 -080042 actionStr = ''
A R Karthicka2e53d62016-02-19 17:38:30 -080043 for ev in events.values():
44 if ev.get('Actions'):
45 actionStr = ','.join(['obj.%s' % action for action in ev['Actions']]) + ','
46 actionStrLen.append(len(actionStr))
47
A R Karthicka2e53d62016-02-19 17:38:30 -080048 ievents = v.get('IgnoredEvents')
49 if ievents:
50 for event in ievents.keys():
51 eventHash[event] = {}
52
53 # ---------------------------- DOT -----------------------------------
A R Karthicka2e53d62016-02-19 17:38:30 -080054 # rankdict setup
55 rank = v.get('DOT_Rank')
56 if rank:
57 print >>sys.stderr, '%s rank %s' % (k, str(rank))
58 rankdict.setdefault(rank, []).append(k)
59
60 # assign a possible color if not specified
61 color = v.get('DOT_Color')
62 if color:
63 print >>sys.stderr, 'using user assigned color %s for %s' % (color, k)
64 else:
65 if stateRadiate and stateRadiate.lower() == 'auto':
66 color = colorList[stateColorIdx % len(colorList)]
67 stateColorIdx+= 1
68 else:
69 color = 'black'
70
71 stateHash[k]['DOT_Color'] = color
A R Karthicka2e53d62016-02-19 17:38:30 -080072 # ---------------------------- DOT -----------------------------------
73
74 # ---------------------------- DOT -----------------------------------
75 # update the event hash with information from the event groups (if present)
76 if eventGroups:
77 for group in eventGroups.values():
78 for event in group['Events'].keys():
79 for attr, val in group['Attrs'].iteritems():
80 eventHash[event][attr] = val
81 print >>sys.stderr, 'assigning event group attr event %s attr %s val %s' % (event, attr, val)
82 # ---------------------------- DOT -----------------------------------
A R Karthicka2e53d62016-02-19 17:38:30 -080083
84 maxStateLen = reduce(max, [len(x) for x in stateHash.keys()]) + 5 + len(prefix)
85 maxEventLen = reduce(max, [len(x) for x in eventHash.keys()]) + 5 + len(prefix)
86 maxActionLen = reduce(max, actionStrLen) + 5
87
88 if opts.dot:
A R Karthicka2e53d62016-02-19 17:38:30 -080089 print 'digraph G {'
90 print ' edge [fontname="Tahoma", fontsize="10", minlen=2];'
91 print ' node [fontname="Tahoma", fontsize="10"];'
92 print ' graph [fontname="Tahoma", label="%s"];' % prefix
A R Karthicka2e53d62016-02-19 17:38:30 -080093 print >>sys.stderr, 'stateRadiate:%s\nignoredIntensity:%d' % (stateRadiate, ignoredIntensity)
94
95 # emit state declarations
96 for state in stateHash.keys():
97 print ' %s[color="%s"];' % (state, stateHash[state]['DOT_Color'])
98
99 # emit rankings
100 for k, v in rankdict.iteritems():
101 print >>sys.stderr, '%s rank %s' % (k, str(v))
102
103 print 'subgraph { rank = same;'
104 for state in v:
105 print ' %s;' % state
106 print '}'
107
108 for state, va in stateHash.iteritems():
A R Karthicka2e53d62016-02-19 17:38:30 -0800109 # emit ignored events
110 if va.get('IgnoredEvents'):
111 for event, v in va['IgnoredEvents'].iteritems():
112 stateStr = state
113 eventStr = event
A R Karthicka2e53d62016-02-19 17:38:30 -0800114 print '%s -> %s [label="%s/",minlen=1, fontcolor="grey%d", color="grey%d"];' % (stateStr, stateStr, eventStr, ignoredIntensity, ignoredIntensity)
115
116 # emit transitions
117 if va.get('Events'):
118 for event, v in va['Events'].iteritems():
119 stateStr = state
120 eventStr = event
121 actionStr = ''
122 if v.get('Actions'):
123 actionStr = '\\n'.join([a.strip('_') for a in v['Actions']])
124 nextStr = v['NextState']
A R Karthicka2e53d62016-02-19 17:38:30 -0800125 labelStr = '%s/\\n%s' % (eventStr, actionStr)
A R Karthicka2e53d62016-02-19 17:38:30 -0800126 if stateRadiate:
127 color = va['DOT_Color']
128 elif len(eventHash[event]):
129 color = eventHash[event]['Color']
130 else:
131 color = 'black'
132
133 fontColor = color
A R Karthicka2e53d62016-02-19 17:38:30 -0800134 styleStr = ''
135 style = eventHash[event].get('Style')
136 if style:
137 styleStr = ',style="%s"' % (style)
138
139 if style == 'invis':
140 fontColor = 'white'
141
142 print '%s -> %s [label="%s", color="%s", fontcolor="%s" %s];' % (stateStr, nextStr, labelStr, color, fontColor, styleStr)
143
144 print
145
146 print '}'
147
A R Karthicka2e53d62016-02-19 17:38:30 -0800148 else:
149
150### emit it
151
152 print header
153
154### enumerations
155 '''
156 print '%sSt = Enumeration("%sState",(' % (prefix, prefix)
157 for state in stateHash.keys():
158 print '%s"%s",' % (' '*12, state)
159 print '%s))' % (' '*12)
160
161 print
162
163 print '%sEv = Enumeration("%sEvent",(' % (prefix, prefix)
164 for event in eventHash.keys():
165 print '%s"%s",' % (' '*12, event)
166 print '%s))' % (' '*12)
167 '''
A R Karthicka2e53d62016-02-19 17:38:30 -0800168### table
169
170 fmt = ' (%' + '-%d.%ds' % (maxStateLen, maxStateLen) + '%' + '-%d.%ds' % (maxEventLen, maxEventLen) + '):( %' +' -%d.%ds' % (maxActionLen, maxActionLen) + '%s),'
171 cfmt= ' ## %' + '-%d.%ds' % (maxStateLen, maxStateLen) + '%' + '-%d.%ds' % (maxEventLen, maxEventLen) + ' %' +' -%d.%ds' % (maxActionLen, maxActionLen) + '%s'
172
173 print 'def init%s%sFsmTable(obj,St,Ev):' % (prefix[0].upper(), prefix[1:])
174# print " %sFsmTable = {" % prefix
175 print " return {"
176 print
177
178 for state, va in stateHash.iteritems():
179
180 print cfmt % ('CurrentState', 'Event', 'Actions', 'NextState')
181 print
182
183 if va.get('IgnoredEvents'):
184 for event, v in va['IgnoredEvents'].iteritems():
185 stateStr = '%sSt.' % ('') + state + ','
186 eventStr = '%sEv.' % ('') + event
187
188 print fmt % (stateStr, eventStr, '(),', stateStr.strip(','))
189
190 if va.get('Events'):
191 for event, v in va['Events'].iteritems():
192 stateStr = '%sSt.' % ('') + state + ','
193 eventStr = '%sEv.' % ('') + event
194 actionStr = ''
195 if v.get('Actions'):
196 actionStr = ','.join(['obj.%s' % action for action in v['Actions']]) + ','
197
198 nextStr = '%sSt.' % ('') + v['NextState']
199
200 print fmt % (stateStr, eventStr, '(%s),' % actionStr , nextStr)
201
202 print
203
204 print "}"
205 print
206
207