ruby-changes:42172
From: nobu <ko1@a...>
Date: Thu, 24 Mar 2016 17:44:09 +0900 (JST)
Subject: [ruby-changes:42172] nobu:r54246 (trunk): strftime.c: fix FMTV
nobu 2016-03-24 17:44:03 +0900 (Thu, 24 Mar 2016) New Revision: 54246 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=54246 Log: strftime.c: fix FMTV * strftime.c (FMT_PADDING): extract format for padding. * strftime.c (FMT_PRECISION): extract precision formula. * strftime.c (FMTV): append formatted string to expand the result. Modified files: trunk/ChangeLog trunk/strftime.c trunk/test/ruby/test_time.rb Index: test/ruby/test_time.rb =================================================================== --- test/ruby/test_time.rb (revision 54245) +++ test/ruby/test_time.rb (revision 54246) @@ -756,6 +756,9 @@ class TestTime < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_time.rb#L756 t = Time.utc(-1,1,4) assert_equal("-0001", t.strftime("%Y")) assert_equal("-0001", t.strftime("%G")) + + t = Time.utc(10000000000000000000000,1,1) + assert_equal("10000000000000000000000", t.strftime("%Y")) end def test_strftime_weeknum Index: ChangeLog =================================================================== --- ChangeLog (revision 54245) +++ ChangeLog (revision 54246) @@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Thu Mar 24 17:44:02 2016 Nobuyoshi Nakada <nobu@r...> + + * strftime.c (FMT_PADDING): extract format for padding. + + * strftime.c (FMT_PRECISION): extract precision formula. + + * strftime.c (FMTV): append formatted string to expand the result. + Thu Mar 24 14:20:21 2016 Nobuyoshi Nakada <nobu@r...> * strftime.c (STRFTIME): deal with case conversion flags for Index: strftime.c =================================================================== --- strftime.c (revision 54245) +++ strftime.c (revision 54246) @@ -195,6 +195,17 @@ case_conv(char *s, ptrdiff_t i, int flag https://github.com/ruby/ruby/blob/trunk/strftime.c#L195 return s; } +static VALUE +format_value(const char *fmt, VALUE val, int precision) +{ + struct RString fmtv; + VALUE str = rb_setup_fake_str(&fmtv, fmt, strlen(fmt), 0); + VALUE args[2]; + args[0] = INT2FIX(precision); + args[1] = val; + return rb_str_format(2, args, str); +} + /* * enc is the encoding of the format. It is used as the encoding of resulted * string, but the name of the month and weekday are always US-ASCII. So it @@ -267,15 +278,20 @@ rb_strftime_with_timespec(VALUE ftime, c https://github.com/ruby/ruby/blob/trunk/strftime.c#L278 NEEDS(i); \ } \ } while (0); +#define FMT_PADDING(fmt, def_pad) \ + (&"%*"fmt"\0""%0*"fmt[\ + (padding == '0' || (!padding && (def_pad) == '0')) ? \ + rb_strlen_lit("%*"fmt)+1 : 0]) +#define FMT_PRECISION(def_prec) \ + ((flags & BIT_OF(LEFT)) ? (precision = 1) : \ + (precision <= 0) ? (precision = (def_prec)) : (precision)) #define FMT(def_pad, def_prec, fmt, val) \ do { \ - if (precision <= 0) precision = (def_prec); \ - if (flags & BIT_OF(LEFT)) precision = 1; \ + precision = FMT_PRECISION(def_prec); \ len = s - start; \ NEEDS(precision); \ rb_str_set_len(ftime, len); \ - rb_str_catf(ftime, \ - ((padding == '0' || (!padding && (def_pad) == '0')) ? "%0*"fmt : "%*"fmt), \ + rb_str_catf(ftime, FMT_PADDING(fmt, def_pad), \ precision, (val)); \ RSTRING_GETMEM(ftime, s, len); \ endp = (start = s) + rb_str_capacity(ftime); \ @@ -307,20 +323,13 @@ rb_strftime_with_timespec(VALUE ftime, c https://github.com/ruby/ruby/blob/trunk/strftime.c#L323 FMT((def_pad), (def_prec), "l"fmt, FIX2LONG(tmp)); \ } \ else { \ - VALUE args[2], result; \ - size_t l; \ - if (precision <= 0) precision = (def_prec); \ - if (flags & BIT_OF(LEFT)) precision = 1; \ - args[0] = INT2FIX(precision); \ - args[1] = (val); \ - if (padding == '0' || (!padding && (def_pad) == '0')) \ - result = rb_str_format(2, args, rb_str_new2("%0*"fmt)); \ - else \ - result = rb_str_format(2, args, rb_str_new2("%*"fmt)); \ - l = strlcpy(s, StringValueCStr(result), endp-s); \ - if ((size_t)(endp-s) <= l) \ - goto err; \ - s += l; \ + const char *fmts = FMT_PADDING(fmt, def_pad); \ + precision = FMT_PRECISION(def_prec); \ + tmp = format_value(fmts, tmp, precision); \ + rb_str_append(ftime, tmp); \ + RSTRING_GETMEM(ftime, s, len); \ + endp = (start = s) + rb_str_capacity(ftime); \ + s += len; \ } \ } while (0) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/