bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: use of thread-unsafe localeconv in vasprintf


From: Bruno Haible
Subject: Re: use of thread-unsafe localeconv in vasprintf
Date: Tue, 27 Mar 2007 22:11:12 +0200
User-agent: KMail/1.5.4

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  <address@hidden>

        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)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]