changeset 30139:4db00ea608c7

vasnprintf: support Irix 5.3 * lib/vasnprintf.c (VASNPRINTF): Also handle -0.0L on platforms that mishandle long double infinity. Reported by Tom G. Christensen. Signed-off-by: Eric Blake <ebb9@byu.net>
author Eric Blake <ebb9@byu.net>
date Tue, 16 Sep 2008 09:36:24 -0600
parents 09fc0fc9c1d7
children 49b384db7c01
files ChangeLog lib/vasnprintf.c
diffstat 2 files changed, 63 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Sep 16 13:05:24 2008 +0200
+++ b/ChangeLog	Tue Sep 16 09:36:24 2008 -0600
@@ -1,3 +1,11 @@
+2008-09-16  Bruno Haible  <bruno@clisp.org>
+	and Eric Blake  <ebb9@byu.net>
+
+	vasnprintf: support Irix 5.3
+	* lib/vasnprintf.c (VASNPRINTF): Also handle -0.0L on platforms
+	that mishandle long double infinity.
+	Reported by Tom G. Christensen.
+
 2008-09-16  Bruno Haible  <bruno@clisp.org>
 
 	* doc/glibc-functions/scandir.texi: Mention the function is missing on
--- a/lib/vasnprintf.c	Tue Sep 16 13:05:24 2008 +0200
+++ b/lib/vasnprintf.c	Tue Sep 16 09:36:24 2008 -0600
@@ -255,11 +255,11 @@
 
 #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
@@ -2578,8 +2578,10 @@
 # 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
 			))
 	      {
@@ -3139,7 +3141,54 @@
 			      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++ = '+';
+				/* Produce the same number of exponent digits as
+				   the native printf implementation.  */
+#   if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+				*p++ = '0';
+#   endif
+				*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
+			      abort ();
 #  endif
 			  }