[{"id":13456,"web_url":"https://patchwork.libcamera.org/comment/13456/","msgid":"<20201023220548.GH5979@pendragon.ideasonboard.com>","date":"2020-10-23T22:05:48","subject":"Re: [libcamera-devel] [PATCH v4 05/12] libcamera: controls:\n\tGenerate an array of valid values","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jacopo,\n\nThank you for the patch.\n\nOn Fri, Oct 23, 2020 at 07:11:09PM +0200, Jacopo Mondi wrote:\n> For each Control that support enumerated values generate a vector\n\ns/support/supports/\ns/a vector/an array/\n\n> of ControlValues which contains the full list of values.\n> \n> At the expense of a slight increase in memory occupation this change\n> allows the construction of the ControlInfo associated with a Control\n> from the values list, defaulting the minimum and maximum values\n> reported by the ControlInfo.\n> \n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nIf anyone is looking for a newbies task, converting the controls and\nproperties templates to jinja is a good candidate, I think it will\nsimplify the scripts and make them easier to maintain.\n\n> ---\n>  include/libcamera/control_ids.h.in |  1 +\n>  src/libcamera/control_ids.cpp.in   |  1 +\n>  utils/gen-controls.py              | 30 ++++++++++++++++++++++++++++++\n>  3 files changed, 32 insertions(+)\n> \n> diff --git a/include/libcamera/control_ids.h.in b/include/libcamera/control_ids.h.in\n> index baadca83b103..7edeb6b65e32 100644\n> --- a/include/libcamera/control_ids.h.in\n> +++ b/include/libcamera/control_ids.h.in\n> @@ -10,6 +10,7 @@\n>  #ifndef __LIBCAMERA_CONTROL_IDS_H__\n>  #define __LIBCAMERA_CONTROL_IDS_H__\n>  \n> +#include <array>\n>  #include <stdint.h>\n>  \n>  #include <libcamera/controls.h>\n> diff --git a/src/libcamera/control_ids.cpp.in b/src/libcamera/control_ids.cpp.in\n> index 056645cfbdfb..5fb1c2c30558 100644\n> --- a/src/libcamera/control_ids.cpp.in\n> +++ b/src/libcamera/control_ids.cpp.in\n> @@ -8,6 +8,7 @@\n>   */\n>  \n>  #include <libcamera/control_ids.h>\n> +#include <libcamera/controls.h>\n>  \n>  /**\n>   * \\file control_ids.h\n> diff --git a/utils/gen-controls.py b/utils/gen-controls.py\n> index bf681503f86a..a0bd43fabc31 100755\n> --- a/utils/gen-controls.py\n> +++ b/utils/gen-controls.py\n> @@ -33,6 +33,12 @@ ${description}''')\n>  ${description}\n>   */''')\n>      def_template = string.Template('extern const Control<${type}> ${name}(${id_name}, \"${name}\");')\n> +    enum_values_doc = string.Template('''/**\n> + * \\\\var ${name}Values\n> + * \\\\brief List of all $name supported values\n> + */''')\n> +    enum_values_start = string.Template('''extern const std::array<const ControlValue, ${size}> ${name}Values = {''')\n> +    enum_values_values = string.Template('''\\tstatic_cast<int32_t>(${name}),''')\n>  \n>      ctrls_doc = []\n>      ctrls_def = []\n> @@ -68,6 +74,7 @@ ${description}\n>              enum_doc = []\n>              enum_doc.append(enum_doc_start_template.substitute(info))\n>  \n> +            num_entries = 0;\n>              for entry in enum:\n>                  value_info = {\n>                      'name' : name,\n> @@ -75,11 +82,25 @@ ${description}\n>                      'description': format_description(entry['description']),\n>                  }\n>                  enum_doc.append(enum_doc_value_template.substitute(value_info))\n> +                num_entries += 1\n>  \n>              enum_doc = '\\n *\\n'.join(enum_doc)\n>              enum_doc += '\\n */'\n>              target_doc.append(enum_doc)\n>  \n> +            values_info = {\n> +                'name' : info['name'],\n> +                'size' : num_entries,\n> +            }\n> +            target_doc.append(enum_values_doc.substitute(values_info))\n> +            target_def.append(enum_values_start.substitute(values_info))\n> +            for entry in enum:\n> +                value_info = {\n> +                    'name' : entry['name']\n> +                }\n> +                target_def.append(enum_values_values.substitute(value_info))\n> +            target_def.append(\"};\")\n> +\n>          target_doc.append(doc_template.substitute(info))\n>          target_def.append(def_template.substitute(info))\n>  \n> @@ -100,6 +121,7 @@ ${description}\n>  def generate_h(controls):\n>      enum_template_start = string.Template('''enum ${name}Enum {''')\n>      enum_value_template = string.Template('''\\t${name} = ${value},''')\n> +    enum_values_template = string.Template('''extern const std::array<const ControlValue, ${size}> ${name}Values;''')\n>      template = string.Template('''extern const Control<${type}> ${name};''')\n>  \n>      ctrls = []\n> @@ -132,14 +154,22 @@ def generate_h(controls):\n>          if enum:\n>              target_ctrls.append(enum_template_start.substitute(info))\n>  \n> +            num_entries = 0\n>              for entry in enum:\n>                  value_info = {\n>                      'name': entry['name'],\n>                      'value': entry['value'],\n>                  }\n>                  target_ctrls.append(enum_value_template.substitute(value_info))\n> +                num_entries += 1\n>              target_ctrls.append(\"};\")\n>  \n> +            values_info = {\n> +                'name' : info['name'],\n> +                'size' : num_entries,\n> +            }\n> +            target_ctrls.append(enum_values_template.substitute(values_info))\n> +\n>          target_ctrls.append(template.substitute(info))\n>          id_value += 1\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 9BCF7C3D3C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 23 Oct 2020 22:06:36 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2AC7561C48;\n\tSat, 24 Oct 2020 00:06:36 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 54400619AF\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 24 Oct 2020 00:06:35 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id D1DFE9BF;\n\tSat, 24 Oct 2020 00:06:34 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"Lkj/G13V\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1603490795;\n\tbh=fiaqbsuDNMqxcZzdzig6t4+qB7jlYp8ZvZqdoVRTmBA=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=Lkj/G13V4/UROWf2sXOSIl7lpR+m6A1U/IMq/hKJOxzxqx5gUvZUvJw/4a1EvFU4Q\n\thauot9ccfQ7tDhn8WeuSJOwdV1hBdyLRK/nSAtHSl7ViTG1G3WbhVznEnxIkuFV23a\n\tcxN61rcIm+sMLpShq/k+fNxhDK4wLhH4xZYjEaxw=","Date":"Sat, 24 Oct 2020 01:05:48 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jacopo Mondi <jacopo@jmondi.org>","Message-ID":"<20201023220548.GH5979@pendragon.ideasonboard.com>","References":"<20201023171116.24899-1-jacopo@jmondi.org>\n\t<20201023171116.24899-6-jacopo@jmondi.org>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20201023171116.24899-6-jacopo@jmondi.org>","Subject":"Re: [libcamera-devel] [PATCH v4 05/12] libcamera: controls:\n\tGenerate an array of valid values","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":13474,"web_url":"https://patchwork.libcamera.org/comment/13474/","msgid":"<20201024223914.GH3943@pendragon.ideasonboard.com>","date":"2020-10-24T22:39:14","subject":"Re: [libcamera-devel] [PATCH v4 05/12] libcamera: controls:\n\tGenerate an array of valid values","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jacopo,\n\nOn Sat, Oct 24, 2020 at 01:05:49AM +0300, Laurent Pinchart wrote:\n> On Fri, Oct 23, 2020 at 07:11:09PM +0200, Jacopo Mondi wrote:\n> > For each Control that support enumerated values generate a vector\n> \n> s/support/supports/\n> s/a vector/an array/\n> \n> > of ControlValues which contains the full list of values.\n> > \n> > At the expense of a slight increase in memory occupation this change\n> > allows the construction of the ControlInfo associated with a Control\n> > from the values list, defaulting the minimum and maximum values\n> > reported by the ControlInfo.\n> > \n> > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>\n> \n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nI've just noticed that checkstyle.py reports a few warnings. Could you\naddress them ? \n\n> If anyone is looking for a newbies task, converting the controls and\n> properties templates to jinja is a good candidate, I think it will\n> simplify the scripts and make them easier to maintain.\n> \n> > ---\n> >  include/libcamera/control_ids.h.in |  1 +\n> >  src/libcamera/control_ids.cpp.in   |  1 +\n> >  utils/gen-controls.py              | 30 ++++++++++++++++++++++++++++++\n> >  3 files changed, 32 insertions(+)\n> > \n> > diff --git a/include/libcamera/control_ids.h.in b/include/libcamera/control_ids.h.in\n> > index baadca83b103..7edeb6b65e32 100644\n> > --- a/include/libcamera/control_ids.h.in\n> > +++ b/include/libcamera/control_ids.h.in\n> > @@ -10,6 +10,7 @@\n> >  #ifndef __LIBCAMERA_CONTROL_IDS_H__\n> >  #define __LIBCAMERA_CONTROL_IDS_H__\n> >  \n> > +#include <array>\n> >  #include <stdint.h>\n> >  \n> >  #include <libcamera/controls.h>\n> > diff --git a/src/libcamera/control_ids.cpp.in b/src/libcamera/control_ids.cpp.in\n> > index 056645cfbdfb..5fb1c2c30558 100644\n> > --- a/src/libcamera/control_ids.cpp.in\n> > +++ b/src/libcamera/control_ids.cpp.in\n> > @@ -8,6 +8,7 @@\n> >   */\n> >  \n> >  #include <libcamera/control_ids.h>\n> > +#include <libcamera/controls.h>\n> >  \n> >  /**\n> >   * \\file control_ids.h\n> > diff --git a/utils/gen-controls.py b/utils/gen-controls.py\n> > index bf681503f86a..a0bd43fabc31 100755\n> > --- a/utils/gen-controls.py\n> > +++ b/utils/gen-controls.py\n> > @@ -33,6 +33,12 @@ ${description}''')\n> >  ${description}\n> >   */''')\n> >      def_template = string.Template('extern const Control<${type}> ${name}(${id_name}, \"${name}\");')\n> > +    enum_values_doc = string.Template('''/**\n> > + * \\\\var ${name}Values\n> > + * \\\\brief List of all $name supported values\n> > + */''')\n> > +    enum_values_start = string.Template('''extern const std::array<const ControlValue, ${size}> ${name}Values = {''')\n> > +    enum_values_values = string.Template('''\\tstatic_cast<int32_t>(${name}),''')\n> >  \n> >      ctrls_doc = []\n> >      ctrls_def = []\n> > @@ -68,6 +74,7 @@ ${description}\n> >              enum_doc = []\n> >              enum_doc.append(enum_doc_start_template.substitute(info))\n> >  \n> > +            num_entries = 0;\n> >              for entry in enum:\n> >                  value_info = {\n> >                      'name' : name,\n> > @@ -75,11 +82,25 @@ ${description}\n> >                      'description': format_description(entry['description']),\n> >                  }\n> >                  enum_doc.append(enum_doc_value_template.substitute(value_info))\n> > +                num_entries += 1\n> >  \n> >              enum_doc = '\\n *\\n'.join(enum_doc)\n> >              enum_doc += '\\n */'\n> >              target_doc.append(enum_doc)\n> >  \n> > +            values_info = {\n> > +                'name' : info['name'],\n> > +                'size' : num_entries,\n> > +            }\n> > +            target_doc.append(enum_values_doc.substitute(values_info))\n> > +            target_def.append(enum_values_start.substitute(values_info))\n> > +            for entry in enum:\n> > +                value_info = {\n> > +                    'name' : entry['name']\n> > +                }\n> > +                target_def.append(enum_values_values.substitute(value_info))\n> > +            target_def.append(\"};\")\n> > +\n> >          target_doc.append(doc_template.substitute(info))\n> >          target_def.append(def_template.substitute(info))\n> >  \n> > @@ -100,6 +121,7 @@ ${description}\n> >  def generate_h(controls):\n> >      enum_template_start = string.Template('''enum ${name}Enum {''')\n> >      enum_value_template = string.Template('''\\t${name} = ${value},''')\n> > +    enum_values_template = string.Template('''extern const std::array<const ControlValue, ${size}> ${name}Values;''')\n> >      template = string.Template('''extern const Control<${type}> ${name};''')\n> >  \n> >      ctrls = []\n> > @@ -132,14 +154,22 @@ def generate_h(controls):\n> >          if enum:\n> >              target_ctrls.append(enum_template_start.substitute(info))\n> >  \n> > +            num_entries = 0\n> >              for entry in enum:\n> >                  value_info = {\n> >                      'name': entry['name'],\n> >                      'value': entry['value'],\n> >                  }\n> >                  target_ctrls.append(enum_value_template.substitute(value_info))\n> > +                num_entries += 1\n> >              target_ctrls.append(\"};\")\n> >  \n> > +            values_info = {\n> > +                'name' : info['name'],\n> > +                'size' : num_entries,\n> > +            }\n> > +            target_ctrls.append(enum_values_template.substitute(values_info))\n> > +\n> >          target_ctrls.append(template.substitute(info))\n> >          id_value += 1\n> >","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 6E7DDBDB13\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSat, 24 Oct 2020 22:40:02 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id E852761DD3;\n\tSun, 25 Oct 2020 00:40:01 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id DA9CD61CB4\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 25 Oct 2020 00:40:00 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 47A46A19;\n\tSun, 25 Oct 2020 00:40:00 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"PbBDnBlp\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1603579200;\n\tbh=ZXEUTXHIYN3v7G0z3yRaaY5o1fYcmHm2bZ/n0KEGDEM=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=PbBDnBlpibnXnMiSWTjrTVXQdvhCmIS03HOU3IWgDl7OK93XQyHi5mMRL2aCgjhnk\n\tpoIEjCypVQ3Lh5LrHYRNd/Dh0rHNPqzWuQUcgaGhiGtdfx7M7vlHfGadKFzXLb0D1j\n\tIQ/RL2L2ryhpEuz8q4dyIZGa3YNDGjmh4BZAb9QQ=","Date":"Sun, 25 Oct 2020 01:39:14 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jacopo Mondi <jacopo@jmondi.org>","Message-ID":"<20201024223914.GH3943@pendragon.ideasonboard.com>","References":"<20201023171116.24899-1-jacopo@jmondi.org>\n\t<20201023171116.24899-6-jacopo@jmondi.org>\n\t<20201023220548.GH5979@pendragon.ideasonboard.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20201023220548.GH5979@pendragon.ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v4 05/12] libcamera: controls:\n\tGenerate an array of valid values","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":13476,"web_url":"https://patchwork.libcamera.org/comment/13476/","msgid":"<20201025141649.x6vvswekcrf4bgrk@uno.localdomain>","date":"2020-10-25T14:16:49","subject":"Re: [libcamera-devel] [PATCH v4 05/12] libcamera: controls:\n\tGenerate an array of valid values","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Laurent,\n\nOn Sun, Oct 25, 2020 at 01:39:14AM +0300, Laurent Pinchart wrote:\n> Hi Jacopo,\n>\n> On Sat, Oct 24, 2020 at 01:05:49AM +0300, Laurent Pinchart wrote:\n> > On Fri, Oct 23, 2020 at 07:11:09PM +0200, Jacopo Mondi wrote:\n> > > For each Control that support enumerated values generate a vector\n> >\n> > s/support/supports/\n> > s/a vector/an array/\n> >\n> > > of ControlValues which contains the full list of values.\n> > >\n> > > At the expense of a slight increase in memory occupation this change\n> > > allows the construction of the ControlInfo associated with a Control\n> > > from the values list, defaulting the minimum and maximum values\n> > > reported by the ControlInfo.\n> > >\n> > > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>\n> >\n> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>\n> I've just noticed that checkstyle.py reports a few warnings. Could you\n> address them ?\n>\n\nOh, I thought they all were false positives, but the style used to\ndefine dictionaries in the rest of the codebase actually has not ' '\nbefore ':'.\n\nI'll fix, thanks for reporting it\n\n> > If anyone is looking for a newbies task, converting the controls and\n> > properties templates to jinja is a good candidate, I think it will\n> > simplify the scripts and make them easier to maintain.\n> >\n> > > ---\n> > >  include/libcamera/control_ids.h.in |  1 +\n> > >  src/libcamera/control_ids.cpp.in   |  1 +\n> > >  utils/gen-controls.py              | 30 ++++++++++++++++++++++++++++++\n> > >  3 files changed, 32 insertions(+)\n> > >\n> > > diff --git a/include/libcamera/control_ids.h.in b/include/libcamera/control_ids.h.in\n> > > index baadca83b103..7edeb6b65e32 100644\n> > > --- a/include/libcamera/control_ids.h.in\n> > > +++ b/include/libcamera/control_ids.h.in\n> > > @@ -10,6 +10,7 @@\n> > >  #ifndef __LIBCAMERA_CONTROL_IDS_H__\n> > >  #define __LIBCAMERA_CONTROL_IDS_H__\n> > >\n> > > +#include <array>\n> > >  #include <stdint.h>\n> > >\n> > >  #include <libcamera/controls.h>\n> > > diff --git a/src/libcamera/control_ids.cpp.in b/src/libcamera/control_ids.cpp.in\n> > > index 056645cfbdfb..5fb1c2c30558 100644\n> > > --- a/src/libcamera/control_ids.cpp.in\n> > > +++ b/src/libcamera/control_ids.cpp.in\n> > > @@ -8,6 +8,7 @@\n> > >   */\n> > >\n> > >  #include <libcamera/control_ids.h>\n> > > +#include <libcamera/controls.h>\n> > >\n> > >  /**\n> > >   * \\file control_ids.h\n> > > diff --git a/utils/gen-controls.py b/utils/gen-controls.py\n> > > index bf681503f86a..a0bd43fabc31 100755\n> > > --- a/utils/gen-controls.py\n> > > +++ b/utils/gen-controls.py\n> > > @@ -33,6 +33,12 @@ ${description}''')\n> > >  ${description}\n> > >   */''')\n> > >      def_template = string.Template('extern const Control<${type}> ${name}(${id_name}, \"${name}\");')\n> > > +    enum_values_doc = string.Template('''/**\n> > > + * \\\\var ${name}Values\n> > > + * \\\\brief List of all $name supported values\n> > > + */''')\n> > > +    enum_values_start = string.Template('''extern const std::array<const ControlValue, ${size}> ${name}Values = {''')\n> > > +    enum_values_values = string.Template('''\\tstatic_cast<int32_t>(${name}),''')\n> > >\n> > >      ctrls_doc = []\n> > >      ctrls_def = []\n> > > @@ -68,6 +74,7 @@ ${description}\n> > >              enum_doc = []\n> > >              enum_doc.append(enum_doc_start_template.substitute(info))\n> > >\n> > > +            num_entries = 0;\n> > >              for entry in enum:\n> > >                  value_info = {\n> > >                      'name' : name,\n> > > @@ -75,11 +82,25 @@ ${description}\n> > >                      'description': format_description(entry['description']),\n> > >                  }\n> > >                  enum_doc.append(enum_doc_value_template.substitute(value_info))\n> > > +                num_entries += 1\n> > >\n> > >              enum_doc = '\\n *\\n'.join(enum_doc)\n> > >              enum_doc += '\\n */'\n> > >              target_doc.append(enum_doc)\n> > >\n> > > +            values_info = {\n> > > +                'name' : info['name'],\n> > > +                'size' : num_entries,\n> > > +            }\n> > > +            target_doc.append(enum_values_doc.substitute(values_info))\n> > > +            target_def.append(enum_values_start.substitute(values_info))\n> > > +            for entry in enum:\n> > > +                value_info = {\n> > > +                    'name' : entry['name']\n> > > +                }\n> > > +                target_def.append(enum_values_values.substitute(value_info))\n> > > +            target_def.append(\"};\")\n> > > +\n> > >          target_doc.append(doc_template.substitute(info))\n> > >          target_def.append(def_template.substitute(info))\n> > >\n> > > @@ -100,6 +121,7 @@ ${description}\n> > >  def generate_h(controls):\n> > >      enum_template_start = string.Template('''enum ${name}Enum {''')\n> > >      enum_value_template = string.Template('''\\t${name} = ${value},''')\n> > > +    enum_values_template = string.Template('''extern const std::array<const ControlValue, ${size}> ${name}Values;''')\n> > >      template = string.Template('''extern const Control<${type}> ${name};''')\n> > >\n> > >      ctrls = []\n> > > @@ -132,14 +154,22 @@ def generate_h(controls):\n> > >          if enum:\n> > >              target_ctrls.append(enum_template_start.substitute(info))\n> > >\n> > > +            num_entries = 0\n> > >              for entry in enum:\n> > >                  value_info = {\n> > >                      'name': entry['name'],\n> > >                      'value': entry['value'],\n> > >                  }\n> > >                  target_ctrls.append(enum_value_template.substitute(value_info))\n> > > +                num_entries += 1\n> > >              target_ctrls.append(\"};\")\n> > >\n> > > +            values_info = {\n> > > +                'name' : info['name'],\n> > > +                'size' : num_entries,\n> > > +            }\n> > > +            target_ctrls.append(enum_values_template.substitute(values_info))\n> > > +\n> > >          target_ctrls.append(template.substitute(info))\n> > >          id_value += 1\n> > >\n>\n> --\n> Regards,\n>\n> Laurent Pinchart","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id AC403C3B5C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSun, 25 Oct 2020 14:16:53 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1F72761DD3;\n\tSun, 25 Oct 2020 15:16:53 +0100 (CET)","from relay10.mail.gandi.net (relay10.mail.gandi.net\n\t[217.70.178.230])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id E50F661D25\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 25 Oct 2020 15:16:51 +0100 (CET)","from uno.localdomain (2-224-242-101.ip172.fastwebnet.it\n\t[2.224.242.101]) (Authenticated sender: jacopo@jmondi.org)\n\tby relay10.mail.gandi.net (Postfix) with ESMTPSA id 434D1240007;\n\tSun, 25 Oct 2020 14:16:50 +0000 (UTC)"],"Date":"Sun, 25 Oct 2020 15:16:49 +0100","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<20201025141649.x6vvswekcrf4bgrk@uno.localdomain>","References":"<20201023171116.24899-1-jacopo@jmondi.org>\n\t<20201023171116.24899-6-jacopo@jmondi.org>\n\t<20201023220548.GH5979@pendragon.ideasonboard.com>\n\t<20201024223914.GH3943@pendragon.ideasonboard.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20201024223914.GH3943@pendragon.ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v4 05/12] libcamera: controls:\n\tGenerate an array of valid values","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]