diff options
| author | Ulrich Drepper <drepper@redhat.com> | 1999-06-16 22:55:47 +0000 |
|---|---|---|
| committer | Ulrich Drepper <drepper@redhat.com> | 1999-06-16 22:55:47 +0000 |
| commit | d64b6ad07585b8a37e5fecc9a47fcee766d52ede (patch) | |
| tree | 076b36cc9c1b82254348212e75939d842885563a /stdio-common/vfprintf.c | |
| parent | bc938d3de936a8e429b16237180c046139be8247 (diff) | |
| download | glibc-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.c | 585 |
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. */ \ |
