controls: Add vendor control/property support to generation scripts
Add support for vendor-specific controls and properties to libcamera. The controls/properties are defined by a "vendor" tag in the YAML control description file, for example: vendor: rpi controls: - MyExampleControl: type: string description: | Test for libcamera vendor-specific controls. This will now generate a control id in the libcamera::controls::rpi namespace, ensuring no id conflict between different vendors, core or draft libcamera controls. Similarly, a ControlIdMap control is generated in the libcamera::controls::rpi namespace. A #define LIBCAMERA_HAS_RPI_VENDOR_CONTROLS is also generated to allow applications to conditionally compile code if the specific vendor controls are present. For the python bindings, the control is available with libcamera.controls.rpi.MyExampleControl. The above controls example applies similarly to properties. Existing libcamera controls defined in control_ids.yaml are given the "libcamera" vendor tag. A new --mode flag is added to gen-controls.py to specify the mode of operation, either 'controls' or 'properties' to allow the code generator to correctly set the #define string. As a drive-by, sort and redefine the output command line argument in gen-controls.py and gen-py-controls.py to ('--output', '-o') for consistency. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
parent
61f6b37242
commit
bd6658943a
12 changed files with 176 additions and 73 deletions
|
@ -32,6 +32,8 @@ ${draft_controls}
|
||||||
|
|
||||||
} /* namespace draft */
|
} /* namespace draft */
|
||||||
|
|
||||||
|
${vendor_controls}
|
||||||
|
|
||||||
} /* namespace controls */
|
} /* namespace controls */
|
||||||
|
|
||||||
} /* namespace libcamera */
|
} /* namespace libcamera */
|
||||||
|
|
|
@ -32,20 +32,21 @@ install_headers(libcamera_public_headers,
|
||||||
|
|
||||||
libcamera_headers_install_dir = get_option('includedir') / libcamera_include_dir
|
libcamera_headers_install_dir = get_option('includedir') / libcamera_include_dir
|
||||||
|
|
||||||
# control_ids.h and property_ids.h
|
# control_ids.h and property_ids.h and associated modes
|
||||||
control_source_files = [
|
control_source_files = {
|
||||||
'control_ids',
|
'control_ids': 'controls',
|
||||||
'property_ids',
|
'property_ids': 'properties',
|
||||||
]
|
}
|
||||||
|
|
||||||
control_headers = []
|
control_headers = []
|
||||||
|
|
||||||
foreach header : control_source_files
|
foreach header, mode : control_source_files
|
||||||
input_files = files('../../src/libcamera/' + header +'.yaml', header + '.h.in')
|
input_files = files('../../src/libcamera/' + header +'.yaml', header + '.h.in')
|
||||||
control_headers += custom_target(header + '_h',
|
control_headers += custom_target(header + '_h',
|
||||||
input : input_files,
|
input : input_files,
|
||||||
output : header + '.h',
|
output : header + '.h',
|
||||||
command : [gen_controls, '-o', '@OUTPUT@', '@INPUT@'],
|
command : [gen_controls, '-o', '@OUTPUT@', '@INPUT@',
|
||||||
|
'--mode', mode],
|
||||||
install : true,
|
install : true,
|
||||||
install_dir : libcamera_headers_install_dir)
|
install_dir : libcamera_headers_install_dir)
|
||||||
endforeach
|
endforeach
|
||||||
|
|
|
@ -31,6 +31,8 @@ ${draft_controls}
|
||||||
|
|
||||||
extern const ControlIdMap properties;
|
extern const ControlIdMap properties;
|
||||||
|
|
||||||
|
${vendor_controls}
|
||||||
|
|
||||||
} /* namespace properties */
|
} /* namespace properties */
|
||||||
|
|
||||||
} /* namespace libcamera */
|
} /* namespace libcamera */
|
||||||
|
|
|
@ -33,6 +33,8 @@ ${draft_controls_doc}
|
||||||
|
|
||||||
} /* namespace draft */
|
} /* namespace draft */
|
||||||
|
|
||||||
|
${vendor_controls_doc}
|
||||||
|
|
||||||
#ifndef __DOXYGEN__
|
#ifndef __DOXYGEN__
|
||||||
/*
|
/*
|
||||||
* Keep the controls definitions hidden from doxygen as it incorrectly parses
|
* Keep the controls definitions hidden from doxygen as it incorrectly parses
|
||||||
|
@ -45,6 +47,9 @@ namespace draft {
|
||||||
${draft_controls_def}
|
${draft_controls_def}
|
||||||
|
|
||||||
} /* namespace draft */
|
} /* namespace draft */
|
||||||
|
|
||||||
|
${vendor_controls_def}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
---
|
---
|
||||||
# Unless otherwise stated, all controls are bi-directional, i.e. they can be
|
# Unless otherwise stated, all controls are bi-directional, i.e. they can be
|
||||||
# set through Request::controls() and returned out through Request::metadata().
|
# set through Request::controls() and returned out through Request::metadata().
|
||||||
|
vendor: libcamera
|
||||||
controls:
|
controls:
|
||||||
- AeEnable:
|
- AeEnable:
|
||||||
type: bool
|
type: bool
|
||||||
|
|
|
@ -127,12 +127,13 @@ endif
|
||||||
|
|
||||||
control_sources = []
|
control_sources = []
|
||||||
|
|
||||||
foreach source : control_source_files
|
foreach source, mode : control_source_files
|
||||||
input_files = files(source +'.yaml', source + '.cpp.in')
|
input_files = files(source +'.yaml', source + '.cpp.in')
|
||||||
control_sources += custom_target(source + '_cpp',
|
control_sources += custom_target(source + '_cpp',
|
||||||
input : input_files,
|
input : input_files,
|
||||||
output : source + '.cpp',
|
output : source + '.cpp',
|
||||||
command : [gen_controls, '-o', '@OUTPUT@', '@INPUT@'])
|
command : [gen_controls, '-o', '@OUTPUT@', '@INPUT@',
|
||||||
|
'--mode', mode])
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
libcamera_sources += control_sources
|
libcamera_sources += control_sources
|
||||||
|
|
|
@ -32,6 +32,8 @@ ${draft_controls_doc}
|
||||||
|
|
||||||
} /* namespace draft */
|
} /* namespace draft */
|
||||||
|
|
||||||
|
${vendor_controls_doc}
|
||||||
|
|
||||||
#ifndef __DOXYGEN__
|
#ifndef __DOXYGEN__
|
||||||
/*
|
/*
|
||||||
* Keep the properties definitions hidden from doxygen as it incorrectly parses
|
* Keep the properties definitions hidden from doxygen as it incorrectly parses
|
||||||
|
@ -44,6 +46,9 @@ namespace draft {
|
||||||
${draft_controls_def}
|
${draft_controls_def}
|
||||||
|
|
||||||
} /* namespace draft */
|
} /* namespace draft */
|
||||||
|
|
||||||
|
${vendor_controls_def}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#
|
#
|
||||||
%YAML 1.1
|
%YAML 1.1
|
||||||
---
|
---
|
||||||
|
vendor: libcamera
|
||||||
controls:
|
controls:
|
||||||
- Location:
|
- Location:
|
||||||
type: int32_t
|
type: int32_t
|
||||||
|
|
|
@ -24,12 +24,24 @@ def find_common_prefix(strings):
|
||||||
def generate_py(controls, mode):
|
def generate_py(controls, mode):
|
||||||
out = ''
|
out = ''
|
||||||
|
|
||||||
for ctrl in controls:
|
vendors_class_def = []
|
||||||
name, ctrl = ctrl.popitem()
|
vendor_defs = []
|
||||||
|
vendors = []
|
||||||
|
for vendor, ctrl_list in controls.items():
|
||||||
|
for ctrls in ctrl_list:
|
||||||
|
name, ctrl = ctrls.popitem()
|
||||||
|
|
||||||
|
if vendor not in vendors and vendor != 'libcamera':
|
||||||
|
vendors_class_def.append('class Py{}Controls\n{{\n}};\n'.format(vendor))
|
||||||
|
vendor_defs.append('\tauto {} = py::class_<Py{}Controls>(controls, \"{}\");'.format(vendor, vendor, vendor))
|
||||||
|
vendors.append(vendor)
|
||||||
|
|
||||||
if ctrl.get('draft'):
|
if ctrl.get('draft'):
|
||||||
ns = 'libcamera::{}::draft::'.format(mode)
|
ns = 'libcamera::{}::draft::'.format(mode)
|
||||||
container = 'draft'
|
container = 'draft'
|
||||||
|
elif vendor != 'libcamera':
|
||||||
|
ns = 'libcamera::{}::{}::'.format(mode, vendor)
|
||||||
|
container = vendor
|
||||||
else:
|
else:
|
||||||
ns = 'libcamera::{}::'.format(mode)
|
ns = 'libcamera::{}::'.format(mode)
|
||||||
container = 'controls'
|
container = 'controls'
|
||||||
|
@ -62,7 +74,9 @@ def generate_py(controls, mode):
|
||||||
|
|
||||||
out += '\t;\n\n'
|
out += '\t;\n\n'
|
||||||
|
|
||||||
return {'controls': out}
|
return {'controls': out,
|
||||||
|
'vendors_class_def': '\n'.join(vendors_class_def),
|
||||||
|
'vendors_defs': '\n'.join(vendor_defs)}
|
||||||
|
|
||||||
|
|
||||||
def fill_template(template, data):
|
def fill_template(template, data):
|
||||||
|
@ -75,14 +89,14 @@ def fill_template(template, data):
|
||||||
def main(argv):
|
def main(argv):
|
||||||
# Parse command line arguments
|
# Parse command line arguments
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('-o', dest='output', metavar='file', type=str,
|
parser.add_argument('--mode', '-m', type=str, required=True,
|
||||||
|
help='Mode is either "controls" or "properties"')
|
||||||
|
parser.add_argument('--output', '-o', metavar='file', type=str,
|
||||||
help='Output file name. Defaults to standard output if not specified.')
|
help='Output file name. Defaults to standard output if not specified.')
|
||||||
parser.add_argument('input', type=str,
|
parser.add_argument('input', type=str,
|
||||||
help='Input file name.')
|
help='Input file name.')
|
||||||
parser.add_argument('template', type=str,
|
parser.add_argument('template', type=str,
|
||||||
help='Template file name.')
|
help='Template file name.')
|
||||||
parser.add_argument('--mode', type=str, required=True,
|
|
||||||
help='Mode is either "controls" or "properties"')
|
|
||||||
args = parser.parse_args(argv[1:])
|
args = parser.parse_args(argv[1:])
|
||||||
|
|
||||||
if args.mode not in ['controls', 'properties']:
|
if args.mode not in ['controls', 'properties']:
|
||||||
|
@ -90,7 +104,10 @@ def main(argv):
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
data = open(args.input, 'rb').read()
|
data = open(args.input, 'rb').read()
|
||||||
controls = yaml.safe_load(data)['controls']
|
|
||||||
|
controls = {}
|
||||||
|
vendor = yaml.safe_load(data)['vendor']
|
||||||
|
controls[vendor] = yaml.safe_load(data)['controls']
|
||||||
|
|
||||||
data = generate_py(controls, args.mode)
|
data = generate_py(controls, args.mode)
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,13 @@ class PyDraftControls
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
${vendors_class_def}
|
||||||
|
|
||||||
void init_py_controls_generated(py::module& m)
|
void init_py_controls_generated(py::module& m)
|
||||||
{
|
{
|
||||||
auto controls = py::class_<PyControls>(m, "controls");
|
auto controls = py::class_<PyControls>(m, "controls");
|
||||||
auto draft = py::class_<PyDraftControls>(controls, "draft");
|
auto draft = py::class_<PyDraftControls>(controls, "draft");
|
||||||
|
${vendors_defs}
|
||||||
|
|
||||||
${controls}
|
${controls}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,13 @@ class PyDraftProperties
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
${vendors_class_def}
|
||||||
|
|
||||||
void init_py_properties_generated(py::module& m)
|
void init_py_properties_generated(py::module& m)
|
||||||
{
|
{
|
||||||
auto controls = py::class_<PyProperties>(m, "properties");
|
auto controls = py::class_<PyProperties>(m, "properties");
|
||||||
auto draft = py::class_<PyDraftProperties>(controls, "draft");
|
auto draft = py::class_<PyDraftProperties>(controls, "draft");
|
||||||
|
${vendors_defs}
|
||||||
|
|
||||||
${controls}
|
${controls}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,11 +35,12 @@ class ControlEnum(object):
|
||||||
|
|
||||||
|
|
||||||
class Control(object):
|
class Control(object):
|
||||||
def __init__(self, name, data):
|
def __init__(self, name, data, vendor):
|
||||||
self.__name = name
|
self.__name = name
|
||||||
self.__data = data
|
self.__data = data
|
||||||
self.__enum_values = None
|
self.__enum_values = None
|
||||||
self.__size = None
|
self.__size = None
|
||||||
|
self.__vendor = vendor
|
||||||
|
|
||||||
enum_values = data.get('enum')
|
enum_values = data.get('enum')
|
||||||
if enum_values is not None:
|
if enum_values is not None:
|
||||||
|
@ -89,6 +90,11 @@ class Control(object):
|
||||||
"""Is the control a draft control"""
|
"""Is the control a draft control"""
|
||||||
return self.__data.get('draft') is not None
|
return self.__data.get('draft') is not None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def vendor(self):
|
||||||
|
"""The vendor string, or None"""
|
||||||
|
return self.__vendor
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"""The control name (CamelCase)"""
|
"""The control name (CamelCase)"""
|
||||||
|
@ -145,15 +151,18 @@ ${description}
|
||||||
enum_values_start = string.Template('''extern const std::array<const ControlValue, ${size}> ${name}Values = {''')
|
enum_values_start = string.Template('''extern const std::array<const ControlValue, ${size}> ${name}Values = {''')
|
||||||
enum_values_values = string.Template('''\tstatic_cast<int32_t>(${name}),''')
|
enum_values_values = string.Template('''\tstatic_cast<int32_t>(${name}),''')
|
||||||
|
|
||||||
ctrls_doc = []
|
ctrls_doc = {}
|
||||||
ctrls_def = []
|
ctrls_def = {}
|
||||||
draft_ctrls_doc = []
|
|
||||||
draft_ctrls_def = []
|
|
||||||
ctrls_map = []
|
ctrls_map = []
|
||||||
|
|
||||||
for ctrl in controls:
|
for ctrl in controls:
|
||||||
id_name = snake_case(ctrl.name).upper()
|
id_name = snake_case(ctrl.name).upper()
|
||||||
|
|
||||||
|
vendor = 'draft' if ctrl.is_draft else ctrl.vendor
|
||||||
|
if vendor not in ctrls_doc:
|
||||||
|
ctrls_doc[vendor] = []
|
||||||
|
ctrls_def[vendor] = []
|
||||||
|
|
||||||
info = {
|
info = {
|
||||||
'name': ctrl.name,
|
'name': ctrl.name,
|
||||||
'type': ctrl.type,
|
'type': ctrl.type,
|
||||||
|
@ -161,11 +170,8 @@ ${description}
|
||||||
'id_name': id_name,
|
'id_name': id_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
target_doc = ctrls_doc
|
target_doc = ctrls_doc[vendor]
|
||||||
target_def = ctrls_def
|
target_def = ctrls_def[vendor]
|
||||||
if ctrl.is_draft:
|
|
||||||
target_doc = draft_ctrls_doc
|
|
||||||
target_def = draft_ctrls_def
|
|
||||||
|
|
||||||
if ctrl.is_enum:
|
if ctrl.is_enum:
|
||||||
enum_doc = []
|
enum_doc = []
|
||||||
|
@ -203,39 +209,68 @@ ${description}
|
||||||
|
|
||||||
ctrls_map.append('\t{ ' + id_name + ', &' + ctrl.q_name + ' },')
|
ctrls_map.append('\t{ ' + id_name + ', &' + ctrl.q_name + ' },')
|
||||||
|
|
||||||
|
vendor_ctrl_doc_sub = []
|
||||||
|
vendor_ctrl_template = string.Template('''
|
||||||
|
/**
|
||||||
|
* \\brief Namespace for ${vendor} controls
|
||||||
|
*/
|
||||||
|
namespace ${vendor} {
|
||||||
|
|
||||||
|
${vendor_controls_str}
|
||||||
|
|
||||||
|
} /* namespace ${vendor} */''')
|
||||||
|
|
||||||
|
for vendor in [v for v in ctrls_doc.keys() if v not in ['libcamera', 'draft']]:
|
||||||
|
vendor_ctrl_doc_sub.append(vendor_ctrl_template.substitute({'vendor': vendor, 'vendor_controls_str': '\n\n'.join(ctrls_doc[vendor])}))
|
||||||
|
|
||||||
|
vendor_ctrl_def_sub = []
|
||||||
|
for vendor in [v for v in ctrls_def.keys() if v not in ['libcamera', 'draft']]:
|
||||||
|
vendor_ctrl_def_sub.append(vendor_ctrl_template.substitute({'vendor': vendor, 'vendor_controls_str': '\n'.join(ctrls_def[vendor])}))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'controls_doc': '\n\n'.join(ctrls_doc),
|
'controls_doc': '\n\n'.join(ctrls_doc['libcamera']),
|
||||||
'controls_def': '\n'.join(ctrls_def),
|
'controls_def': '\n'.join(ctrls_def['libcamera']),
|
||||||
'draft_controls_doc': '\n\n'.join(draft_ctrls_doc),
|
'draft_controls_doc': '\n\n'.join(ctrls_doc['draft']),
|
||||||
'draft_controls_def': '\n\n'.join(draft_ctrls_def),
|
'draft_controls_def': '\n\n'.join(ctrls_def['draft']),
|
||||||
'controls_map': '\n'.join(ctrls_map),
|
'controls_map': '\n'.join(ctrls_map),
|
||||||
|
'vendor_controls_doc': '\n'.join(vendor_ctrl_doc_sub),
|
||||||
|
'vendor_controls_def': '\n'.join(vendor_ctrl_def_sub),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def generate_h(controls):
|
def generate_h(controls, mode):
|
||||||
enum_template_start = string.Template('''enum ${name}Enum {''')
|
enum_template_start = string.Template('''enum ${name}Enum {''')
|
||||||
enum_value_template = string.Template('''\t${name} = ${value},''')
|
enum_value_template = string.Template('''\t${name} = ${value},''')
|
||||||
enum_values_template = string.Template('''extern const std::array<const ControlValue, ${size}> ${name}Values;''')
|
enum_values_template = string.Template('''extern const std::array<const ControlValue, ${size}> ${name}Values;''')
|
||||||
template = string.Template('''extern const Control<${type}> ${name};''')
|
template = string.Template('''extern const Control<${type}> ${name};''')
|
||||||
|
|
||||||
ctrls = []
|
ctrls = {}
|
||||||
draft_ctrls = []
|
ids = {}
|
||||||
ids = []
|
id_value = {}
|
||||||
id_value = 1
|
|
||||||
|
|
||||||
for ctrl in controls:
|
for ctrl in controls:
|
||||||
id_name = snake_case(ctrl.name).upper()
|
id_name = snake_case(ctrl.name).upper()
|
||||||
|
|
||||||
ids.append('\t' + id_name + ' = ' + str(id_value) + ',')
|
vendor = 'draft' if ctrl.is_draft else ctrl.vendor
|
||||||
|
if vendor not in ctrls:
|
||||||
|
ids[vendor] = []
|
||||||
|
id_value[vendor] = 1
|
||||||
|
ctrls[vendor] = []
|
||||||
|
|
||||||
|
# Core and draft controls use the same ID value
|
||||||
|
target_ids = ids['libcamera'] if vendor in ['libcamera', 'draft'] else ids[vendor]
|
||||||
|
target_ids.append('\t' + id_name + ' = ' + str(id_value[vendor]) + ',')
|
||||||
|
|
||||||
info = {
|
info = {
|
||||||
'name': ctrl.name,
|
'name': ctrl.name,
|
||||||
'type': ctrl.type,
|
'type': ctrl.type,
|
||||||
}
|
}
|
||||||
|
|
||||||
target_ctrls = ctrls
|
target_ctrls = ctrls['libcamera']
|
||||||
if ctrl.is_draft:
|
if ctrl.is_draft:
|
||||||
target_ctrls = draft_ctrls
|
target_ctrls = ctrls['draft']
|
||||||
|
elif vendor != 'libcamera':
|
||||||
|
target_ctrls = ctrls[vendor]
|
||||||
|
|
||||||
if ctrl.is_enum:
|
if ctrl.is_enum:
|
||||||
target_ctrls.append(enum_template_start.substitute(info))
|
target_ctrls.append(enum_template_start.substitute(info))
|
||||||
|
@ -257,12 +292,35 @@ def generate_h(controls):
|
||||||
target_ctrls.append(enum_values_template.substitute(values_info))
|
target_ctrls.append(enum_values_template.substitute(values_info))
|
||||||
|
|
||||||
target_ctrls.append(template.substitute(info))
|
target_ctrls.append(template.substitute(info))
|
||||||
id_value += 1
|
id_value[vendor] += 1
|
||||||
|
|
||||||
|
vendor_template = string.Template('''
|
||||||
|
namespace ${vendor} {
|
||||||
|
|
||||||
|
#define LIBCAMERA_HAS_${vendor_def}_VENDOR_${mode}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
${vendor_enums}
|
||||||
|
};
|
||||||
|
|
||||||
|
${vendor_controls}
|
||||||
|
|
||||||
|
} /* namespace ${vendor} */
|
||||||
|
''')
|
||||||
|
|
||||||
|
vendor_sub = []
|
||||||
|
for vendor in [v for v in ctrls.keys() if v not in ['libcamera', 'draft']]:
|
||||||
|
vendor_sub.append(vendor_template.substitute({'mode': mode.upper(),
|
||||||
|
'vendor': vendor,
|
||||||
|
'vendor_def': vendor.upper(),
|
||||||
|
'vendor_enums': '\n'.join(ids[vendor]),
|
||||||
|
'vendor_controls': '\n'.join(ctrls[vendor])}))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'ids': '\n'.join(ids),
|
'ids': '\n'.join(ids['libcamera']),
|
||||||
'controls': '\n'.join(ctrls),
|
'controls': '\n'.join(ctrls['libcamera']),
|
||||||
'draft_controls': '\n'.join(draft_ctrls)
|
'draft_controls': '\n'.join(ctrls['draft']),
|
||||||
|
'vendor_controls': '\n'.join(vendor_sub)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -278,22 +336,26 @@ def main(argv):
|
||||||
|
|
||||||
# Parse command line arguments
|
# Parse command line arguments
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('-o', dest='output', metavar='file', type=str,
|
parser.add_argument('--mode', '-m', type=str, required=True, choices=['controls', 'properties'],
|
||||||
|
help='Mode of operation')
|
||||||
|
parser.add_argument('--output', '-o', metavar='file', type=str,
|
||||||
help='Output file name. Defaults to standard output if not specified.')
|
help='Output file name. Defaults to standard output if not specified.')
|
||||||
parser.add_argument('input', type=str,
|
parser.add_argument('input', type=str,
|
||||||
help='Input file name.')
|
help='Input file name.')
|
||||||
parser.add_argument('template', type=str,
|
parser.add_argument('template', type=str,
|
||||||
help='Template file name.')
|
help='Template file name.')
|
||||||
|
|
||||||
args = parser.parse_args(argv[1:])
|
args = parser.parse_args(argv[1:])
|
||||||
|
|
||||||
data = open(args.input, 'rb').read()
|
data = open(args.input, 'rb').read()
|
||||||
|
vendor = yaml.safe_load(data)['vendor']
|
||||||
controls = yaml.safe_load(data)['controls']
|
controls = yaml.safe_load(data)['controls']
|
||||||
controls = [Control(*ctrl.popitem()) for ctrl in controls]
|
controls = [Control(*ctrl.popitem(), vendor) for ctrl in controls]
|
||||||
|
|
||||||
if args.template.endswith('.cpp.in'):
|
if args.template.endswith('.cpp.in'):
|
||||||
data = generate_cpp(controls)
|
data = generate_cpp(controls)
|
||||||
elif args.template.endswith('.h.in'):
|
elif args.template.endswith('.h.in'):
|
||||||
data = generate_h(controls)
|
data = generate_h(controls, args.mode)
|
||||||
else:
|
else:
|
||||||
raise RuntimeError('Unknown template type')
|
raise RuntimeError('Unknown template type')
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue