blob: 353dc15bcac48df63bf904e6fcc89e0dc01bfa9a [file] [log] [blame]
Brad Bishopbf066a62016-10-19 08:09:44 -04001#!/usr/bin/env python
2
Brad Bishop22cfbe62016-11-30 13:25:10 -05003'''Phosphor Inventory Manager YAML parser and code generator.
4
5The parser workflow is broken down as follows:
6 1 - Import YAML files as native python type(s) instance(s).
7 2 - Create an instance of the Everything class from the
8 native python type instance(s) with the Everything.load
9 method.
10 3 - The Everything class constructor orchestrates conversion of the
11 native python type(s) instances(s) to render helper types.
12 Each render helper type constructor imports its attributes
13 from the native python type(s) instances(s).
14 4 - Present the converted YAML to the command processing method
15 requested by the script user.
16'''
17
Brad Bishopbf066a62016-10-19 08:09:44 -040018import sys
19import os
Brad Bishopbf066a62016-10-19 08:09:44 -040020import argparse
Brad Bishopcfb3c892016-11-12 11:43:37 -050021import subprocess
Brad Bishop22cfbe62016-11-30 13:25:10 -050022import yaml
23import mako.lookup
24import sdbusplus.property
25from sdbusplus.namedelement import NamedElement
26from sdbusplus.renderer import Renderer
Brad Bishopbf066a62016-10-19 08:09:44 -040027
28
Brad Bishop9b5a12f2017-01-21 14:42:11 -050029def cppTypeName(yaml_type):
30 ''' Convert yaml types to cpp types.'''
31 return sdbusplus.property.Property(type=yaml_type).cppTypeName
32
33
Brad Bishop22cfbe62016-11-30 13:25:10 -050034class Interface(list):
35 '''Provide various interface transformations.'''
36
37 def __init__(self, iface):
38 super(Interface, self).__init__(iface.split('.'))
39
40 def namespace(self):
41 '''Represent as an sdbusplus namespace.'''
42 return '::'.join(['sdbusplus'] + self[:-1] + ['server', self[-1]])
43
44 def header(self):
45 '''Represent as an sdbusplus server binding header.'''
46 return os.sep.join(self + ['server.hpp'])
47
48 def __str__(self):
49 return '.'.join(self)
Brad Bishopbf066a62016-10-19 08:09:44 -040050
Brad Bishopcfb3c892016-11-12 11:43:37 -050051
Brad Bishop9b5a12f2017-01-21 14:42:11 -050052class Indent(object):
53 '''Help templates be depth agnostic.'''
54
55 def __init__(self, depth=0):
56 self.depth = depth
57
58 def __add__(self, depth):
59 return Indent(self.depth + depth)
60
61 def __call__(self, depth):
62 '''Render an indent at the current depth plus depth.'''
63 return 4*' '*(depth + self.depth)
64
65
66class Template(NamedElement):
67 '''Associate a template name with its namespace.'''
68
69 def __init__(self, **kw):
Brad Bishopc1f47982017-02-09 01:27:38 -050070 self.namespace = kw.pop('namespace', [])
Brad Bishop9b5a12f2017-01-21 14:42:11 -050071 super(Template, self).__init__(**kw)
72
73 def qualified(self):
74 return '::'.join(self.namespace + [self.name])
75
76
Brad Bishopdb9b3252017-01-30 08:58:40 -050077class FixBool(object):
78 '''Un-capitalize booleans.'''
79
80 def __call__(self, arg):
81 return '{0}'.format(arg.lower())
82
83
Brad Bishop9b5a12f2017-01-21 14:42:11 -050084class Quote(object):
85 '''Decorate an argument by quoting it.'''
86
87 def __call__(self, arg):
88 return '"{0}"'.format(arg)
89
90
91class Cast(object):
92 '''Decorate an argument by casting it.'''
93
94 def __init__(self, cast, target):
95 '''cast is the cast type (static, const, etc...).
96 target is the cast target type.'''
97 self.cast = cast
98 self.target = target
99
100 def __call__(self, arg):
101 return '{0}_cast<{1}>({2})'.format(self.cast, self.target, arg)
102
103
104class Literal(object):
105 '''Decorate an argument with a literal operator.'''
106
107 literals = {
108 'string': 's',
109 'int64': 'll',
110 'uint64': 'ull'
111 }
112
113 def __init__(self, type):
114 self.type = type
115
116 def __call__(self, arg):
117 literal = self.literals.get(self.type)
118
119 if literal:
120 return '{0}{1}'.format(arg, literal)
121
122 return arg
123
124
Brad Bishop75800cf2017-01-21 15:24:18 -0500125class Argument(NamedElement, Renderer):
126 '''Define argument type inteface.'''
127
128 def __init__(self, **kw):
129 self.type = kw.pop('type', None)
130 super(Argument, self).__init__(**kw)
131
132 def argument(self, loader, indent):
133 raise NotImplementedError
134
135
136class TrivialArgument(Argument):
137 '''Non-array type arguments.'''
Brad Bishop14a9fe52016-11-12 12:51:26 -0500138
Brad Bishop22cfbe62016-11-30 13:25:10 -0500139 def __init__(self, **kw):
140 self.value = kw.pop('value')
Brad Bishop75800cf2017-01-21 15:24:18 -0500141 self.decorators = kw.pop('decorators', [])
142 if kw.get('type', None) == 'string':
143 self.decorators.insert(0, Quote())
Brad Bishopdb9b3252017-01-30 08:58:40 -0500144 if kw.get('type', None) == 'boolean':
145 self.decorators.insert(0, FixBool())
Brad Bishop75800cf2017-01-21 15:24:18 -0500146
Brad Bishop75800cf2017-01-21 15:24:18 -0500147 super(TrivialArgument, self).__init__(**kw)
148
149 def argument(self, loader, indent):
150 a = str(self.value)
151 for d in self.decorators:
152 a = d(a)
153
154 return a
Brad Bishop14a9fe52016-11-12 12:51:26 -0500155
Brad Bishop14a9fe52016-11-12 12:51:26 -0500156
Brad Bishop9b5a12f2017-01-21 14:42:11 -0500157class InitializerList(Argument):
158 '''Initializer list arguments.'''
159
160 def __init__(self, **kw):
161 self.values = kw.pop('values')
162 super(InitializerList, self).__init__(**kw)
163
164 def argument(self, loader, indent):
165 return self.render(
166 loader,
167 'argument.mako.cpp',
168 arg=self,
169 indent=indent)
170
171
Brad Bishop75800cf2017-01-21 15:24:18 -0500172class DbusSignature(Argument):
173 '''DBus signature arguments.'''
174
175 def __init__(self, **kw):
176 self.sig = {x: y for x, y in kw.iteritems()}
177 kw.clear()
178 super(DbusSignature, self).__init__(**kw)
179
180 def argument(self, loader, indent):
181 return self.render(
182 loader,
183 'signature.mako.cpp',
184 signature=self,
185 indent=indent)
186
187
Brad Bishopc93bcc92017-01-21 16:23:39 -0500188class MethodCall(Argument):
Brad Bishop22cfbe62016-11-30 13:25:10 -0500189 '''Render syntatically correct c++ method calls.'''
190
191 def __init__(self, **kw):
192 self.namespace = kw.pop('namespace', [])
Brad Bishopc93bcc92017-01-21 16:23:39 -0500193 self.templates = kw.pop('templates', [])
194 self.args = kw.pop('args', [])
Brad Bishop22cfbe62016-11-30 13:25:10 -0500195 super(MethodCall, self).__init__(**kw)
196
Brad Bishopcab2bdd2017-01-21 15:00:54 -0500197 def call(self, loader, indent):
198 return self.render(
199 loader,
200 'method.mako.cpp',
201 method=self,
202 indent=indent)
203
204 def argument(self, loader, indent):
205 return self.call(loader, indent)
206
Brad Bishop14a9fe52016-11-12 12:51:26 -0500207
Brad Bishop9b5a12f2017-01-21 14:42:11 -0500208class Vector(MethodCall):
209 '''Convenience type for vectors.'''
210
211 def __init__(self, **kw):
212 kw['name'] = 'vector'
213 kw['namespace'] = ['std']
214 kw['args'] = [InitializerList(values=kw.pop('args'))]
215 super(Vector, self).__init__(**kw)
216
217
Brad Bishopc1f47982017-02-09 01:27:38 -0500218class Filter(MethodCall):
Brad Bishopc93bcc92017-01-21 16:23:39 -0500219 '''Convenience type for filters'''
Brad Bishopbf066a62016-10-19 08:09:44 -0400220
Brad Bishop22cfbe62016-11-30 13:25:10 -0500221 def __init__(self, **kw):
Brad Bishopc1f47982017-02-09 01:27:38 -0500222 kw['name'] = 'make_filter'
Brad Bishop22cfbe62016-11-30 13:25:10 -0500223 super(Filter, self).__init__(**kw)
Brad Bishopbf066a62016-10-19 08:09:44 -0400224
Brad Bishop0a6a4792016-11-12 12:10:07 -0500225
Brad Bishopc1f47982017-02-09 01:27:38 -0500226class Action(MethodCall):
Brad Bishopc93bcc92017-01-21 16:23:39 -0500227 '''Convenience type for actions'''
Brad Bishop561a5652016-10-26 21:13:32 -0500228
Brad Bishop22cfbe62016-11-30 13:25:10 -0500229 def __init__(self, **kw):
Brad Bishopc1f47982017-02-09 01:27:38 -0500230 kw['name'] = 'make_action'
Brad Bishop22cfbe62016-11-30 13:25:10 -0500231 super(Action, self).__init__(**kw)
Brad Bishop92665b22016-10-26 20:51:16 -0500232
Brad Bishopcfb3c892016-11-12 11:43:37 -0500233
Brad Bishopd0f48ad2017-01-30 08:52:26 -0500234class PathCondition(MethodCall):
235 '''Convenience type for path conditions'''
236
237 def __init__(self, **kw):
238 kw['name'] = 'make_path_condition'
239 super(PathCondition, self).__init__(**kw)
240
241
Brad Bishopc1f47982017-02-09 01:27:38 -0500242class CreateObjects(MethodCall):
243 '''Assemble a createObjects functor.'''
Brad Bishopdb92c282017-01-21 23:44:28 -0500244
245 def __init__(self, **kw):
246 objs = []
247
248 for path, interfaces in kw.pop('objs').iteritems():
249 key_o = TrivialArgument(
250 value=path,
251 type='string',
252 decorators=[Literal('string')])
253 value_i = []
254
255 for interface, properties, in interfaces.iteritems():
256 key_i = TrivialArgument(value=interface, type='string')
257 value_p = []
258
259 for prop, value in properties.iteritems():
260 key_p = TrivialArgument(value=prop, type='string')
261 value_v = TrivialArgument(
262 decorators=[Literal(value.get('type', None))],
263 **value)
264 value_p.append(InitializerList(values=[key_p, value_v]))
265
266 value_p = InitializerList(values=value_p)
267 value_i.append(InitializerList(values=[key_i, value_p]))
268
269 value_i = InitializerList(values=value_i)
270 objs.append(InitializerList(values=[key_o, value_i]))
271
272 kw['args'] = [InitializerList(values=objs)]
Brad Bishopc1f47982017-02-09 01:27:38 -0500273 kw['namespace'] = ['functor']
Brad Bishopdb92c282017-01-21 23:44:28 -0500274 super(CreateObjects, self).__init__(**kw)
275
276
Brad Bishopc1f47982017-02-09 01:27:38 -0500277class DestroyObjects(MethodCall):
278 '''Assemble a destroyObject functor.'''
Brad Bishop22cfbe62016-11-30 13:25:10 -0500279
280 def __init__(self, **kw):
Brad Bishop7b7e7122017-01-21 21:21:46 -0500281 values = [{'value': x, 'type': 'string'} for x in kw.pop('paths')]
Brad Bishopd0f48ad2017-01-30 08:52:26 -0500282 conditions = [
283 Event.functor_map[
284 x['name']](**x) for x in kw.pop('conditions', [])]
285 conditions = [PathCondition(args=[x]) for x in conditions]
Brad Bishop7b7e7122017-01-21 21:21:46 -0500286 args = [InitializerList(
287 values=[TrivialArgument(**x) for x in values])]
Brad Bishopd0f48ad2017-01-30 08:52:26 -0500288 args.append(InitializerList(values=conditions))
Brad Bishopc93bcc92017-01-21 16:23:39 -0500289 kw['args'] = args
Brad Bishopc1f47982017-02-09 01:27:38 -0500290 kw['namespace'] = ['functor']
Brad Bishop7b7e7122017-01-21 21:21:46 -0500291 super(DestroyObjects, self).__init__(**kw)
Brad Bishop22cfbe62016-11-30 13:25:10 -0500292
293
Brad Bishopc1f47982017-02-09 01:27:38 -0500294class SetProperty(MethodCall):
295 '''Assemble a setProperty functor.'''
Brad Bishope2e402f2016-11-30 18:00:17 -0500296
297 def __init__(self, **kw):
Brad Bishopc93bcc92017-01-21 16:23:39 -0500298 args = []
299
300 value = kw.pop('value')
301 prop = kw.pop('property')
302 iface = kw.pop('interface')
303 iface = Interface(iface)
304 namespace = iface.namespace().split('::')[:-1]
305 name = iface[-1]
306 t = Template(namespace=namespace, name=iface[-1])
307
Brad Bishope2e402f2016-11-30 18:00:17 -0500308 member = '&%s' % '::'.join(
Brad Bishopc93bcc92017-01-21 16:23:39 -0500309 namespace + [name, NamedElement(name=prop).camelCase])
310 member_type = cppTypeName(value['type'])
311 member_cast = '{0} ({1}::*)({0})'.format(member_type, t.qualified())
Brad Bishope2e402f2016-11-30 18:00:17 -0500312
Brad Bishop02ca0212017-01-28 23:25:58 -0500313 paths = [{'value': x, 'type': 'string'} for x in kw.pop('paths')]
314 args.append(InitializerList(
315 values=[TrivialArgument(**x) for x in paths]))
316
Brad Bishopd0f48ad2017-01-30 08:52:26 -0500317 conditions = [
318 Event.functor_map[
319 x['name']](**x) for x in kw.pop('conditions', [])]
320 conditions = [PathCondition(args=[x]) for x in conditions]
321
322 args.append(InitializerList(values=conditions))
Brad Bishopc93bcc92017-01-21 16:23:39 -0500323 args.append(TrivialArgument(value=str(iface), type='string'))
324 args.append(TrivialArgument(
325 value=member, decorators=[Cast('static', member_cast)]))
326 args.append(TrivialArgument(**value))
Brad Bishope2e402f2016-11-30 18:00:17 -0500327
Brad Bishopc93bcc92017-01-21 16:23:39 -0500328 kw['templates'] = [Template(name=name, namespace=namespace)]
329 kw['args'] = args
Brad Bishopc1f47982017-02-09 01:27:38 -0500330 kw['namespace'] = ['functor']
Brad Bishope2e402f2016-11-30 18:00:17 -0500331 super(SetProperty, self).__init__(**kw)
332
333
Brad Bishopc1f47982017-02-09 01:27:38 -0500334class PropertyChanged(MethodCall):
335 '''Assemble a propertyChanged functor.'''
Brad Bishop22cfbe62016-11-30 13:25:10 -0500336
337 def __init__(self, **kw):
Brad Bishopc93bcc92017-01-21 16:23:39 -0500338 args = []
339 args.append(TrivialArgument(value=kw.pop('interface'), type='string'))
340 args.append(TrivialArgument(value=kw.pop('property'), type='string'))
341 args.append(TrivialArgument(
342 decorators=[
343 Literal(kw['value'].get('type', None))], **kw.pop('value')))
344 kw['args'] = args
Brad Bishopc1f47982017-02-09 01:27:38 -0500345 kw['namespace'] = ['functor']
Brad Bishop22cfbe62016-11-30 13:25:10 -0500346 super(PropertyChanged, self).__init__(**kw)
347
348
Brad Bishopc1f47982017-02-09 01:27:38 -0500349class PropertyIs(MethodCall):
350 '''Assemble a propertyIs functor.'''
Brad Bishop040e18b2017-01-21 22:04:00 -0500351
352 def __init__(self, **kw):
353 args = []
Brad Bishopd0f48ad2017-01-30 08:52:26 -0500354 path = kw.pop('path', None)
355 if not path:
356 path = TrivialArgument(value='nullptr')
357 else:
358 path = TrivialArgument(value=path, type='string')
359
360 args.append(path)
Brad Bishop040e18b2017-01-21 22:04:00 -0500361 args.append(TrivialArgument(value=kw.pop('interface'), type='string'))
362 args.append(TrivialArgument(value=kw.pop('property'), type='string'))
363 args.append(TrivialArgument(
364 decorators=[
365 Literal(kw['value'].get('type', None))], **kw.pop('value')))
366
367 service = kw.pop('service', None)
368 if service:
369 args.append(TrivialArgument(value=service, type='string'))
370
371 kw['args'] = args
Brad Bishopc1f47982017-02-09 01:27:38 -0500372 kw['namespace'] = ['functor']
Brad Bishop040e18b2017-01-21 22:04:00 -0500373 super(PropertyIs, self).__init__(**kw)
374
375
Brad Bishopc93bcc92017-01-21 16:23:39 -0500376class Event(MethodCall):
377 '''Assemble an inventory manager event.'''
Brad Bishop22cfbe62016-11-30 13:25:10 -0500378
Brad Bishopd0f48ad2017-01-30 08:52:26 -0500379 functor_map = {
Brad Bishop7b7e7122017-01-21 21:21:46 -0500380 'destroyObjects': DestroyObjects,
Brad Bishopdb92c282017-01-21 23:44:28 -0500381 'createObjects': CreateObjects,
Brad Bishopc93bcc92017-01-21 16:23:39 -0500382 'propertyChangedTo': PropertyChanged,
Brad Bishop040e18b2017-01-21 22:04:00 -0500383 'propertyIs': PropertyIs,
Brad Bishopd0f48ad2017-01-30 08:52:26 -0500384 'setProperty': SetProperty,
Brad Bishopc93bcc92017-01-21 16:23:39 -0500385 }
386
Brad Bishop22cfbe62016-11-30 13:25:10 -0500387 def __init__(self, **kw):
Brad Bishopc93bcc92017-01-21 16:23:39 -0500388 self.summary = kw.pop('name')
389
390 filters = [
Brad Bishopd0f48ad2017-01-30 08:52:26 -0500391 self.functor_map[x['name']](**x) for x in kw.pop('filters', [])]
Brad Bishopc1f47982017-02-09 01:27:38 -0500392 filters = [Filter(args=[x]) for x in filters]
Brad Bishop064c94a2017-01-21 21:33:30 -0500393 filters = Vector(
Brad Bishop12f8a3c2017-02-09 00:02:00 -0500394 templates=[Template(name='Filter', namespace=[])],
Brad Bishop064c94a2017-01-21 21:33:30 -0500395 args=filters)
Brad Bishopc93bcc92017-01-21 16:23:39 -0500396
397 event = MethodCall(
398 name='make_shared',
399 namespace=['std'],
400 templates=[Template(
401 name=kw.pop('event'),
402 namespace=kw.pop('event_namespace', []))],
Brad Bishop064c94a2017-01-21 21:33:30 -0500403 args=kw.pop('event_args', []) + [filters])
Brad Bishopc93bcc92017-01-21 16:23:39 -0500404
405 events = Vector(
Brad Bishop12f8a3c2017-02-09 00:02:00 -0500406 templates=[Template(name='EventBasePtr', namespace=[])],
Brad Bishopc93bcc92017-01-21 16:23:39 -0500407 args=[event])
408
Brad Bishop12f8a3c2017-02-09 00:02:00 -0500409 action_type = Template(name='Action', namespace=[])
Brad Bishopc93bcc92017-01-21 16:23:39 -0500410 action_args = [
Brad Bishopd0f48ad2017-01-30 08:52:26 -0500411 self.functor_map[x['name']](**x) for x in kw.pop('actions', [])]
Brad Bishopc1f47982017-02-09 01:27:38 -0500412 action_args = [Action(args=[x]) for x in action_args]
Brad Bishopc93bcc92017-01-21 16:23:39 -0500413 actions = Vector(
414 templates=[action_type],
415 args=action_args)
416
417 kw['name'] = 'make_tuple'
418 kw['namespace'] = ['std']
419 kw['args'] = [events, actions]
Brad Bishop22cfbe62016-11-30 13:25:10 -0500420 super(Event, self).__init__(**kw)
Brad Bishopcfb3c892016-11-12 11:43:37 -0500421
Brad Bishopcfb3c892016-11-12 11:43:37 -0500422
Brad Bishop22cfbe62016-11-30 13:25:10 -0500423class MatchEvent(Event):
424 '''Associate one or more dbus signal match signatures with
425 a filter.'''
426
Brad Bishop22cfbe62016-11-30 13:25:10 -0500427 def __init__(self, **kw):
Brad Bishopc93bcc92017-01-21 16:23:39 -0500428 kw['event'] = 'DbusSignal'
Brad Bishop12f8a3c2017-02-09 00:02:00 -0500429 kw['event_namespace'] = []
Brad Bishopc93bcc92017-01-21 16:23:39 -0500430 kw['event_args'] = [
431 DbusSignature(**x) for x in kw.pop('signatures', [])]
432
Brad Bishop22cfbe62016-11-30 13:25:10 -0500433 super(MatchEvent, self).__init__(**kw)
434
435
Brad Bishop828df832017-01-21 22:20:43 -0500436class StartupEvent(Event):
437 '''Assemble a startup event.'''
438
439 def __init__(self, **kw):
440 kw['event'] = 'StartupEvent'
Brad Bishop12f8a3c2017-02-09 00:02:00 -0500441 kw['event_namespace'] = []
Brad Bishop828df832017-01-21 22:20:43 -0500442 super(StartupEvent, self).__init__(**kw)
443
444
Brad Bishop22cfbe62016-11-30 13:25:10 -0500445class Everything(Renderer):
446 '''Parse/render entry point.'''
447
448 class_map = {
449 'match': MatchEvent,
Brad Bishop828df832017-01-21 22:20:43 -0500450 'startup': StartupEvent,
Brad Bishop22cfbe62016-11-30 13:25:10 -0500451 }
452
453 @staticmethod
454 def load(args):
Brad Bishop22cfbe62016-11-30 13:25:10 -0500455 # Aggregate all the event YAML in the events.d directory
456 # into a single list of events.
457
Brad Bishop22cfbe62016-11-30 13:25:10 -0500458 events = []
Brad Bishopa6fcd562017-02-03 11:00:27 -0500459 events_dir = os.path.join(args.inputdir, 'events.d')
460
461 if os.path.exists(events_dir):
462 yaml_files = filter(
463 lambda x: x.endswith('.yaml'),
464 os.listdir(events_dir))
465
466 for x in yaml_files:
467 with open(os.path.join(events_dir, x), 'r') as fd:
468 for e in yaml.safe_load(fd.read()).get('events', {}):
469 events.append(e)
Brad Bishop22cfbe62016-11-30 13:25:10 -0500470
Brad Bishop834989f2017-02-06 12:08:20 -0500471 interfaces = Everything.get_interfaces(args.ifacesdir)
472 extra_interfaces = Everything.get_interfaces(
473 os.path.join(args.inputdir, 'extra_interfaces.d'))
474
Brad Bishop22cfbe62016-11-30 13:25:10 -0500475 return Everything(
476 *events,
Brad Bishop834989f2017-02-06 12:08:20 -0500477 interfaces=interfaces + extra_interfaces)
Brad Bishop22cfbe62016-11-30 13:25:10 -0500478
479 @staticmethod
Brad Bishop834989f2017-02-06 12:08:20 -0500480 def get_interfaces(targetdir):
481 '''Scan the interfaces directory for interfaces that PIM can create.'''
Brad Bishop22cfbe62016-11-30 13:25:10 -0500482
Brad Bishop834989f2017-02-06 12:08:20 -0500483 yaml_files = []
Brad Bishop22cfbe62016-11-30 13:25:10 -0500484 interfaces = []
Brad Bishopa6fcd562017-02-03 11:00:27 -0500485
Brad Bishop834989f2017-02-06 12:08:20 -0500486 if targetdir and os.path.exists(targetdir):
487 for directory, _, files in os.walk(targetdir):
488 if not files:
489 continue
490
491 yaml_files += map(
492 lambda f: os.path.relpath(
493 os.path.join(directory, f),
494 targetdir),
495 filter(lambda f: f.endswith('.interface.yaml'), files))
496
497 for y in yaml_files:
498 with open(os.path.join(targetdir, y)) as fd:
499 i = y.replace('.interface.yaml', '').replace(os.sep, '.')
500
501 # PIM can't create interfaces with methods.
502 # PIM can't create interfaces without properties.
503 parsed = yaml.safe_load(fd.read())
504 if parsed.get('methods', None):
505 continue
506 if not parsed.get('properties', None):
507 continue
508
509 interfaces.append(i)
Brad Bishop22cfbe62016-11-30 13:25:10 -0500510
511 return interfaces
512
513 def __init__(self, *a, **kw):
514 self.interfaces = \
515 [Interface(x) for x in kw.pop('interfaces', [])]
516 self.events = [
517 self.class_map[x['type']](**x) for x in a]
518 super(Everything, self).__init__(**kw)
519
Brad Bishop22cfbe62016-11-30 13:25:10 -0500520 def generate_cpp(self, loader):
521 '''Render the template with the provided events and interfaces.'''
522 with open(os.path.join(
523 args.outputdir,
524 'generated.cpp'), 'w') as fd:
525 fd.write(
526 self.render(
527 loader,
528 'generated.mako.cpp',
529 events=self.events,
Brad Bishop9b5a12f2017-01-21 14:42:11 -0500530 interfaces=self.interfaces,
531 indent=Indent()))
Brad Bishopbf066a62016-10-19 08:09:44 -0400532
Brad Bishop95dd98f2016-11-12 12:39:15 -0500533
534if __name__ == '__main__':
535 script_dir = os.path.dirname(os.path.realpath(__file__))
Brad Bishop14a9fe52016-11-12 12:51:26 -0500536 valid_commands = {
537 'generate-cpp': 'generate_cpp',
Brad Bishop22cfbe62016-11-30 13:25:10 -0500538 }
Brad Bishop95dd98f2016-11-12 12:39:15 -0500539
540 parser = argparse.ArgumentParser(
541 description='Phosphor Inventory Manager (PIM) YAML '
542 'scanner and code generator.')
543 parser.add_argument(
544 '-o', '--output-dir', dest='outputdir',
545 default='.', help='Output directory.')
546 parser.add_argument(
Brad Bishop834989f2017-02-06 12:08:20 -0500547 '-i', '--interfaces-dir', dest='ifacesdir',
548 help='Location of interfaces to be supported.')
549 parser.add_argument(
Brad Bishop95dd98f2016-11-12 12:39:15 -0500550 '-d', '--dir', dest='inputdir',
551 default=os.path.join(script_dir, 'example'),
552 help='Location of files to process.')
Brad Bishopf4666f52016-11-12 12:44:42 -0500553 parser.add_argument(
554 'command', metavar='COMMAND', type=str,
555 choices=valid_commands.keys(),
Brad Bishopc029f6a2017-01-18 19:43:26 -0500556 help='%s.' % " | ".join(valid_commands.keys()))
Brad Bishop95dd98f2016-11-12 12:39:15 -0500557
558 args = parser.parse_args()
Brad Bishop22cfbe62016-11-30 13:25:10 -0500559
560 if sys.version_info < (3, 0):
561 lookup = mako.lookup.TemplateLookup(
562 directories=[script_dir],
563 disable_unicode=True)
564 else:
565 lookup = mako.lookup.TemplateLookup(
566 directories=[script_dir])
567
568 function = getattr(
569 Everything.load(args),
570 valid_commands[args.command])
571 function(lookup)
Brad Bishop95dd98f2016-11-12 12:39:15 -0500572
573
Brad Bishopbf066a62016-10-19 08:09:44 -0400574# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4