mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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:
parent
8f1f47a072
commit
08732d4f57
2 changed files with 60 additions and 27 deletions
|
@ -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.
|
||||||
|
|
|
@ -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;
|
size = prec;
|
||||||
} else
|
}
|
||||||
size = prec;
|
else {
|
||||||
} else
|
fieldsz = strlen(cp);
|
||||||
size = 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 */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue