about summary refs log tree commit diff
path: root/stdio-common/printf_fp.c
diff options
context:
space:
mode:
Diffstat (limited to 'stdio-common/printf_fp.c')
-rw-r--r--stdio-common/printf_fp.c139
1 files changed, 38 insertions, 101 deletions
diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c
index c7a381a69d..ed225e05a6 100644
--- a/stdio-common/printf_fp.c
+++ b/stdio-common/printf_fp.c
@@ -1,5 +1,5 @@
 /* Floating point output for `printf'.
-   Copyright (C) 1995-2003, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1995-1999,2000,2001,2002,2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
 
@@ -71,11 +71,7 @@
     {									      \
       register const int outc = (ch);					      \
       if (putc (outc, fp) == EOF)					      \
-	{								      \
-	  if (buffer_malloced)						      \
-	    free (wbuffer);						      \
-	  return -1;							      \
-	}								      \
+	return -1;							      \
       ++done;								      \
     } while (0)
 
@@ -86,11 +82,7 @@
       if (len > 20)							      \
 	{								      \
 	  if (PUT (fp, wide ? (const char *) wptr : ptr, outlen) != outlen)   \
-	    {								      \
-	      if (buffer_malloced)					      \
-		free (wbuffer);						      \
-	      return -1;						      \
-	    }								      \
+	    return -1;							      \
 	  ptr += outlen;						      \
 	  done += outlen;						      \
 	}								      \
@@ -109,11 +101,7 @@
   do									      \
     {									      \
       if (PAD (fp, ch, len) != len)					      \
-	{								      \
-	  if (buffer_malloced)						      \
-	    free (wbuffer);						      \
-	  return -1;							      \
-	}								      \
+	return -1;							      \
       done += len;							      \
     }									      \
   while (0)
@@ -150,9 +138,9 @@ static wchar_t *group_number (wchar_t *buf, wchar_t *bufend,
 
 
 int
-___printf_fp (FILE *fp,
-	      const struct printf_info *info,
-	      const void *const *args)
+__printf_fp (FILE *fp,
+	     const struct printf_info *info,
+	     const void *const *args)
 {
   /* The floating-point value to output.  */
   union
