From patchwork Sun Jan 8 21:43:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 18098 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 1DECEC322E for ; Sun, 8 Jan 2023 21:44:05 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CAD3F625E2; Sun, 8 Jan 2023 22:44:04 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1673214244; bh=KNj4VmbsOtr15SGL6TtOBEOGJUOlMlXXBv6eM1MclHU=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=BbHjpRbBq0DGmlC6WaywU1SpB8383Rej7Y3t1Q190gKnjHMfMhhzvJU/gP1cGEndb nVMv215yveE85IpwbbszLXNCkxZOdNsC06all7nxh2Vfku9N3J1K8y5SnRfh0WrosD onaopjrCvCyMrIAOh3leHTS7TZrVGEc92Uq+dalS1cQmsywI/hx5MqZLL5ng6FENjS n2NztIrkJe4QFBpD0IUhaq7BuebQuqQizXz/B4BXy7/eqfvJE82uQNOM8J2GeLAkVA mgNFekoToFW1gyN1g4+e2e02lIFq9CgcDzlJGFQvzB8gXA4snmSnNRIuLVVUkYn9nO 0Y95rILzoSrig== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C3191625D8 for ; Sun, 8 Jan 2023 22:44:02 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="K326f5h8"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (213-243-189-158.bb.dnainternet.fi [213.243.189.158]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 3BD106CF for ; Sun, 8 Jan 2023 22:44:02 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1673214242; bh=KNj4VmbsOtr15SGL6TtOBEOGJUOlMlXXBv6eM1MclHU=; h=From:To:Subject:Date:In-Reply-To:References:From; b=K326f5h8CJ5RqechnGOZmUX33WVv858A4xIK6mU3Oz7mvO3PVvtBO297w7K3cLlxi 8c5c7j5+YjBBnnjCfbLwGEg4xtAt2KP2THNtBS0fdo5L+DY3Y1uAy09qTlpAbwN4+P g+gg8MNC/hKv4PBbwoKEo7HLdRfyQObfv1R7hyEg= To: libcamera-devel@lists.libcamera.org Date: Sun, 8 Jan 2023 23:43:56 +0200 Message-Id: <20230108214357.12641-2-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.38.2 In-Reply-To: <20230108214357.12641-1-laurent.pinchart@ideasonboard.com> References: <20230108214357.12641-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 1/2] base: utils: Add and use strtod() helper X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" 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 --- include/libcamera/base/utils.h | 2 ++ src/libcamera/base/utils.cpp | 46 ++++++++++++++++++++++++++++++++++ src/libcamera/yaml_parser.cpp | 34 +------------------------ 3 files changed, 49 insertions(+), 33 deletions(-) diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h index eb7bcdf4c173..37d9af609ec7 100644 --- a/include/libcamera/base/utils.h +++ b/include/libcamera/base/utils.h @@ -367,6 +367,8 @@ decltype(auto) abs_diff(const T &a, const T &b) return a - b; } +double strtod(const char *__restrict nptr, char **__restrict endptr); + } /* namespace utils */ #ifndef __DOXYGEN__ diff --git a/src/libcamera/base/utils.cpp b/src/libcamera/base/utils.cpp index 6a307940448e..4a239427a4d9 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__ diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp index 2806c591f75d..153a6d53c3f9 100644 --- a/src/libcamera/yaml_parser.cpp +++ b/src/libcamera/yaml_parser.cpp @@ -31,38 +31,6 @@ 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 system locale configuration. - * - * For more information see: - * - https://bugs.libcamera.org/show_bug.cgi?id=174 - */ -class Locale -{ -public: - Locale(const char *locale) - { - locale_ = newlocale(LC_ALL_MASK, locale, static_cast(0)); - if (locale_ == static_cast(0)) - LOG(YamlParser, Fatal) - << "Failed to construct a locale"; - } - - ~Locale() - { - freelocale(locale_); - } - - locale_t locale() { return locale_; } - -private: - locale_t locale_; -}; - -Locale yamlLocale("C"); - } /* namespace */ /** @@ -315,7 +283,7 @@ std::optional YamlObject::get() const char *end; errno = 0; - double value = strtod_l(value_.c_str(), &end, yamlLocale.locale()); + double value = utils::strtod(value_.c_str(), &end); if ('\0' != *end || errno == ERANGE) return std::nullopt; From patchwork Sun Jan 8 21:43:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 18099 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id D1718C3292 for ; Sun, 8 Jan 2023 21:44:05 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 41234625CF; Sun, 8 Jan 2023 22:44:05 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1673214245; bh=ma5lAArjP3pxlwDCj4C5a6tW6F1ZaaPcb5DIgycmRMc=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=V2HNjZ0ZdJJyj7Xi2N0JUI1G0NFmh/XSNmZM6E5ASsvzkRJmz63w2nDetgQMBHDXw sFk5AS7llvzgO4lfRy98fRJBSJ8EDEZV801/Y6dxeTA3iSNK1DFunh455Wi1la0VCx eybeSPB3+2eIkTZ/r0+EH89kNgXS8EXQd44gxS0ZzFb9XRJPRRM64xS9ztpcVenHl1 TkaTl62cSl5Zz/4kOQqoqUXZtKsuIm03REHvJhIuKzqdLUN/r1uywuyqupFwgqh9Oy pG5B3df1uHYfoccrwxPs7LkTTwM8whV5GRqLjqx0IjW8p/wlpOrlIaQV1djy2MhciZ YCSgf6H9SGySQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 60DDF625CF for ; Sun, 8 Jan 2023 22:44:04 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Y0N6alnc"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (213-243-189-158.bb.dnainternet.fi [213.243.189.158]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DAECC6DB for ; Sun, 8 Jan 2023 22:44:03 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1673214244; bh=ma5lAArjP3pxlwDCj4C5a6tW6F1ZaaPcb5DIgycmRMc=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Y0N6alncshtHXtb7qyjBf06Kom2LI9aZOxfaI6r9wo2msHhl32LYjKq1iBdTCyzsx fsxfFt9G7LweULJPgWGwkP/uG9xPP2+TsXSkToiZTiUPi5FwQ6vNbsE/eY4RxyWqsW 8gjg8STqeKxRKzAEKzqNkZNoc52P7nmV41P5Y6fU= To: libcamera-devel@lists.libcamera.org Date: Sun, 8 Jan 2023 23:43:57 +0200 Message-Id: <20230108214357.12641-3-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.38.2 In-Reply-To: <20230108214357.12641-1-laurent.pinchart@ideasonboard.com> References: <20230108214357.12641-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 2/2] libcamera: base: utils: Support C libraries lacking locale support X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Not all C libraries include support for locale objects (locale_t) and the strto*_l() family of functions. A notable example is uClibc that can be compiled with a hardcoded "C" locale. Compilation then fails as the newlocale(), freelocale() and strtod_l() functions are not defined. Fix the compilation breakage by checking for the availability of newlocale(), and fall back to strtod() when the function isn't available. This may not lead to the correct result if support for locale objects isn't available and the locale isn't hardcoded to "C", but that is such a corner case that we will likely never encounter it. Fixes: e8ae254970cf ("libcamera: yaml_parser: Use C locale") Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham Reviewed-by: Jacopo Mondi --- meson.build | 4 ++++ src/libcamera/base/utils.cpp | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/meson.build b/meson.build index e86673dd5c0c..7dcd34d3e6b3 100644 --- a/meson.build +++ b/meson.build @@ -72,6 +72,10 @@ if cc.has_header_symbol('unistd.h', 'issetugid') config_h.set('HAVE_ISSETUGID', 1) endif +if cc.has_header_symbol('locale.h', 'newlocale', prefix : '#define _GNU_SOURCE') + config_h.set('HAVE_NEWLOCALE', 1) +endif + if cc.has_header_symbol('stdlib.h', 'secure_getenv', prefix : '#define _GNU_SOURCE') config_h.set('HAVE_SECURE_GETENV', 1) endif diff --git a/src/libcamera/base/utils.cpp b/src/libcamera/base/utils.cpp index 4a239427a4d9..ac3e1311995e 100644 --- a/src/libcamera/base/utils.cpp +++ b/src/libcamera/base/utils.cpp @@ -464,6 +464,8 @@ std::string toAscii(const std::string &str) * \a b */ +#if HAVE_NEWLOCALE + namespace { /* @@ -493,6 +495,8 @@ Locale cLocale("C"); } /* namespace */ +#endif /* HAVE_NEWLOCALE */ + /** * \brief Convert a string to a double independently of the current locale * \param[in] nptr The string to convert @@ -506,7 +510,15 @@ Locale cLocale("C"); */ double strtod(const char *__restrict nptr, char **__restrict endptr) { +#if HAVE_NEWLOCALE return strtod_l(nptr, endptr, cLocale.locale()); +#else + /* + * If the libc implementation doesn't provide locale object support, + * assume that strtod() is locale-independent. + */ + return strtod(nptr, endptr); +#endif } } /* namespace utils */