📄 vfprintf.c
字号:
else \ len = str2 - string - (ps.__count & 7); \ } \ } \ else \ len = strlen (string); \ } \ else \ { \ const wchar_t *s2 = (const wchar_t *) string; \ mbstate_t mbstate; \ \ memset (&mbstate, '\0', sizeof (mbstate_t)); \ \ if (prec >= 0) \ { \ /* The string `s2' might not be NUL terminated. */ \ if (__libc_use_alloca (prec)) \ string = (char *) alloca (prec); \ else if ((string = (char *) malloc (prec)) == NULL) \ { \ done = -1; \ goto all_done; \ } \ else \ string_malloced = 1; \ len = __wcsrtombs (string, &s2, prec, &mbstate); \ } \ else \ { \ len = __wcsrtombs (NULL, &s2, 0, &mbstate); \ if (len != (size_t) -1) \ { \ assert (__mbsinit (&mbstate)); \ s2 = (const wchar_t *) string; \ if (__libc_use_alloca (len + 1)) \ string = (char *) alloca (len + 1); \ else if ((string = (char *) malloc (len + 1)) == NULL) \ { \ done = -1; \ goto all_done; \ } \ else \ string_malloced = 1; \ (void) __wcsrtombs (string, &s2, len + 1, &mbstate); \ } \ } \ \ if (len == (size_t) -1) \ { \ /* Illegal wide-character string. */ \ done = -1; \ goto all_done; \ } \ } \ \ if ((width -= len) < 0) \ { \ outstring (string, len); \ break; \ } \ \ if (!left) \ PAD (' '); \ outstring (string, len); \ if (left) \ PAD (' '); \ if (__builtin_expect (string_malloced, 0)) \ free (string); \ } \ break;#endif /* Orient the stream. */#ifdef ORIENT ORIENT;#endif /* Sanity check of arguments. */ ARGCHECK (s, format);#ifdef ORIENT /* Check for correct orientation. */ if (_IO_vtable_offset (s) == 0 && _IO_fwide (s, sizeof (CHAR_T) == 1 ? -1 : 1) != (sizeof (CHAR_T) == 1 ? -1 : 1)) /* The stream is already oriented otherwise. */ return EOF;#endif if (UNBUFFERED_P (s)) /* Use a helper function which will allocate a local temporary buffer for the stream and then call us again. */ return buffered_vfprintf (s, format, ap); /* Initialize local variables. */ done = 0; grouping = (const char *) -1;#ifdef __va_copy /* This macro will be available soon in gcc's <stdarg.h>. We need it since on some systems `va_list' is not an integral type. */ __va_copy (ap_save, ap);#else ap_save = ap;#endif nspecs_done = 0;#ifdef COMPILE_WPRINTF /* Find the first format specifier. */ f = lead_str_end = __find_specwc ((const UCHAR_T *) format);#else /* Put state for processing format string in initial state. */ memset (&mbstate, '\0', sizeof (mbstate_t)); /* Find the first format specifier. */ f = lead_str_end = __find_specmb (format, &mbstate);#endif /* Lock stream. */ _IO_cleanup_region_start ((void (*) (void *)) &_IO_funlockfile, s); _IO_flockfile (s); /* Write the literal text before the first format. */ outstring ((const UCHAR_T *) format, lead_str_end - (const UCHAR_T *) format); /* If we only have to print a simple string, return now. */ if (*f == L_('\0')) goto all_done; /* Process whole format string. */ do {#if defined HAVE_SUBTRACT_LOCAL_LABELS && defined SHARED# define REF(Name) &&do_##Name - &&do_form_unknown#else# define REF(Name) &&do_##Name#endif#define LABEL(Name) do_##Name STEP0_3_TABLE; STEP4_TABLE; union printf_arg *args_value; /* This is not used here but ... */ int is_negative; /* Flag for negative number. */ union { unsigned long long int longlong; unsigned long int word; } number; int base; union printf_arg the_arg; CHAR_T *string; /* Pointer to argument string. */ int alt = 0; /* Alternate format. */ int space = 0; /* Use space prefix if no sign is needed. */ int left = 0; /* Left-justify output. */ int showsign = 0; /* Always begin with plus or minus sign. */ int group = 0; /* Print numbers according grouping rules. */ int is_long_double = 0; /* Argument is long double/ long long int. */ int is_short = 0; /* Argument is short int. */ int is_long = 0; /* Argument is long int. */ int is_char = 0; /* Argument is promoted (unsigned) char. */ int width = 0; /* Width of output; 0 means none specified. */ int prec = -1; /* Precision of output; -1 means none specified. */ /* This flag is set by the 'I' modifier and selects the use of the `outdigits' as determined by the current locale. */ int use_outdigits = 0; UCHAR_T pad = L_(' ');/* Padding character. */ CHAR_T spec; workstart = NULL; workend = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T)]; /* Get current character in format string. */ JUMP (*++f, step0_jumps); /* ' ' flag. */ LABEL (flag_space): space = 1; JUMP (*++f, step0_jumps); /* '+' flag. */ LABEL (flag_plus): showsign = 1; JUMP (*++f, step0_jumps); /* The '-' flag. */ LABEL (flag_minus): left = 1; pad = L_(' '); JUMP (*++f, step0_jumps); /* The '#' flag. */ LABEL (flag_hash): alt = 1; JUMP (*++f, step0_jumps); /* The '0' flag. */ LABEL (flag_zero): if (!left) pad = L_('0'); JUMP (*++f, step0_jumps); /* The '\'' flag. */ 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); /* Get width from argument. */ LABEL (width_asterics): { const UCHAR_T *tmp; /* Temporary value. */ tmp = ++f; if (ISDIGIT (*tmp) && read_int (&tmp) && *tmp == L_('$')) /* The width comes from a positional parameter. */ goto do_positional; width = va_arg (ap, int); /* Negative width means left justified. */ if (width < 0) { width = -width; pad = L_(' '); left = 1; } if (width + 32 >= (int) (sizeof (work_buffer) / sizeof (work_buffer[0]))) { /* We have to use a special buffer. The "32" is just a safe bet for all the output which is not counted in the width. */ if (__libc_use_alloca ((width + 32) * sizeof (CHAR_T))) workend = ((CHAR_T *) alloca ((width + 32) * sizeof (CHAR_T)) + (width + 32)); else { workstart = (CHAR_T *) malloc ((width + 32) * sizeof (CHAR_T)); if (workstart == NULL) { done = -1; goto all_done; } workend = workstart + (width + 32); } } } JUMP (*f, step1_jumps); /* Given width in format string. */ LABEL (width): width = read_int (&f); if (width + 32 >= (int) (sizeof (work_buffer) / sizeof (work_buffer[0]))) { /* We have to use a special buffer. The "32" is just a safe bet for all the output which is not counted in the width. */ if (__libc_use_alloca ((width + 32) * sizeof (CHAR_T))) workend = ((CHAR_T *) alloca ((width + 32) * sizeof (CHAR_T)) + (width + 32)); else { workstart = (CHAR_T *) malloc ((width + 32) * sizeof (CHAR_T)); if (workstart == NULL) { done = -1; goto all_done; } workend = workstart + (width + 32); } } if (*f == L_('$')) /* Oh, oh. The argument comes from a positional parameter. */ goto do_positional; JUMP (*f, step1_jumps); LABEL (precision): ++f; if (*f == L_('*')) { const UCHAR_T *tmp; /* Temporary value. */ tmp = ++f; if (ISDIGIT (*tmp) && read_int (&tmp) > 0 && *tmp == L_('$')) /* The precision comes from a positional parameter. */ goto do_positional; prec = va_arg (ap, int); /* If the precision is negative the precision is omitted. */ if (prec < 0) prec = -1; } else if (ISDIGIT (*f)) prec = read_int (&f); else prec = 0; if (prec > width && prec + 32 > (int)(sizeof (work_buffer) / sizeof (work_buffer[0]))) { if (__libc_use_alloca ((prec + 32) * sizeof (CHAR_T))) workend = ((CHAR_T *) alloca ((prec + 32) * sizeof (CHAR_T))) + (prec + 32); else { workstart = (CHAR_T *) malloc ((prec + 32) * sizeof (CHAR_T)); if (workstart == NULL) { done = -1; goto all_done; } workend = workstart + (prec + 32); } } JUMP (*f, step2_jumps); /* Process 'h' modifier. There might another 'h' following. */ LABEL (mod_half): is_short = 1; JUMP (*++f, step3a_jumps); /* Process 'hh' modifier. */ LABEL (mod_halfhalf): is_short = 0; is_char = 1; JUMP (*++f, step4_jumps); /* Process 'l' modifier. There might another 'l' following. */ LABEL (mod_long): is_long = 1; JUMP (*++f, step3b_jumps); /* Process 'L', 'q', or 'll' modifier. No other modifier is allowed to follow. */ 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); /* Process current format. */ while (1) { process_arg (((struct printf_spec *) NULL)); process_string_arg (((struct printf_spec *) NULL));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -