Message ID | 20240809005914.20662-9-laurent.pinchart@ideasonboard.com |
---|---|
State | Accepted |
Headers | show |
Series |
|
Related | show |
Hi Laurent On 09/08/2024 01:59, 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 > module to PYTHONPATH This doesn't happen in this patch...though given they're in the same directory the import works anyway, so it isn't causing harm. With the commit message corrected: Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com> > , and use it when invoking the gen-controls.py > script. > > Signed-off-by: Laurent Pinchart <laurent.pinchart@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@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):
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? Paul > module to PYTHONPATH, and use it when invoking the gen-controls.py > script. > > Signed-off-by: Laurent Pinchart <laurent.pinchart@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@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 >
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@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@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):
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@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):
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@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