mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50502 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									d28001f01a
								
							
						
					
					
						commit
						80e0ef3a81
					
				
					 2 changed files with 81 additions and 28 deletions
				
			
		
							
								
								
									
										23
									
								
								range.c
									
										
									
									
									
								
							
							
						
						
									
										23
									
								
								range.c
									
										
									
									
									
								
							|  | @ -174,7 +174,7 @@ range_eq(VALUE range, VALUE obj) | |||
| /* 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) | |||
| 	!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); | ||||
|  |  | |||
							
								
								
									
										86
									
								
								string.c
									
										
									
									
									
								
							
							
						
						
									
										86
									
								
								string.c
									
										
									
									
									
								
							|  | @ -3459,6 +3459,15 @@ all_digits_p(const char *s, long len) | |||
|     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 | |||
| rb_str_upto(int argc, VALUE *argv, VALUE beg) | ||||
| { | ||||
|     VALUE end, exclusive; | ||||
|     VALUE current, after_end; | ||||
|     ID succ; | ||||
|     int n, excl, ascii; | ||||
|     rb_encoding *enc; | ||||
| 
 | ||||
|     rb_scan_args(argc, argv, "11", &end, &exclusive); | ||||
|     RETURN_ENUMERATOR(beg, argc, argv); | ||||
|     excl = RTEST(exclusive); | ||||
|     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, ascii; | ||||
|     rb_encoding *enc; | ||||
| 
 | ||||
|     CONST_ID(succ, "succ"); | ||||
|     StringValue(end); | ||||
|     enc = rb_enc_check(beg, end); | ||||
|  | @ -3514,7 +3529,7 @@ rb_str_upto(int argc, VALUE *argv, VALUE beg) | |||
| 
 | ||||
| 	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 beg) | |||
| 
 | ||||
| 	    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 beg) | |||
| 	    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 beg) | |||
| 	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 beg) | |||
|     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) | ||||
| { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 nobu
						nobu