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

ruby-changes:38421

From: nobu <ko1@a...>
Date: Fri, 15 May 2015 21:40:15 +0900 (JST)
Subject: [ruby-changes:38421] nobu:r50502 (trunk): range.c: move String specific code

nobu	2015-05-15 21:39:56 +0900 (Fri, 15 May 2015)

  New Revision: 50502

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

  Log:
    range.c: move String specific code
    
    * range.c (range_include): call rb_str_include_range_p on String.
    
    * string.c (str_upto_each): extract from rb_str_upto.
    
    * string.c (rb_str_include_range_p): move String specific code
      from Range#include? in range.c.

  Modified files:
    trunk/range.c
    trunk/string.c
Index: string.c
===================================================================
--- string.c	(revision 50501)
+++ string.c	(revision 50502)
@@ -3459,6 +3459,15 @@ all_digits_p(const char *s, long len) https://github.com/ruby/ruby/blob/trunk/string.c#L3459
     return 1;
 }
 
+static VALUE str_upto_each(VALUE beg, VALUE end, int excl, int (*each)(VALUE, VALUE), VALUE);
+
+static int
+str_upto_i(VALUE str, VALUE arg)
+{
+    rb_yield(str);
+    return 0;
+}
+
 /*
  *  call-seq:
  *     str.upto(other_str, exclusive=false) {|s| block }   -> str
@@ -3495,14 +3504,20 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/string.c#L3504
 rb_str_upto(int argc, VALUE *argv, VALUE beg)
 {
     VALUE end, exclusive;
+
+    rb_scan_args(argc, argv, "11", &end, &exclusive);
+    RETURN_ENUMERATOR(beg, argc, argv);
+    return str_upto_each(beg, end, RTEST(exclusive), str_upto_i, Qnil);
+}
+
+static VALUE
+str_upto_each(VALUE beg, VALUE end, int excl, int (*each)(VALUE, VALUE), VALUE arg)
+{
     VALUE current, after_end;
     ID succ;
-    int n, excl, ascii;
+    int n, ascii;
     rb_encoding *enc;
 
-    rb_scan_args(argc, argv, "11", &end, &exclusive);
-    RETURN_ENUMERATOR(beg, argc, argv);
-    excl = RTEST(exclusive);
     CONST_ID(succ, "succ");
     StringValue(end);
     enc = rb_enc_check(beg, end);
@@ -3514,7 +3529,7 @@ rb_str_upto(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/string.c#L3529
 
 	if (c > e || (excl && c == e)) return beg;
 	for (;;) {
-	    rb_yield(rb_enc_str_new(&c, 1, enc));
+	    if ((*each)(rb_enc_str_new(&c, 1, enc), arg)) break;
 	    if (!excl && c == e) break;
 	    c++;
 	    if (excl && c == e) break;
@@ -3538,7 +3553,7 @@ rb_str_upto(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/string.c#L3553
 
 	    while (bi <= ei) {
 		if (excl && bi == ei) break;
-		rb_yield(rb_enc_sprintf(usascii, "%.*ld", width, bi));
+		if ((*each)(rb_enc_sprintf(usascii, "%.*ld", width, bi), arg)) break;
 		bi++;
 	    }
 	}
@@ -3549,7 +3564,7 @@ rb_str_upto(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/string.c#L3564
 	    args[0] = INT2FIX(width);
 	    while (rb_funcall(b, op, 1, e)) {
 		args[1] = b;
-		rb_yield(rb_str_format(numberof(args), args, fmt));
+		if ((*each)(rb_str_format(numberof(args), args, fmt), arg)) break;
 		b = rb_funcallv(b, succ, 0, 0);
 	    }
 	}
@@ -3565,7 +3580,7 @@ rb_str_upto(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/string.c#L3580
 	VALUE next = Qnil;
 	if (excl || !rb_str_equal(current, end))
 	    next = rb_funcallv(current, succ, 0, 0);
-	rb_yield(current);
+	if ((*each)(current, arg)) break;
 	if (NIL_P(next)) break;
 	current = next;
 	StringValue(current);
@@ -3577,6 +3592,59 @@ rb_str_upto(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/string.c#L3592
     return beg;
 }
 
+static int
+include_range_i(VALUE str, VALUE arg)
+{
+    VALUE *argp = (VALUE *)arg;
+    if (!rb_equal(str, *argp)) return 0;
+    *argp = Qnil;
+    return 1;
+}
+
+VALUE
+rb_str_include_range_p(VALUE beg, VALUE end, VALUE val, VALUE exclusive)
+{
+    beg = rb_str_new_frozen(beg);
+    StringValue(end);
+    end = rb_str_new_frozen(end);
+    if (NIL_P(val)) return Qfalse;
+    val = rb_check_string_type(val);
+    if (NIL_P(val)) return Qfalse;
+    if (rb_enc_asciicompat(STR_ENC_GET(beg)) &&
+	rb_enc_asciicompat(STR_ENC_GET(end)) &&
+	rb_enc_asciicompat(STR_ENC_GET(val))) {
+	const char *bp = RSTRING_PTR(beg);
+	const char *ep = RSTRING_PTR(end);
+	const char *vp = RSTRING_PTR(val);
+	if (RSTRING_LEN(beg) == 1 && RSTRING_LEN(end) == 1) {
+	    if (RSTRING_LEN(val) == 0 || RSTRING_LEN(val) > 1)
+		return Qfalse;
+	    else {
+		char b = *bp;
+		char e = *ep;
+		char v = *vp;
+
+		if (ISASCII(b) && ISASCII(e) && ISASCII(v)) {
+		    if (b <= v && v < e) return Qtrue;
+		    if (!RTEST(exclusive) && v == e) return Qtrue;
+		    return Qfalse;
+		}
+	    }
+	}
+#if 0
+	/* both edges are all digits */
+	if (ISDIGIT(*bp) && ISDIGIT(*ep) &&
+	    all_digits_p(bp, RSTRING_LEN(beg)) &&
+	    all_digits_p(ep, RSTRING_LEN(end))) {
+	    /* TODO */
+	}
+#endif
+    }
+    str_upto_each(beg, end, RTEST(exclusive), include_range_i, (VALUE)&val);
+
+    return NIL_P(val) ? Qtrue : Qfalse;
+}
+
 static VALUE
 rb_str_subpat(VALUE str, VALUE re, VALUE backref)
 {
Index: range.c
===================================================================
--- range.c	(revision 50501)
+++ range.c	(revision 50502)
@@ -174,7 +174,7 @@ range_eq(VALUE range, VALUE obj) https://github.com/ruby/ruby/blob/trunk/range.c#L174
 /* compares _a_ and _b_ and returns:
  * < 0: a < b
  * = 0: a = b
- * > 0: a > b or not-comparable
+ * > 0: a > b or non-comparable
  */
 static int
 r_less(VALUE a, VALUE b)
@@ -1165,24 +1165,9 @@ range_include(VALUE range, VALUE val) https://github.com/ruby/ruby/blob/trunk/range.c#L1165
 	!NIL_P(rb_check_to_integer(end, "to_int"))) {
 	return r_cover_p(range, beg, end, val);
     }
