From 230b845fa218a9c22013e752efc5d01943831159 Mon Sep 17 00:00:00 2001 From: nobu Date: Sun, 14 Sep 2014 23:13:36 +0000 Subject: sprintf.c: improve rational 'f' format * sprintf.c (rb_str_format): rational 'f' format works for more values. [fix GH-717] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47588 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- sprintf.c | 52 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 13 deletions(-) (limited to 'sprintf.c') diff --git a/sprintf.c b/sprintf.c index d2bc9f89b5..b73aabd823 100644 --- a/sprintf.c +++ b/sprintf.c @@ -1027,6 +1027,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt) VALUE val = GETARG(), num, den; int sign = (flags&FPLUS) ? 1 : 0, zero = 0; long len; + int i, done = 0, prefix = 0; if (!RB_TYPE_P(val, T_RATIONAL)) { nextvalue = val; goto float_value; @@ -1062,28 +1063,53 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt) if (sign || (flags&FSPACE)) ++len; if (prec > 0) ++len; /* period */ CHECK(len > width ? len : width); - if (width > len) { - width -= (int)len; - if (!(flags&FMINUS)) { - FILL(' ', width); - width = 0; - } + if (sign || (flags&FSPACE)) { + buf[blen++] = sign > 0 ? '+' : sign < 0 ? '-' : ' '; + prefix++; + done++; } - if (sign || (flags&FSPACE)) buf[blen++] = sign > 0 ? '+' : sign < 0 ? '-' : ' '; len = RSTRING_LEN(val) + zero; t = RSTRING_PTR(val); - if (len > prec) + if (len > prec) { memcpy(&buf[blen], t, len - prec); - else + blen += len - prec; + done += len - prec; + } + else { buf[blen++] = '0'; - blen += len - prec; - if (prec > 0) buf[blen++] = '.'; - if (zero) FILL('0', zero); + done++; + } + if (prec > 0) { + buf[blen++] = '.'; + done++; + } + if (zero) { + FILL('0', zero); + done += zero; + } + else if (prec > len) { + FILL('0', prec - len); + memcpy(&buf[blen], t, len); + blen += len; + done += prec; + } else if (prec > 0) { memcpy(&buf[blen], t + len - prec, prec); blen += prec; + done += prec; + } + if ((flags & FWIDTH) && width > done) { + if (!(flags&FMINUS)) { + int shifting = (flags&FZERO) ? done - prefix : done; + for (i = 1; i <= shifting; i++) + buf[width - i] = buf[done - i]; + blen -= shifting; + FILL((flags&FZERO) ? '0' : ' ', width - done); + blen += shifting; + } else { + FILL(' ', width - done); + } } - if (width > 0) FILL(' ', width); RB_GC_GUARD(val); break; } -- cgit v1.2.3