| #!/usr/bin/env python |
| |
| import sys |
| import os |
| import re |
| import argparse |
| import yaml |
| import subprocess |
| from mako.template import Template |
| |
| valid_c_name_pattern = re.compile('[\W_]+') |
| |
| |
| 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 |
| |
| |
| def get_interfaces(args): |
| interfaces_dir = os.path.join(args.inputdir, 'interfaces.d') |
| yaml_files = filter( |
| lambda x: x.endswith('.yaml'), |
| os.listdir(interfaces_dir)) |
| |
| interfaces = [] |
| for x in yaml_files: |
| with open(os.path.join(interfaces_dir, x), 'r') as fd: |
| for i in yaml.load(fd.read()): |
| interfaces.append(i) |
| |
| return interfaces |
| |
| |
| def list_interfaces(args): |
| print ' '.join(get_interfaces(args)) |
| |
| |
| def generate_cpp(args): |
| # Aggregate all the event YAML in the events.d directory |
| # into a single list of events. |
| events_dir = os.path.join(args.inputdir, 'events.d') |
| yaml_files = filter( |
| lambda x: x.endswith('.yaml'), |
| os.listdir(events_dir)) |
| |
| events = [] |
| for x in yaml_files: |
| with open(os.path.join(events_dir, x), 'r') as fd: |
| for e in yaml.load(fd.read()).get('events', {}): |
| events.append(parse_event(e)) |
| |
| # Aggregate all the interface YAML in the interfaces.d |
| # directory into a single list of interfaces. |
| template = os.path.join(script_dir, 'generated.mako.cpp') |
| t = Template(filename=template) |
| |
| interfaces = get_interfaces(args) |
| |
| # Render the template with the provided events and interfaces. |
| template = os.path.join(script_dir, 'generated.mako.cpp') |
| t = Template(filename=template) |
| with open(os.path.join(args.outputdir, 'generated.cpp'), 'w') as fd: |
| fd.write( |
| t.render( |
| interfaces=interfaces, |
| events=events)) |
| |
| # Invoke sdbus++ to generate any extra interface bindings for |
| # extra interfaces that aren't defined externally. |
| yaml_files = [] |
| extra_ifaces_dir = os.path.join(args.inputdir, 'extra_interfaces.d') |
| if os.path.exists(extra_ifaces_dir): |
| for directory, _, files in os.walk(extra_ifaces_dir): |
| if not files: |
| continue |
| |
| yaml_files += map( |
| lambda f: os.path.relpath( |
| os.path.join(directory, f), |
| extra_ifaces_dir), |
| filter(lambda f: f.endswith('.interface.yaml'), files)) |
| |
| genfiles = { |
| 'server-cpp': lambda x: '%s.cpp' % ( |
| x.replace(os.sep, '.')), |
| 'server-header': lambda x: os.path.join( |
| os.path.join( |
| *x.split('.')), 'server.hpp') |
| } |
| |
| for i in yaml_files: |
| iface = i.replace('.interface.yaml', '').replace(os.sep, '.') |
| for process, f in genfiles.iteritems(): |
| |
| dest = os.path.join(args.outputdir, f(iface)) |
| parent = os.path.dirname(dest) |
| if parent and not os.path.exists(parent): |
| os.makedirs(parent) |
| |
| with open(dest, 'w') as fd: |
| subprocess.call([ |
| 'sdbus++', |
| '-r', |
| extra_ifaces_dir, |
| 'interface', |
| process, |
| iface], |
| stdout=fd) |
| |
| |
| if __name__ == '__main__': |
| script_dir = os.path.dirname(os.path.realpath(__file__)) |
| valid_commands = { |
| 'generate-cpp': 'generate_cpp', |
| 'list-interfaces': 'list_interfaces'} |
| |
| parser = argparse.ArgumentParser( |
| description='Phosphor Inventory Manager (PIM) YAML ' |
| 'scanner and code generator.') |
| parser.add_argument( |
| '-o', '--output-dir', dest='outputdir', |
| default='.', help='Output directory.') |
| parser.add_argument( |
| '-d', '--dir', dest='inputdir', |
| default=os.path.join(script_dir, 'example'), |
| help='Location of files to process.') |
| parser.add_argument( |
| 'command', metavar='COMMAND', type=str, |
| choices=valid_commands.keys(), |
| help='Command to run.') |
| |
| args = parser.parse_args() |
| function = getattr(sys.modules[__name__], valid_commands[args.command]) |
| function(args) |
| |
| |
| # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 |