📄 vfprintf.c
字号:
.left = left, \ .showsign = showsign, \ .group = group, \ .pad = pad, \ .extra = 0, \ .i18n = use_outdigits, \ .wide = sizeof (CHAR_T) != 1 }; \ \ if (is_long_double) \ the_arg.pa_long_double = va_arg (ap, long double); \ else \ the_arg.pa_double = va_arg (ap, double); \ ptr = (const void *) &the_arg; \ \ function_done = __printf_fp (s, &info, &ptr); \ } \ else \ { \ ptr = (const void *) &args_value[fspec->data_arg]; \ \ function_done = __printf_fp (s, &fspec->info, &ptr); \ } \ \ if (function_done < 0) \ { \ /* Error in print handler. */ \ done = -1; \ goto all_done; \ } \ \ done += function_done; \ } \ break; \ \ LABEL (form_floathex): \ { \ /* Floating point number printed as hexadecimal number. */ \ const void *ptr; \ int function_done; \ \ if (fspec == NULL) \ { \ 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, \ .wide = sizeof (CHAR_T) != 1 }; \ \ if (is_long_double) \ the_arg.pa_long_double = va_arg (ap, long double); \ else \ the_arg.pa_double = va_arg (ap, double); \ ptr = (const void *) &the_arg; \ \ function_done = __printf_fphex (s, &info, &ptr); \ } \ else \ { \ ptr = (const void *) &args_value[fspec->data_arg]; \ \ function_done = __printf_fphex (s, &fspec->info, &ptr); \ } \ \ if (function_done < 0) \ { \ /* Error in print handler. */ \ done = -1; \ goto all_done; \ } \ \ done += function_done; \ } \ 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 = L_('x'); \ goto LABEL (number); \ } \ else \ { \ /* Write "(nil)" for a nil pointer. */ \ string = (CHAR_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): \ if (s->_flags2 & _IO_FLAGS2_FORTIFY) \ { \ if (! readonly_format) \ { \ extern int __readonly_area (const void *, size_t) \ attribute_hidden; \ readonly_format \ = __readonly_area (format, ((STR_LEN (format) + 1) \ * sizeof (CHAR_T))); \ } \ if (readonly_format < 0) \ __libc_fatal ("*** %n in writable segment detected ***\n"); \ } \ /* 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_char) \ *(char *) 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_char) \ *(char *) 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 = \ (CHAR_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_int)); \ if (left) \ PAD (L' '); \ break; \ \ LABEL (form_wcharacter): \ { \ /* Wide character. */ \ --width; \ if (!left) \ PAD (L' '); \ if (fspec == NULL) \ outchar (va_arg (ap, wchar_t)); \ else \ outchar (args_value[fspec->data_arg].pa_wchar); \ if (left) \ PAD (L' '); \ } \ break; \ \ LABEL (form_string): \ { \ size_t len; \ int string_malloced; \ \ /* The string argument could in fact be `char *' or `wchar_t *'. \ But this should not make a difference here. */ \ if (fspec == NULL) \ string = (CHAR_T *) va_arg (ap, const wchar_t *); \ else \ string = (CHAR_T *) args_value[fspec->data_arg].pa_wstring; \ \ /* Entry point for printing other strings. */ \ LABEL (print_string): \ \ string_malloced = 0; \ if (string == NULL) \ { \ /* Write "(null)" if there's space. */ \ if (prec == -1 \ || prec >= (int) (sizeof (null) / sizeof (null[0])) - 1) \ { \ string = (CHAR_T *) null; \ len = (sizeof (null) / sizeof (null[0])) - 1; \ } \ else \ { \ string = (CHAR_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 ? (size_t) prec : strlen (mbs); \ \ /* Allocate dynamically an array which definitely is long \ 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))) \ == NULL) \ { \ done = -1; \ goto all_done; \ } \ else \ string_malloced = 1; \ \ memset (&mbstate, '\0', sizeof (mbstate_t)); \ len = __mbsrtowcs (string, &mbs, len, &mbstate); \ if (len == (size_t) -1) \ { \ /* Illegal multibyte character. */ \ done = -1; \ goto all_done; \ } \ } \ else \ { \ if (prec != -1) \ /* Search for the end of the string, but don't search past \ the length specified by the precision. */ \ len = __wcsnlen (string, prec); \ else \ len = __wcslen (string); \ } \ \ if ((width -= len) < 0) \ { \ outstring (string, len); \ break; \ } \ \ if (!left) \ PAD (L' '); \ outstring (string, len); \ if (left) \ PAD (L' '); \ if (__builtin_expect (string_malloced, 0)) \ free (string); \ } \ break;#else# 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 (' '); \ if (fspec == NULL) \ outchar ((unsigned char) va_arg (ap, int)); /* Promoted. */ \ else \ outchar ((unsigned char) args_value[fspec->data_arg].pa_int); \ if (left) \ PAD (' '); \ break; \ \ LABEL (form_wcharacter): \ { \ /* Wide character. */ \ char buf[MB_CUR_MAX]; \ mbstate_t mbstate; \ size_t len; \ \ memset (&mbstate, '\0', sizeof (mbstate_t)); \ len = __wcrtomb (buf, (fspec == NULL ? va_arg (ap, wchar_t) \ : args_value[fspec->data_arg].pa_wchar), \ &mbstate); \ if (len == (size_t) -1) \ { \ /* Something went wron gduring the conversion. Bail out. */ \ done = -1; \ goto all_done; \ } \ width -= len; \ if (!left) \ PAD (' '); \ outstring (buf, len); \ if (left) \ PAD (' '); \ } \ break; \ \ LABEL (form_string): \ { \ size_t len; \ int string_malloced; \ \ /* The string argument could in fact be `char *' or `wchar_t *'. \ But this should not make a difference here. */ \ if (fspec == NULL) \ string = (char *) va_arg (ap, const char *); \ else \ string = (char *) args_value[fspec->data_arg].pa_string; \ \ /* Entry point for printing other strings. */ \ LABEL (print_string): \ \ string_malloced = 0; \ if (string == NULL) \ { \ /* Write "(null)" if there's space. */ \ if (prec == -1 || prec >= (int) sizeof (null) - 1) \ { \ string = (char *) null; \ len = sizeof (null) - 1; \ } \ else \ { \ string = (char *) ""; \ len = 0; \ } \ } \ else if (!is_long && spec != L_('S')) \ { \ if (prec != -1) \ { \ /* Search for the end of the string, but don't search past \ the length (in bytes) specified by the precision. Also \ don't use incomplete characters. */ \ if (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MB_CUR_MAX) == 1) \ len = __strnlen (string, prec); \ else \ { \ /* In case we have a multibyte character set the \ situation is more compilcated. We must not copy \ bytes at the end which form an incomplete character. */\ wchar_t ignore[prec]; \ const char *str2 = string; \ mbstate_t ps; \ \ 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); \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -