diff options
Diffstat (limited to 'stdio-common/vfprintf.c')
-rw-r--r-- | stdio-common/vfprintf.c | 43 |
1 files changed, 16 insertions, 27 deletions
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c index bf5227873b..53339f3078 100644 --- a/stdio-common/vfprintf.c +++ b/stdio-common/vfprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006, 2007 +/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -1025,11 +1025,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 +1159,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 \ @@ -1626,8 +1618,6 @@ do_positional: /* Just a counter. */ size_t cnt; - free (workstart); - workstart = NULL; if (grouping == (const char *) -1) { @@ -1802,9 +1792,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 +1888,8 @@ do_positional: break; } - free (workstart); + if (__builtin_expect (workstart != NULL, 0)) + free (workstart); workstart = NULL; /* Write the following constant string. */ @@ -1928,7 +1917,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; |