diff --git a/configure.ac b/configure.ac index d82db4578..6b4ffa22d 100644 --- a/configure.ac +++ b/configure.ac @@ -76,6 +76,9 @@ if test "x$have_dlsym" = "xyes"; then fi AM_CONDITIONAL(CAIRO_HAS_DLSYM, test "x$have_dlsym" = "xyes") +AC_CHECK_HEADERS(xlocale.h) +AC_CHECK_FUNCS(newlocale strtod_l) + dnl =========================================================================== CAIRO_ENABLE_SURFACE_BACKEND(xlib, Xlib, auto, [ 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 #include +#include +#ifdef HAVE_XLOCALE_H +#include +#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: