blob: 95d9b72e3758017cf683b00b5b96985e74eda445 [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
Brad Bishopcfb3c892016-11-12 11:43:37 -05008import subprocess
Brad Bishop92665b22016-10-26 20:51:16 -05009from mako.template import Template
Brad Bishopbf066a62016-10-19 08:09:44 -040010
11valid_c_name_pattern = re.compile('[\W_]+')
Brad Bishopbf066a62016-10-19 08:09:44 -040012
13
Brad Bishop92665b22016-10-26 20:51:16 -050014def parse_event(e):
15 e['name'] = valid_c_name_pattern.sub('_', e['name']).lower()
16 if e.get('filter') is None:
17 e.setdefault('filter', {}).setdefault('type', 'none')
18 if e.get('action') is None:
19 e.setdefault('action', {}).setdefault('type', 'noop')
20 return e
Brad Bishopbf066a62016-10-19 08:09:44 -040021
Brad Bishopcfb3c892016-11-12 11:43:37 -050022
Brad Bishopbf066a62016-10-19 08:09:44 -040023if __name__ == '__main__':
Brad Bishop79d8f7a2016-11-09 22:40:57 -050024 script_dir = os.path.dirname(os.path.realpath(__file__))
25
Brad Bishopbf066a62016-10-19 08:09:44 -040026 parser = argparse.ArgumentParser(
27 description='Phosphor Inventory Manager (PIM) YAML '
28 'scanner and code generator.')
29 parser.add_argument(
Brad Bishop4d16b692016-11-12 11:45:35 -050030 '-o', '--output-dir', dest='outputdir',
31 default='.', help='Output directory.')
Brad Bishopbf066a62016-10-19 08:09:44 -040032 parser.add_argument(
33 '-d', '--dir', dest='inputdir',
Brad Bishopf30db4c2016-11-09 22:47:05 -050034 default=os.path.join(script_dir, 'example'),
Brad Bishop09fc2562016-10-21 22:58:08 -040035 help='Location of files to process.')
Brad Bishopbf066a62016-10-19 08:09:44 -040036
37 args = parser.parse_args()
38
Brad Bishop3904cf42016-11-12 12:00:03 -050039 # Aggregate all the event YAML in the events.d directory
Brad Bishopcfb3c892016-11-12 11:43:37 -050040 # into a single list of events.
Brad Bishop3904cf42016-11-12 12:00:03 -050041 events_dir = os.path.join(args.inputdir, 'events.d')
Brad Bishopbf066a62016-10-19 08:09:44 -040042 yaml_files = filter(
43 lambda x: x.endswith('.yaml'),
Brad Bishopbbf13bd2016-11-09 22:29:09 -050044 os.listdir(events_dir))
Brad Bishopbf066a62016-10-19 08:09:44 -040045
Brad Bishop92665b22016-10-26 20:51:16 -050046 events = []
47 for x in yaml_files:
Brad Bishopbbf13bd2016-11-09 22:29:09 -050048 with open(os.path.join(events_dir, x), 'r') as fd:
Brad Bishop92665b22016-10-26 20:51:16 -050049 for e in yaml.load(fd.read()).get('events', {}):
50 events.append(parse_event(e))
Brad Bishopbf066a62016-10-19 08:09:44 -040051
Brad Bishop0a6a4792016-11-12 12:10:07 -050052 # Aggregate all the interface YAML in the interfaces.d
53 # directory into a single list of interfaces.
54 template = os.path.join(script_dir, 'generated.mako.cpp')
55 t = Template(filename=template)
56
57 interfaces_dir = os.path.join(args.inputdir, 'interfaces.d')
58 yaml_files = filter(
59 lambda x: x.endswith('.yaml'),
60 os.listdir(interfaces_dir))
61
62 interfaces = []
63 for x in yaml_files:
64 with open(os.path.join(interfaces_dir, x), 'r') as fd:
65 for i in yaml.load(fd.read()):
66 interfaces.append(i)
Brad Bishop561a5652016-10-26 21:13:32 -050067
Brad Bishopcfb3c892016-11-12 11:43:37 -050068 # Render the template with the provided events and interfaces.
69 template = os.path.join(script_dir, 'generated.mako.cpp')
70 t = Template(filename=template)
Brad Bishop4d16b692016-11-12 11:45:35 -050071 with open(os.path.join(args.outputdir, 'generated.cpp'), 'w') as fd:
Brad Bishop92665b22016-10-26 20:51:16 -050072 fd.write(
73 t.render(
Brad Bishop561a5652016-10-26 21:13:32 -050074 interfaces=interfaces,
Brad Bishop92665b22016-10-26 20:51:16 -050075 events=events))
76
Brad Bishopcfb3c892016-11-12 11:43:37 -050077 # Invoke sdbus++ to generate any extra interface bindings for
78 # extra interfaces that aren't defined externally.
79 yaml_files = []
Brad Bishopea6d93a2016-11-12 12:02:24 -050080 extra_ifaces_dir = os.path.join(args.inputdir, 'extra_interfaces.d')
Brad Bishopcfb3c892016-11-12 11:43:37 -050081 if os.path.exists(extra_ifaces_dir):
82 for directory, _, files in os.walk(extra_ifaces_dir):
83 if not files:
84 continue
85
86 yaml_files += map(
87 lambda f: os.path.relpath(
88 os.path.join(directory, f),
89 extra_ifaces_dir),
90 filter(lambda f: f.endswith('.interface.yaml'), files))
91
92 genfiles = {
93 'server-cpp': lambda x: '%s.cpp' % (
94 x.replace(os.sep, '.')),
95 'server-header': lambda x: os.path.join(
96 os.path.join(
97 *x.split('.')), 'server.hpp')
98 }
99
100 for i in yaml_files:
101 iface = i.replace('.interface.yaml', '').replace(os.sep, '.')
102 for process, f in genfiles.iteritems():
103
104 dest = os.path.join(args.outputdir, f(iface))
105 parent = os.path.dirname(dest)
106 if parent and not os.path.exists(parent):
107 os.makedirs(parent)
108
109 with open(dest, 'w') as fd:
110 subprocess.call([
111 'sdbus++',
112 '-r',
113 extra_ifaces_dir,
114 'interface',
115 process,
116 iface],
117 stdout=fd)
Brad Bishopbf066a62016-10-19 08:09:44 -0400118
119# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4