about summary refs log tree commit diff
path: root/stdio-common/vfprintf.c
diff options
context:
space:
mode:
Diffstat (limited to 'stdio-common/vfprintf.c')
-rw-r--r--stdio-common/vfprintf.c85
1 files changed, 41 insertions, 44 deletions
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index 2a077b480a..91179564fd 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -22,12 +22,12 @@
 #include <stdarg.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include <string.h>
 #include <errno.h>
 #include <wchar.h>
 #include <bits/libc-lock.h>
 #include <sys/param.h>
 #include "_itoa.h"
-#include "_i18n_itoa.h"
 #include <locale/localeinfo.h>
 
 /* This code is shared between the standard stdio implementation found
@@ -70,7 +70,7 @@
 #  define UCHAR_T	unsigned char
 #  define INT_T		int
 #  define L_(Str)	Str
-#  define ISDIGIT(Ch)	isdigit (Ch)
+#  define ISDIGIT(Ch)	((unsigned int) ((Ch) - '0') < 10)
 
 #  define PUT(F, S, N)	_IO_sputn ((F), (S), (N))
 #  define PAD(Padchar) \
@@ -80,16 +80,15 @@
 #  define ORIENT	if (s->_vtable_offset == 0 && _IO_fwide (s, -1) != -1)\
 			  return -1
 # else
-# include "_itowa.h"
-# include "_i18n_itowa.h"
-
 #  define vfprintf	_IO_vfwprintf
 #  define CHAR_T	wchar_t
 /* This is a hack!!!  There should be a type uwchar_t.  */
 #  define UCHAR_T	unsigned int /* uwchar_t */
 #  define INT_T		wint_t
 #  define L_(Str)	L##Str
-#  define ISDIGIT(Ch)	iswdigit (Ch)
+#  define ISDIGIT(Ch)	((unsigned int) ((Ch) - L'0') < 10)
+
+#  include "_itowa.h"
 
 #  define PUT(F, S, N)	_IO_sputn ((F), (S), (N))
 #  define PAD(Padchar) \
@@ -100,11 +99,11 @@
 
 #  define _itoa(Val, Buf, Base, Case) _itowa (Val, Buf, Base, Case)
 #  define _itoa_word(Val, Buf, Base, Case) _itowa_word (Val, Buf, Base, Case)
-#  define _i18n_itoa(Val, Buf) _i18n_itowa (Val, Buf)
-#  define _i18n_itoa_word(Val, Buf) _i18n_itowa_word (Val, Buf)
 #  undef EOF
 #  define EOF WEOF
 # endif
+
+# include "_i18n_number.h"
 #else /* ! USE_IN_LIBIO */
 /* This code is for use in the GNU C library.  */
 # include <stdio.h>
@@ -638,20 +637,19 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	    {								      \
 	      string = workend;						      \
 	      if (base == 8 && alt)					      \
-		*string-- = L_('0');					      \
+		*--string = L_('0');					      \
 	    }								      \
 	  else								      \
 	    {								      \
 	      /* Put the number in WORK.  */				      \
-	      if (use_outdigits && base == 10)				      \
-	        string = _i18n_itoa (number.longlong, workend + 1);	      \
-	      else							      \
-	        string = _itoa (number.longlong, workend + 1, base,	      \
-			        spec == L_('X'));			      \
-	      string -= 1;						      \
+	      string = _itoa (number.longlong, workend, base,		      \
+			      spec == L_('X'));				      \
 	      if (group && grouping)					      \
 		string = group_number (string, workend, grouping,	      \
 				       thousands_sep);			      \
+									      \
+	      if (use_outdigits && base == 10)				      \
+		string = _i18n_number_rewrite (string, workend);	      \
 	    }								      \
 	  /* Simplify further test for num != 0.  */			      \
 	  number.word = number.longlong != 0;				      \
@@ -695,26 +693,25 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	    {								      \
 	      string = workend;						      \
 	      if (base == 8 && alt)					      \
-		*string-- = L_('0');					      \
+		*--string = L_('0');					      \
 	    }								      \
 	  else								      \
 	    {								      \
 	      /* Put the number in WORK.  */				      \
-	      if (use_outdigits && base == 10)				      \
-	        string = _i18n_itoa_word (number.word, workend + 1);	      \
-	      else							      \
-	        string = _itoa_word (number.word, workend + 1, base,	      \
-				     spec == L_('X'));			      \
-	      string -= 1;						      \
+	      string = _itoa_word (number.word, workend, base,		      \
+				   spec == L_('X'));			      \
 	      if (group && grouping)					      \
 		string = group_number (string, workend, grouping,	      \
 				       thousands_sep);			      \
+									      \
+	      if (use_outdigits && base == 10)				      \
+		string = _i18n_number_rewrite (string, workend);	      \
 	    }								      \
 	}								      \
 									      \
       if (prec <= workend - string && number.word != 0 && alt && base == 8)   \
 	/* Add octal marker.  */					      \
-	*string-- = L_('0');						      \
+	*--string = L_('0');						      \
 									      \
       prec = MAX (0, prec - (workend - string));			      \
 									      \
