[PATCH 08/10] utils: codegen: gen-controls.py: Move helper classes to separate file
Paul Elder
paul.elder at ideasonboard.com
Thu Aug 15 06:34:04 CEST 2024
On Thu, Aug 15, 2024 at 01:21:02PM +0900, Paul Elder wrote:
> On Fri, Aug 09, 2024 at 03:59:12AM +0300, Laurent Pinchart wrote:
> > 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
>
> Where is the python build environment being extended?
Oh I see it's in the next patch.
Paul
>
> > 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):
More information about the libcamera-devel
mailing list