| #!/usr/bin/env python |
| |
| import sys |
| import os |
| import re |
| import argparse |
| import yaml |
| |
| 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('name') |
| 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]) |
| |
| |
| if __name__ == '__main__': |
| parser = argparse.ArgumentParser( |
| description='Phosphor Inventory Manager (PIM) YAML ' |
| 'scanner and code generator.') |
| parser.add_argument( |
| '-o', '--output', dest='output', |
| default='generated.hpp', help='Output file name.') |
| parser.add_argument( |
| '-d', '--dir', dest='inputdir', |
| default='examples', help='Location of files to process.') |
| |
| args = parser.parse_args() |
| |
| yaml_files = filter( |
| lambda x: x.endswith('.yaml'), |
| os.listdir(args.inputdir)) |
| |
| def get_parsers(x): |
| with open(os.path.join(args.inputdir, x), 'r') as fd: |
| return DictParse(yaml.load(fd.read())) |
| |
| head = """// This file was auto generated. Do not edit. |
| |
| #pragma once |
| |
| const Manager::Events Manager::_events{ |
| """ |
| |
| tail = """}; |
| """ |
| |
| 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)) |
| |
| with open(args.output, 'w') as fd: |
| r(fd) |
| |
| # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 |