63 #include <sys/types.h>
64 #define u_long unsigned long
65 #define u_short unsigned short
66 #define u_int unsigned int
68 #if !defined(HAVE_STDARG_PROTOTYPES)
70 #define HAVE_STDARG_PROTOTYPES 1
75 #if defined(HAVE_STDARG_PROTOTYPES)
88 #define _BSD_VA_LIST_ va_list
99 # define LONG_MAX 2147483647
115 #if SIZEOF_LONG > SIZEOF_INT
127 unsigned char *_base;
173 const char *(*vextra)(
struct __sFILE*, size_t,
void*,
long*, int);
177 #define __SLBF 0x0001
178 #define __SNBF 0x0002
183 #define __SEOF 0x0020
184 #define __SERR 0x0040
185 #define __SMBF 0x0080
186 #define __SAPP 0x0100
187 #define __SSTR 0x0200
188 #define __SOPT 0x0400
189 #define __SNPT 0x0800
190 #define __SOFF 0x1000
191 #define __SMOD 0x2000
197 #define BSD__sfeof(p) (((p)->_flags & __SEOF) != 0)
198 #define BSD__sferror(p) (((p)->_flags & __SERR) != 0)
199 #define BSD__sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF)))
200 #define BSD__sfileno(p) ((p)->_file)
205 #define feof(p) BSD__sfeof(p)
206 #define ferror(p) BSD__sferror(p)
207 #define clearerr(p) BSD__sclearerr(p)
210 #define fileno(p) BSD__sfileno(p)
218 const void *iov_base;
234 BSD__sfvwrite(
register FILE *fp,
register struct __suio *uio)
237 register const char *p;
238 register struct __siov *iov;
241 if ((
len = uio->uio_resid) == 0)
243 #define MIN(a, b) ((a) < (b) ? (a) : (b))
244 #define COPY(n) (void)memcpy((void *)fp->_p, (void *)p, (size_t)(n))
250 #define GETIOV(extra_work) \
254 len = iov->iov_len; \
257 if (fp->_flags & __SNBF) {
261 }
else if ((fp->_flags & __SLBF) == 0) {
276 if (fp->_flags & __SSTR) {
290 }
while ((uio->uio_resid -= w) != 0);
310 BSD__sprint(
FILE *fp,
register struct __suio *uio)
314 if (uio->uio_resid == 0) {
318 err = (*fp->vwrite)(fp, uio);
331 BSD__sbprintf(
register FILE *fp,
const char *fmt, va_list ap)
341 #define to_digit(c) ((c) - '0')
342 #define is_digit(c) ((unsigned)to_digit(c) <= 9)
343 #define to_char(n) (char)((n) + '0')
345 #ifdef _HAVE_SANE_QUAD_
353 BSD__uqtoa(
register u_quad_t val,
char *endp,
int base,
int octzero,
const char *xdigs)
355 register char *cp = endp;
356 register quad_t sval;
365 *--cp = to_char(val);
374 if (val > LLONG_MAX) {
375 *--cp = to_char(val % 10);
380 *--cp = to_char(sval % 10);
387 *--cp = to_char(val & 7);
390 if (octzero && *cp !=
'0')
396 *--cp = xdigs[val & 15];
418 BSD__ultoa(
register u_long val,
char *endp,
int base,
int octzero,
const char *xdigs)
420 register char *cp = endp;
430 *--cp = to_char(val);
439 if (val > LONG_MAX) {
440 *--cp = to_char(val % 10);
445 *--cp = to_char(sval % 10);
452 *--cp = to_char(val & 7);
455 if (octzero && *cp !=
'0')
461 *--cp = xdigs[val & 15];
475 #ifdef FLOATING_POINT
481 # if DBL_MAX_10_EXP > -DBL_MIN_10_EXP
482 # define MAXEXP (DBL_MAX_10_EXP)
484 # define MAXEXP (-DBL_MIN_10_EXP)
489 # define MAXFRACT (MAXEXP*10/3)
492 #define BUF (MAXEXP+MAXFRACT+1)
495 static char *cvt(
double,
int,
int,
char *,
int *,
int,
int *,
char *);
496 static int exponent(
char *,
int,
int);
504 #ifndef lower_hexdigits
505 # define lower_hexdigits "0123456789abcdef"
507 #ifndef upper_hexdigits
508 # define upper_hexdigits "0123456789ABCDEF"
515 #define HEXPREFIX 0x002
516 #define LADJUST 0x004
517 #define LONGDBL 0x008
518 #define LONGINT 0x010
520 #ifdef _HAVE_SANE_QUAD_
521 #define QUADINT 0x020
524 #define SHORTINT 0x040
525 #define ZEROPAD 0x080
527 ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(
static ssize_t BSD_vfprintf(
FILE *fp,
const char *fmt0, va_list ap));
529 BSD_vfprintf(
FILE *fp,
const char *fmt0, va_list ap)
531 #ifdef PRI_EXTRA_MARK
532 const int PRI_EXTRA_MARK_LEN =
rb_strlen_lit(PRI_EXTRA_MARK);
534 register const char *fmt;
537 register const char *cp;
538 register struct __siov *iovp;
544 #ifdef FLOATING_POINT
553 u_long MAYBE_UNUSED(ulval) = 0;
554 #ifdef _HAVE_SANE_QUAD_
555 u_quad_t MAYBE_UNUSED(uqval) = 0;
562 const char *xdigs = 0;
568 char *
const ebuf = buf +
sizeof(buf);
569 #if SIZEOF_LONG > SIZEOF_INT
579 static const char blanks[PADSIZE] =
580 {
' ',
' ',
' ',
' ',
' ',
' ',
' ',
' ',
' ',
' ',
' ',
' ',
' ',
' ',
' ',
' '};
581 static const char zeroes[PADSIZE] =
582 {
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0'};
587 #define PRINT(ptr, len) { \
588 iovp->iov_base = (ptr); \
589 iovp->iov_len = (len); \
590 uio.uio_resid += (len); \
592 if (++uio.uio_iovcnt >= NIOV) { \
593 if (BSD__sprint(fp, &uio)) \
598 #define PAD(howmany, with) { \
599 if ((n = (howmany)) > 0) { \
600 while (n > PADSIZE) { \
601 PRINT((with), PADSIZE); \
607 #if SIZEOF_LONG > SIZEOF_INT
609 #define PAD_L(howmany, with) { \
611 if ((long)((int)ln) != ln) { \
615 if (ln > 0) PAD((int)ln, (with)); \
618 #define PAD_L(howmany, with) PAD((howmany), (with))
621 if (uio.uio_resid && BSD__sprint(fp, &uio)) \
623 uio.uio_iovcnt = 0; \
632 (flags&LONGINT ? va_arg(ap, long) : \
633 flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
634 (long)va_arg(ap, int))
636 (flags&LONGINT ? va_arg(ap, u_long) : \
637 flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
638 (u_long)va_arg(ap, u_int))
641 if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
643 return (BSD__sbprintf(fp, fmt0, ap));
646 uio.uio_iov = iovp = iov;
657 for (cp = fmt; (ch = *fmt) !=
'\0' && ch !=
'%'; fmt++)
659 if ((nc = fmt - cp) != 0) {
674 reswitch:
switch (ch) {
694 if ((width = va_arg(ap,
int)) >= 0)
705 if ((ch = *fmt++) ==
'*') {
707 prec = n < 0 ? -1 : n;
711 while (is_digit(ch)) {
712 n = 10 * n + to_digit(ch);
715 prec = n < 0 ? -1 : n;
725 case '1':
case '2':
case '3':
case '4':
726 case '5':
case '6':
case '7':
case '8':
case '9':
729 n = 10 * n + to_digit(ch);
731 }
while (is_digit(ch));
734 #ifdef FLOATING_POINT
742 #if SIZEOF_PTRDIFF_T == SIZEOF_LONG
745 #if SIZEOF_SIZE_T == SIZEOF_LONG
749 #ifdef _HAVE_SANE_QUAD_
760 #ifdef _HAVE_SANE_QUAD_
761 #if SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
764 #if SIZEOF_SIZE_T == SIZEOF_LONG_LONG
773 if (*fmt ==
'3' && *(fmt + 1) ==
'2') {
777 #ifdef _HAVE_SANE_QUAD_
778 else if (*fmt ==
'6' && *(fmt + 1) ==
'4') {
784 #if defined(_HAVE_SANE_QUAD_) && SIZEOF_SIZE_T == SIZEOF_LONG_LONG
793 *buf = (char)va_arg(ap,
int);
798 #ifdef _HAVE_SANE_QUAD_
799 # define INTPTR_MASK (QUADINT|LONGINT|SHORTINT)
801 # define INTPTR_MASK (LONGINT|SHORTINT)
803 #if defined _HAVE_SANE_QUAD_ && SIZEOF_VOIDP == SIZEOF_LONG_LONG
804 # define INTPTR_FLAG QUADINT
805 #elif SIZEOF_VOIDP == SIZEOF_LONG
806 # define INTPTR_FLAG LONGINT
808 # define INTPTR_FLAG 0
810 #ifdef PRI_EXTRA_MARK
811 # define IS_PRI_EXTRA_MARK(s) \
812 (PRI_EXTRA_MARK_LEN < 1 || \
813 (*(s) == PRI_EXTRA_MARK[0] && \
814 (PRI_EXTRA_MARK_LEN == 1 || \
815 strncmp((s)+1, &PRI_EXTRA_MARK[1], \
816 PRI_EXTRA_MARK_LEN-1) == 0)))
818 # define PRI_EXTRA_MARK_LEN 0
819 # define IS_PRI_EXTRA_MARK(s) 1
821 if (fp->vextra && (flags & INTPTR_MASK) == INTPTR_FLAG &&
822 IS_PRI_EXTRA_MARK(fmt)) {
823 fmt += PRI_EXTRA_MARK_LEN;
825 #if defined _HAVE_SANE_QUAD_ && SIZEOF_VOIDP == SIZEOF_LONG_LONG
826 uqval = va_arg(ap, u_quad_t);
827 cp = (*fp->vextra)(fp,
sizeof(uqval), &uqval, &fieldsz, sign);
829 ulval = va_arg(ap, u_long);
830 cp = (*fp->vextra)(fp,
sizeof(ulval), &ulval, &fieldsz, sign);
834 if (prec < 0)
goto long_len;
835 size = fieldsz < prec ? (int)fieldsz : prec;
844 #ifdef _HAVE_SANE_QUAD_
845 if (flags & QUADINT) {
846 uqval = va_arg(ap, quad_t);
847 if ((quad_t)uqval < 0) {
848 uqval = -(quad_t)uqval;
855 if ((
long)ulval < 0) {
856 ulval = (u_long)(-(
long)ulval);
862 #ifdef FLOATING_POINT
875 prec = (prec == -1) ?
876 DEFPREC + 1 : (fprec = prec + 1);
888 fp_begin: _double = va_arg(ap,
double);
890 if (isinf(_double)) {
897 if (isnan(_double)) {
903 cp = cvt(_double, (prec < MAXFRACT ? prec : MAXFRACT), flags, &softsign,
904 &expt, ch, &ndig, buf);
905 if (ch ==
'g' || ch ==
'G') {
906 if (expt <= -4 || (expt > prec && expt > 1))
907 ch = (ch ==
'g') ?
'e' :
'E';
911 if (ch ==
'a' || ch ==
'A') {
914 expsize = exponent(expstr, expt, ch +
'p' -
'a');
916 size = expsize + ndig;
917 if (ndig > 1 || flags & ALT)
920 else if (ch <=
'e') {
922 expsize = exponent(expstr, expt, ch);
923 size = expsize + ndig;
924 if (ndig > 1 || flags & ALT)
926 }
else if (ch ==
'f') {
929 if (prec || flags & ALT)
937 }
else if (expt >= ndig) {
942 size = ndig + (expt > 0 ?
950 #ifdef _HAVE_SANE_QUAD_
952 *va_arg(ap, quad_t *) = ret;
953 else if (flags & LONGINT)
957 *va_arg(ap,
long *) = ret;
958 else if (flags & SHORTINT)
959 *va_arg(ap,
short *) = (short)ret;
961 *va_arg(ap,
int *) = (int)ret;
967 #ifdef _HAVE_SANE_QUAD_
969 uqval = va_arg(ap, u_quad_t);
983 prec = (int)(
sizeof(
void*)*CHAR_BIT/4);
985 uqval = (u_quad_t)va_arg(ap,
void *);
986 flags = (flags) | QUADINT | HEXPREFIX;
988 ulval = (u_long)va_arg(ap,
void *);
989 #ifdef _HAVE_SANE_QUAD_
990 flags = (flags & ~QUADINT) | HEXPREFIX;
992 flags = (flags) | HEXPREFIX;
996 xdigs = lower_hexdigits;
1000 if ((cp = va_arg(ap,
char *)) == NULL)
1008 const char *p = (
char *)memchr(cp, 0, prec);
1010 if (p != NULL && (p - cp) < prec)
1011 size = (
int)(p - cp);
1016 fieldsz = strlen(cp);
1025 #ifdef _HAVE_SANE_QUAD_
1026 if (flags & QUADINT)
1027 uqval = va_arg(ap, u_quad_t);
1034 xdigs = upper_hexdigits;
1037 xdigs = lower_hexdigits;
1039 #ifdef _HAVE_SANE_QUAD_
1040 if (flags & QUADINT)
1041 uqval = va_arg(ap, u_quad_t);
1048 #ifdef _HAVE_SANE_QUAD_
1049 (flags & QUADINT ? uqval != 0 : ulval != 0)
1057 nosign: sign =
'\0';
1063 number:
if ((dprec = prec) >= 0)
1072 #ifdef _HAVE_SANE_QUAD_
1073 if (flags & QUADINT) {
1074 if (uqval != 0 || prec != 0)
1075 cp = BSD__uqtoa(uqval, ebuf, base,
1076 flags & ALT, xdigs);
1081 if (ulval != 0 || prec != 0)
1082 cp = BSD__ultoa(ulval, ebuf, base,
1083 flags & ALT, xdigs);
1085 size = (int)(ebuf - cp);
1114 realsz = dprec > fieldsz ? dprec : fieldsz;
1117 if (flags & HEXPREFIX)
1121 if ((flags & (LADJUST|ZEROPAD)) == 0)
1122 PAD_L(width - realsz, blanks);
1128 if (flags & HEXPREFIX) {
1135 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
1136 PAD_L(width - realsz, zeroes);
1139 PAD_L(dprec - fieldsz, zeroes);
1142 #ifdef FLOATING_POINT
1143 if ((flags & FPT) == 0) {
1146 if (flags & HEXPREFIX) {
1147 if (ndig > 1 || flags & ALT) {
1151 if (ndig > 0) PRINT(cp, ndig-1);
1154 PAD(fprec-ndig, zeroes);
1155 PRINT(expstr, expsize);
1157 else if (ch >=
'f') {
1161 (flags & ALT) == 0) {
1165 PAD((ndig >= fprec ? ndig - 1 : fprec - (ch !=
'f')),
1168 }
else if (expt == 0 && ndig == 0 && (flags & ALT) == 0) {
1170 }
else if (expt <= 0) {
1175 PAD(fprec - ndig + (ch ==
'f' ? expt : 0), zeroes);
1176 }
else if (expt >= ndig) {
1178 PAD(expt - ndig, zeroes);
1185 PRINT(cp, ndig-expt);
1187 PAD(fprec - ndig + (ch ==
'f' ? expt : 0), zeroes);
1190 if (ndig > 1 || flags & ALT) {
1198 PAD(ndig - 1, zeroes);
1199 if (flags & ALT) PAD(fprec - ndig - 1, zeroes);
1202 PRINT(expstr, expsize);
1209 if (flags & LADJUST)
1210 PAD_L(width - realsz, blanks);
1213 ret += width > realsz ? width : realsz;
1220 return (BSD__sferror(fp) ? EOF : ret);
1224 #ifdef FLOATING_POINT
1226 extern char *BSD__dtoa(
double,
int,
int,
int *,
int *,
char **);
1227 extern char *BSD__hdtoa(
double,
const char *,
int,
int *,
int *,
char **);
1230 cvt(
double value,
int ndigits,
int flags,
char *sign,
int *decpt,
int ch,
int *length,
char *buf)
1233 char *digits, *bp, *rve;
1243 }
else if (value == 0.0 && signbit(value)) {
1248 if (ch ==
'a' || ch ==
'A') {
1249 digits = BSD__hdtoa(value,
1250 ch ==
'a' ? lower_hexdigits : upper_hexdigits,
1251 ndigits, decpt, &dsgn, &rve);
1254 digits = BSD__dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
1257 memcpy(buf, digits, rve - digits);
1258 rve = buf + (rve - digits);
1262 bp = digits + ndigits;
1264 if (*digits ==
'0' && value)
1265 *decpt = -ndigits + 1;
1271 *length = (int)(rve - digits);
1276 exponent(
char *p0,
int exp,
int fmtch)
1278 register char *p, *t;
1279 char expbuf[2 + (MAXEXP < 1000 ? 3 : MAXEXP < 10000 ? 4 : 5)];
1289 t = expbuf +
sizeof(expbuf);
1292 *--t = to_char(exp % 10);
1293 }
while ((exp /= 10) > 9);
1294 *--t = to_char(exp);
1295 for (; t < expbuf +
sizeof(expbuf); *p++ = *t++);
1298 if (fmtch & 15) *p++ =
'0';
1299 *p++ = to_char(exp);
1301 return (
int)(p - p0);
#define rb_strlen_lit(str)
Length of a string literal.
int len
Length of the buffer.