Simon Josefsson wrote: > > Yes, I finally had the same idea. How about this? We don't care much about > > efficiency at this point in the code. > > Seems fine to me, thanks! ... > > Stuffing this logic into a separate module might be cleaner though... > there is some duplicated code now.
There is code duplication, indeed, but so far I think it's not much of use outside 'vasnprintf', so I don't make it a module of its own (yet). Thanks for the suggestion. 2007-03-27 Bruno Haible <[EMAIL PROTECTED]> Make vasnprintf multithread-safe. * lib/vasnprintf.c (decimal_point_char): New function. (VASNPRINTF): Use it. Suggested by Simon Josefsson. *** lib/vasnprintf.c 26 Mar 2007 02:15:46 -0000 1.36 --- lib/vasnprintf.c 27 Mar 2007 20:10:12 -0000 *************** *** 127,132 **** --- 127,159 ---- /* 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,527 **** 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] : '.'); /* This loop terminates because we assume that FLT_RADIX is a power of 2. */ while (mantissa > 0.0L) --- 537,543 ---- if ((flags & FLAG_ALT) || mantissa > 0.0L || precision > 0) { ! *p++ = decimal_point_char (); /* This loop terminates because we assume that FLT_RADIX is a power of 2. */ while (mantissa > 0.0L) *************** *** 667,684 **** 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] : '.'); /* This loop terminates because we assume that FLT_RADIX is a power of 2. */ while (mantissa > 0.0) --- 683,689 ---- if ((flags & FLAG_ALT) || mantissa > 0.0 || precision > 0) { ! *p++ = decimal_point_char (); /* This loop terminates because we assume that FLT_RADIX is a power of 2. */ while (mantissa > 0.0)