📄 vfnprintf.cxx
字号:
/* FALLTHROUGH */ case '-': flags |= LADJUST; goto rflag; case '+': sign = '+'; goto rflag; case '.': if ((ch = *fmt++) == '*') { x = va_arg(arg, int); prec = x < 0 ? -1 : x; goto rflag; } x = 0; while (is_digit(ch)) { x = 10 * x + to_digit(ch); ch = *fmt++; } prec = x < 0 ? -1 : x; goto reswitch; case '0': /* * ``Note that 0 is taken as a flag, not as the * beginning of a field width.'' * -- ANSI X3J11 */ flags |= ZEROPAD; goto rflag; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': x = 0; do { x = 10 * x + to_digit(ch); ch = *fmt++; } while (is_digit(ch)); width = x; goto reswitch;#ifdef CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT case 'L': flags |= LONGDBL; goto rflag;#endif case 'h': flags |= SHORTINT; goto rflag; case 'l': if (*fmt == 'l') { fmt++; flags |= QUADINT; } else { flags |= LONGINT; } goto rflag; case 'q': flags |= QUADINT; goto rflag; case 'c': *(cp = buf) = va_arg(arg, int); size = 1; sign = '\0'; break; case 'D': flags |= LONGINT; /*FALLTHROUGH*/ case 'd': case 'i': _uquad = SARG();#ifndef _NO_LONGLONG if ((quad_t)_uquad < 0)#else if ((long) _uquad < 0)#endif { _uquad = -_uquad; sign = '-'; } base = DEC; goto number;#ifdef CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT case 'e': case 'E': case 'f': case 'g': case 'G': _double = va_arg(arg, double); /* * don't do unrealistic precision; just pad it with * zeroes later, so buffer size stays rational. */ if (prec > MAXFRACT) { if ((ch != 'g' && ch != 'G') || (flags&ALT)) fpprec = prec - MAXFRACT; prec = MAXFRACT; } else if (prec == -1) prec = DEFPREC; /* * cvt may have to round up before the "start" of * its buffer, i.e. ``intf("%.2f", (double)9.999);''; * if the first character is still NUL, it did. * softsign avoids negative 0 if _double < 0 but * no significant digits will be shown. */ cp = buf; *cp = '\0'; size = cvt(_double, prec, flags, &softsign, ch, cp, buf + sizeof(buf)); if (softsign) sign = '-'; if (*cp == '\0') cp++; break;#else case 'e': case 'E': case 'f': case 'g': case 'G': // Output nothing at all (void) va_arg(arg, double); // take off arg anyway cp = ""; size = 0; sign = '\0'; break; #endif // ifdef CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT case 'n':#ifndef _NO_LONGLONG if (flags & QUADINT) *va_arg(arg, quad_t *) = ret; else #endif if (flags & LONGINT) *va_arg(arg, long *) = ret; else if (flags & SHORTINT) *va_arg(arg, short *) = ret; else *va_arg(arg, int *) = ret; continue; /* no output */ case 'O': flags |= LONGINT; /*FALLTHROUGH*/ case 'o': _uquad = UARG(); base = OCT; goto nosign; case 'p': /* * ``The argument shall be a pointer to void. The * value of the pointer is converted to a sequence * of printable characters, in an implementation- * defined manner.'' * -- ANSI X3J11 */ /* NOSTRICT */ _uquad = (unsigned long)va_arg(arg, void *); base = HEX; xdigs = "0123456789abcdef"; flags |= HEXPREFIX; ch = 'x'; goto nosign; case 's': if ((cp = va_arg(arg, char *)) == NULL) cp = "(null)"; if (prec >= 0) { /* * can't use strlen; can only look for the * NUL in the first `prec' characters, and * strlen() will go further. */ char *p = (char *)_memchr(cp, 0, prec); if (p != NULL) { size = p - cp; if (size > prec) size = prec; } else size = prec; } else size = _strlen(cp); sign = '\0'; break; case 'U': flags |= LONGINT; /*FALLTHROUGH*/ case 'u': _uquad = UARG(); base = DEC; goto nosign; case 'X': xdigs = "0123456789ABCDEF"; goto hex; case 'x': xdigs = "0123456789abcdef";hex: _uquad = UARG(); base = HEX; /* leading 0x/X only if non-zero */ if (flags & ALT && _uquad != 0) flags |= HEXPREFIX; /* unsigned conversions */nosign: sign = '\0'; /* * ``... diouXx conversions ... if a precision is * specified, the 0 flag will be ignored.'' * -- ANSI X3J11 */number: if ((dprec = prec) >= 0) flags &= ~ZEROPAD; /* * ``The result of converting a zero value with an * explicit precision of zero is no characters.'' * -- ANSI X3J11 */ cp = buf + BUF; if (_uquad != 0 || prec != 0) { /* * Unsigned mod is hard, and unsigned mod * by a constant is easier than that by * a variable; hence this switch. */ switch (base) { case OCT: do { *--cp = to_char(_uquad & 7); _uquad >>= 3; } while (_uquad); /* handle octal leading 0 */ if (flags & ALT && *cp != '0') *--cp = '0'; break; case DEC: /* many numbers are 1 digit */ while (_uquad >= 10) { *--cp = to_char(_uquad % 10); _uquad /= 10; } *--cp = to_char(_uquad); break; case HEX: do { *--cp = xdigs[_uquad & 15]; _uquad >>= 4; } while (_uquad); break; default: cp = "bug in vfprintf: bad base"; size = _strlen(cp); goto skipsize; } } size = buf + BUF - cp; skipsize: break; default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') goto done; /* pretend it was %c with argument ch */ cp = buf; *cp = ch; size = 1; sign = '\0'; break; } /* * All reasonable formats wind up here. At this point, `cp' * points to a string which (if not flags&LADJUST) should be * padded out to `width' places. If flags&ZEROPAD, it should * first be prefixed by any sign or other prefix; otherwise, * it should be blank padded before the prefix is emitted. * After any left-hand padding and prefixing, emit zeroes * required by a decimal [diouxX] precision, then print the * string proper, then emit zeroes required by any leftover * floating precision; finally, if LADJUST, pad with blanks. * * Compute actual size, so we know how much to pad. * fieldsz excludes decimal prec; realsz includes it. */#ifdef CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT fieldsz = size + fpprec;#else fieldsz = size;#endif if (sign) fieldsz++; else if (flags & HEXPREFIX) fieldsz+= 2; realsz = dprec > fieldsz ? dprec : fieldsz; /* right-adjusting blank padding */ if ((flags & (LADJUST|ZEROPAD)) == 0) PAD(width - realsz, blanks); /* prefix */ if (sign) { PRINT(&sign, 1); } else if (flags & HEXPREFIX) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -