[libcamera-devel] [PATCH] libcamera: yaml_parser: Use C locale

Kieran Bingham kieran.bingham at ideasonboard.com
Wed Dec 21 18:44:28 CET 2022


Quoting Kieran Bingham (2022-12-21 17:38:47)
> When parsing configuration files on systems with differing locales, the
> use of strtod can produce different results, or in the worst case - fail
> to parse expected values.
> 
> Provide an RAII implementation to construct a locale specific to the
> expected mappings for configuration files provided by libcamera.

We might want to document somewhere that this implies/requires all
configuration files to be written with the 'C' locale ... But I have no
idea where we would document that currently.

--
Kieran


> 
> Bug: https://bugs.libcamera.org/show_bug.cgi?id=174
> Bug: https://github.com/raspberrypi/libcamera/issues/29
> Reported-by: https://github.com/kralo
> Reported-by: Hannes Winkler <hanneswinkler2000 at web.de>
> Signed-off-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
> ---
>  src/libcamera/yaml_parser.cpp | 32 +++++++++++++++++++++++++++++++-
>  1 file changed, 31 insertions(+), 1 deletion(-)
> 
> diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp
> index d8a7c2f9250f..8ddc6d6b5fd5 100644
> --- a/src/libcamera/yaml_parser.cpp
> +++ b/src/libcamera/yaml_parser.cpp
> @@ -31,6 +31,36 @@ namespace {
>  /* Empty static YamlObject as a safe result for invalid operations */
>  static const YamlObject empty;
>  
> +/*
> + * Construct a global RAII locale for use by all YAML parser instances to
> + * ensure consistency when parsing configuration files and types regardless of
> + * the host Locale configuration.
> + *
> + * For more information see:
> + * - https://bugs.libcamera.org/show_bug.cgi?id=174
> + */
> +class Locale
> +{
> +public:
> +       Locale(std::string locale)
> +       {
> +               locale_ = newlocale(LC_ALL_MASK, locale.c_str(), (locale_t)0);
> +               if (locale_ == (locale_t)0)
> +                       LOG(YamlParser, Fatal)
> +                               << "Failed to construct a locale";
> +       }
> +       ~Locale()
> +       {
> +               freelocale(locale_);
> +       }
> +       locale_t locale() { return locale_; }
> +
> +private:
> +       locale_t locale_;
> +};
> +
> +static Locale yamlLocale("C");
> +
>  } /* namespace */
>  
>  /**
> @@ -283,7 +313,7 @@ std::optional<double> YamlObject::get() const
>         char *end;
>  
>         errno = 0;
> -       double value = std::strtod(value_.c_str(), &end);
> +       double value = strtod_l(value_.c_str(), &end, yamlLocale.locale());
>  
>         if ('\0' != *end || errno == ERANGE)
>                 return std::nullopt;
> -- 
> 2.34.1
>


More information about the libcamera-devel mailing list