-    else if (RB_TYPE_P(beg, T_STRING) && RB_TYPE_P(end, T_STRING) &&
-	     RSTRING_LEN(beg) == 1 && RSTRING_LEN(end) == 1) {
-	if (NIL_P(val)) return Qfalse;
-	if (RB_TYPE_P(val, T_STRING)) {
-	    if (RSTRING_LEN(val) == 0 || RSTRING_LEN(val) > 1)
-		return Qfalse;
-	    else {
-		char b = RSTRING_PTR(beg)[0];
-		char e = RSTRING_PTR(end)[0];
-		char v = RSTRING_PTR(val)[0];
-
-		if (ISASCII(b) && ISASCII(e) && ISASCII(v)) {
-		    if (b <= v && v < e) return Qtrue;
-		    if (!EXCL(range) && v == e) return Qtrue;
-		    return Qfalse;
-		}
-	    }
-	}
+    else if (RB_TYPE_P(beg, T_STRING) && RB_TYPE_P(end, T_STRING)) {
+	VALUE rb_str_include_range_p(VALUE beg, VALUE end, VALUE val, VALUE exclusive);
+	return rb_str_include_range_p(beg, end, val, RANGE_EXCL(range));
     }
     /* TODO: ruby_frame->this_func = rb_intern("include?"); */
     return rb_call_super(1, &val);

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

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