blob: 661fa54ba729e0e59906fdedeb1c8548065e7b9a [file] [log] [blame]
A R Karthicka2e53d62016-02-19 17:38:30 -08001#!/usr/bin/env python
2
3import yaml, pprint, sys, pdb
4#import configFsm
5
6stateHash = {}
7
8header = '''#!python
9'''
10
11# ---------------------------- DOT -----------------------------------
12colorList = ['aquamarine4', 'crimson', 'chartreuse4', 'darkolivegreen', 'darkgoldenrod', 'dodgerblue3', 'blue4', 'cyan4']
13rankdict = {}
14# ---------------------------- DOT -----------------------------------
15
16
17if __name__ == '__main__':
18
19 usage = ''
20
21 # optparse
22 from optparse import OptionParser
23
24 parser = OptionParser(usage)
25
26 parser.add_option('-p', '--prefix', dest='prefix', type='string', action='store', help='prefix for state table')
27 parser.add_option('-f', '--file', dest='file', type='string', action='store', help='input yaml filename')
28 parser.add_option('-d', '--dot', dest='dot', default=False, action='store_true', help='output DOT')
29
30 (opts, args) = parser.parse_args()
31
32 prefix = opts.prefix
33
34 f = open(opts.file, 'r')
35 y = yaml.load(f)
36 f.close()
37
38 stateHash = y['States']
39
40 eventHash = {}
41
42 # GLOBAL DOT DIRECTIVES
43 stateRadiate = y.get('DOT_StateRadiate')
44 ignoredIntensity = abs(int(y.get('DOT_IgnoredIntensity', 100)) - 100)
45 eventGroups = y.get('DOT_EventGroups')
46
47 if stateRadiate is not None:
48 stateRadiate = str(stateRadiate)
49
50 actionStrLen = [0]
51 stateColorIdx = 0
52 for k, v in stateHash.iteritems():
53 events = v.get('Events')
54 if events:
55 for event in events.keys():
56 eventHash[event] = {}
57
58 actionStr = ''
59
60 for ev in events.values():
61 if ev.get('Actions'):
62 actionStr = ','.join(['obj.%s' % action for action in ev['Actions']]) + ','
63 actionStrLen.append(len(actionStr))
64
65
66 ievents = v.get('IgnoredEvents')
67 if ievents:
68 for event in ievents.keys():
69 eventHash[event] = {}
70
71 # ---------------------------- DOT -----------------------------------
72
73 # rankdict setup
74 rank = v.get('DOT_Rank')
75 if rank:
76 print >>sys.stderr, '%s rank %s' % (k, str(rank))
77 rankdict.setdefault(rank, []).append(k)
78
79 # assign a possible color if not specified
80 color = v.get('DOT_Color')
81 if color:
82 print >>sys.stderr, 'using user assigned color %s for %s' % (color, k)
83 else:
84 if stateRadiate and stateRadiate.lower() == 'auto':
85 color = colorList[stateColorIdx % len(colorList)]
86 stateColorIdx+= 1
87 else:
88 color = 'black'
89
90 stateHash[k]['DOT_Color'] = color
91
92 # ---------------------------- DOT -----------------------------------
93
94 # ---------------------------- DOT -----------------------------------
95 # update the event hash with information from the event groups (if present)
96 if eventGroups:
97 for group in eventGroups.values():
98 for event in group['Events'].keys():
99 for attr, val in group['Attrs'].iteritems():
100 eventHash[event][attr] = val
101 print >>sys.stderr, 'assigning event group attr event %s attr %s val %s' % (event, attr, val)
102 # ---------------------------- DOT -----------------------------------
103
104 '''
105 for key in stateHash.keys():
106# try:
107 print key
108 x = eval('configFsm.cfgSt.%s' % key)
109# except AttributeError, e:
110 print '%s not in config.cfgSt!' % x
111
112
113 for key in eventHash.keys():
114 print key
115# try:
116 x = eval('configFsm.cfgEv.%s' % key)
117# except KeyError, e:
118 print '%s not in config.cfgEv!' % x
119 '''
120
121
122 maxStateLen = reduce(max, [len(x) for x in stateHash.keys()]) + 5 + len(prefix)
123 maxEventLen = reduce(max, [len(x) for x in eventHash.keys()]) + 5 + len(prefix)
124 maxActionLen = reduce(max, actionStrLen) + 5
125
126 if opts.dot:
127
128 print 'digraph G {'
129 print ' edge [fontname="Tahoma", fontsize="10", minlen=2];'
130 print ' node [fontname="Tahoma", fontsize="10"];'
131 print ' graph [fontname="Tahoma", label="%s"];' % prefix
132
133# rankdict = {}
134
135 print >>sys.stderr, 'stateRadiate:%s\nignoredIntensity:%d' % (stateRadiate, ignoredIntensity)
136
137 # emit state declarations
138 for state in stateHash.keys():
139 print ' %s[color="%s"];' % (state, stateHash[state]['DOT_Color'])
140
141 # emit rankings
142 for k, v in rankdict.iteritems():
143 print >>sys.stderr, '%s rank %s' % (k, str(v))
144
145 print 'subgraph { rank = same;'
146 for state in v:
147 print ' %s;' % state
148 print '}'
149
150 for state, va in stateHash.iteritems():
151
152 # emit ignored events
153 if va.get('IgnoredEvents'):
154 for event, v in va['IgnoredEvents'].iteritems():
155 stateStr = state
156 eventStr = event
157
158 print '%s -> %s [label="%s/",minlen=1, fontcolor="grey%d", color="grey%d"];' % (stateStr, stateStr, eventStr, ignoredIntensity, ignoredIntensity)
159
160 # emit transitions
161 if va.get('Events'):
162 for event, v in va['Events'].iteritems():
163 stateStr = state
164 eventStr = event
165 actionStr = ''
166 if v.get('Actions'):
167 actionStr = '\\n'.join([a.strip('_') for a in v['Actions']])
168 nextStr = v['NextState']
169
170 labelStr = '%s/\\n%s' % (eventStr, actionStr)
171
172 if stateRadiate:
173 color = va['DOT_Color']
174 elif len(eventHash[event]):
175 color = eventHash[event]['Color']
176 else:
177 color = 'black'
178
179 fontColor = color
180
181 styleStr = ''
182 style = eventHash[event].get('Style')
183 if style:
184 styleStr = ',style="%s"' % (style)
185
186 if style == 'invis':
187 fontColor = 'white'
188
189 print '%s -> %s [label="%s", color="%s", fontcolor="%s" %s];' % (stateStr, nextStr, labelStr, color, fontColor, styleStr)
190
191 print
192
193 print '}'
194
195
196# pprint.pprint(states)
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252 else:
253
254### emit it
255
256 print header
257
258### enumerations
259 '''
260 print '%sSt = Enumeration("%sState",(' % (prefix, prefix)
261 for state in stateHash.keys():
262 print '%s"%s",' % (' '*12, state)
263 print '%s))' % (' '*12)
264
265 print
266
267 print '%sEv = Enumeration("%sEvent",(' % (prefix, prefix)
268 for event in eventHash.keys():
269 print '%s"%s",' % (' '*12, event)
270 print '%s))' % (' '*12)
271 '''
272
273
274### table
275
276 fmt = ' (%' + '-%d.%ds' % (maxStateLen, maxStateLen) + '%' + '-%d.%ds' % (maxEventLen, maxEventLen) + '):( %' +' -%d.%ds' % (maxActionLen, maxActionLen) + '%s),'
277 cfmt= ' ## %' + '-%d.%ds' % (maxStateLen, maxStateLen) + '%' + '-%d.%ds' % (maxEventLen, maxEventLen) + ' %' +' -%d.%ds' % (maxActionLen, maxActionLen) + '%s'
278
279 print 'def init%s%sFsmTable(obj,St,Ev):' % (prefix[0].upper(), prefix[1:])
280# print " %sFsmTable = {" % prefix
281 print " return {"
282 print
283
284 for state, va in stateHash.iteritems():
285
286 print cfmt % ('CurrentState', 'Event', 'Actions', 'NextState')
287 print
288
289 if va.get('IgnoredEvents'):
290 for event, v in va['IgnoredEvents'].iteritems():
291 stateStr = '%sSt.' % ('') + state + ','
292 eventStr = '%sEv.' % ('') + event
293
294 print fmt % (stateStr, eventStr, '(),', stateStr.strip(','))
295
296 if va.get('Events'):
297 for event, v in va['Events'].iteritems():
298 stateStr = '%sSt.' % ('') + state + ','
299 eventStr = '%sEv.' % ('') + event
300 actionStr = ''
301 if v.get('Actions'):
302 actionStr = ','.join(['obj.%s' % action for action in v['Actions']]) + ','
303
304 nextStr = '%sSt.' % ('') + v['NextState']
305
306 print fmt % (stateStr, eventStr, '(%s),' % actionStr , nextStr)
307
308 print
309
310 print "}"
311 print
312
313