[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]