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.c113
1 files changed, 42 insertions, 71 deletions
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index bf5227873b..832a6ed547 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -1,5 +1,4 @@
-/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006, 2007
-   Free Software Foundation, Inc.
+/* Copyright (C) 1991-2002, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -65,7 +64,7 @@
 #define UNBUFFERED_P(S) ((S)->_IO_file_flags & _IO_UNBUFFERED)
 
 #ifndef COMPILE_WPRINTF
-# define vfprintf	_IO_vfprintf_internal
+# define vfprintf	_IO_vfprintf
 # define CHAR_T		char
 # define UCHAR_T	unsigned char
 # define INT_T		int
@@ -258,7 +257,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 
 #define NOT_IN_JUMP_RANGE(Ch) ((Ch) < L_(' ') || (Ch) > L_('z'))
 #define CHAR_CLASS(Ch) (jump_table[(INT_T) (Ch) - L_(' ')])
-#ifdef SHARED
+#if defined HAVE_SUBTRACT_LOCAL_LABELS && defined SHARED
   /* 'int' is enough and it saves some space on 64 bit systems.  */
 # define JUMP_TABLE_TYPE const int
 # define JUMP(ChExpr, table)						      \
@@ -530,24 +529,14 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	    {								      \
 	      if (is_long_num)						      \
 		signed_number = va_arg (ap, long int);			      \
-	      else if (is_char)						      \
-	        signed_number = (signed char) va_arg (ap, unsigned int);      \
-	      else if (!is_short)					      \
+	      else  /* `char' and `short int' will be promoted to `int'.  */  \
 		signed_number = va_arg (ap, int);			      \
-	      else							      \
-		signed_number = (short int) va_arg (ap, unsigned int);	      \
 	    }								      \
 	  else								      \
 	    if (is_long_num)						      \
 	      signed_number = args_value[fspec->data_arg].pa_long_int;	      \
-	    else if (is_char)						      \
-	      signed_number = (signed char)				      \
-		args_value[fspec->data_arg].pa_u_int;			      \
-	    else if (!is_short)						      \
+	    else  /* `char' and `short int' will be promoted to `int'.  */    \
 	      signed_number = args_value[fspec->data_arg].pa_int;	      \
-	    else							      \
-	      signed_number = (short int)				      \
-		args_value[fspec->data_arg].pa_u_int;			      \
 									      \
 	  is_negative = signed_number < 0;				      \
 	  number.word = is_negative ? (- signed_number) : signed_number;      \
