blob: d88490213cbe54341c7b21c91b706f794a20ea58 [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
17import yaml, pprint, sys, pdb
A R Karthicka2e53d62016-02-19 17:38:30 -080018
19stateHash = {}
A R Karthick85ed65e2016-02-22 09:49:57 -080020header = '''#!/usr/bin/env python
A R Karthicka2e53d62016-02-19 17:38:30 -080021'''
A R Karthicka2e53d62016-02-19 17:38:30 -080022# ---------------------------- DOT -----------------------------------
23colorList = ['aquamarine4', 'crimson', 'chartreuse4', 'darkolivegreen', 'darkgoldenrod', 'dodgerblue3', 'blue4', 'cyan4']
24rankdict = {}
25# ---------------------------- DOT -----------------------------------
26
A R Karthicka2e53d62016-02-19 17:38:30 -080027if __name__ == '__main__':
28
29 usage = ''
A R Karthicka2e53d62016-02-19 17:38:30 -080030 from optparse import OptionParser
A R Karthicka2e53d62016-02-19 17:38:30 -080031 parser = OptionParser(usage)
A R Karthicka2e53d62016-02-19 17:38:30 -080032 parser.add_option('-p', '--prefix', dest='prefix', type='string', action='store', help='prefix for state table')
33 parser.add_option('-f', '--file', dest='file', type='string', action='store', help='input yaml filename')
34 parser.add_option('-d', '--dot', dest='dot', default=False, action='store_true', help='output DOT')
A R Karthicka2e53d62016-02-19 17:38:30 -080035 (opts, args) = parser.parse_args()
A R Karthicka2e53d62016-02-19 17:38:30 -080036 prefix = opts.prefix
A R Karthicka2e53d62016-02-19 17:38:30 -080037 f = open(opts.file, 'r')
38 y = yaml.load(f)
39 f.close()
A R Karthicka2e53d62016-02-19 17:38:30 -080040 stateHash = y['States']
A R Karthicka2e53d62016-02-19 17:38:30 -080041 eventHash = {}
A R Karthicka2e53d62016-02-19 17:38:30 -080042 # 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')
A R Karthicka2e53d62016-02-19 17:38:30 -080046 if stateRadiate is not None:
47 stateRadiate = str(stateRadiate)
48
49 actionStrLen = [0]
50 stateColorIdx = 0
51 for k, v in stateHash.iteritems():
52 events = v.get('Events')
53 if events:
54 for event in events.keys():
55 eventHash[event] = {}
A R Karthicka2e53d62016-02-19 17:38:30 -080056 actionStr = ''
A R Karthicka2e53d62016-02-19 17:38:30 -080057 for ev in events.values():
58 if ev.get('Actions'):
59 actionStr = ','.join(['obj.%s' % action for action in ev['Actions']]) + ','
60 actionStrLen.append(len(actionStr))
61
A R Karthicka2e53d62016-02-19 17:38:30 -080062 ievents = v.get('IgnoredEvents')
63 if ievents:
64 for event in ievents.keys():
65 eventHash[event] = {}
66
67 # ---------------------------- DOT -----------------------------------
A R Karthicka2e53d62016-02-19 17:38:30 -080068 # rankdict setup
69 rank = v.get('DOT_Rank')
70 if rank:
71 print >>sys.stderr, '%s rank %s' % (k, str(rank))
72 rankdict.setdefault(rank, []).append(k)
73
74 # assign a possible color if not specified
75 color = v.get('DOT_Color')
76 if color:
77 print >>sys.stderr, 'using user assigned color %s for %s' % (color, k)
78 else:
79 if stateRadiate and stateRadiate.lower() == 'auto':
80 color = colorList[stateColorIdx % len(colorList)]
81 stateColorIdx+= 1
82 else:
83 color = 'black'
84
85 stateHash[k]['DOT_Color'] = color
A R Karthicka2e53d62016-02-19 17:38:30 -080086 # ---------------------------- DOT -----------------------------------
87
88 # ---------------------------- DOT -----------------------------------
89 # update the event hash with information from the event groups (if present)
90 if eventGroups:
91 for group in eventGroups.values():
92 for event in group['Events'].keys():
93 for attr, val in group['Attrs'].iteritems():
94 eventHash[event][attr] = val
95 print >>sys.stderr, 'assigning event group attr event %s attr %s val %s' % (event, attr, val)
96 # ---------------------------- DOT -----------------------------------
A R Karthicka2e53d62016-02-19 17:38:30 -080097
98 maxStateLen = reduce(max, [len(x) for x in stateHash.keys()]) + 5 + len(prefix)
99 maxEventLen = reduce(max, [len(x) for x in eventHash.keys()]) + 5 + len(prefix)
100 maxActionLen = reduce(max, actionStrLen) + 5
101
102 if opts.dot:
A R Karthicka2e53d62016-02-19 17:38:30 -0800103 print 'digraph G {'
104 print ' edge [fontname="Tahoma", fontsize="10", minlen=2];'
105 print ' node [fontname="Tahoma", fontsize="10"];'
106 print ' graph [fontname="Tahoma", label="%s"];' % prefix
A R Karthicka2e53d62016-02-19 17:38:30 -0800107 print >>sys.stderr, 'stateRadiate:%s\nignoredIntensity:%d' % (stateRadiate, ignoredIntensity)
108
109 # emit state declarations
110 for state in stateHash.keys():
111 print ' %s[color="%s"];' % (state, stateHash[state]['DOT_Color'])
112
113 # emit rankings
114 for k, v in rankdict.iteritems():
115 print >>sys.stderr, '%s rank %s' % (k, str(v))
116
117 print 'subgraph { rank = same;'
118 for state in v:
119 print ' %s;' % state
120 print '}'
121
122 for state, va in stateHash.iteritems():
A R Karthicka2e53d62016-02-19 17:38:30 -0800123 # emit ignored events
124 if va.get('IgnoredEvents'):
125 for event, v in va['IgnoredEvents'].iteritems():
126 stateStr = state
127 eventStr = event
A R Karthicka2e53d62016-02-19 17:38:30 -0800128 print '%s -> %s [label="%s/",minlen=1, fontcolor="grey%d", color="grey%d"];' % (stateStr, stateStr, eventStr, ignoredIntensity, ignoredIntensity)
129
130 # emit transitions
131 if va.get('Events'):
132 for event, v in va['Events'].iteritems():
133 stateStr = state
134 eventStr = event
135 actionStr = ''
136 if v.get('Actions'):
137 actionStr = '\\n'.join([a.strip('_') for a in v['Actions']])
138 nextStr = v['NextState']
A R Karthicka2e53d62016-02-19 17:38:30 -0800139 labelStr = '%s/\\n%s' % (eventStr, actionStr)
A R Karthicka2e53d62016-02-19 17:38:30 -0800140 if stateRadiate:
141 color = va['DOT_Color']
142 elif len(eventHash[event]):
143 color = eventHash[event]['Color']
144 else:
145 color = 'black'
146
147 fontColor = color
A R Karthicka2e53d62016-02-19 17:38:30 -0800148 styleStr = ''
149 style = eventHash[event].get('Style')
150 if style:
151 styleStr = ',style="%s"' % (style)
152
153 if style == 'invis':
154 fontColor = 'white'
155
156 print '%s -> %s [label="%s", color="%s", fontcolor="%s" %s];' % (stateStr, nextStr, labelStr, color, fontColor, styleStr)
157
158 print
159
160 print '}'
161
A R Karthicka2e53d62016-02-19 17:38:30 -0800162 else:
163
164### emit it
165
166 print header
167
168### enumerations
169 '''
170 print '%sSt = Enumeration("%sState",(' % (prefix, prefix)
171 for state in stateHash.keys():
172 print '%s"%s",' % (' '*12, state)
173 print '%s))' % (' '*12)
174
175 print
176
177 print '%sEv = Enumeration("%sEvent",(' % (prefix, prefix)
178 for event in eventHash.keys():
179 print '%s"%s",' % (' '*12, event)
180 print '%s))' % (' '*12)
181 '''
A R Karthicka2e53d62016-02-19 17:38:30 -0800182### table
183
184 fmt = ' (%' + '-%d.%ds' % (maxStateLen, maxStateLen) + '%' + '-%d.%ds' % (maxEventLen, maxEventLen) + '):( %' +' -%d.%ds' % (maxActionLen, maxActionLen) + '%s),'
185 cfmt= ' ## %' + '-%d.%ds' % (maxStateLen, maxStateLen) + '%' + '-%d.%ds' % (maxEventLen, maxEventLen) + ' %' +' -%d.%ds' % (maxActionLen, maxActionLen) + '%s'
186
187 print 'def init%s%sFsmTable(obj,St,Ev):' % (prefix[0].upper(), prefix[1:])
188# print " %sFsmTable = {" % prefix
189 print " return {"
190 print
191
192 for state, va in stateHash.iteritems():
193
194 print cfmt % ('CurrentState', 'Event', 'Actions', 'NextState')
195 print
196
197 if va.get('IgnoredEvents'):
198 for event, v in va['IgnoredEvents'].iteritems():
199 stateStr = '%sSt.' % ('') + state + ','
200 eventStr = '%sEv.' % ('') + event
201
202 print fmt % (stateStr, eventStr, '(),', stateStr.strip(','))
203
204 if va.get('Events'):
205 for event, v in va['Events'].iteritems():
206 stateStr = '%sSt.' % ('') + state + ','
207 eventStr = '%sEv.' % ('') + event
208 actionStr = ''
209 if v.get('Actions'):
210 actionStr = ','.join(['obj.%s' % action for action in v['Actions']]) + ','
211
212 nextStr = '%sSt.' % ('') + v['NextState']
213
214 print fmt % (stateStr, eventStr, '(%s),' % actionStr , nextStr)
215
216 print
217
218 print "}"
219 print
220
221