vasnprintf: fix x86/glibc regression on printf("%La", 0.0L)
authorEric Blake <ebb9@byu.net>
Mon, 22 Sep 2008 23:54:22 +0000 (01:54 +0200)
committerBruno Haible <bruno@clisp.org>
Mon, 22 Sep 2008 23:54:22 +0000 (01:54 +0200)
ChangeLog
lib/vasnprintf.c

index 5b06d29..41e6aad 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2008-09-22  Eric Blake  <ebb9@byu.net>
+            Bruno Haible  <bruno@clisp.org>
+
+       vasnprintf: fix x86/glibc regression on printf("%La", 0.0L)
+       * lib/vasnprintf.c (VASNPRINTF): Support 0.0 on platforms that
+       supply %A but mishandle pseudo-NaN.
+       Reported by Simon Josefsson.
+
 2008-09-21  Bruno Haible  <bruno@clisp.org>
 
        * tests/test-lock.c (main): Tweak skip message.
index e4bfca3..421e445 100644 (file)
@@ -2663,9 +2663,11 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 
                /* POSIX specifies the default precision to be 6 for %f, %F,
                   %e, %E, but not for %g, %G.  Implementations appear to use
-                  the same default precision also for %g, %G.  */
+                  the same default precision also for %g, %G.  But for %a, %A,
+                  the default precision is 0.  */
                if (!has_precision)
-                 precision = 6;
+                 if (!(dp->conversion == 'a' || dp->conversion == 'A'))
+                   precision = 6;
 
                /* Allocate a temporary buffer of sufficient size.  */
 # if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
@@ -3182,6 +3184,22 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                      *p++ = '0';
                                  }
                              }
+                           else if (dp->conversion == 'a' || dp->conversion == 'A')
+                             {
+                               *p++ = '0';
+                               *p++ = dp->conversion - 'A' + 'X';
+                               pad_ptr = p;
+                               *p++ = '0';
+                               if ((flags & FLAG_ALT) || precision > 0)
+                                 {
+                                   *p++ = decimal_point_char ();
+                                   for (; precision > 0; precision--)
+                                     *p++ = '0';
+                                 }
+                               *p++ = dp->conversion - 'A' + 'P';
+                               *p++ = '+';
+                               *p++ = '0';
+                             }
                            else
                              abort ();
 #  endif