[PATCH 08/10] utils: codegen: gen-controls.py: Move helper classes to separate file

Laurent Pinchart laurent.pinchart at ideasonboard.com
Fri Aug 9 02:59:12 CEST 2024


The ControlEnum and Control helper classes defined in gen-controls.py
are useful for other generator scripts. Move them to a separate file to
make it possible to share them.

Extend the Python build environment to add the path to the new Python
module to PYTHONPATH, and use it when invoking the gen-controls.py
script.

Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 include/libcamera/meson.build |   1 +
 src/libcamera/meson.build     |   3 +-
 utils/codegen/controls.py     | 112 ++++++++++++++++++++++++++++++++++
 utils/codegen/gen-controls.py | 105 +------------------------------
 4 files changed, 116 insertions(+), 105 deletions(-)
 create mode 100644 utils/codegen/controls.py

diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build
index d90a8615e52d..a969a95dbf7a 100644
--- a/include/libcamera/meson.build
+++ b/include/libcamera/meson.build
@@ -88,6 +88,7 @@ foreach mode, entry : controls_map
                                      command : [gen_controls, '-o', '@OUTPUT@',
                                                 '--mode', mode, '-t', template_file,
                                                 '-r', ranges_file, '@INPUT@'],
+                                     env : py_build_env,
                                      install : true,
                                      install_dir : libcamera_headers_install_dir)
 endforeach
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index 3fd3a87e9f95..aa9ab0291854 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -151,7 +151,8 @@ foreach mode, inout_files : controls_mode_files
                                      output : output_file,
                                      command : [gen_controls, '-o', '@OUTPUT@',
                                                 '--mode', mode, '-t', template_file,
-                                                '-r', ranges_file, '@INPUT@'])
+                                                '-r', ranges_file, '@INPUT@'],
+                                     env : py_build_env)
 endforeach
 
 libcamera_public_sources += control_sources
diff --git a/utils/codegen/controls.py b/utils/codegen/controls.py
new file mode 100644
index 000000000000..7bafee599c80
--- /dev/null
+++ b/utils/codegen/controls.py
@@ -0,0 +1,112 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (C) 2019, Google Inc.
+#
+# Author: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
+#
+# Helper classes to handle source code generation for libcamera controls
+
+
+class ControlEnum(object):
+    def __init__(self, data):
+        self.__data = data
+
+    @property
+    def description(self):
+        """The enum description"""
+        return self.__data.get('description')
+
+    @property
+    def name(self):
+        """The enum name"""
+        return self.__data.get('name')
+
+    @property
+    def value(self):
+        """The enum value"""
+        return self.__data.get('value')
+
+
+class Control(object):
+    def __init__(self, name, data, vendor):
+        self.__name = name
+        self.__data = data
+        self.__enum_values = None
+        self.__size = None
+        self.__vendor = vendor
+
+        enum_values = data.get('enum')
+        if enum_values is not None:
+            self.__enum_values = [ControlEnum(enum) for enum in enum_values]
+
+        size = self.__data.get('size')
+        if size is not None:
+            if len(size) == 0:
+                raise RuntimeError(f'Control `{self.__name}` size must have at least one dimension')
+
+            # Compute the total number of elements in the array. If any of the
+            # array dimension is a string, the array is variable-sized.
+            num_elems = 1
+            for dim in size:
+                if type(dim) is str:
+                    num_elems = 0
+                    break
+
+                dim = int(dim)
+                if dim <= 0:
+                    raise RuntimeError(f'Control `{self.__name}` size must have positive values only')
+
+                num_elems *= dim
+
+            self.__size = num_elems
+
+    @property
+    def description(self):
+        """The control description"""
+        return self.__data.get('description')
+
+    @property
+    def enum_values(self):
+        """The enum values, if the control is an enumeration"""
+        if self.__enum_values is None:
+            return
+        for enum in self.__enum_values:
+            yield enum
+
+    @property
+    def enum_values_count(self):
+        """The number of enum values, if the control is an enumeration"""
+        if self.__enum_values is None:
+            return 0
+        return len(self.__enum_values)
+
+    @property
+    def is_enum(self):
+        """Is the control an enumeration"""
+        return self.__enum_values is not None
+
+    @property
+    def vendor(self):
+        """The vendor string, or None"""
+        return self.__vendor
+
+    @property
+    def name(self):
+        """The control name (CamelCase)"""
+        return self.__name
+
+    @property
+    def type(self):
+        typ = self.__data.get('type')
+        size = self.__data.get('size')
+
+        if typ == 'string':
+            return 'std::string'
+
+        if self.__size is None:
+            return typ
+
+        if self.__size:
+            return f"Span<const {typ}, {self.__size}>"
+        else:
+            return f"Span<const {typ}>"
diff --git a/utils/codegen/gen-controls.py b/utils/codegen/gen-controls.py
index 685ef7a00d5f..2968eb9a5d4e 100755
--- a/utils/codegen/gen-controls.py
+++ b/utils/codegen/gen-controls.py
@@ -12,110 +12,7 @@ import os
 import sys
 import yaml
 
