libcamera: base: utils: Support C libraries lacking locale support

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 the
locale_t type, and fall back to strtod() when the type 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: e8ae254970 ("libcamera: yaml_parser: Use C locale")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
This commit is contained in:
Laurent Pinchart 2023-01-06 00:47:31 +02:00
parent 0e3b8d71f5
commit aed615e173
2 changed files with 16 additions and 0 deletions

View file

@ -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', 'locale_t', prefix : '#define _GNU_SOURCE')
config_h.set('HAVE_LOCALE_T', 1)
endif
if cc.has_header_symbol('stdlib.h', 'secure_getenv', prefix : '#define _GNU_SOURCE')
config_h.set('HAVE_SECURE_GETENV', 1)
endif

View file

@ -464,6 +464,8 @@ std::string toAscii(const std::string &str)
* \a b
*/
#if HAVE_LOCALE_T
namespace {
/*
@ -493,6 +495,8 @@ Locale cLocale("C");
} /* namespace */
#endif /* HAVE_LOCALE_T */
/**
* \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_LOCALE_T
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 */