sprintf.c: refactor Rational f
* sprintf.c (rb_str_format): refactor floating point format of Rational by using gereric Integer functions. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54306 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
21102e16ac
commit
7d378a5b3a
@ -1,4 +1,7 @@
|
|||||||
Mon Mar 28 08:18:51 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Mon Mar 28 08:19:49 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* sprintf.c (rb_str_format): refactor floating point format of
|
||||||
|
Rational by using gereric Integer functions.
|
||||||
|
|
||||||
* sprintf.c (rb_str_format): fix buffer overflow, length must be
|
* sprintf.c (rb_str_format): fix buffer overflow, length must be
|
||||||
greater than precision. reported by William Bowling <will AT
|
greater than precision. reported by William Bowling <will AT
|
||||||
|
48
sprintf.c
48
sprintf.c
@ -65,12 +65,20 @@ sign_bits(int base, const char *p)
|
|||||||
|
|
||||||
#define PUSH(s, l) do { \
|
#define PUSH(s, l) do { \
|
||||||
CHECK(l);\
|
CHECK(l);\
|
||||||
|
PUSH_(s, l);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define PUSH_(s, l) do { \
|
||||||
memcpy(&buf[blen], (s), (l));\
|
memcpy(&buf[blen], (s), (l));\
|
||||||
blen += (l);\
|
blen += (l);\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define FILL(c, l) do { \
|
#define FILL(c, l) do { \
|
||||||
CHECK(l);\
|
CHECK(l);\
|
||||||
|
FILL_(c, l);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define FILL_(c, l) do { \
|
||||||
memset(&buf[blen], (c), (l));\
|
memset(&buf[blen], (c), (l));\
|
||||||
blen += (l);\
|
blen += (l);\
|
||||||
} while (0)
|
} while (0)
|
||||||
@ -1034,8 +1042,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
|
|||||||
{
|
{
|
||||||
VALUE val = GETARG(), num, den;
|
VALUE val = GETARG(), num, den;
|
||||||
int sign = (flags&FPLUS) ? 1 : 0, zero = 0;
|
int sign = (flags&FPLUS) ? 1 : 0, zero = 0;
|
||||||
long len, done = blen;
|
long len, fill;
|
||||||
int prefix = 0;
|
|
||||||
if (FIXNUM_P(val) || RB_TYPE_P(val, T_BIGNUM)) {
|
if (FIXNUM_P(val) || RB_TYPE_P(val, T_BIGNUM)) {
|
||||||
den = INT2FIX(1);
|
den = INT2FIX(1);
|
||||||
num = val;
|
num = val;
|
||||||
@ -1074,15 +1081,20 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
|
|||||||
if (sign || (flags&FSPACE)) ++len;
|
if (sign || (flags&FSPACE)) ++len;
|
||||||
if (prec > 0) ++len; /* period */
|
if (prec > 0) ++len; /* period */
|
||||||
CHECK(len > width ? len : width);
|
CHECK(len > width ? len : width);
|
||||||
|
fill = width > len ? width - len : 0;
|
||||||
|
if (fill && !(flags&FMINUS) && !(flags&FZERO)) {
|
||||||
|
FILL_(' ', fill);
|
||||||
|
}
|
||||||
if (sign || (flags&FSPACE)) {
|
if (sign || (flags&FSPACE)) {
|
||||||
buf[blen++] = sign > 0 ? '+' : sign < 0 ? '-' : ' ';
|
buf[blen++] = sign > 0 ? '+' : sign < 0 ? '-' : ' ';
|
||||||
prefix++;
|
}
|
||||||
|
if (fill && !(flags&FMINUS) && (flags&FZERO)) {
|
||||||
|
FILL_('0', fill);
|
||||||
}
|
}
|
||||||
len = RSTRING_LEN(val) + zero;
|
len = RSTRING_LEN(val) + zero;
|
||||||
t = RSTRING_PTR(val);
|
t = RSTRING_PTR(val);
|
||||||
if (len > prec) {
|
if (len > prec) {
|
||||||
memcpy(&buf[blen], t, len - prec);
|
PUSH_(t, len - prec);
|
||||||
blen += len - prec;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
buf[blen++] = '0';
|
buf[blen++] = '0';
|
||||||
@ -1091,31 +1103,17 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
|
|||||||
buf[blen++] = '.';
|
buf[blen++] = '.';
|
||||||
}
|
}
|
||||||
if (zero) {
|
if (zero) {
|
||||||
FILL('0', zero);
|
FILL_('0', zero);
|
||||||
}
|
}
|
||||||
else if (prec > len) {
|
else if (prec > len) {
|
||||||
FILL('0', prec - len);
|
FILL_('0', prec - len);
|
||||||
memcpy(&buf[blen], t, len);
|
PUSH_(t, len);
|
||||||
blen += len;
|
|
||||||
}
|
}
|
||||||
else if (prec > 0) {
|
else if (prec > 0) {
|
||||||
memcpy(&buf[blen], t + len - prec, prec);
|
PUSH_(t + len - prec, prec);
|
||||||
blen += prec;
|
|
||||||
}
|
}
|
||||||
if ((flags & FWIDTH) && width > (done = blen - done)) {
|
if (fill && (flags&FMINUS)) {
|
||||||
int fill = ' ';
|
FILL_(' ', fill);
|
||||||
long shifting = 0;
|
|
||||||
if (!(flags&FMINUS)) {
|
|
||||||
shifting = done;
|
|
||||||
if (flags&FZERO) {
|
|
||||||
shifting -= prefix;
|
|
||||||
fill = '0';
|
|
||||||
}
|
|
||||||
blen -= shifting;
|
|
||||||
memmove(&buf[blen + width - done], &buf[blen], shifting);
|
|
||||||
}
|
|
||||||
FILL(fill, width - done);
|
|
||||||
blen += shifting;
|
|
||||||
}
|
}
|
||||||
RB_GC_GUARD(val);
|
RB_GC_GUARD(val);
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user