int vfprintf (FILE *s, const CHAR_T *format, va_list ap, unsigned int mode_flags) { THOUSANDS_SEP_T thousands_sep = 0; const char *grouping; int done; const UCHAR_T *f; const UCHAR_T *lead_str_end; const UCHAR_T *end_of_spec; CHAR_T work_buffer[WORK_BUFFER_SIZE]; CHAR_T *workend; va_list ap_save; int nspecs_done; int save_errno = errno;
int readonly_format = 0; #ifdef ORIENT ORIENT; #endif ARGCHECK (s, format); #ifdef ORIENT if (_IO_vtable_offset (s) == 0 && _IO_fwide (s, sizeof (CHAR_T) == 1 ? -1 : 1) != (sizeof (CHAR_T) == 1 ? -1 : 1)) return EOF; #endif if (UNBUFFERED_P (s))
return buffered_vfprintf (s, format, ap, mode_flags); done = 0; grouping = (const char *) -1; #ifdef __va_copy
__va_copy (ap_save, ap); #else ap_save = ap; #endif nspecs_done = 0; #ifdef COMPILE_WPRINTF f = lead_str_end = __find_specwc ((const UCHAR_T *) format); #else f = lead_str_end = __find_specmb ((const UCHAR_T *) format); #endif _IO_cleanup_region_start ((void (*) (void *)) &_IO_funlockfile, s); _IO_flockfile (s); outstring ((const UCHAR_T *) format, lead_str_end - (const UCHAR_T *) format); if (*f == L_('\0')) goto all_done; if (__glibc_unlikely (__printf_function_table != NULL || __printf_modifier_table != NULL || __printf_va_arg_table != NULL)) goto do_positional; do { STEP0_3_TABLE; STEP4_TABLE; int is_negative; union { unsigned long long int longlong; unsigned long int word; } number; int base; union printf_arg the_arg; CHAR_T *string; int alt = 0; int space = 0; int left = 0; int showsign = 0; int group = 0;
int is_long_double __attribute__ ((unused)) = 0; int is_short = 0; int is_long = 0; int is_char = 0; int width = 0; int prec = -1;
int use_outdigits = 0; UCHAR_T pad = L_(' '); CHAR_T spec; workend = work_buffer + WORK_BUFFER_SIZE; JUMP (*++f, step0_jumps); LABEL (flag_space): space = 1; JUMP (*++f, step0_jumps); LABEL (flag_plus): showsign = 1; JUMP (*++f, step0_jumps); LABEL (flag_minus): left = 1; pad = L_(' '); JUMP (*++f, step0_jumps); LABEL (flag_hash): alt = 1; JUMP (*++f, step0_jumps); LABEL (flag_zero): if (!left) pad = L_('0'); JUMP (*++f, step0_jumps); LABEL (flag_quote): group = 1; if (grouping == (const char *) -1) { #ifdef COMPILE_WPRINTF thousands_sep = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC); #else thousands_sep = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP); #endif grouping = _NL_CURRENT (LC_NUMERIC, GROUPING); if (*grouping == '\0' || *grouping == CHAR_MAX #ifdef COMPILE_WPRINTF || thousands_sep == L'\0' #else || *thousands_sep == '\0' #endif ) grouping = NULL; } JUMP (*++f, step0_jumps); LABEL (flag_i18n): use_outdigits = 1; JUMP (*++f, step0_jumps); LABEL (width_asterics): { const UCHAR_T *tmp; tmp = ++f; if (ISDIGIT (*tmp)) { int pos = read_int (&tmp); if (pos == -1) { __set_errno (EOVERFLOW); done = -1; goto all_done; } if (pos && *tmp == L_('$')) goto do_positional; } width = va_arg (ap, int); if (width < 0) { width = -width; pad = L_(' '); left = 1; } } JUMP (*f, step1_jumps); LABEL (width): width = read_int (&f); if (__glibc_unlikely (width == -1)) { __set_errno (EOVERFLOW); done = -1; goto all_done; } if (*f == L_('$')) goto do_positional; JUMP (*f, step1_jumps); LABEL (precision): ++f; if (*f == L_('*')) { const UCHAR_T *tmp; tmp = ++f; if (ISDIGIT (*tmp)) { int pos = read_int (&tmp); if (pos == -1) { __set_errno (EOVERFLOW); done = -1; goto all_done; } if (pos && *tmp == L_('$')) goto do_positional; } prec = va_arg (ap, int); if (prec < 0) prec = -1; } else if (ISDIGIT (*f)) { prec = read_int (&f);
if (prec == -1) { __set_errno (EOVERFLOW); done = -1; goto all_done; } } else prec = 0; JUMP (*f, step2_jumps); LABEL (mod_half): is_short = 1; JUMP (*++f, step3a_jumps); LABEL (mod_halfhalf): is_short = 0; is_char = 1; JUMP (*++f, step4_jumps); LABEL (mod_long): is_long = 1; JUMP (*++f, step3b_jumps);
LABEL (mod_longlong): is_long_double = 1; is_long = 1; JUMP (*++f, step4_jumps); LABEL (mod_size_t): is_long_double = sizeof (size_t) > sizeof (unsigned long int); is_long = sizeof (size_t) > sizeof (unsigned int); JUMP (*++f, step4_jumps); LABEL (mod_ptrdiff_t): is_long_double = sizeof (ptrdiff_t) > sizeof (unsigned long int); is_long = sizeof (ptrdiff_t) > sizeof (unsigned int); JUMP (*++f, step4_jumps); LABEL (mod_intmax_t): is_long_double = sizeof (intmax_t) > sizeof (unsigned long int); is_long = sizeof (intmax_t) > sizeof (unsigned int); JUMP (*++f, step4_jumps); while (1) { #define process_arg_int() va_arg (ap, int) #define process_arg_long_int() va_arg (ap, long int) #define process_arg_long_long_int() va_arg (ap, long long int) #define process_arg_pointer() va_arg (ap, void *) #define process_arg_string() va_arg (ap, const char *) #define process_arg_unsigned_int() va_arg (ap, unsigned int) #define process_arg_unsigned_long_int() va_arg (ap, unsigned long int) #define process_arg_unsigned_long_long_int() va_arg (ap, unsigned long long int) #define process_arg_wchar_t() va_arg (ap, wchar_t) #define process_arg_wstring() va_arg (ap, const wchar_t *) process_arg (); process_string_arg (); #undef process_arg_int #undef process_arg_long_int #undef process_arg_long_long_int #undef process_arg_pointer #undef process_arg_string #undef process_arg_unsigned_int #undef process_arg_unsigned_long_int #undef process_arg_unsigned_long_long_int #undef process_arg_wchar_t #undef process_arg_wstring LABEL (form_float): LABEL (form_floathex): { if (__glibc_unlikely ((mode_flags & PRINTF_LDBL_IS_DBL) != 0)) is_long_double = 0; struct printf_info info = { .prec = prec, .width = width, .spec = spec, .is_long_double = is_long_double, .is_short = is_short, .is_long = is_long, .alt = alt, .space = space, .left = left, .showsign = showsign, .group = group, .pad = pad, .extra = 0, .i18n = use_outdigits, .wide = sizeof (CHAR_T) != 1, .is_binary128 = 0 }; PARSE_FLOAT_VA_ARG_EXTENDED (info); const void *ptr = &the_arg; int function_done = __printf_fp_spec (s, &info, &ptr); if (function_done < 0) { done = -1; goto all_done; } done_add (function_done); } break; LABEL (form_unknown): if (spec == L_('\0')) { __set_errno (EINVAL); done = -1; goto all_done; }
goto do_positional; } ++nspecs_done; #ifdef COMPILE_WPRINTF f = __find_specwc ((end_of_spec = ++f)); #else f = __find_specmb ((end_of_spec = ++f)); #endif outstring (end_of_spec, f - end_of_spec); } while (*f != L_('\0')); goto all_done; do_positional: done = printf_positional (s, format, readonly_format, ap, &ap_save, done, nspecs_done, lead_str_end, work_buffer, save_errno, grouping, thousands_sep, mode_flags); all_done: _IO_funlockfile (s); _IO_cleanup_region_end (0); return done; }
|