@@ -769,9 +758,6 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 									      \
 	if (fspec == NULL)						      \
 	  {								      \
-	    if (__ldbl_is_dbl)						      \
-	      is_long_double = 0;					      \
-									      \
 	    struct printf_info info = { .prec = prec,			      \
 					.width = width,			      \
 					.spec = spec,			      \
@@ -799,11 +785,6 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	else								      \
 	  {								      \
 	    ptr = (const void *) &args_value[fspec->data_arg];		      \
-	    if (__ldbl_is_dbl)						      \
-	      {								      \
-		fspec->data_arg_type = PA_DOUBLE;			      \
-		fspec->info.is_long_double = 0;				      \
-	      }								      \
 									      \
 	    function_done = __printf_fp (s, &fspec->info, &ptr);	      \
 	  }								      \
@@ -827,9 +808,6 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 									      \
 	if (fspec == NULL)						      \
 	  {								      \
-	    if (__ldbl_is_dbl)						      \
-	      is_long_double = 0;					      \
-									      \
 	    struct printf_info info = { .prec = prec,			      \
 					.width = width,			      \
 					.spec = spec,			      \
@@ -856,8 +834,6 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	else								      \
 	  {								      \
 	    ptr = (const void *) &args_value[fspec->data_arg];		      \
-	    if (__ldbl_is_dbl)						      \
-	      fspec->info.is_long_double = 0;				      \
 									      \
 	    function_done = __printf_fphex (s, &fspec->info, &ptr);	      \
 	  }								      \
@@ -1025,11 +1001,10 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	    const char *mbs = (const char *) string;			      \
 	    mbstate_t mbstate;						      \
 									      \
-	    len = prec != -1 ? __strnlen (mbs, (size_t) prec) : strlen (mbs); \
+	    len = prec != -1 ? (size_t) prec : strlen (mbs);		      \
 									      \
 	    /* Allocate dynamically an array which definitely is long	      \
-	       enough for the wide character version.  Each byte in the	      \
-	       multi-byte string can produce at most one wide character.  */  \
+	       enough for the wide character version.  */		      \
 	    if (__libc_use_alloca (len * sizeof (wchar_t)))		      \
 	      string = (CHAR_T *) alloca (len * sizeof (wchar_t));	      \
 	    else if ((string = (CHAR_T *) malloc (len * sizeof (wchar_t)))    \
@@ -1160,26 +1135,19 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 		else							      \
 		  {							      \
 		    /* In case we have a multibyte character set the	      \
-		       situation is more complicated.  We must not copy	      \
+		       situation is more compilcated.  We must not copy	      \
 		       bytes at the end which form an incomplete character. */\
-		    size_t ignore_size = (unsigned) prec > 1024 ? 1024 : prec;\
-		    wchar_t ignore[ignore_size];			      \
+		    wchar_t ignore[prec];				      \
 		    const char *str2 = string;				      \
-		    const char *strend = string + prec;			      \
-		    if (strend < string)				      \
-		      strend = (const char *) UINTPTR_MAX;		      \
-									      \
 		    mbstate_t ps;					      \
-		    memset (&ps, '\0', sizeof (ps));			      \
-									      \
-		    while (str2 != NULL && str2 < strend)		      \
-		      if (__mbsnrtowcs (ignore, &str2, strend - str2,	      \
-					ignore_size, &ps) == (size_t) -1)     \
-			{						      \
-			  done = -1;					      \
-			  goto all_done;				      \
-			}						      \
 									      \
+		    memset (&ps, '\0', sizeof (ps));			      \
+		    if (__mbsnrtowcs (ignore, &str2, prec, prec, &ps)	      \
+			== (size_t) -1)					      \
+		      {							      \
+			done = -1;					      \
+			goto all_done;					      \
+		      }							      \
 		    if (str2 == NULL)					      \
 		      len = strlen (string);				      \
 		    else						      \
@@ -1315,7 +1283,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
   /* Process whole format string.  */
   do
     {
-#ifdef SHARED
+#if defined HAVE_SUBTRACT_LOCAL_LABELS && defined SHARED
 # define REF(Name) &&do_##Name - &&do_form_unknown
 #else
 # define REF(Name) &&do_##Name
@@ -1626,8 +1594,6 @@ do_positional:
     /* Just a counter.  */
     size_t cnt;
 
-    free (workstart);
-    workstart = NULL;
 
     if (grouping == (const char *) -1)
       {
@@ -1738,15 +1704,7 @@ do_positional:
 	T (PA_INT|PA_FLAG_LONG_LONG, pa_long_long_int, long long int);
 	T (PA_FLOAT, pa_double, double);	/* Promoted.  */
 	T (PA_DOUBLE, pa_double, double);
-	case PA_DOUBLE|PA_FLAG_LONG_DOUBLE:
-	  if (__ldbl_is_dbl)
-	    {
-	      args_value[cnt].pa_double = va_arg (ap_save, double);
-	      args_type[cnt] &= ~PA_FLAG_LONG_DOUBLE;
-	    }
-	  else
-	    args_value[cnt].pa_long_double = va_arg (ap_save, long double);
-	  break;
+	T (PA_DOUBLE|PA_FLAG_LONG_DOUBLE, pa_long_double, long double);
 	T (PA_STRING, pa_string, const char *);
 	T (PA_WSTRING, pa_wstring, const wchar_t *);
 	T (PA_POINTER, pa_pointer, void *);
@@ -1768,7 +1726,7 @@ do_positional:
     for (; (size_t) nspecs_done < nspecs; ++nspecs_done)
       {
 #undef REF
-#ifdef SHARED
+#if defined HAVE_SUBTRACT_LOCAL_LABELS && defined SHARED
 # define REF(Name) &&do2_##Name - &&do_form_unknown
 #else
 # define REF(Name) &&do2_##Name
@@ -1802,9 +1760,7 @@ do_positional:
 	int use_outdigits = specs[nspecs_done].info.i18n;
 	char pad = specs[nspecs_done].info.pad;
 	CHAR_T spec = specs[nspecs_done].info.spec;
-
-	workstart = NULL;
-	workend = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T)];
+	CHAR_T *workstart = NULL;
 
 	/* Fill in last information.  */
 	if (specs[nspecs_done].width_arg != -1)
@@ -1900,7 +1856,8 @@ do_positional:
 	    break;
 	  }
 
-	free (workstart);
+	if (__builtin_expect (workstart != NULL, 0))
+	  free (workstart);
 	workstart = NULL;
 
 	/* Write the following constant string.  */
@@ -1928,7 +1885,7 @@ printf_unknown (FILE *s, const struct printf_info *info,
 
 {
   int done = 0;
-  CHAR_T work_buffer[MAX (sizeof (info->width), sizeof (info->prec)) * 3];
+  CHAR_T work_buffer[MAX (info->width, info->spec) + 32];
   CHAR_T *const workend
     = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T)];
   register CHAR_T *w;
@@ -2197,11 +2154,25 @@ buffered_vfprintf (register _IO_FILE *s, const CHAR_T *format,
 }
 
 #undef vfprintf
-#ifdef COMPILE_WPRINTF
+#ifdef strong_alias
+/* This is for glibc.  */
+# ifdef COMPILE_WPRINTF
 strong_alias (_IO_vfwprintf, __vfwprintf);
-ldbl_weak_alias (_IO_vfwprintf, vfwprintf);
+weak_alias (_IO_vfwprintf, vfwprintf);
+# else
+strong_alias (_IO_vfprintf, vfprintf);
+libc_hidden_def (vfprintf)
+INTDEF(_IO_vfprintf)
+# endif
 #else
-ldbl_strong_alias (_IO_vfprintf_internal, vfprintf);
-ldbl_hidden_def (_IO_vfprintf_internal, vfprintf)
-ldbl_strong_alias (_IO_vfprintf_internal, _IO_vfprintf);
+# if defined __ELF__ || defined __GNU_LIBRARY__
+#  include <gnu-stabs.h>
+#  ifdef weak_alias
+#   ifdef COMPILE_WPRINTF
+weak_alias (_IO_vfwprintf, vfwprintf);
+#   else
+weak_alias (_IO_vfprintf, vfprintf);
+#   endif
+#  endif
+# endif
 #endif