blob: 462e974a5a7fb3d7a5b4d18ad590e8edacc47010 [file] [log] [blame]
Chetan Gaonkercfcce782016-05-10 10:10:42 -07001#
2# Copyright 2016-present Ciena Corporation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
A R Karthicka2e53d62016-02-19 17:38:30 -080016#!/usr/bin/env python
17
18import yaml, pprint, sys, pdb
A R Karthicka2e53d62016-02-19 17:38:30 -080019
20stateHash = {}
A R Karthick85ed65e2016-02-22 09:49:57 -080021header = '''#!/usr/bin/env python
A R Karthicka2e53d62016-02-19 17:38:30 -080022'''
A R Karthicka2e53d62016-02-19 17:38:30 -080023# ---------------------------- DOT -----------------------------------
24colorList = ['aquamarine4', 'crimson', 'chartreuse4', 'darkolivegreen', 'darkgoldenrod', 'dodgerblue3', 'blue4', 'cyan4']
25rankdict = {}
26# ---------------------------- DOT -----------------------------------
27
A R Karthicka2e53d62016-02-19 17:38:30 -080028if __name__ == '__main__':
29
30 usage = ''
A R Karthicka2e53d62016-02-19 17:38:30 -080031 from optparse import OptionParser
A R Karthicka2e53d62016-02-19 17:38:30 -080032 parser = OptionParser(usage)
A R Karthicka2e53d62016-02-19 17:38:30 -080033 parser.add_option('-p', '--prefix', dest='prefix', type='string', action='store', help='prefix for state table')
34 parser.add_option('-f', '--file', dest='file', type='string', action='store', help='input yaml filename')
35 parser.add_option('-d', '--dot', dest='dot', default=False, action='store_true', help='output DOT')
A R Karthicka2e53d62016-02-19 17:38:30 -080036 (opts, args) = parser.parse_args()
A R Karthicka2e53d62016-02-19 17:38:30 -080037 prefix = opts.prefix
A R Karthicka2e53d62016-02-19 17:38:30 -080038 f = open(opts.file, 'r')
39 y = yaml.load(f)
40 f.close()
A R Karthicka2e53d62016-02-19 17:38:30 -080041 stateHash = y['States']
A R Karthicka2e53d62016-02-19 17:38:30 -080042 eventHash = {}
A R Karthicka2e53d62016-02-19 17:38:30 -080043 # GLOBAL DOT DIRECTIVES
44 stateRadiate = y.get('DOT_StateRadiate')
45 ignoredIntensity = abs(int(y.get('DOT_IgnoredIntensity', 100)) - 100)
46 eventGroups = y.get('DOT_EventGroups')
A R Karthicka2e53d62016-02-19 17:38:30 -080047 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] = {}
A R Karthicka2e53d62016-02-19 17:38:30 -080057 actionStr = ''
A R Karthicka2e53d62016-02-19 17:38:30 -080058 for ev in events.values():
59 if ev.get('Actions'):
60 actionStr = ','.join(['obj.%s' % action for action in ev['Actions']]) + ','
61 actionStrLen.append(len(actionStr))
62
A R Karthicka2e53d62016-02-19 17:38:30 -080063 ievents = v.get('IgnoredEvents')
64 if ievents:
65 for event in ievents.keys():
66 eventHash[event] = {}
67
68 # ---------------------------- DOT -----------------------------------
A R Karthicka2e53d62016-02-19 17:38:30 -080069 # rankdict setup
70 rank = v.get('DOT_Rank')
71 if rank:
72 print >>sys.stderr, '%s rank %s' % (k, str(rank))
73 rankdict.setdefault(rank, []).append(k)
74
75 # assign a possible color if not specified
76 color = v.get('DOT_Color')
77 if color:
78 print >>sys.stderr, 'using user assigned color %s for %s' % (color, k)
79 else:
80 if stateRadiate and stateRadiate.lower() == 'auto':
81 color = colorList[stateColorIdx % len(colorList)]
82 stateColorIdx+= 1
83 else:
84 color = 'black'
85
86 stateHash[k]['DOT_Color'] = color
A R Karthicka2e53d62016-02-19 17:38:30 -080087 # ---------------------------- DOT -----------------------------------
88
89 # ---------------------------- DOT -----------------------------------
90 # update the event hash with information from the event groups (if present)
91 if eventGroups:
92 for group in eventGroups.values():
93 for event in group['Events'].keys():
94 for attr, val in group['Attrs'].iteritems():
95 eventHash[event][attr] = val
96 print >>sys.stderr, 'assigning event group attr event %s attr %s val %s' % (event, attr, val)
97 # ---------------------------- DOT -----------------------------------
A R Karthicka2e53d62016-02-19 17:38:30 -080098
99 maxStateLen = reduce(max, [len(x) for x in stateHash.keys()]) + 5 + len(prefix)
100 maxEventLen = reduce(max, [len(x) for x in eventHash.keys()]) + 5 + len(prefix)
101 maxActionLen = reduce(max, actionStrLen) + 5
102
103 if opts.dot:
A R Karthicka2e53d62016-02-19 17:38:30 -0800104 print 'digraph G {'
105 print ' edge [fontname="Tahoma", fontsize="10", minlen=2];'
106 print ' node [fontname="Tahoma", fontsize="10"];'
107 print ' graph [fontname="Tahoma", label="%s"];' % prefix
A R Karthicka2e53d62016-02-19 17:38:30 -0800108 print >>sys.stderr, 'stateRadiate:%s\nignoredIntensity:%d' % (stateRadiate, ignoredIntensity)
109
110 # emit state declarations
111 for state in stateHash.keys():
112 print ' %s[color="%s"];' % (state, stateHash[state]['DOT_Color'])
113
114 # emit rankings
115 for k, v in rankdict.iteritems():
116 print >>sys.stderr, '%s rank %s' % (k, str(v))
117
118 print 'subgraph { rank = same;'
119 for state in v:
120 print ' %s;' % state
121 print '}'
122
123 for state, va in stateHash.iteritems():
A R Karthicka2e53d62016-02-19 17:38:30 -0800124 # emit ignored events
125 if va.get('IgnoredEvents'):
126 for event, v in va['IgnoredEvents'].iteritems():
127 stateStr = state
128 eventStr = event
A R Karthicka2e53d62016-02-19 17:38:30 -0800129 print '%s -> %s [label="%s/",minlen=1, fontcolor="grey%d", color="grey%d"];' % (stateStr, stateStr, eventStr, ignoredIntensity, ignoredIntensity)
130
131 # emit transitions
132 if va.get('Events'):
133 for event, v in va['Events'].iteritems():
134 stateStr = state
135 eventStr = event
136 actionStr = ''
137 if v.get('Actions'):
138 actionStr = '\\n'.join([a.strip('_') for a in v['Actions']])
139 nextStr = v['NextState']
A R Karthicka2e53d62016-02-19 17:38:30 -0800140 labelStr = '%s/\\n%s' % (eventStr, actionStr)
A R Karthicka2e53d62016-02-19 17:38:30 -0800141 if stateRadiate:
142 color = va['DOT_Color']
143 elif len(eventHash[event]):
144 color = eventHash[event]['Color']
145 else:
146 color = 'black'
147
148 fontColor = color
A R Karthicka2e53d62016-02-19 17:38:30 -0800149 styleStr = ''
150 style = eventHash[event].get('Style')
151 if style:
152 styleStr = ',style="%s"' % (style)
153
154 if style == 'invis':
155 fontColor = 'white'
156
157 print '%s -> %s [label="%s", color="%s", fontcolor="%s" %s];' % (stateStr, nextStr, labelStr, color, fontColor, styleStr)
158
159 print
160
161 print '}'
162
A R Karthicka2e53d62016-02-19 17:38:30 -0800163 else:
164
165### emit it
166
167 print header
168
169### enumerations
170 '''
171 print '%sSt = Enumeration("%sState",(' % (prefix, prefix)
172 for state in stateHash.keys():
173 print '%s"%s",' % (' '*12, state)
174 print '%s))' % (' '*12)
175
176 print
177
178 print '%sEv = Enumeration("%sEvent",(' % (prefix, prefix)
179 for event in eventHash.keys():
180 print '%s"%s",' % (' '*12, event)
181 print '%s))' % (' '*12)
182 '''
A R Karthicka2e53d62016-02-19 17:38:30 -0800183### table
184
185 fmt = ' (%' + '-%d.%ds' % (maxStateLen, maxStateLen) + '%' + '-%d.%ds' % (maxEventLen, maxEventLen) + '):( %' +' -%d.%ds' % (maxActionLen, maxActionLen) + '%s),'
186 cfmt= ' ## %' + '-%d.%ds' % (maxStateLen, maxStateLen) + '%' + '-%d.%ds' % (maxEventLen, maxEventLen) + ' %' +' -%d.%ds' % (maxActionLen, maxActionLen) + '%s'
187
188 print 'def init%s%sFsmTable(obj,St,Ev):' % (prefix[0].upper(), prefix[1:])
189# print " %sFsmTable = {" % prefix
190 print " return {"
191 print
192
193 for state, va in stateHash.iteritems():
194
195 print cfmt % ('CurrentState', 'Event', 'Actions', 'NextState')
196 print
197
198 if va.get('IgnoredEvents'):
199 for event, v in va['IgnoredEvents'].iteritems():
200 stateStr = '%sSt.' % ('') + state + ','
201 eventStr = '%sEv.' % ('') + event
202
203 print fmt % (stateStr, eventStr, '(),', stateStr.strip(','))
204
205 if va.get('Events'):
206 for event, v in va['Events'].iteritems():
207 stateStr = '%sSt.' % ('') + state + ','
208 eventStr = '%sEv.' % ('') + event
209 actionStr = ''
210 if v.get('Actions'):
211 actionStr = ','.join(['obj.%s' % action for action in v['Actions']]) + ','
212
213 nextStr = '%sSt.' % ('') + v['NextState']
214
215 print fmt % (stateStr, eventStr, '(%s),' % actionStr , nextStr)
216
217 print
218
219 print "}"
220 print
221
222