Use a Mako template for generated code.
Change-Id: I8901e7719da57f13eff7ba49d50113b01fec88aa
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/generated.mako.cpp b/generated.mako.cpp
new file mode 100644
index 0000000..a92daf1
--- /dev/null
+++ b/generated.mako.cpp
@@ -0,0 +1,60 @@
+## This file is a template. The comment below is emitted
+## into the rendered file; feel free to edit this file.
+// This file was auto generated. Do not edit.
+
+#include "manager.hpp"
+
+namespace phosphor
+{
+namespace inventory
+{
+namespace manager
+{
+
+const Manager::Events Manager::_events{
+% for e in events:
+ {
+ % if e.get('description'):
+ // ${e['description']}
+ % endif
+ "${e['name']}",
+ std::make_tuple(
+ % for i, s in enumerate(e['signature'].items()):
+ % if i + 1 == len(e['signature']):
+ ${'"{0}=\'{1}\'"'.format(*s)},
+ % else:
+ ${'"{0}=\'{1}\',"'.format(*s)}
+ % endif
+ % endfor
+ % if e['filter'].get('args'):
+ filters::${e['filter']['type']}(
+ % for i, a in enumerate(e['filter']['args']):
+ % if i + 1 == len(e['filter']['args']):
+ "${a['value']}"),
+ % else:
+ "${a['value']}",
+ % endif
+ % endfor
+ % else:
+ filters::${e['filter']['type']},
+ % endif
+ % if e['action'].get('args'):
+ actions::${e['action']['type']}(
+ % for i, a in enumerate(e['action']['args']):
+ % if i + 1 == len(e['action']['args']):
+ "${a['value']}")
+ % else:
+ "${a['value']}",
+ % endif
+ % endfor
+ % else:
+ actions::${e['action']['type']}
+ % endif
+ ),
+ },
+% endfor
+};
+
+} // namespace manager
+} // namespace inventory
+} // namespace phosphor
diff --git a/pimgen.py b/pimgen.py
index c21c418..7c32594 100755
--- a/pimgen.py
+++ b/pimgen.py
@@ -5,140 +5,18 @@
import re
import argparse
import yaml
+from mako.template import Template
valid_c_name_pattern = re.compile('[\W_]+')
-ignore_list = ['description']
-all_names = []
-def get_parser(x, fmt, lmbda=lambda x: x.capitalize()):
- try:
- return getattr(
- sys.modules[__name__],
- '%s' % (fmt.format(lmbda(x))))
- except AttributeError:
- raise NotImplementedError("Don't know how to parse '%s'" % x)
-
-
-class RenderList(list):
- def __init__(self, renderers):
- self.extend(renderers)
-
- def __call__(self, fd):
- for x in self:
- x(fd)
-
-
-class ParseList(list):
- def __init__(self, parsers):
- self.extend(parsers)
-
- def __call__(self):
- return RenderList([x() for x in self])
-
-
-class MatchRender(object):
- def __init__(self, name, signature, fltr, action):
- self.name = valid_c_name_pattern.sub('_', name).lower()
- self.signature = signature
- self.fltr = fltr
- self.action = action
-
- if self.name in all_names:
- raise RuntimeError('The name "%s" is not unique.' % name)
- else:
- all_names.append(self.name)
-
- def __call__(self, fd):
- sig = ['%s=\'%s\'' % (k, v) for k, v in self.signature.iteritems()]
- sig = ['%s,' % x for x in sig[:-1]] + [sig[-1]]
- sig = ['"%s"' % x for x in sig]
- sig = ['%s\n' % x for x in sig[:-1]] + [sig[-1]]
-
- fd.write(' {\n')
- fd.write(' "%s",\n' % self.name)
- fd.write(' std::make_tuple(\n')
- for s in sig:
- fd.write(' %s' % s)
- fd.write(',\n')
- self.fltr(fd)
- fd.write(',\n')
- self.action(fd)
- fd.write('\n')
- fd.write(' ),\n')
- fd.write(' },\n')
-
-
-class FilterRender(object):
- namespace = 'filters'
- default = 'none'
-
- def __init__(self, fltr):
- self.args = None
- if fltr is None:
- self.name = self.default
- else:
- self.name = fltr.get('type')
- self.args = fltr.get('args')
-
- def __call__(self, fd):
- def fmt(x):
- if x.get('type') is None:
- return '"%s"' % x['value']
- return str(x['value'])
-
- fd.write(' %s::%s' % (self.namespace, self.name))
- if self.args:
- fd.write('(')
- buf = ','.join(([fmt(x) for x in self.args]))
- fd.write(buf)
- fd.write(')')
-
-
-class ActionRender(FilterRender):
- namespace = 'actions'
- default = 'noop'
-
- def __init__(self, action):
- FilterRender.__init__(self, action)
-
-
-class MatchEventParse(object):
- def __init__(self, match):
- self.name = match['name']
- self.signature = match['signature']
- self.fltr = match.get('filter')
- self.action = match.get('action')
-
- def __call__(self):
- return MatchRender(
- self.name,
- self.signature,
- FilterRender(self.fltr),
- ActionRender(self.action))
-
-
-class EventsParse(object):
- def __init__(self, event):
- self.delegate = None
- cls = event['type']
- if cls not in ignore_list:
- fmt = '{0}EventParse'
- self.delegate = get_parser(cls, fmt)(event)
-
- def __call__(self):
- if self.delegate:
- return self.delegate()
- return lambda x: None
-
-
-class DictParse(ParseList):
- def __init__(self, data):
- fmt = '{0}Parse'
- parse = set(data.iterkeys()).difference(ignore_list)
- ParseList.__init__(
- self, [get_parser(x, fmt)(*data[x]) for x in parse])
-
+def parse_event(e):
+ e['name'] = valid_c_name_pattern.sub('_', e['name']).lower()
+ if e.get('filter') is None:
+ e.setdefault('filter', {}).setdefault('type', 'none')
+ if e.get('action') is None:
+ e.setdefault('action', {}).setdefault('type', 'noop')
+ return e
if __name__ == '__main__':
parser = argparse.ArgumentParser(
@@ -151,6 +29,10 @@
'-d', '--dir', dest='inputdir',
default=os.path.join('example', 'events'),
help='Location of files to process.')
+ parser.add_argument(
+ '-t', '--templatedir', dest='template',
+ default='generated.mako.cpp',
+ help='Location of mako template.')
args = parser.parse_args()
@@ -158,36 +40,17 @@
lambda x: x.endswith('.yaml'),
os.listdir(args.inputdir))
- def get_parsers(x):
+ events = []
+ for x in yaml_files:
with open(os.path.join(args.inputdir, x), 'r') as fd:
- return DictParse(yaml.load(fd.read()))
+ for e in yaml.load(fd.read()).get('events', {}):
+ events.append(parse_event(e))
- head = """// This file was auto generated. Do not edit.
-
-#include "manager.hpp"
-
-namespace phosphor
-{
-namespace inventory
-{
-namespace manager
-{
-
-const Manager::Events Manager::_events{
-"""
-
- tail = """};
-
-} // namespace manager
-} // namespace inventory
-} // namespace phosphor
-"""
-
- r = ParseList([get_parsers(x) for x in yaml_files])()
- r.insert(0, lambda x: x.write(head))
- r.append(lambda x: x.write(tail))
-
+ t = Template(filename=args.template)
with open(args.output, 'w') as fd:
- r(fd)
+ fd.write(
+ t.render(
+ events=events))
+
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4