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

ruby-changes:42168

From: nobu <ko1@a...>
Date: Thu, 24 Mar 2016 12:43:10 +0900 (JST)
Subject: [ruby-changes:42168] nobu:r54242 (trunk): date_core.c: fix jisx0301 and iso8601

nobu	2016-03-24 12:43:06 +0900 (Thu, 24 Mar 2016)

  New Revision: 54242

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=54242

  Log:
    date_core.c: fix jisx0301 and iso8601
    
    * ext/date/date_core.c (d_lite_jisx0301, iso8601_timediv),
      (dt_lite_jisx0301): format by the format string in local buffer
      to prevent intermediate strings from GC.

  Modified files:
    trunk/ChangeLog
    trunk/ext/date/date_core.c
    trunk/ext/date/depend
Index: ext/date/depend
===================================================================
--- ext/date/depend	(revision 54241)
+++ ext/date/depend	(revision 54242)
@@ -9,6 +9,7 @@ date_core.o: $(hdrdir)/ruby/oniguruma.h https://github.com/ruby/ruby/blob/trunk/ext/date/depend#L9
 date_core.o: $(hdrdir)/ruby/ruby.h
 date_core.o: $(hdrdir)/ruby/st.h
 date_core.o: $(hdrdir)/ruby/subst.h
+date_core.o: $(hdrdir)/ruby/util.h
 date_core.o: $(top_srcdir)/include/ruby.h
 date_core.o: date_core.c
 date_core.o: date_tmx.h
Index: ext/date/date_core.c
===================================================================
--- ext/date/date_core.c	(revision 54241)
+++ ext/date/date_core.c	(revision 54242)
@@ -4,6 +4,7 @@ https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L4
 
 #include "ruby.h"
 #include "ruby/encoding.h"
+#include "ruby/util.h"
 #include <math.h>
 #include <time.h>
 #if defined(HAVE_SYS_TIME_H)
