Remove old, dead code in last commit.
[gnulib.git] / lib / vasnprintf.c
index 9018c60..421e445 100644 (file)
@@ -95,7 +95,7 @@
 
 #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
 # include <math.h>
-# include "isnand.h"
+# include "isnand-nolibm.h"
 #endif
 
 #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL
 
 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
 # include <math.h>
-# include "isnand.h"
+# include "isnand-nolibm.h"
 # include "printf-frexp.h"
 #endif
 
 # include "fpucw.h"
 #endif
 
-/* Use this to suppress gcc's `...may be used before initialized' warnings. */
-#ifdef lint
-# define IF_LINT(Code) Code
-#else
-# define IF_LINT(Code) /* empty */
-#endif
-
 #if HAVE_WCHAR_T
 # if HAVE_WCSLEN
 #  define local_wcslen wcslen
@@ -207,6 +200,14 @@ local_wcslen (const wchar_t *s)
 /* Here we need to call the native sprintf, not rpl_sprintf.  */
 #undef sprintf
 
+/* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
+   warnings in this file.  Use -Dlint to suppress them.  */
+#ifdef lint
+# define IF_LINT(Code) Code
+#else
+# define IF_LINT(Code) /* empty */
+#endif
+
 /* Avoid some warnings from "gcc -Wshadow".
    This file doesn't use the exp() and remainder() functions.  */
 #undef exp
@@ -214,7 +215,7 @@ local_wcslen (const wchar_t *s)
 #undef remainder
 #define remainder rem
 
-#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
+#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
 /* Determine the decimal-point character according to the current locale.  */
 # ifndef decimal_point_char_defined
 #  define decimal_point_char_defined 1
@@ -254,11 +255,11 @@ is_infinite_or_zero (double x)
 
 #if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
 
-/* Equivalent to !isfinite(x), but does not require libm.  */
+/* Equivalent to !isfinite(x) || x == 0, but does not require libm.  */
 static int
-is_infinitel (long double x)
+is_infinite_or_zerol (long double x)
 {
-  return isnanl (x) || (x + x == x && x != 0.0L);
+  return isnanl (x) || x + x == x;
 }
 
 #endif
@@ -1230,7 +1231,7 @@ scale10_round_decimal_long_double (long double x, int n)
 static char *
 scale10_round_decimal_double (double x, int n)
 {
-  int e;
+  int e IF_LINT(= 0);
   mpn_t m;
   void *memory = decode_double (x, &e, &m);
   return scale10_round_decimal_decoded (e, m, memory, n);
@@ -2577,8 +2578,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 # elif NEED_PRINTF_INFINITE_LONG_DOUBLE
                         || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
                             /* Some systems produce wrong output for Inf,
-                               -Inf, and NaN.  */
-                            && is_infinitel (a.arg[dp->arg_index].a.a_longdouble))
+                               -Inf, and NaN.  Some systems in this category
+                               (IRIX 5.3) also do so for -0.0.  Therefore we
+                               treat this case here as well.  */
+                            && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble))
 # endif
                        ))
              {
@@ -2660,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
@@ -3138,7 +3143,65 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                              abort ();
 #  else
                            /* arg is finite.  */
-                           abort ();
+                           if (!(arg == 0.0L))
+                             abort ();
+
+                           pad_ptr = p;
+
+                           if (dp->conversion == 'f' || dp->conversion == 'F')
+                             {
+                               *p++ = '0';
+                               if ((flags & FLAG_ALT) || precision > 0)
+                                 {
+                                   *p++ = decimal_point_char ();
+                                   for (; precision > 0; precision--)
+                                     *p++ = '0';
+                                 }
+                             }
+                           else if (dp->conversion == 'e' || dp->conversion == 'E')
+                             {
+                               *p++ = '0';
+                               if ((flags & FLAG_ALT) || precision > 0)
+                                 {
+                                   *p++ = decimal_point_char ();
+                                   for (; precision > 0; precision--)
+                                     *p++ = '0';
+                                 }
+                               *p++ = dp->conversion; /* 'e' or 'E' */
+                               *p++ = '+';
+                               *p++ = '0';
+                               *p++ = '0';
+                             }
+                           else if (dp->conversion == 'g' || dp->conversion == 'G')
+                             {
+                               *p++ = '0';
+                               if (flags & FLAG_ALT)
+                                 {
+                                   size_t ndigits =
+                                     (precision > 0 ? precision - 1 : 0);
+                                   *p++ = decimal_point_char ();
+                                   for (; ndigits > 0; --ndigits)
+                                     *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
                          }
 
@@ -3707,7 +3770,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 #endif
                TCHAR_T *fbp;
                unsigned int prefix_count;
-               int prefixes[2];
+               int prefixes[2] IF_LINT (= { 0 });
 #if !USE_SNPRINTF
                size_t tmp_length;
                TCHAR_T tmpbuf[700];
@@ -4175,7 +4238,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                      abort ();
                    prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
                  }
-               if (dp->precision_arg_index != ARG_NONE)
+               if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
                  {
                    if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
                      abort ();