From patchwork Mon May 9 10:10:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 15834 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 4AE3EC326D for ; Mon, 9 May 2022 10:10:56 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D254D65656; Mon, 9 May 2022 12:10:55 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1652091055; bh=URTxjejuCgweTyaKW5/Dg30Xf5WDVGdIYESgALOQwFg=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=OwFhUmHhfEBqR4einzVDLc+aOA8D2SY9tUcChiseBZQsD5UAwIB9WnOdYgRsjelFH xPdPt2JXMRNWGywBKMl9YJKwA3aYKOCa6tV7Z94s95v1+hwY/QkcxmZved85VSZIwF JiAbjbducyfrPNLps2oVDVAGLSAMh7/SsZ/LBYyCLnKsVNk1s11ds4nC1nYMPoXBwe OM+j14dGPvZMjSrZqeGcYM3vyNa4gMk89ftd00UBvYZkNGtGPa+3IJc8j929N6bTOr AW5Gh1iOJzrTZCVEt6Fsfl9S7GGQhOwmUuVgbcvRqDfsAFIygkxTqVjisVk8B5yz4n wmu6IsMkj0izw== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E3F3C6564D for ; Mon, 9 May 2022 12:10:50 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="HTZIV+bp"; dkim-atps=neutral Received: from deskari.lan (91-156-85-209.elisa-laajakaista.fi [91.156.85.209]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 51D5D3E4; Mon, 9 May 2022 12:10:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1652091050; bh=URTxjejuCgweTyaKW5/Dg30Xf5WDVGdIYESgALOQwFg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HTZIV+bpMHdN7dE2ox7YqeT39jhv5Bv0doi1lOoEtWU0Gz81ZAycswEZKmw4PuPyO HWSD0ryxuY8cUDUTVCx+6yhO5GqY0kArHPWBmA1v/kbdbLHXFyak9OkdUfhwyNOdfm 58UO1NzB9Ke6VshrFj85NvZOEfS6P+7Uft9UZhcI= To: libcamera-devel@lists.libcamera.org, David Plowman , Kieran Bingham , Laurent Pinchart , Jacopo Mondi Date: Mon, 9 May 2022 13:10:21 +0300 Message-Id: <20220509101023.35569-6-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220509101023.35569-1-tomi.valkeinen@ideasonboard.com> References: <20220509101023.35569-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v10 5/7] py: generate control enums from yaml X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tomi Valkeinen via libcamera-devel From: Tomi Valkeinen Reply-To: Tomi Valkeinen Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" 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 Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/py/libcamera/gen-py-control-enums.py | 95 +++++++++++++++++++++++ src/py/libcamera/meson.build | 12 +++ src/py/libcamera/pyenums_generated.cpp.in | 21 +++++ src/py/libcamera/pymain.cpp | 2 + 4 files changed, 130 insertions(+) create mode 100755 src/py/libcamera/gen-py-control-enums.py create mode 100644 src/py/libcamera/pyenums_generated.cpp.in 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 + * + * Python bindings - Auto-generated enums + * + * This file is auto-generated. Do not edit. + */ + +#include + +#include + +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 a4087541..c983da3a 100644 --- a/src/py/libcamera/pymain.cpp +++ b/src/py/libcamera/pymain.cpp @@ -136,10 +136,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 */