blob: 2f0bc778655d81bd78e728514957d46ca72268af [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 Bishop95dd98f2016-11-12 12:39:15 -050023def generate_cpp(args):
Brad Bishop3904cf42016-11-12 12:00:03 -050024 # Aggregate all the event YAML in the events.d directory
Brad Bishopcfb3c892016-11-12 11:43:37 -050025 # into a single list of events.
Brad Bishop3904cf42016-11-12 12:00:03 -050026 events_dir = os.path.join(args.inputdir, 'events.d')
Brad Bishopbf066a62016-10-19 08:09:44 -040027 yaml_files = filter(
28 lambda x: x.endswith('.yaml'),
Brad Bishopbbf13bd2016-11-09 22:29:09 -050029 os.listdir(events_dir))
Brad Bishopbf066a62016-10-19 08:09:44 -040030
Brad Bishop92665b22016-10-26 20:51:16 -050031 events = []
32 for x in yaml_files:
Brad Bishopbbf13bd2016-11-09 22:29:09 -050033 with open(os.path.join(events_dir, x), 'r') as fd:
Brad Bishop92665b22016-10-26 20:51:16 -050034 for e in yaml.load(fd.read()).get('events', {}):
35 events.append(parse_event(e))
Brad Bishopbf066a62016-10-19 08:09:44 -040036
Brad Bishop0a6a4792016-11-12 12:10:07 -050037 # Aggregate all the interface YAML in the interfaces.d
38 # directory into a single list of interfaces.
39 template = os.path.join(script_dir, 'generated.mako.cpp')
40 t = Template(filename=template)
41
42 interfaces_dir = os.path.join(args.inputdir, 'interfaces.d')
43 yaml_files = filter(
44 lambda x: x.endswith('.yaml'),
45 os.listdir(interfaces_dir))
46
47 interfaces = []
48 for x in yaml_files:
49 with open(os.path.join(interfaces_dir, x), 'r') as fd:
50 for i in yaml.load(fd.read()):
51 interfaces.append(i)
Brad Bishop561a5652016-10-26 21:13:32 -050052
Brad Bishopcfb3c892016-11-12 11:43:37 -050053 # Render the template with the provided events and interfaces.
54 template = os.path.join(script_dir, 'generated.mako.cpp')
55 t = Template(filename=template)
Brad Bishop4d16b692016-11-12 11:45:35 -050056 with open(os.path.join(args.outputdir, 'generated.cpp'), 'w') as fd:
Brad Bishop92665b22016-10-26 20:51:16 -050057 fd.write(
58 t.render(
Brad Bishop561a5652016-10-26 21:13:32 -050059 interfaces=interfaces,
Brad Bishop92665b22016-10-26 20:51:16 -050060 events=events))
61
Brad Bishopcfb3c892016-11-12 11:43:37 -050062 # Invoke sdbus++ to generate any extra interface bindings for
63 # extra interfaces that aren't defined externally.
64 yaml_files = []
Brad Bishopea6d93a2016-11-12 12:02:24 -050065 extra_ifaces_dir = os.path.join(args.inputdir, 'extra_interfaces.d')
Brad Bishopcfb3c892016-11-12 11:43:37 -050066 if os.path.exists(extra_ifaces_dir):
67 for directory, _, files in os.walk(extra_ifaces_dir):
68 if not files:
69 continue
70
71 yaml_files += map(
72 lambda f: os.path.relpath(
73 os.path.join(directory, f),
74 extra_ifaces_dir),
75 filter(lambda f: f.endswith('.interface.yaml'), files))
76
77 genfiles = {
78 'server-cpp': lambda x: '%s.cpp' % (
79 x.replace(os.sep, '.')),
80 'server-header': lambda x: os.path.join(
81 os.path.join(
82 *x.split('.')), 'server.hpp')
83 }
84
85 for i in yaml_files:
86 iface = i.replace('.interface.yaml', '').replace(os.sep, '.')
87 for process, f in genfiles.iteritems():
88
89 dest = os.path.join(args.outputdir, f(iface))
90 parent = os.path.dirname(dest)
91 if parent and not os.path.exists(parent):
92 os.makedirs(parent)
93
94 with open(dest, 'w') as fd:
95 subprocess.call([
96 'sdbus++',
97 '-r',
98 extra_ifaces_dir,
99 'interface',
100 process,
101 iface],
102 stdout=fd)
Brad Bishopbf066a62016-10-19 08:09:44 -0400103
Brad Bishop95dd98f2016-11-12 12:39:15 -0500104
105if __name__ == '__main__':
106 script_dir = os.path.dirname(os.path.realpath(__file__))
107
108 parser = argparse.ArgumentParser(
109 description='Phosphor Inventory Manager (PIM) YAML '
110 'scanner and code generator.')
111 parser.add_argument(
112 '-o', '--output-dir', dest='outputdir',
113 default='.', help='Output directory.')
114 parser.add_argument(
115 '-d', '--dir', dest='inputdir',
116 default=os.path.join(script_dir, 'example'),
117 help='Location of files to process.')
118
119 args = parser.parse_args()
120 generate_cpp(args)
121
122
Brad Bishopbf066a62016-10-19 08:09:44 -0400123# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4