blob: 15c91f63f2a6ba9ace626d7809cf6baf9c7cec80 [file] [log] [blame]
Brad Bishopbf066a62016-10-19 08:09:44 -04001#!/usr/bin/env python
2
3import sys
4import os
5import re
6import argparse
7import yaml
8
9valid_c_name_pattern = re.compile('[\W_]+')
10ignore_list = ['description']
11all_names = []
12
13
14def get_parser(x, fmt, lmbda=lambda x: x.capitalize()):
15 try:
16 return getattr(
17 sys.modules[__name__],
18 '%s' % (fmt.format(lmbda(x))))
19 except AttributeError:
20 raise NotImplementedError("Don't know how to parse '%s'" % x)
21
22
23class RenderList(list):
24 def __init__(self, renderers):
25 self.extend(renderers)
26
27 def __call__(self, fd):
28 for x in self:
29 x(fd)
30
31
32class ParseList(list):
33 def __init__(self, parsers):
34 self.extend(parsers)
35
36 def __call__(self):
37 return RenderList([x() for x in self])
38
39
40class MatchRender(object):
41 def __init__(self, name, signature):
42 self.name = valid_c_name_pattern.sub('_', name).lower()
43 self.signature = signature
44
45 if self.name in all_names:
46 raise RuntimeError('The name "%s" is not unique.' % name)
47 else:
48 all_names.append(self.name)
49
50 def __call__(self, fd):
51 sig = ['%s=\'%s\'' % (k, v) for k, v in self.signature.iteritems()]
52 sig = ['%s,' % x for x in sig[:-1]] + [sig[-1]]
53 sig = ['"%s"' % x for x in sig]
54 sig = ['%s\n' % x for x in sig[:-1]] + [sig[-1]]
55
56 fd.write(' {\n')
57 fd.write(' "%s",\n' % self.name)
Brad Bishop49aefb32016-10-19 11:54:14 -040058 fd.write(' std::make_tuple(\n')
Brad Bishopbf066a62016-10-19 08:09:44 -040059 for s in sig:
60 fd.write(' %s' % s)
Brad Bishop49aefb32016-10-19 11:54:14 -040061 fd.write('\n')
62 fd.write(' ),\n')
Brad Bishopbf066a62016-10-19 08:09:44 -040063 fd.write(' },\n')
64
65
66class MatchEventParse(object):
67 def __init__(self, match):
68 self.name = match['name']
69 self.signature = match['signature']
70
71 def __call__(self):
72 return MatchRender(
73 self.name,
74 self.signature)
75
76
77class EventsParse(object):
78 def __init__(self, event):
79 self.delegate = None
80 cls = event['type']
81 if cls not in ignore_list:
82 fmt = '{0}EventParse'
83 self.delegate = get_parser(cls, fmt)(event)
84
85 def __call__(self):
86 if self.delegate:
87 return self.delegate()
88 return lambda x: None
89
90
91class DictParse(ParseList):
92 def __init__(self, data):
93 fmt = '{0}Parse'
94 parse = set(data.iterkeys()).difference(ignore_list)
95 ParseList.__init__(
96 self, [get_parser(x, fmt)(*data[x]) for x in parse])
97
98
99if __name__ == '__main__':
100 parser = argparse.ArgumentParser(
101 description='Phosphor Inventory Manager (PIM) YAML '
102 'scanner and code generator.')
103 parser.add_argument(
104 '-o', '--output', dest='output',
105 default='generated.hpp', help='Output file name.')
106 parser.add_argument(
107 '-d', '--dir', dest='inputdir',
108 default='examples', help='Location of files to process.')
109
110 args = parser.parse_args()
111
112 yaml_files = filter(
113 lambda x: x.endswith('.yaml'),
114 os.listdir(args.inputdir))
115
116 def get_parsers(x):
117 with open(os.path.join(args.inputdir, x), 'r') as fd:
118 return DictParse(yaml.load(fd.read()))
119
120 head = """// This file was auto generated. Do not edit.
121
122#pragma once
123
124const Manager::Events Manager::_events{
125"""
126
127 tail = """};
128"""
129
130 r = ParseList([get_parsers(x) for x in yaml_files])()
131 r.insert(0, lambda x: x.write(head))
132 r.append(lambda x: x.write(tail))
133
134 with open(args.output, 'w') as fd:
135 r(fd)
136
137# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4