@@ -751,7 +748,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	  width += prec;						      \
 	  PAD (L_('0'));						      \
 									      \
-	  outstring (string + 1, workend - string);			      \
+	  outstring (string, workend - string);				      \
 									      \
 	  break;							      \
 	}								      \
@@ -790,7 +787,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	      width = temp;						      \
 	    }								      \
 									      \
-	  outstring (string + 1, workend - string);			      \
+	  outstring (string, workend - string);				      \
 									      \
 	  PAD (L_(' '));						      \
 	  break;							      \
@@ -1325,7 +1322,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
       UCHAR_T pad = L_(' ');/* Padding character.  */
       CHAR_T spec;
 
-      workend = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T) - 1];
+      workend = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T)];
 
       /* Get current character in format string.  */
       JUMP (*++f, step0_jumps);
@@ -1410,7 +1407,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	  /* We have to use a special buffer.  The "32" is just a safe
 	     bet for all the output which is not counted in the width.  */
 	  workend = ((CHAR_T *) alloca ((width + 32) * sizeof (CHAR_T))
-		     + (width + 31));
+		     + (width + 32));
       }
       JUMP (*f, step1_jumps);
 
@@ -1422,7 +1419,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	/* We have to use a special buffer.  The "32" is just a safe
 	   bet for all the output which is not counted in the width.  */
 	workend = ((CHAR_T *) alloca ((width + 32) * sizeof (CHAR_T))
-		   + (width + 31));
+		   + (width + 32));
       if (*f == L_('$'))
 	/* Oh, oh.  The argument comes from a positional parameter.  */
 	goto do_positional;
@@ -1451,7 +1448,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	prec = 0;
       if (prec > width
 	  && prec + 32 > sizeof (work_buffer) / sizeof (work_buffer[0]))
-	workend = alloca (spec + 32) + (spec + 31);
+	workend = alloca (spec + 32) + (spec + 32);
       JUMP (*f, step2_jumps);
 
       /* Process 'h' modifier.  There might another 'h' following.  */
@@ -1749,7 +1746,7 @@ do_positional:
 	if (MAX (prec, width) + 32 > sizeof (work_buffer) / sizeof (CHAR_T))
 	  workend = ((CHAR_T *) alloca ((MAX (prec, width) + 32)
 					* sizeof (CHAR_T))
-		     + (MAX (prec, width) + 31));
+		     + (MAX (prec, width) + 32));
 
 	/* Process format specifiers.  */
 	while (1)
@@ -1826,7 +1823,7 @@ printf_unknown (FILE *s, const struct printf_info *info,
   int done = 0;
   CHAR_T work_buffer[MAX (info->width, info->spec) + 32];
   CHAR_T *const workend
-    = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T) - 1];
+    = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T)];
   register CHAR_T *w;
 
   outchar (L_('%'));
@@ -1848,16 +1845,16 @@ printf_unknown (FILE *s, const struct printf_info *info,
 
   if (info->width != 0)
     {
-      w = _itoa_word (info->width, workend + 1, 10, 0);
-      while (w <= workend)
+      w = _itoa_word (info->width, workend, 10, 0);
+      while (w < workend)
 	outchar (*w++);
     }
 
   if (info->prec != -1)
     {
       outchar (L_('.'));
-      w = _itoa_word (info->prec, workend + 1, 10, 0);
-      while (w <= workend)
+      w = _itoa_word (info->prec, workend, 10, 0);
+      while (w < workend)
 	outchar (*w++);
     }
 
@@ -1896,24 +1893,24 @@ group_number (CHAR_T *w, CHAR_T *rear_ptr, const char *grouping,
 
   /* Copy existing string so that nothing gets overwritten.  */
   src = (CHAR_T *) alloca ((rear_ptr - w) * sizeof (CHAR_T));
-  s = (CHAR_T *) __mempcpy (src, w + 1,
-			    (rear_ptr - w) * sizeof (CHAR_T)) - 1;
+  s = (CHAR_T *) __mempcpy (src, w,
+			    (rear_ptr - w) * sizeof (CHAR_T));
   w = rear_ptr;
 
   /* Process all characters in the string.  */
-  while (s >= src)
+  while (s > src)
     {
-      *w-- = *s--;
+      *--w = *--s;
 
-      if (--len == 0 && s >= src)
+      if (--len == 0 && s > src)
 	{
 	  /* A new group begins.  */
 #ifdef COMPILE_WPRINTF
-	  *w-- = thousands_sep;
+	  *--w = thousands_sep;
 #else
 	  int cnt = tlen;
 	  do
-	    *w-- = thousands_sep[--cnt];
+	    *--w = thousands_sep[--cnt];
 	  while (cnt > 0);
 #endif
 
@@ -1930,8 +1927,8 @@ group_number (CHAR_T *w, CHAR_T *rear_ptr, const char *grouping,
 	      /* No further grouping to be done.
 		 Copy the rest of the number.  */
 	      do
-		*w-- = *s--;
-	      while (s >= src);
+		*--w = *--s;
+	      while (s > src);
 	      break;
 	    }
 	}