@@ -6880,6 +6881,7 @@ strftimev(const char *fmt, VALUE self, https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L6881
 
     (*func)(self, &tmx);
     len = date_strftime_alloc(&buf, fmt, &tmx);
+    RB_GC_GUARD(self);
     str = rb_usascii_str_new(buf, len);
     if (buf != buffer) xfree(buf);
     return str;
@@ -6953,30 +6955,40 @@ d_lite_httpdate(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L6955
     return strftimev("%a, %d %b %Y %T GMT", dup, set_tmx);
 }
 
-static VALUE
-jisx0301_date(VALUE jd, VALUE y)
-{
-    VALUE a[2];
+enum {
+    DECIMAL_SIZE_OF_LONG = DECIMAL_SIZE_OF_BITS(CHAR_BIT*sizeof(long)),
+    JISX0301_DATE_SIZE = DECIMAL_SIZE_OF_LONG+8
+};
 
-    if (f_lt_p(jd, INT2FIX(2405160)))
-	return rb_usascii_str_new2("%Y-%m-%d");
-    if (f_lt_p(jd, INT2FIX(2419614))) {
-	a[0] = rb_usascii_str_new2("M%02d" ".%%m.%%d");
-	a[1] = f_sub(y, INT2FIX(1867));
-    }
-    else if (f_lt_p(jd, INT2FIX(2424875))) {
-	a[0] = rb_usascii_str_new2("T%02d" ".%%m.%%d");
-	a[1] = f_sub(y, INT2FIX(1911));
-    }
-    else if (f_lt_p(jd, INT2FIX(2447535))) {
-	a[0] = rb_usascii_str_new2("S%02d" ".%%m.%%d");
-	a[1] = f_sub(y, INT2FIX(1925));
-    }
-    else {
-	a[0] = rb_usascii_str_new2("H%02d" ".%%m.%%d");
-	a[1] = f_sub(y, INT2FIX(1988));
+static const char *
+jisx0301_date_format(char *fmt, size_t size, VALUE jd, VALUE y)
+{
+    if (FIXNUM_P(jd)) {
+	long d = FIX2INT(jd);
+	long s;
+	char c;
+	if (d < 2405160)
+	    return "%Y-%m-%d";
+	if (d < 2419614) {
+	    c = 'M';
+	    s = 1867;
+	}
+	else if (d < 2424875) {
+	    c = 'T';
+	    s = 1911;
+	}
+	else if (d < 2447535) {
+	    c = 'S';
+	    s = 1925;
+	}
+	else {
+	    c = 'H';
+	    s = 1988;
+	}
+	snprintf(fmt, size, "%c%02ld" ".%%m.%%d", c, FIX2INT(y) - s);
+	return fmt;
     }
-    return rb_f_sprintf(2, a);
+    return "%Y-%m-%d";
 }
 
 /*
@@ -6990,12 +7002,14 @@ jisx0301_date(VALUE jd, VALUE y) https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L7002
 static VALUE
 d_lite_jisx0301(VALUE self)
 {
-    VALUE s;
+    char fmtbuf[JISX0301_DATE_SIZE];
+    const char *fmt;
 
     get_d1(self);
-    s = jisx0301_date(m_real_local_jd(dat),
-		      m_real_year(dat));
-    return strftimev(RSTRING_PTR(s), self, set_tmx);
+    fmt = jisx0301_date_format(fmtbuf, sizeof(fmtbuf),
+			       m_real_local_jd(dat),
+			       m_real_year(dat));
+    return strftimev(fmt, self, set_tmx);
 }
 
 #ifndef NDEBUG
@@ -8301,26 +8315,19 @@ dt_lite_strftime(int argc, VALUE *argv, https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L8315
 }
 
 static VALUE
-iso8601_timediv(VALUE self, VALUE n)
+iso8601_timediv(VALUE self, long n)
 {
-    VALUE fmt;
-
-    n = to_integer(n);
-    fmt = rb_usascii_str_new2("T%H:%M:%S");
-    if (f_gt_p(n, INT2FIX(0))) {
-	VALUE argv[3];
-
-	get_d1(self);
-
-	argv[0] = rb_usascii_str_new2(".%0*d");
-	argv[1] = n;
-	argv[2] = f_round(f_quo(m_sf_in_sec(dat),
-				f_quo(INT2FIX(1),
-				      f_expt(INT2FIX(10), n))));
-	rb_str_append(fmt, rb_f_sprintf(3, argv));
-    }
-    rb_str_append(fmt, rb_usascii_str_new2("%:z"));
-    return strftimev(RSTRING_PTR(fmt), self, set_tmx);
+    static const char timefmt[] = "T%H:%M:%S";
+    static const char zone[] = "%:z";
+    char fmt[sizeof(timefmt) + sizeof(zone) + rb_strlen_lit(".%N") +
+	     DECIMAL_SIZE_OF_LONG];
+    char *p = fmt;
+
+    memcpy(p, timefmt, sizeof(timefmt)-1);
+    p += sizeof(timefmt)-1;
+    if (n > 0) p += snprintf(p, fmt+sizeof(fmt)-p, ".%%%ldN", n);
+    memcpy(p, zone, sizeof(zone));
+    return strftimev(fmt, self, set_tmx);
 }
 
 /*
@@ -8337,12 +8344,11 @@ iso8601_timediv(VALUE self, VALUE n) https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L8344
 static VALUE
 dt_lite_iso8601(int argc, VALUE *argv, VALUE self)
 {
-    VALUE n;
-
-    rb_scan_args(argc, argv, "01", &n);
+    long n = 0;
 
-    if (argc < 1)
-	n = INT2FIX(0);
+    rb_check_arity(argc, 0, 1);
+    if (argc >= 1)
+	n = NUM2LONG(argv[0]);
 
     return f_add(strftimev("%Y-%m-%d", self, set_tmx),
 		 iso8601_timediv(self, n));
@@ -8377,18 +8383,15 @@ dt_lite_rfc3339(int argc, VALUE *argv, V https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L8383
 static VALUE
 dt_lite_jisx0301(int argc, VALUE *argv, VALUE self)
 {
-    VALUE n, s;
-
-    rb_scan_args(argc, argv, "01", &n);
+    long n = 0;
 
-    if (argc < 1)
-	n = INT2FIX(0);
+    rb_check_arity(argc, 0, 1);
+    if (argc >= 1)
+	n = NUM2LONG(argv[0]);
 
     {
 	get_d1(self);
-	s = jisx0301_date(m_real_local_jd(dat),
-			  m_real_year(dat));
-	return rb_str_append(strftimev(RSTRING_PTR(s), self, set_tmx),
+	return rb_str_append(d_lite_jisx0301(self),
 			     iso8601_timediv(self, n));
     }
 }
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 54241)
+++ ChangeLog	(revision 54242)
@@ -1,4 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
-Thu Mar 24 12:42:36 2016  Nobuyoshi Nakada  <nobu@r...>
+Thu Mar 24 12:43:05 2016  Nobuyoshi Nakada  <nobu@r...>
+
+	* ext/date/date_core.c (d_lite_jisx0301, iso8601_timediv),
+	  (dt_lite_jisx0301): format by the format string in local buffer
+	  to prevent intermediate strings from GC.
 
 	* ext/date/date_core.c (mk_inspect_raw, mk_inspect): inspect by
 	  "%+"PRIsVALUE, to prevent intermediate strings from GC.

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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