@@ -211,11 +199,6 @@ ___printf_fp (FILE *fp,
   /* Nonzero if this is output on a wide character stream.  */
   int wide = info->wide;
 
-  /* Buffer in which we produce the output.  */
-  wchar_t *wbuffer = NULL;
-  /* Flag whether wbuffer is malloc'ed or not.  */
-  int buffer_malloced = 0;
-
   auto wchar_t hack_digit (void);
 
   wchar_t hack_digit (void)
@@ -792,7 +775,7 @@ ___printf_fp (FILE *fp,
   else
     {
       /* This is a special case.  We don't need a factor because the
-	 numbers are in the range of 1.0 <= |fp| < 8.0.  We simply
+	 numbers are in the range of 0.0 <= fp < 8.0.  We simply
 	 shift it to the right place and divide it by 1.0 to get the
 	 leading digit.	 (Of course this division is not really made.)	*/
       assert (0 <= exponent && exponent < 3 &&
@@ -806,18 +789,17 @@ ___printf_fp (FILE *fp,
 
   {
     int width = info->width;
-    wchar_t *wstartp, *wcp;
+    wchar_t *wbuffer, *wstartp, *wcp;
+    int buffer_malloced;
     int chars_needed;
     int expscale;
     int intdig_max, intdig_no = 0;
-    int fracdig_min;
-    int fracdig_max;
+    int fracdig_min, fracdig_max, fracdig_no = 0;
     int dig_max;
     int significant;
     int ngroups = 0;
-    char spec = _tolower (info->spec);
 
-    if (spec == 'e')
+    if (_tolower (info->spec) == 'e')
       {
 	type = info->spec;
 	intdig_max = 1;
@@ -827,7 +809,7 @@ ___printf_fp (FILE *fp,
 	dig_max = INT_MAX;		/* Unlimited.  */
 	significant = 1;		/* Does not matter here.  */
       }
-    else if (spec == 'f')
+    else if (_tolower (info->spec) == 'f')
       {
 	type = 'f';
 	fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec;
@@ -924,9 +906,7 @@ ___printf_fp (FILE *fp,
       }
 
     /* Generate the needed number of fractional digits.	 */
-    int fracdig_no = 0;
-    int added_zeros = 0;
-    while (fracdig_no < fracdig_min + added_zeros
+    while (fracdig_no < fracdig_min
 	   || (fracdig_no < fracdig_max && (fracsize > 1 || frac[0] != 0)))
       {
 	++fracdig_no;
@@ -937,7 +917,7 @@ ___printf_fp (FILE *fp,
 	  {
 	    ++fracdig_max;
 	    if (fracdig_min > 0)
-	      ++added_zeros;
+	      ++fracdig_min;
 	  }
       }
 
@@ -974,23 +954,11 @@ ___printf_fp (FILE *fp,
 	  {
 	    /* Process fractional digits.  Terminate if not rounded or
 	       radix character is reached.  */
-	    int removed = 0;
 	    while (*--wtp != decimalwc && *wtp == L'9')
-	      {
-		*wtp = L'0';
-		++removed;
-	      }
-	    if (removed == fracdig_min && added_zeros > 0)
-	      --added_zeros;
+	      *wtp = '0';
 	    if (*wtp != decimalwc)
 	      /* Round up.  */
 	      (*wtp)++;
-	    else if (__builtin_expect (spec == 'g' && type == 'f' && info->alt,
-				       0))
-	      /* This is a special case: the rounded number is 1.0,
-		 the format is 'g' or 'G', and the alternative format
-		 is selected.  This means the result must be "1.".  */
-	      --added_zeros;
 	  }
 
 	if (fracdig_no == 0 || *wtp == decimalwc)
@@ -1012,12 +980,6 @@ ___printf_fp (FILE *fp,
 		  {
 		    *wstartp = '1';
 		    exponent += expsign == 0 ? 1 : -1;
-
-		    /* The above exponent adjustment could lead to 1.0e-00,
-		       e.g. for 0.999999999.  Make sure exponent 0 always
-		       uses + sign.  */
-		    if (exponent == 0)
-		      expsign = 0;
 		  }
 		else if (intdig_no == dig_max)
 		  {
@@ -1063,7 +1025,7 @@ ___printf_fp (FILE *fp,
 
   do_expo:
     /* Now remove unnecessary '0' at the end of the string.  */
-    while (fracdig_no > fracdig_min + added_zeros && *(wcp - 1) == L'0')
+    while (fracdig_no > fracdig_min && *(wcp - 1) == L'0')
       {
 	--wcp;
 	--fracdig_no;
@@ -1081,46 +1043,26 @@ ___printf_fp (FILE *fp,
     /* Write the exponent if it is needed.  */
     if (type != 'f')
       {
-	if (__builtin_expect (expsign != 0 && exponent == 4 && spec == 'g', 0))
-	  {
-	    /* This is another special case.  The exponent of the number is
-	       really smaller than -4, which requires the 'e'/'E' format.
-	       But after rounding the number has an exponent of -4.  */
-	    assert (wcp >= wstartp + 1);
-	    assert (wstartp[0] == L'1');
-	    __wmemcpy (wstartp, L"0.0001", 6);
-	    wstartp[1] = decimalwc;
-	    if (wcp >= wstartp + 2)
-	      {
-		wmemset (wstartp + 6, L'0', wcp - (wstartp + 2));
-		wcp += 4;
-	      }
-	    else
-	      wcp += 5;
-	  }
-	else
-	  {
-	    *wcp++ = (wchar_t) type;
-	    *wcp++ = expsign ? L'-' : L'+';
+	*wcp++ = (wchar_t) type;
+	*wcp++ = expsign ? L'-' : L'+';
 
-	    /* Find the magnitude of the exponent.	*/
-	    expscale = 10;
-	    while (expscale <= exponent)
-	      expscale *= 10;
+	/* Find the magnitude of the exponent.	*/
+	expscale = 10;
+	while (expscale <= exponent)
+	  expscale *= 10;
 
-	    if (exponent < 10)
-	      /* Exponent always has at least two digits.  */
-	      *wcp++ = L'0';
-	    else
-	      do
-		{
-		  expscale /= 10;
-		  *wcp++ = L'0' + (exponent / expscale);
-		  exponent %= expscale;
-		}
-	      while (expscale > 10);
-	    *wcp++ = L'0' + exponent;
-	  }
+	if (exponent < 10)
+	  /* Exponent always has at least two digits.  */
+	  *wcp++ = L'0';
+	else
+	  do
+	    {
+	      expscale /= 10;
+	      *wcp++ = L'0' + (exponent / expscale);
+	      exponent %= expscale;
+	    }
+	  while (expscale > 10);
+	*wcp++ = L'0' + exponent;
       }
 
     /* Compute number of characters which must be filled with the padding
@@ -1166,12 +1108,8 @@ ___printf_fp (FILE *fp,
 	      buffer = (char *) malloc (2 + chars_needed + decimal_len
 					+ ngroups * thousands_sep_len);
 	      if (buffer == NULL)
-		{
-		  /* Signal an error to the caller.  */
-		  if (buffer_malloced)
-		    free (wbuffer);
-		  return -1;
-		}
+		/* Signal an error to the caller.  */
+		return -1;
 	    }
 	  else
 	    buffer = (char *) alloca (2 + chars_needed + decimal_len
@@ -1215,8 +1153,7 @@ ___printf_fp (FILE *fp,
   }
   return done;
 }
-ldbl_hidden_def (___printf_fp, __printf_fp)
-ldbl_strong_alias (___printf_fp, __printf_fp)
+libc_hidden_def (__printf_fp)
 
 /* Return the number of extra grouping characters that will be inserted
    into a number with INTDIG_MAX integer digits.  */