From 0e3b8d71f590d93540b2e6a6500cc7739f7199e9 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 5 Jan 2023 14:07:54 +0200 Subject: base: utils: Add and use strtod() helper The strtod() function is locale-dependent, and thus ill-suited to parse numbers coming from, for instance, YAML files. The YamlObject class uses strtod_l() to fix that issue, but that function is not available with all libc implementations. Correctly handling this problem is becoming out of scope for the YamlObject class. As a first step, add a strtod() helper function in the utils namespace that copies the implementation from YamlObject, and use it in YamlObject. The core issue will then be fixed in utils::strtod(). Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- src/libcamera/base/utils.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'src/libcamera/base/utils.cpp') diff --git a/src/libcamera/base/utils.cpp b/src/libcamera/base/utils.cpp index 6a307940..4a239427 100644 --- a/src/libcamera/base/utils.cpp +++ b/src/libcamera/base/utils.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -463,6 +464,51 @@ std::string toAscii(const std::string &str) * \a b */ +namespace { + +/* + * RAII wrapper around locale_t instances, to support global locale instances + * without leaking memory. + */ +class Locale +{ +public: + Locale(const char *locale) + { + locale_ = newlocale(LC_ALL_MASK, locale, static_cast(0)); + } + + ~Locale() + { + freelocale(locale_); + } + + locale_t locale() { return locale_; } + +private: + locale_t locale_; +}; + +Locale cLocale("C"); + +} /* namespace */ + +/** + * \brief Convert a string to a double independently of the current locale + * \param[in] nptr The string to convert + * \param[out] endptr Pointer to trailing portion of the string after conversion + * + * This function is a locale-independent version of the std::strtod() function. + * It behaves as the standard function, but uses the "C" locale instead of the + * current locale. + * + * \return The converted value, if any, or 0.0 if the conversion failed. + */ +double strtod(const char *__restrict nptr, char **__restrict endptr) +{ + return strtod_l(nptr, endptr, cLocale.locale()); +} + } /* namespace utils */ #ifndef __DOXYGEN__ -- cgit v1.2.1