summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ideasonboard.com>2022-05-09 13:10:21 +0300
committerKieran Bingham <kieran.bingham@ideasonboard.com>2022-05-10 13:53:43 +0200
commit6e92cb9dc49e0bdd7b909f3da72c6032bcaa2c42 (patch)
tree99173565dd5e4bcdef7f1a6d7182671b96a2ce15
parent8aa02271fd716ed046970a0b1f89176963303f50 (diff)
py: Generate control enums from yaml
Generate enums for controls from control_ids.yaml. The generator script has some heuristics to generate nicer enum names. E.g. instead of having "LensShadingMapMode.LensShadingMapModeOff" we get "LensShadingMapMode.Off". This heuristics may need to be updated when the yaml file is changed or new controls are added. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
-rwxr-xr-xsrc/py/libcamera/gen-py-control-enums.py95
-rw-r--r--src/py/libcamera/meson.build12
-rw-r--r--src/py/libcamera/pyenums_generated.cpp.in21
-rw-r--r--src/py/libcamera/pymain.cpp2
4 files changed, 130 insertions, 0 deletions
diff --git a/src/py/libcamera/gen-py-control-enums.py b/src/py/libcamera/gen-py-control-enums.py
new file mode 100755
index 00000000..dcc28b1a
--- /dev/null
+++ b/src/py/libcamera/gen-py-control-enums.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Generate Python bindings enums for controls from YAML
+
+import argparse
+import string
+import sys
+import yaml
+
+
+def find_common_prefix(strings):
+ prefix = strings[0]
+
+ for string in strings[1:]:
+ while string[:len(prefix)] != prefix and prefix:
+ prefix = prefix[:len(prefix) - 1]
+ if not prefix:
+ break
+
+ return prefix
+
+
+def generate_py(controls):
+ out = ''
+
+ for ctrl in controls:
+ name, ctrl = ctrl.popitem()
+
+ enum = ctrl.get('enum')
+ if not enum:
+ continue
+
+ if ctrl.get('draft'):
+ ns = 'libcamera::controls::draft::'
+ else:
+ ns = 'libcamera::controls::'
+
+ cpp_enum = name + 'Enum'
+
+ out += '\tpy::enum_<{}{}>(m, \"{}\")\n'.format(ns, cpp_enum, name)
+
+ if name == 'LensShadingMapMode':
+ prefix = 'LensShadingMapMode'
+ else:
+ prefix = find_common_prefix([e['name'] for e in enum])
+
+ for entry in enum:
+ cpp_enum = entry['name']
+ py_enum = entry['name'][len(prefix):]
+
+ out += '\t\t.value(\"{}\", {}{})\n'.format(py_enum, ns, cpp_enum)
+
+ out += '\t;\n'
+
+ return {'enums': out}
+
+
+def fill_template(template, data):
+ template = open(template, 'rb').read()
+ template = template.decode('utf-8')
+ template = string.Template(template)
+ return template.substitute(data)
+
+
+def main(argv):
+ # Parse command line arguments
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-o', dest='output', metavar='file', type=str,
+ help='Output file name. Defaults to standard output if not specified.')
+ parser.add_argument('input', type=str,
+ help='Input file name.')
+ parser.add_argument('template', type=str,
+ help='Template file name.')
+ args = parser.parse_args(argv[1:])
+
+ data = open(args.input, 'rb').read()
+ controls = yaml.safe_load(data)['controls']
+
+ data = generate_py(controls)
+
+ data = fill_template(args.template, data)
+
+ if args.output:
+ output = open(args.output, 'wb')
+ output.write(data.encode('utf-8'))
+ output.close()
+ else:
+ sys.stdout.write(data)
+
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
diff --git a/src/py/libcamera/meson.build b/src/py/libcamera/meson.build
index edf4a629..842db1ed 100644
--- a/src/py/libcamera/meson.build
+++ b/src/py/libcamera/meson.build
@@ -17,6 +17,18 @@ pycamera_sources = files([
'pymain.cpp',
])
+gen_input_files = [
+ meson.project_source_root() / 'src' / 'libcamera' / 'control_ids.yaml',
+ 'pyenums_generated.cpp.in',
+]
+
+generated_sources = custom_target('py_gen_controls',
+ input : gen_input_files,
+ output : ['pyenums_generated.cpp'],
+ command : ['gen-py-control-enums.py', '-o', '@OUTPUT@', '@INPUT@'])
+
+pycamera_sources += generated_sources
+
pycamera_deps = [
libcamera_public,
py3_dep,
diff --git a/src/py/libcamera/pyenums_generated.cpp.in b/src/py/libcamera/pyenums_generated.cpp.in
new file mode 100644
index 00000000..6aaf4795
--- /dev/null
+++ b/src/py/libcamera/pyenums_generated.cpp.in
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2022, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+ *
+ * Python bindings - Auto-generated enums
+ *
+ * This file is auto-generated. Do not edit.
+ */
+
+#include <libcamera/libcamera.h>
+
+#include <pybind11/smart_holder.h>
+
+namespace py = pybind11;
+
+using namespace libcamera;
+
+void init_pyenums_generated(py::module& m)
+{
+${enums}
+}
diff --git a/src/py/libcamera/pymain.cpp b/src/py/libcamera/pymain.cpp
index 84829e63..fb89975c 100644
--- a/src/py/libcamera/pymain.cpp
+++ b/src/py/libcamera/pymain.cpp
@@ -137,10 +137,12 @@ static void handleRequestCompleted(Request *req)
}
void init_pyenums(py::module &m);
+void init_pyenums_generated(py::module &m);
PYBIND11_MODULE(_libcamera, m)
{
init_pyenums(m);
+ init_pyenums_generated(m);
/* Forward declarations */