From: Bruno Haible Date: Tue, 27 Mar 2007 20:11:59 +0000 (+0000) Subject: Use multithread-safe primitives for determining the decimal point character. X-Git-Tag: cvs-readonly~649 X-Git-Url: http://erislabs.org.uk/gitweb/?a=commitdiff_plain;h=968e64725705da1084e3122127debacfc96e1fe9;p=gnulib.git Use multithread-safe primitives for determining the decimal point character. --- diff --git a/ChangeLog b/ChangeLog index b159f5682..79fc2df32 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2007-03-27 Bruno Haible + + Make vasnprintf multithread-safe. + * lib/vasnprintf.c (decimal_point_char): New function. + (VASNPRINTF): Use it. + Suggested by Simon Josefsson. + 2007-03-27 Eric Blake Support sub-second birthtime on cygwin. diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c index ab82b2124..adce60817 100644 --- a/lib/vasnprintf.c +++ b/lib/vasnprintf.c @@ -127,6 +127,33 @@ local_wcslen (const wchar_t *s) /* Here we need to call the native sprintf, not rpl_sprintf. */ #undef sprintf +#if NEED_PRINTF_DIRECTIVE_A && !defined IN_LIBINTL +/* Determine the decimal-point character according to the current locale. */ +# ifndef decimal_point_char_defined +# define decimal_point_char_defined 1 +static char +decimal_point_char () +{ + const char *point; + /* Determine it in a multithread-safe way. We know nl_langinfo is + multithread-safe on glibc systems, but is not required to be multithread- + safe by POSIX. sprintf(), however, is multithread-safe. localeconv() + is rarely multithread-safe. */ +# if HAVE_NL_LANGINFO && __GLIBC__ + point = nl_langinfo (RADIXCHAR); +# elif 1 + char pointbuf[5]; + sprintf (pointbuf, "%#.0f", 1.0); + point = &pointbuf[1]; +# else + point = localeconv () -> decimal_point; +# endif + /* The decimal point is always a single byte: either '.' or ','. */ + return (point[0] != '\0' ? point[0] : '.'); +} +# endif +#endif + CHAR_T * VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list args) { @@ -510,18 +537,7 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar if ((flags & FLAG_ALT) || mantissa > 0.0L || precision > 0) { - const char *point; - /* Prefer nl_langinfo() over localeconv(), - since the latter is not multithread- - safe. */ -# if HAVE_NL_LANGINFO - point = nl_langinfo (RADIXCHAR); -# else - point = localeconv () -> decimal_point; -# endif - /* The decimal point is always a single byte: - either '.' or ','. */ - *p++ = (point[0] != '\0' ? point[0] : '.'); + *p++ = decimal_point_char (); /* This loop terminates because we assume that FLT_RADIX is a power of 2. */ while (mantissa > 0.0L) @@ -667,18 +683,7 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar if ((flags & FLAG_ALT) || mantissa > 0.0 || precision > 0) { - const char *point; - /* Prefer nl_langinfo() over localeconv(), - since the latter is not multithread- - safe. */ -# if HAVE_NL_LANGINFO - point = nl_langinfo (RADIXCHAR); -# else - point = localeconv () -> decimal_point; -# endif - /* The decimal point is always a single byte: - either '.' or ','. */ - *p++ = (point[0] != '\0' ? point[0] : '.'); + *p++ = decimal_point_char (); /* This loop terminates because we assume that FLT_RADIX is a power of 2. */ while (mantissa > 0.0)