diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | include/ruby/intern.h | 1 | ||||
-rw-r--r-- | range.c | 31 | ||||
-rw-r--r-- | string.c | 61 | ||||
-rw-r--r-- | version.h | 6 |
5 files changed, 51 insertions, 57 deletions
@@ -1,3 +1,12 @@ +Fri Jun 22 23:55:59 2007 Yukihiro Matsumoto <matz@ruby-lang.org> + + * string.c (rb_str_upto): add optional argument to specify + exclusiveness. + + * range.c (range_step): use String#upto with optional argument. + + * range.c (range_each): ditto. + Fri Jun 22 19:55:51 2007 Tanaka Akira <akr@fsij.org> * proc.c (proc_to_s): revert the change from %p to %lx at YARV diff --git a/include/ruby/intern.h b/include/ruby/intern.h index a74bd8ed23..05c7643914 100644 --- a/include/ruby/intern.h +++ b/include/ruby/intern.h @@ -518,7 +518,6 @@ VALUE rb_str_concat(VALUE, VALUE); int rb_memhash(const void *ptr, long len); int rb_str_hash(VALUE); int rb_str_cmp(VALUE, VALUE); -VALUE rb_str_upto(VALUE, VALUE, int); void rb_str_update(VALUE, long, long, VALUE); VALUE rb_str_inspect(VALUE); VALUE rb_str_dump(VALUE); @@ -218,14 +218,6 @@ range_hash(VALUE range) return LONG2FIX(hash); } -static VALUE -str_step(VALUE arg) -{ - VALUE *args = (VALUE *)arg; - - return rb_str_upto(args[0], args[1], EXCL(args[2])); -} - static void range_each_func(VALUE range, VALUE (*func) (VALUE, void *), VALUE v, VALUE e, void *arg) @@ -323,16 +315,15 @@ range_step(int argc, VALUE *argv, VALUE range) VALUE tmp = rb_check_string_type(b); if (!NIL_P(tmp)) { - VALUE args[5]; + VALUE args[2]; long iter[2]; b = tmp; - args[0] = b; - args[1] = e; - args[2] = range; + args[0] = e; + args[1] = EXCL(range) ? Qtrue : Qfalse; iter[0] = 1; iter[1] = unit; - rb_iterate(str_step, (VALUE)args, step_i, (VALUE)iter); + rb_block_call(b, rb_intern("upto"), 2, args, step_i, (VALUE)iter); } else if (rb_obj_is_kind_of(b, rb_cNumeric)) { ID c = rb_intern(EXCL(range) ? "<" : "<="); @@ -409,15 +400,11 @@ range_each(VALUE range) } } else if (TYPE(beg) == T_STRING) { - VALUE args[5]; - long iter[2]; - - args[0] = beg; - args[1] = end; - args[2] = range; - iter[0] = 1; - iter[1] = 1; - rb_iterate(str_step, (VALUE)args, step_i, (VALUE)iter); + VALUE args[2]; + + args[0] = end; + args[1] = EXCL(range) ? Qtrue : Qfalse; + rb_block_call(beg, rb_intern("upto"), 2, args, rb_yield, 0); } else { range_each_func(range, each_i, beg, end, NULL); @@ -1549,41 +1549,16 @@ rb_str_succ_bang(VALUE str) return str; } -VALUE -rb_str_upto(VALUE beg, VALUE end, int excl) -{ - VALUE current, after_end; - ID succ = rb_intern("succ"); - int n; - - StringValue(end); - n = rb_str_cmp(beg, end); - if (n > 0 || (excl && n == 0)) return beg; - after_end = rb_funcall(end, succ, 0, 0); - current = beg; - while (!rb_str_equal(current, after_end)) { - rb_yield(current); - if (!excl && rb_str_equal(current, end)) break; - current = rb_funcall(current, succ, 0, 0); - StringValue(current); - if (excl && rb_str_equal(current, end)) break; - StringValue(current); - if (RSTRING_LEN(current) > RSTRING_LEN(end) || RSTRING_LEN(current) == 0) - break; - } - - return beg; -} - /* * call-seq: - * str.upto(other_str) {|s| block } => str + * str.upto(other_str, exclusive=false) {|s| block } => str * * Iterates through successive values, starting at <i>str</i> and * ending at <i>other_str</i> inclusive, passing each value in turn to * the block. The <code>String#succ</code> method is used to generate - * each value. + * each value. If optional second arguent excle is omitted or is <code>false</code>, + * the last value will be included; otherwise it will be excluded. * * "a8".upto("b6") {|s| print s, ' ' } * for s in "a8".."b6" @@ -1597,9 +1572,33 @@ rb_str_upto(VALUE beg, VALUE end, int excl) */ static VALUE -rb_str_upto_m(VALUE beg, VALUE end) +rb_str_upto(int argc, VALUE *argv, VALUE beg) { - return rb_str_upto(beg, end, Qfalse); + VALUE end, exclusive; + VALUE current, after_end; + ID succ; + int n, excl; + + rb_scan_args(argc, argv, "11", &end, &exclusive); + excl = RTEST(exclusive); + succ = rb_intern("succ"); + StringValue(end); + n = rb_str_cmp(beg, end); + if (n > 0 || (excl && n == 0)) return beg; + after_end = rb_funcall(end, succ, 0, 0); + current = beg; + while (!rb_str_equal(current, after_end)) { + rb_yield(current); + if (!excl && rb_str_equal(current, end)) break; + current = rb_funcall(current, succ, 0, 0); + StringValue(current); + if (excl && rb_str_equal(current, end)) break; + StringValue(current); + if (RSTRING_LEN(current) > RSTRING_LEN(end) || RSTRING_LEN(current) == 0) + break; + } + + return beg; } static VALUE @@ -4911,7 +4910,7 @@ Init_String(void) rb_define_method(rb_cString, "succ!", rb_str_succ_bang, 0); rb_define_method(rb_cString, "next", rb_str_succ, 0); rb_define_method(rb_cString, "next!", rb_str_succ_bang, 0); - rb_define_method(rb_cString, "upto", rb_str_upto_m, 1); + rb_define_method(rb_cString, "upto", rb_str_upto, -1); rb_define_method(rb_cString, "index", rb_str_index_m, -1); rb_define_method(rb_cString, "rindex", rb_str_rindex_m, -1); rb_define_method(rb_cString, "replace", rb_str_replace, 1); @@ -1,7 +1,7 @@ #define RUBY_VERSION "1.9.0" -#define RUBY_RELEASE_DATE "2007-06-21" +#define RUBY_RELEASE_DATE "2007-06-23" #define RUBY_VERSION_CODE 190 -#define RUBY_RELEASE_CODE 20070621 +#define RUBY_RELEASE_CODE 20070623 #define RUBY_PATCHLEVEL 0 #define RUBY_VERSION_MAJOR 1 @@ -9,7 +9,7 @@ #define RUBY_VERSION_TEENY 0 #define RUBY_RELEASE_YEAR 2007 #define RUBY_RELEASE_MONTH 6 -#define RUBY_RELEASE_DAY 21 +#define RUBY_RELEASE_DAY 23 #ifdef RUBY_EXTERN RUBY_EXTERN const char ruby_version[]; |