ruby-changes:42979
From: naruse <ko1@a...>
Date: Wed, 18 May 2016 13:56:09 +0900 (JST)
Subject: [ruby-changes:42979] naruse:r55053 (trunk): * re.c (match_ary_subseq): get subseq of match array without creating
naruse 2016-05-18 13:56:02 +0900 (Wed, 18 May 2016) New Revision: 55053 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=55053 Log: * re.c (match_ary_subseq): get subseq of match array without creating temporary array. * re.c (match_ary_aref): get element(s) of match array without creating temporary array. * re.c (match_aref): Use match_ary_subseq with handling irregulars. * re.c (match_values_at): Use match_ary_aref. Modified files: trunk/ChangeLog trunk/re.c trunk/test/ruby/test_regexp.rb Index: test/ruby/test_regexp.rb =================================================================== --- test/ruby/test_regexp.rb (revision 55052) +++ test/ruby/test_regexp.rb (revision 55053) @@ -374,23 +374,46 @@ class TestRegexp < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_regexp.rb#L374 def test_match_aref m = /(...)(...)(...)(...)?/.match("foobarbaz") + assert_equal("foobarbaz", m[0]) assert_equal("foo", m[1]) + assert_equal("foo", m[-4]) + assert_nil(m[-1]) + assert_nil(m[-11]) + assert_nil(m[-11, 1]) + assert_nil(m[-11..1]) + assert_nil(m[5]) + assert_nil(m[9]) assert_equal(["foo", "bar", "baz"], m[1..3]) + assert_equal(["foo", "bar", "baz"], m[1, 3]) + assert_equal([], m[3..1]) + assert_equal([], m[3, 0]) + assert_equal(nil, m[3, -1]) + assert_equal(nil, m[9, 1]) + assert_equal(["baz"], m[3, 1]) + assert_equal(["baz", nil], m[3, 5]) assert_nil(m[5]) assert_raise(IndexError) { m[:foo] } + assert_raise(TypeError) { m[nil] } end def test_match_values_at + idx = Object.new + def idx.to_int; 2; end m = /(...)(...)(...)(...)?/.match("foobarbaz") assert_equal(["foo", "bar", "baz"], m.values_at(1, 2, 3)) assert_equal(["foo", "bar", "baz"], m.values_at(1..3)) + assert_equal(["foo", "bar", "baz", nil, nil], m.values_at(1..5)) + assert_equal([], m.values_at(3..1)) + assert_equal([nil, nil, nil, nil, nil], m.values_at(5..9)) + assert_equal(["bar"], m.values_at(idx)) + assert_raise(RangeError){ m.values_at(-11..1) } + assert_raise(TypeError){ m.values_at(nil) } m = /(?<a>\d+) *(?<op>[+\-*\/]) *(?<b>\d+)/.match("1 + 2") assert_equal(["1", "2", "+"], m.values_at(:a, 'b', :op)) - idx = Object.new - def idx.to_int; 2; end assert_equal(["+"], m.values_at(idx)) assert_raise(TypeError){ m.values_at(nil) } + assert_raise(IndexError){ m.values_at(:foo) } end def test_match_string Index: re.c =================================================================== --- re.c (revision 55052) +++ re.c (revision 55053) @@ -1851,6 +1851,42 @@ namev_to_backref_number(struct re_regist https://github.com/ruby/ruby/blob/trunk/re.c#L1851 } } +static VALUE +match_ary_subseq(VALUE match, long beg, long len, VALUE result) +{ + long olen = RMATCH_REGS(match)->num_regs; + long j, end = olen < beg+len ? olen : beg+len; + if (NIL_P(result)) result = rb_ary_new_capa(len); + if (len == 0) return result; + + for (j = beg; j < end; j++) { + rb_ary_push(result, rb_reg_nth_match((int)j, match)); + } + if (beg + len > j) { + rb_ary_resize(result, RARRAY_LEN(result) + (beg + len) - j); + } + return result; +} + +static VALUE +match_ary_aref(VALUE match, VALUE idx, VALUE result) +{ + long beg, len; + int num_regs = RMATCH_REGS(match)->num_regs; + + /* check if idx is Range */ + switch (rb_range_beg_len(idx, &beg, &len, (long)num_regs, !NIL_P(result))) { + case Qfalse: + if (NIL_P(result)) return rb_reg_nth_match(NUM2INT(idx), match); + rb_ary_push(result, rb_reg_nth_match(NUM2INT(idx), match)); + return result; + case Qnil: + return Qnil; + default: + return match_ary_subseq(match, beg, len, result); + } +} + /* * call-seq: * mtch[i] -> str or nil @@ -1881,12 +1917,12 @@ namev_to_backref_number(struct re_regist https://github.com/ruby/ruby/blob/trunk/re.c#L1917 static VALUE match_aref(int argc, VALUE *argv, VALUE match) { - VALUE idx, rest; + VALUE idx, length; match_check(match); - rb_scan_args(argc, argv, "11", &idx, &rest); + rb_scan_args(argc, argv, "11", &idx, &length); - if (NIL_P(rest)) { + if (NIL_P(length)) { if (FIXNUM_P(idx)) { return rb_reg_nth_match(FIX2INT(idx), match); } @@ -1895,10 +1931,30 @@ match_aref(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/re.c#L1931 if (num >= 0) { return rb_reg_nth_match(num, match); } + else { + return match_ary_aref(match, idx, Qnil); + } } } - - return rb_ary_aref(argc, argv, match_to_a(match)); + else { + long beg = NUM2LONG(idx); + long len = NUM2LONG(length); + long num_regs = RMATCH_REGS(match)->num_regs; + if (len < 0) { + return Qnil; + } + if (beg < 0) { + beg += num_regs; + if (beg < 0) return Qnil; + } + else if (beg > num_regs) { + return Qnil; + } + else if (beg+len > num_regs) { + len = num_regs - beg; + } + return match_ary_subseq(match, beg, len, Qnil); + } } /* @@ -1921,7 +1977,6 @@ match_aref(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/re.c#L1977 static VALUE match_values_at(int argc, VALUE *argv, VALUE match) { - struct re_registers *regs = RMATCH_REGS(match); VALUE result; int i; @@ -1929,31 +1984,18 @@ match_values_at(int argc, VALUE *argv, V https://github.com/ruby/ruby/blob/trunk/re.c#L1984 result = rb_ary_new2(argc); for (i=0; i<argc; i++) { - VALUE tmp; - int num; - long beg, len, olen; if (FIXNUM_P(argv[i])) { rb_ary_push(result, rb_reg_nth_match(FIX2INT(argv[i]), match)); - continue; } - num = namev_to_backref_number(regs, RMATCH(match)->regexp, argv[i]); - if (num >= 0) { - rb_ary_push(result, rb_reg_nth_match(num, match)); - continue; - } - /* check if idx is Range */ - olen = regs->num_regs; - if (rb_range_beg_len(argv[i], &beg, &len, olen, 1)) { - long j, end = olen < beg+len ? olen : beg+len; - for (j = beg; j < end; j++) { - rb_ary_push(result, rb_reg_nth_match((int)j, match)); + else { + int num = namev_to_backref_number(RMATCH_REGS(match), RMATCH(match)->regexp, argv[i]); + if (num >= 0) { + rb_ary_push(result, rb_reg_nth_match(num, match)); + } + else { + match_ary_aref(match, argv[i], result); } - if (beg + len > j) - rb_ary_resize(result, RARRAY_LEN(result) + (beg + len) - j); - continue; } - tmp = rb_to_int(argv[i]); - rb_ary_push(result, rb_reg_nth_match(NUM2INT(tmp), match)); } return result; } Index: ChangeLog =================================================================== --- ChangeLog (revision 55052) +++ ChangeLog (revision 55053) @@ -1,3 +1,15 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed May 18 13:11:44 2016 NARUSE, Yui <naruse@r...> + + * re.c (match_ary_subseq): get subseq of match array without creating + temporary array. + + * re.c (match_ary_aref): get element(s) of match array without creating + temporary array. + + * re.c (match_aref): Use match_ary_subseq with handling irregulars. + + * re.c (match_values_at): Use match_ary_aref. + Wed May 18 13:03:07 2016 Kazuki Yamaguchi <k@r...> * ext/openssl/ossl_x509cert.c (ossl_x509_verify): X509_verify() -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/