* missing/vsnprintf.c (BSD_vfprintf): support for 'z' modifier.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@23509 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2009-05-21 12:07:25 +00:00
parent 8f1f47a072
commit 08732d4f57
2 changed files with 60 additions and 27 deletions

View File

@ -1,3 +1,7 @@
Thu May 21 21:07:22 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
* missing/vsnprintf.c (BSD_vfprintf): support for 'z' modifier.
Thu May 21 18:55:33 2009 Yuki Sonoda (Yugui) <yugui@yugui.jp> Thu May 21 18:55:33 2009 Yuki Sonoda (Yugui) <yugui@yugui.jp>
* gem_prelude.rb (Gem.default_dir and misc.): use rubylibprefix. * gem_prelude.rb (Gem.default_dir and misc.): use rubylibprefix.

View File

@ -223,7 +223,7 @@ struct __siov {
struct __suio { struct __suio {
struct __siov *uio_iov; struct __siov *uio_iov;
int uio_iovcnt; int uio_iovcnt;
int uio_resid; size_t uio_resid;
}; };
#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_SNPRINTF) #if !defined(HAVE_VSNPRINTF) || !defined(HAVE_SNPRINTF)
@ -520,7 +520,7 @@ static int exponent __P((char *, int, int));
#define SHORTINT 0x040 /* short integer */ #define SHORTINT 0x040 /* short integer */
#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ #define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
#define FPT 0x100 /* Floating point number */ #define FPT 0x100 /* Floating point number */
static int static ssize_t
BSD_vfprintf(FILE *fp, const char *fmt0, va_list ap) BSD_vfprintf(FILE *fp, const char *fmt0, va_list ap)
{ {
register const char *fmt; /* format string */ register const char *fmt; /* format string */
@ -529,7 +529,7 @@ BSD_vfprintf(FILE *fp, const char *fmt0, va_list ap)
register const char *cp;/* handy char pointer (short term usage) */ register const char *cp;/* handy char pointer (short term usage) */
register struct __siov *iovp;/* for PRINT macro */ register struct __siov *iovp;/* for PRINT macro */
register int flags; /* flags as above */ register int flags; /* flags as above */
int ret; /* return value accumulator */ ssize_t ret; /* return value accumulator */
int width; /* width from format (%8d), or 0 */ int width; /* width from format (%8d), or 0 */
int prec; /* precision from format (%.3d), or -1 */ int prec; /* precision from format (%.3d), or -1 */
char sign; /* sign prefix (' ', '+', '-', or \0) */ char sign; /* sign prefix (' ', '+', '-', or \0) */
@ -547,8 +547,8 @@ BSD_vfprintf(FILE *fp, const char *fmt0, va_list ap)
#endif /* _HAVE_SANE_QUAD_ */ #endif /* _HAVE_SANE_QUAD_ */
int base; /* base for [diouxX] conversion */ int base; /* base for [diouxX] conversion */
int dprec; /* a copy of prec if [diouxX], 0 otherwise */ int dprec; /* a copy of prec if [diouxX], 0 otherwise */
int fieldsz; /* field size expanded by sign, etc */ long fieldsz; /* field size expanded by sign, etc */
int realsz; /* field size expanded by dprec */ long realsz; /* field size expanded by dprec */
int size; /* size of converted field or string */ int size; /* size of converted field or string */
const char *xdigs = 0; /* digits for [xX] conversion */ const char *xdigs = 0; /* digits for [xX] conversion */
#define NIOV 8 #define NIOV 8
@ -557,6 +557,9 @@ BSD_vfprintf(FILE *fp, const char *fmt0, va_list ap)
char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */ char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */
char ox[2]; /* space for 0x hex-prefix */ char ox[2]; /* space for 0x hex-prefix */
char *const ebuf = buf + sizeof(buf); char *const ebuf = buf + sizeof(buf);
#if SIZEOF_LONG > SIZEOF_INT
long ln;
#endif
/* /*
* Choose PADSIZE to trade efficiency vs. size. If larger printf * Choose PADSIZE to trade efficiency vs. size. If larger printf
@ -592,6 +595,19 @@ BSD_vfprintf(FILE *fp, const char *fmt0, va_list ap)
PRINT(with, n); \ PRINT(with, n); \
} \ } \
} }
#if SIZEOF_LONG > SIZEOF_INT
/* abandon if too larger padding */
#define PAD_L(howmany, with) { \
ln = (howmany);
if ((long)((int)ln) != ln) { \
errno = ENOMEM; \
goto error; \
} \
if (ln > 0) PAD((int)ln, with); \
}
#else
#define PAD_L(howmany, with) PAD(howmany, with)
#endif
#define FLUSH() { \ #define FLUSH() { \
if (uio.uio_resid && BSD__sprint(fp, &uio)) \ if (uio.uio_resid && BSD__sprint(fp, &uio)) \
goto error; \ goto error; \
@ -628,11 +644,12 @@ BSD_vfprintf(FILE *fp, const char *fmt0, va_list ap)
* Scan the format for conversions (`%' character). * Scan the format for conversions (`%' character).
*/ */
for (;;) { for (;;) {
size_t nc;
for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
/* void */; /* void */;
if ((n = fmt - cp) != 0) { if ((nc = fmt - cp) != 0) {
PRINT(cp, n); PRINT(cp, nc);
ret += n; ret += nc;
} }
if (ch == '\0') if (ch == '\0')
goto done; goto done;
@ -715,6 +732,9 @@ reswitch: switch (ch) {
goto rflag; goto rflag;
#if SIZEOF_PTRDIFF_T == SIZEOF_LONG #if SIZEOF_PTRDIFF_T == SIZEOF_LONG
case 't': case 't':
#endif
#if SIZEOF_SIZE_T == SIZEOF_LONG
case 'z':
#endif #endif
case 'l': case 'l':
flags |= LONGINT; flags |= LONGINT;
@ -722,6 +742,9 @@ reswitch: switch (ch) {
#ifdef _HAVE_SANE_QUAD_ #ifdef _HAVE_SANE_QUAD_
#if SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG #if SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
case 't': case 't':
#endif
#if SIZEOF_SIZE_T == SIZEOF_LONG_LONG
case 'z':
#endif #endif
case 'q': case 'q':
flags |= QUADINT; flags |= QUADINT;
@ -832,9 +855,9 @@ fp_begin: _double = va_arg(ap, double);
#endif /* _HAVE_SANE_QUAD_ */ #endif /* _HAVE_SANE_QUAD_ */
*va_arg(ap, long *) = ret; *va_arg(ap, long *) = ret;
else if (flags & SHORTINT) else if (flags & SHORTINT)
*va_arg(ap, short *) = ret; *va_arg(ap, short *) = (short)ret;
else else
*va_arg(ap, int *) = ret; *va_arg(ap, int *) = (int)ret;
continue; /* no output */ continue; /* no output */
case 'O': case 'O':
flags |= LONGINT; flags |= LONGINT;
@ -856,7 +879,7 @@ fp_begin: _double = va_arg(ap, double);
* defined manner.'' * defined manner.''
* -- ANSI X3J11 * -- ANSI X3J11
*/ */
prec = sizeof(void*)*CHAR_BIT/4; prec = (int)(sizeof(void*)*CHAR_BIT/4);
#ifdef _HAVE_LLP64_ #ifdef _HAVE_LLP64_
uqval = (u_long)va_arg(ap, void *); uqval = (u_long)va_arg(ap, void *);
flags = (flags) | QUADINT | HEXPREFIX; flags = (flags) | QUADINT | HEXPREFIX;
@ -883,14 +906,15 @@ fp_begin: _double = va_arg(ap, double);
*/ */
const char *p = (char *)memchr(cp, 0, prec); const char *p = (char *)memchr(cp, 0, prec);
if (p != NULL) { if (p != NULL && (p - cp) > prec)
size = p - cp; size = (int)(p - cp);
if (size > prec) else
size = prec;
} else
size = prec; size = prec;
} else }
size = strlen(cp); else {
fieldsz = strlen(cp);
goto long_len;
}
sign = '\0'; sign = '\0';
break; break;
case 'U': case 'U':
@ -956,7 +980,7 @@ number: if ((dprec = prec) >= 0)
cp = BSD__ultoa(ulval, ebuf, base, cp = BSD__ultoa(ulval, ebuf, base,
flags & ALT, xdigs); flags & ALT, xdigs);
} }
size = ebuf - cp; size = (int)(ebuf - cp);
break; break;
default: /* "%?" prints ?, unless ? is NUL */ default: /* "%?" prints ?, unless ? is NUL */
if (ch == '\0') if (ch == '\0')
@ -984,6 +1008,7 @@ number: if ((dprec = prec) >= 0)
* fieldsz excludes decimal prec; realsz includes it. * fieldsz excludes decimal prec; realsz includes it.
*/ */
fieldsz = size; fieldsz = size;
long_len:
if (sign) if (sign)
fieldsz++; fieldsz++;
else if (flags & HEXPREFIX) else if (flags & HEXPREFIX)
@ -992,7 +1017,7 @@ number: if ((dprec = prec) >= 0)
/* right-adjusting blank padding */ /* right-adjusting blank padding */
if ((flags & (LADJUST|ZEROPAD)) == 0) if ((flags & (LADJUST|ZEROPAD)) == 0)
PAD(width - realsz, blanks); PAD_L(width - realsz, blanks);
/* prefix */ /* prefix */
if (sign) { if (sign) {
@ -1005,15 +1030,19 @@ number: if ((dprec = prec) >= 0)
/* right-adjusting zero padding */ /* right-adjusting zero padding */
if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
PAD(width - realsz, zeroes); PAD_L(width - realsz, zeroes);
/* leading zeroes from decimal precision */ /* leading zeroes from decimal precision */
PAD(dprec - fieldsz, zeroes); PAD_L(dprec - fieldsz, zeroes);
if (sign)
fieldsz--;
else if (flags & HEXPREFIX)
fieldsz -= 2;
/* the string or number proper */ /* the string or number proper */
#ifdef FLOATING_POINT #ifdef FLOATING_POINT
if ((flags & FPT) == 0) { if ((flags & FPT) == 0) {
PRINT(cp, size); PRINT(cp, fieldsz);
} else { /* glue together f_p fragments */ } else { /* glue together f_p fragments */
if (ch >= 'f') { /* 'f' or 'g' */ if (ch >= 'f') { /* 'f' or 'g' */
if (_double == 0) { if (_double == 0) {
@ -1058,11 +1087,11 @@ number: if ((dprec = prec) >= 0)
} }
} }
#else #else
PRINT(cp, size); PRINT(cp, fieldsz);
#endif #endif
/* left-adjusting padding (always blank) */ /* left-adjusting padding (always blank) */
if (flags & LADJUST) if (flags & LADJUST)
PAD(width - realsz, blanks); PAD_L(width - realsz, blanks);
/* finally, adjust ret */ /* finally, adjust ret */
ret += width > realsz ? width : realsz; ret += width > realsz ? width : realsz;
@ -1119,7 +1148,7 @@ cvt(value, ndigits, flags, sign, decpt, ch, length, buf)
while (rve < bp) while (rve < bp)
*rve++ = '0'; *rve++ = '0';
} }
*length = rve - digits; *length = (int)(rve - digits);
return (digits); return (digits);
} }
@ -1151,7 +1180,7 @@ exponent(p0, exp, fmtch)
*p++ = '0'; *p++ = '0';
*p++ = to_char(exp); *p++ = to_char(exp);
} }
return (p - p0); return (int)(p - p0);
} }
#endif /* FLOATING_POINT */ #endif /* FLOATING_POINT */