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