diff options
author | Matthias Clasen <mclasen@redhat.com> | 2017-09-17 11:17:13 -0400 |
---|---|---|
committer | Behdad Esfahbod <behdad@behdad.org> | 2017-12-19 15:17:01 -0500 |
commit | a8ae2eafc85fda76fde79defa40fe06000d907db (patch) | |
tree | f05c686541ad60f5b26b5d0218a5af28d5e8bdef /src/cairo-misc.c | |
parent | ac5acc45383f7ada422dec3e7c8a71bdb041fc8a (diff) | |
download | cairo-a8ae2eafc85fda76fde79defa40fe06000d907db.tar.gz |
Use strtod_l when available
Using strtod_l and newlocale is a nicer way to have provide
a C-locale-only strtod. Since these APIs are not available
everywhere, keep the old code as a fallback.
Diffstat (limited to 'src/cairo-misc.c')
-rw-r--r-- | src/cairo-misc.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/cairo-misc.c b/src/cairo-misc.c index 1ecbabf33..cf0d6d160 100644 --- a/src/cairo-misc.c +++ b/src/cairo-misc.c @@ -43,6 +43,10 @@ #include <stdio.h> #include <errno.h> +#include <locale.h> +#ifdef HAVE_XLOCALE_H +#include <xlocale.h> +#endif COMPILE_TIME_ASSERT ((int)CAIRO_STATUS_LAST_STATUS < (int)CAIRO_INT_STATUS_UNSUPPORTED); COMPILE_TIME_ASSERT (CAIRO_INT_STATUS_LAST_STATUS <= 127); @@ -789,6 +793,38 @@ _cairo_get_locale_decimal_point (void) } #endif +#if defined (HAVE_NEWLOCALE) && defined (HAVE_STRTOD_L) + +static locale_t C_locale; + +static locale_t +get_C_locale (void) +{ + locale_t C; + +retry: + C = (locale_t) _cairo_atomic_ptr_get (&C_locale); + + if (unlikely (!C)) { + C = newlocale (LC_ALL_MASK, "C", NULL); + + if (!_cairo_atomic_ptr_cmpxchg (&C_locale, NULL, C)) { + freelocale (C_locale); + goto retry; + } + } + + return C; +} + +double +_cairo_strtod (const char *nptr, char **endptr) +{ + return strtod_l (nptr, endptr, get_C_locale ()); +} + +#else + /* strtod replacement that ignores locale and only accepts decimal points */ double _cairo_strtod (const char *nptr, char **endptr) @@ -844,6 +880,7 @@ _cairo_strtod (const char *nptr, char **endptr) return value; } +#endif /** * _cairo_fopen: |