-
-class ControlEnum(object):
-    def __init__(self, data):
-        self.__data = data
-
-    @property
-    def description(self):
-        """The enum description"""
-        return self.__data.get('description')
-
-    @property
-    def name(self):
-        """The enum name"""
-        return self.__data.get('name')
-
-    @property
-    def value(self):
-        """The enum value"""
-        return self.__data.get('value')
-
-
-class Control(object):
-    def __init__(self, name, data, vendor):
-        self.__name = name
-        self.__data = data
-        self.__enum_values = None
-        self.__size = None
-        self.__vendor = vendor
-
-        enum_values = data.get('enum')
-        if enum_values is not None:
-            self.__enum_values = [ControlEnum(enum) for enum in enum_values]
-
-        size = self.__data.get('size')
-        if size is not None:
-            if len(size) == 0:
-                raise RuntimeError(f'Control `{self.__name}` size must have at least one dimension')
-
-            # Compute the total number of elements in the array. If any of the
-            # array dimension is a string, the array is variable-sized.
-            num_elems = 1
-            for dim in size:
-                if type(dim) is str:
-                    num_elems = 0
-                    break
-
-                dim = int(dim)
-                if dim <= 0:
-                    raise RuntimeError(f'Control `{self.__name}` size must have positive values only')
-
-                num_elems *= dim
-
-            self.__size = num_elems
-
-    @property
-    def description(self):
-        """The control description"""
-        return self.__data.get('description')
-
-    @property
-    def enum_values(self):
-        """The enum values, if the control is an enumeration"""
-        if self.__enum_values is None:
-            return
-        for enum in self.__enum_values:
-            yield enum
-
-    @property
-    def enum_values_count(self):
-        """The number of enum values, if the control is an enumeration"""
-        if self.__enum_values is None:
-            return 0
-        return len(self.__enum_values)
-
-    @property
-    def is_enum(self):
-        """Is the control an enumeration"""
-        return self.__enum_values is not None
-
-    @property
-    def vendor(self):
-        """The vendor string, or None"""
-        return self.__vendor
-
-    @property
-    def name(self):
-        """The control name (CamelCase)"""
-        return self.__name
-
-    @property
-    def type(self):
-        typ = self.__data.get('type')
-        size = self.__data.get('size')
-
-        if typ == 'string':
-            return 'std::string'
-
-        if self.__size is None:
-            return typ
-
-        if self.__size:
-            return f"Span<const {typ}, {self.__size}>"
-        else:
-            return f"Span<const {typ}>"
+from controls import Control
 
 
 def snake_case(s):
-- 
Regards,

Laurent Pinchart



More information about the libcamera-devel mailing list