aboutsummaryrefslogtreecommitdiff
path: root/stdio-common/vfprintf.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1999-06-16 22:55:47 +0000
committerUlrich Drepper <drepper@redhat.com>1999-06-16 22:55:47 +0000
commitd64b6ad07585b8a37e5fecc9a47fcee766d52ede (patch)
tree076b36cc9c1b82254348212e75939d842885563a /stdio-common/vfprintf.c
parentbc938d3de936a8e429b16237180c046139be8247 (diff)
downloadglibc-d64b6ad07585b8a37e5fecc9a47fcee766d52ede.tar.xz
glibc-d64b6ad07585b8a37e5fecc9a47fcee766d52ede.zip
Update.
* Versions.def: Add GLIBC_2.2 for libc. * iconv/gconv.h: Make header suitable for inclusion in public header by protecting all names with __. * iconv/gconv.c: Adapt for symbol name changes. * iconv/gconv.h: Likewise. * iconv/gconv_builtin.c: Likewise. * iconv/gconv_close.c: Likewise. * iconv/gconv_db.c: Likewise. * iconv/gconv_dl.c: Likewise. * iconv/gconv_int.h: Likewise. * iconv/gconv_open.c: Likewise. * iconv/gconv_simple.c: Likewise. * iconv/iconv.c: Likewise. * iconv/iconv_close.c: Likewise. * iconv/iconv_open.c: Likewise. * iconv/loop.c: Likewise. * iconv/skeleton.c: Likewise. * iconvdata/8bit-gap.c: Likewise. * iconvdata/8bit-generic.c: Likewise. * iconvdata/ansi_x3.110.c: Likewise. * iconvdata/big5.c: Likewise. * iconvdata/cns11643.h: Likewise. * iconvdata/cns11643l1.h: Likewise. * iconvdata/euc-cn.c: Likewise. * iconvdata/euc-jp.c: Likewise. * iconvdata/euc-kr.c: Likewise. * iconvdata/euc-tw.c: Likewise. * iconvdata/gb2312.h: Likewise. * iconvdata/iso-2022-jp.c: Likewise. * iconvdata/iso-2022-kr.c: Likewise. * iconvdata/iso646.c: Likewise. * iconvdata/iso8859-1.c: Likewise. * iconvdata/iso_6937-2.c: Likewise. * iconvdata/iso_6937.c: Likewise. * iconvdata/jis0201.h: Likewise. * iconvdata/jis0208.h: Likewise. * iconvdata/jis0212.h: Likewise. * iconvdata/johab.c: Likewise. * iconvdata/ksc5601.h: Likewise. * iconvdata/sjis.c: Likewise. * iconvdata/t.61.c: Likewise. * iconvdata/uhc.c: Likewise. * stdlib/mblen.c: Likewise. * stdlib/mbtowc.c: Likewise. * stdlib/wctomb.c: Likewise. * wcsmbs/btowc.c: Likewise. * wcsmbs/mbrtowc.c: Likewise. * wcsmbs/mbsnrtowcs.c: Likewise. * wcsmbs/mbsrtowcs.c: Likewise. * wcsmbs/wchar.h: Likewise. * wcsmbs/wcrtomb.c: Likewise. * wcsmbs/wcsmbsload.c: Likewise. * wcsmbs/wcsmbsload.h: Likewise. * wcsmbs/wcsnrtombs.c: Likewise. * wcsmbs/wcsrtombs.c: Likewise. * wcsmbs/wctob.c: Likewise. * include/limits.h (MB_LEN_MAX): Increase to 16. * sysdeps/generic/_G_config.h: Define _G_fpos_t as struct. Define _G_iconv_t. * sysdeps/unix/sysv/linux/_G_config.h: Likewise. * include/wchar.h: Change mbstate_t to __mbstate_t. * libio/Makefile (routines): Add wfiledoalloc, oldiofgetpos, oldiofgetpos64, oldiofsetpos, oldiofsetpos64, fputwc, fputwc_u, getwc, getwc_u, getwchar, getwchar_u, iofgetws, iofgetws_u, iofputws, iofputws_u, iogetwline, iowpadn, ioungetwc, putwc, putwc_u, putchar, putchar_u, swprintf, vwprintf, wprintf, wscanf, fwscanf, vwscanf, vswprintf, iovswscanf, swscanf, wgenops, wstrops, wfileops, and iofwide. (tests): Add tst_swprintf, tst_wprintf, tst_swscanf, and tst_wscanf. * libio/Versions: Add _IO_fgetpos, _IO_fgetpos64, _IO_fsetpos, _IO_fsetpos64, fgetpos, fgetpos64, fgetwc, fgetwc_unlocked, fgetws, fgetws_unlocked, fputwc, fputwc_unlocked, fputws, fputws_unlocked, fsetpos, fsetpos64, fwide, fwprintf, fwscanf, getwc, getwc_unlocked, getwchar, getwchar_unlocked, putwc, putwc_unlocked, putwchar, putwchar_unlocked, swprintf, swscanf, ungetwc, vfwprintf, vswprintf, vwprintf, vfwscanf, vswscanf, vwscanf, wprintf, and wscanf to GLIBC_2.2 for libc. * libio/libio.h: Define codecvt struct. Define _IO_wide_data. Extend _IO_file contain pointer to codecvt, widedata and mode. (_IO_getwc_unlocked): New macro. (_IO_putwc_unlocked): New macro. (_IO_fwide): New macro. * libio/libioP.h: Add new prototypes and adjust existing declarations. * libio/fileops.c (_IO_new_file_close_it): Reset normal or widedata buffers based on mode. (new_do_write): Set _IO_write_end to _IO_buf_end if stream is wide oriented. (_IO_new_file_overflow): Don't depend only on _IO_CURRENTLY_PUTTING flag to be enough to signal unallocated buffer. For wide oriented stream don't make it linebuffered. Don't use _IO_do_flush, use _IO_new_do_write directly. (_IO_new_file_seekoff): Change return value type to _IO_off64_t. (_IO_file_seek): Likewise. * libio/genops.c (_IO_least_marker): Make global. (__underflow): Orient stream if not already done. (__uflow): Likewise. (_IO_default_seekpos): Change to type _IO_off64_t. (_IO_default_seekoff): Likewise. (_IO_default_seek): Likewise. (_IO_no_init): New function. Similar to _IO_init but allows to orient in initialization. * libio/iolibio.h: Add prototype for _IO_vswprintf. Change _IO_pos_BAD to use _IO_off64_t. * libio/ftello.c: Use _IO_off_t. For now abort when use with wide char stream. * libio/ftello64.c: Likewise. * libio/ioftell.c: Likewise. * libio/iofopncook.c: Likewise. * libio/ioseekoff.c: Likewise. * libio/ioseekpos.c: Likewise. * libio/oldfileops.c: Likewise. * libio/iofgetpos.c: Store state of conversion if necessary. * libio/iofgetpos64.c: Likewise. * libio/iofsetpos.c: Restore conversion state if necessary. * libio/iofsetpos64.c: Likewise. * libio/iofdopen.c: Initialize so that stream can be wide oriented. * libio/iofopen.c: Likewise. * libio/iofopen64.c: Likewise. * libio/iopopen.c: Likewise. * libio/iovdprintf.c: Likewise. * libio/iovsprintf.c: Likewise. * libio/iovsscanf.c: Likewise. * libio/memstream.c: Likewise. * libio/obprintf.c: Likewise. * libio/iofputs.c: Orient stream if not already happened. * libio/iofputs_u.c: Likewise. * libio/iofwrite.c: Likewise. * libio/iofwrite_u.c: Likewise. * libio/ioputs.c: Likewise. * libio/iosetbuffer.c: Handle not yet oriented stream. * libio/iosetvbuf.c: Likewise. * libio/oldstdfiles.c: Adjust FILEBUF_LITERAL call. * libio/stdfiles.c: Likewise. * libio/strops.c (_IO_str_overflow): Correctly free buffer after failed allocation. (_IO_str_seekoff): Use _IO_off64_t. * libio/vasprintf.c: Pre-orient stream. * libio/vsnprintf.c: Likewise. * libio/fputwc.c: New file. * libio/fputwc_u.c: New file. * libio/fwprintf.c: New file. * libio/fwscanf.c: New file. * libio/getwc.c: New file. * libio/getwc_u.c: New file. * libio/getwchar.c: New file. * libio/getwchar_u.c: New file. * libio/iofgetws.c: New file. * libio/iofgetws_u.c: New file. * libio/iofputws.c: New file. * libio/iofputws_u.c: New file. * libio/iofwide.c: New file. * libio/iogetwline.c: New file. * libio/ioungetwc.c: New file. * libio/iovswscanf.c: New file. * libio/iowpadn.c: New file. * libio/oldiofgetpos.c: New file. * libio/oldiofgetpos64.c: New file. * libio/oldiofsetpos.c: New file. * libio/oldiofsetpos64.c: New file. * libio/putwc.c: New file. * libio/putwc_u.c: New file. * libio/putwchar.c: New file. * libio/putwchar_u.c: New file. * libio/swprintf.c: New file. * libio/swscanf.c: New file. * libio/tst_swprintf.c: New file. * libio/tst_swscanf.c: New file. * libio/tst_wprintf.c: New file. * libio/tst_wscanf.c: New file. * libio/tst_wscanf.input: New file. * libio/vswprintf.c: New file. * libio/vwprintf.c: New file. * libio/vwscanf.c: New file. * libio/wfiledoalloc.c: New file. * libio/wfileops.c: New file. * libio/wgenops.c: New file. * libio/wprintf.c: New file. * libio/wscanf.c: New file. * libio/wstrops.c: New file. * stdio-common/Makefile (routines): Add _itowa, itowa-digits, vfwprintf, and vfwscanf. * stdio-common/_itoa.c (base_table): Rename to _IO_base_table and make global. * stdio-common/_itowa.c: New file. * stdio-common/_itowa.h: New file. * stdio-common/itoa-digits.c: Minimal optimization. * stdio-common/itowa-digits.c: New file. * stdio-common/printf-parse.h: Allow use in wide character context. * stdio-common/printf-prs.c: Define ISASCII and MBRLEN. * stdio-common/printf.h (printf_info): Add wide bit. * stdio-common/printf_fp.c: Determine from wide bit whether stream is wide oriented or not. * stdio-common/printf_size.c: Likewise. * sysdeps/generic/printf_fphex.c: Likewise. * stdlib/strfmon.c: Call __printf_fp with wide bit cleared. * stdio-common/vfprintf.c: Rewrite to allow use in wide character context. * stdio-common/vfscand.c: Likewise. * stdio-common/vfwprintf.c: New file. * stdio-common/vfwscanf.c: New file. * time/Makefile (routines): Add wcsftime. (tests): Add tst_wcsftime. * time/Versions: Add wcsftime to GLIBC_2.2 for libc. * time/strftime.c: Make usable as wcsftime. * time/wcsftime.c: New file. * time/tst_wcsftime.c: New file. * wcsmbs/Makefile (routines): Add wmempcpy and wcschrnul. * wcsmbs/Versions: Add wmempcpy and wcschrnul to GLIBC_2.2 for libc. * wcsmbs/wcschrnul.c: New file. * wcsmbs/wmemcpy.c: New file. * wcsmbs/wmemcpy.c: Rename to __wmemcpy and make wmemcpy weak alias. * wcsmbs/wmemmove.c: Likewise for wmemmove. * manual/stdio.texi: Document is_char and wide element if printf_info. * manual/time.texi: Document wcsftime. * include/wchar.h: Add prototypes for __wmemcpy, __wmempcpy, __wmemmove, __wcschrnul, and __vfwscanf. * locale/langinfo.h: Add new LC_TIME entries for wchar_t data. * locale/C-time.c: Adapt for above change. * locale/categories.def: Likewise. * locale/localeinfo.h: Likewise. * localedata/Makefile: Don't run tests for now.
Diffstat (limited to 'stdio-common/vfprintf.c')
-rw-r--r--stdio-common/vfprintf.c585
1 files changed, 375 insertions, 210 deletions
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index 390ce91f71..fe145d6a3d 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -36,74 +36,16 @@
Beside this it is also shared between the normal and wide character
implementation as defined in ISO/IEC 9899:1990/Amendment 1:1995. */
-#ifndef COMPILE_WPRINTF
-# define CHAR_T char
-# define UCHAR_T unsigned char
-# define INT_T int
-# define L_(Str) Str
-# define ISDIGIT(Ch) isdigit (Ch)
-
-# ifdef USE_IN_LIBIO
-# define PUT(F, S, N) _IO_sputn ((F), (S), (N))
-# define PAD(Padchar) \
- if (width > 0) \
- done += _IO_padn (s, (Padchar), width)
-# else
-# define PUTC(C, F) putc (C, F)
-ssize_t __printf_pad __P ((FILE *, char pad, size_t n));
-# define PAD(Padchar) \
- if (width > 0) \
- { ssize_t __res = __printf_pad (s, (Padchar), width); \
- if (__res == -1) \
- { \
- done = -1; \
- goto all_done; \
- } \
- done += __res; }
-# endif
-#else
-# define vfprintf vfwprintf
-# define CHAR_T wchar_t
-# define UCHAR_T uwchar_t
-# define INT_T wint_t
-# define L_(Str) L##Str
-# define ISDIGIT(Ch) iswdigit (Ch)
-
-# ifdef USE_IN_LIBIO
-# define PUT(F, S, N) _IO_sputn ((F), (S), (N))
-# define PAD(Padchar) \
- if (width > 0) \
- done += _IO_wpadn (s, (Padchar), width)
-# else
-# define PUTC(C, F) wputc (C, F)
-ssize_t __wprintf_pad __P ((FILE *, wchar_t pad, size_t n));
-# define PAD(Padchar) \
- if (width > 0) \
- { ssize_t __res = __wprintf_pad (s, (Padchar), width); \
- if (__res == -1) \
- { \
- done = -1; \
- goto all_done; \
- } \
- done += __res; }
-# endif
-#endif
-
-/* Include the shared code for parsing the format string. */
-#include "printf-parse.h"
-
#ifdef USE_IN_LIBIO
/* This code is for use in libio. */
# include <libioP.h>
-# define PUTC(C, F) _IO_putc_unlocked (C, F)
-# define vfprintf _IO_vfprintf
# define FILE _IO_FILE
# undef va_list
# define va_list _IO_va_list
-# undef BUFSIZ
+# undef BUFSIZ
# define BUFSIZ _IO_BUFSIZ
-# define ARGCHECK(S, Format) \
+# define ARGCHECK(S, Format) \
do \
{ \
/* Check file argument for consistence. */ \
@@ -120,11 +62,54 @@ ssize_t __wprintf_pad __P ((FILE *, wchar_t pad, size_t n));
} \
} while (0)
# define UNBUFFERED_P(S) ((S)->_IO_file_flags & _IO_UNBUFFERED)
+
+# ifndef COMPILE_WPRINTF
+# define vfprintf _IO_vfprintf
+# define CHAR_T char
+# define UCHAR_T unsigned char
+# define INT_T int
+# define L_(Str) Str
+# define ISDIGIT(Ch) isdigit (Ch)
+# define ISASCII(Ch) isascii (Ch)
+# define MBRLEN(Cp, L, St) mbrlen (Cp, L, St)
+
+# define PUT(F, S, N) _IO_sputn ((F), (S), (N))
+# define PAD(Padchar) \
+ if (width > 0) \
+ done += _IO_padn (s, (Padchar), width)
+# define PUTC(C, F) _IO_putc_unlocked (C, F)
+# define ORIENT if (_IO_fwide (s, -1) != -1) return -1
+# else
+# include "_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 ISASCII(Ch) (((unsigned int) (Ch) & ~0x7f) == 0)
+# define MBRLEN(Cp, L, St) wcslen ((const wchar_t *) (Cp))
+
+# define PUT(F, S, N) _IO_sputn ((F), (S), (N))
+# define PAD(Padchar) \
+ if (width > 0) \
+ done += _IO_wpadn (s, (Padchar), width)
+# define PUTC(C, F) _IO_putwc_unlocked (C, F)
+# define ORIENT if (_IO_fwide (s, 1) != 1) return -1
+
+# define _itoa(Val, Buf, Base, Case) _itowa (Val, (wchar_t *) Buf, Base, Case)
+# define _itoa_word(Val, Buf, Base, Case) _itowa_word (Val, (wchar_t *) Buf, \
+ Base, Case)
+# undef EOF
+# define EOF WEOF
+# endif
#else /* ! USE_IN_LIBIO */
/* This code is for use in the GNU C library. */
# include <stdio.h>
# define PUT(F, S, N) fwrite (S, 1, N, F)
-# define ARGCHECK(S, Format) \
+# define ARGCHECK(S, Format) \
do \
{ \
/* Check file argument for consistence. */ \
@@ -153,11 +138,14 @@ extern void __flockfile (FILE *);
extern void __funlockfile (FILE *);
#endif /* USE_IN_LIBIO */
+/* Include the shared code for parsing the format string. */
+#include "printf-parse.h"
+
#define outchar(Ch) \
do \
{ \
- register const int outc = (Ch); \
+ register const INT_T outc = (Ch); \
if (PUTC (outc, s) == EOF) \
{ \
done = -1; \
@@ -199,7 +187,7 @@ extern void __funlockfile (FILE *);
/* Global variables. */
-static const char null[] = "(null)";
+static const CHAR_T null[] = L_("(null)");
/* Helper function to provide temporary buffering for unbuffered streams. */
@@ -211,7 +199,8 @@ static int printf_unknown __P ((FILE *, const struct printf_info *,
const void *const *));
/* Group digits of number string. */
-static char *group_number __P ((CHAR_T *, CHAR_T *, const CHAR_T *, wchar_t))
+static UCHAR_T *group_number __P ((UCHAR_T *, UCHAR_T *, const char *,
+ wchar_t))
internal_function;
@@ -238,11 +227,13 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
const UCHAR_T *end_of_spec;
/* Buffer intermediate results. */
- char work_buffer[1000];
- char *workend;
+ UCHAR_T work_buffer[1000];
+ UCHAR_T *workend;
/* State for restartable multibyte character handling functions. */
+#ifndef COMPILE_WPRINTF
mbstate_t mbstate;
+#endif
/* We have to save the original argument pointer. */
va_list ap_save;
@@ -505,7 +496,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
now process the wanted format specifier. */ \
LABEL (form_percent): \
/* Write a literal "%". */ \
- outchar ('%'); \
+ outchar (L_('%')); \
break; \
\
LABEL (form_integer): \
@@ -588,7 +579,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
else \
/* We have to take care for the '0' flag. If a precision \
is given it must be ignored. */ \
- pad = ' '; \
+ pad = L_(' '); \
\
/* If the precision is 0 and the number is 0 nothing has to \
be written for the number, except for the 'o' format in \
@@ -597,13 +588,13 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
{ \
string = workend; \
if (base == 8 && alt) \
- *string-- = '0'; \
+ *string-- = L_('0'); \
} \
else \
{ \
/* Put the number in WORK. */ \
- string = _itoa (number.longlong, workend + 1, base, \
- spec == 'X'); \
+ string = (UCHAR_T *) _itoa (number.longlong, workend + 1, base, \
+ spec == L_('X')); \
string -= 1; \
if (group && grouping) \
string = group_number (string, workend, grouping, \
@@ -642,7 +633,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
else \
/* We have to take care for the '0' flag. If a precision \
is given it must be ignored. */ \
- pad = ' '; \
+ pad = L_(' '); \
\
/* If the precision is 0 and the number is 0 nothing has to \
be written for the number, except for the 'o' format in \
@@ -651,13 +642,13 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
{ \
string = workend; \
if (base == 8 && alt) \
- *string-- = '0'; \
+ *string-- = L_('0'); \
} \
else \
{ \
/* Put the number in WORK. */ \
- string = _itoa_word (number.word, workend + 1, base, \
- spec == 'X'); \
+ string = (UCHAR_T *) _itoa_word (number.word, workend + 1, \
+ base, spec == L_('X')); \
string -= 1; \
if (group && grouping) \
string = group_number (string, workend, grouping, \
@@ -670,10 +661,10 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
if (prec > 0) \
/* Add zeros to the precision. */ \
while (prec-- > 0) \
- *string-- = '0'; \
+ *string-- = L_('0'); \
else if (number.word != 0 && alt && base == 8) \
/* Add octal marker. */ \
- *string-- = '0'; \
+ *string-- = L_('0'); \
\
if (!left) \
{ \
@@ -686,41 +677,41 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
if (is_negative || showsign || space) \
--width; \
\
- if (pad == '0') \
+ if (pad == L_('0')) \
{ \
while (width-- > 0) \
- *string-- = '0'; \
+ *string-- = L_('0'); \
\
if (number.word != 0 && alt && base == 16) \
{ \
*string-- = spec; \
- *string-- = '0'; \
+ *string-- = L_('0'); \
} \
\
if (is_negative) \
- *string-- = '-'; \
+ *string-- = L_('-'); \
else if (showsign) \
- *string-- = '+'; \
+ *string-- = L_('+'); \
else if (space) \
- *string-- = ' '; \
+ *string-- = L_(' '); \
} \
else \
{ \
if (number.word != 0 && alt && base == 16) \
{ \
*string-- = spec; \
- *string-- = '0'; \
+ *string-- = L_('0'); \
} \
\
if (is_negative) \
- *string-- = '-'; \
+ *string-- = L_('-'); \
else if (showsign) \
- *string-- = '+'; \
+ *string-- = L_('+'); \
else if (space) \
- *string-- = ' '; \
+ *string-- = L_(' '); \
\
while (width-- > 0) \
- *string-- = ' '; \
+ *string-- = L_(' '); \
} \
\
outstring (string + 1, workend - string); \
@@ -732,20 +723,20 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
if (number.word != 0 && alt && base == 16) \
{ \
*string-- = spec; \
- *string-- = '0'; \
+ *string-- = L_('0'); \
} \
\
if (is_negative) \
- *string-- = '-'; \
+ *string-- = L_('-'); \
else if (showsign) \
- *string-- = '+'; \
+ *string-- = L_('+'); \
else if (space) \
- *string-- = ' '; \
+ *string-- = L_(' '); \
\
width -= workend - string; \
outstring (string + 1, workend - string); \
\
- PAD (' '); \
+ PAD (L_(' ')); \
break; \
} \
\
@@ -771,7 +762,8 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
showsign: showsign, \
group: group, \
pad: pad, \
- extra: 0 }; \
+ extra: 0, \
+ wide: sizeof (CHAR_T) != 1 }; \
\
if (is_long_double) \
the_arg.pa_long_double = va_arg (ap, long double); \
@@ -821,7 +813,8 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
showsign: showsign, \
group: group, \
pad: pad, \
- extra: 0 }; \
+ extra: 0, \
+ wide: sizeof (CHAR_T) != 1 }; \
\
if (is_long_double) \
the_arg.pa_long_double = va_arg (ap, long double); \
@@ -849,6 +842,178 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
} \
break; \
\
+ LABEL (form_pointer): \
+ /* Generic pointer. */ \
+ { \
+ const void *ptr; \
+ if (fspec == NULL) \
+ ptr = va_arg (ap, void *); \
+ else \
+ ptr = args_value[fspec->data_arg].pa_pointer; \
+ if (ptr != NULL) \
+ { \
+ /* If the pointer is not NULL, write it as a %#x spec. */ \
+ base = 16; \
+ number.word = (unsigned long int) ptr; \
+ is_negative = 0; \
+ alt = 1; \
+ group = 0; \
+ spec = 'x'; \
+ goto LABEL (number); \
+ } \
+ else \
+ { \
+ /* Write "(nil)" for a nil pointer. */ \
+ string = (UCHAR_T *) L_("(nil)"); \
+ /* Make sure the full string "(nil)" is printed. */ \
+ if (prec < 5) \
+ prec = 5; \
+ is_long = 0; /* This is no wide-char string. */ \
+ goto LABEL (print_string); \
+ } \
+ } \
+ /* NOTREACHED */ \
+ \
+ LABEL (form_number): \
+ /* Answer the count of characters written. */ \
+ if (fspec == NULL) \
+ { \
+ if (is_longlong) \
+ *(long long int *) va_arg (ap, void *) = done; \
+ else if (is_long_num) \
+ *(long int *) va_arg (ap, void *) = done; \
+ else if (!is_short) \
+ *(int *) va_arg (ap, void *) = done; \
+ else \
+ *(short int *) va_arg (ap, void *) = done; \
+ } \
+ else \
+ if (is_longlong) \
+ *(long long int *) args_value[fspec->data_arg].pa_pointer = done; \
+ else if (is_long_num) \
+ *(long int *) args_value[fspec->data_arg].pa_pointer = done; \
+ else if (!is_short) \
+ *(int *) args_value[fspec->data_arg].pa_pointer = done; \
+ else \
+ *(short int *) args_value[fspec->data_arg].pa_pointer = done; \
+ break; \
+ \
+ LABEL (form_strerror): \
+ /* Print description of error ERRNO. */ \
+ string = \
+ (UCHAR_T *) __strerror_r (save_errno, (char *) work_buffer, \
+ sizeof work_buffer); \
+ is_long = 0; /* This is no wide-char string. */ \
+ goto LABEL (print_string)
+
+#ifdef COMPILE_WPRINTF
+# define process_string_arg(fspec) \
+ LABEL (form_character): \
+ /* Character. */ \
+ if (is_long) \
+ goto LABEL (form_wcharacter); \
+ --width; /* Account for the character itself. */ \
+ if (!left) \
+ PAD (L' '); \
+ if (fspec == NULL) \
+ outchar (btowc ((unsigned char) va_arg (ap, int))); /* Promoted. */ \
+ else \
+ outchar (btowc ((unsigned char) args_value[fspec->data_arg].pa_char));\
+ if (left) \
+ PAD (L' '); \
+ break; \
+ \
+ LABEL (form_wcharacter): \
+ { \
+ /* Wide character. */ \
+ --width; \
+ if (!left) \
+ PAD (L' '); \
+ if (fspec == NULL) \
+ outchar (va_arg (ap, wint_t)); \
+ else \
+ outchar (args_value[fspec->data_arg].pa_wchar); \
+ if (left) \
+ PAD (L' '); \
+ } \
+ break; \
+ \
+ LABEL (form_string): \
+ { \
+ size_t len; \
+ \
+ /* The string argument could in fact be `char *' or `wchar_t *'. \
+ But this should not make a difference here. */ \
+ if (fspec == NULL) \
+ string = (UCHAR_T *) va_arg (ap, const wchar_t *); \
+ else \
+ string = (UCHAR_T *) args_value[fspec->data_arg].pa_wstring; \
+ \
+ /* Entry point for printing other strings. */ \
+ LABEL (print_string): \
+ \
+ if (string == NULL) \
+ { \
+ /* Write "(null)" if there's space. */ \
+ if (prec == -1 \
+ || prec >= (int) (sizeof (null) / sizeof (null[0])) - 1) \
+ { \
+ string = (UCHAR_T *) null; \
+ len = (sizeof (null) / sizeof (null[0])) - 1; \
+ } \
+ else \
+ { \
+ string = (UCHAR_T *) L""; \
+ len = 0; \
+ } \
+ } \
+ else if (!is_long && spec != L_('S')) \
+ { \
+ /* This is complicated. We have to transform the multibyte \
+ string into a wide character string. */ \
+ const char *mbs = (const char *) string; \
+ mbstate_t mbstate; \
+ \
+ len = prec == -1 ? strnlen (mbs, prec) : strlen (mbs); \
+ \
+ /* Allocate dynamically an array which definitely is long \
+ enough for the wide character version. */ \
+ string = (UCHAR_T *) alloca ((len + 1) * sizeof (wchar_t)); \
+ \
+ memset (&mbstate, '\0', sizeof (mbstate_t)); \
+ len = __mbsrtowcs ((wchar_t *) string, &mbs, len + 1, &mbstate); \
+ if (len == (size_t) -1) \
+ { \
+ /* Illegal multibyte character. */ \