From f414bd65aec6093f38860d5a9ddca4e4d581c95d Mon Sep 17 00:00:00 2001 From: akr Date: Sat, 14 Mar 2009 18:04:21 +0000 Subject: * string.c (rb_str_subpat): accept capture name. (rb_str_aref): follow above change. (rb_str_aref_m): pass the 2nd argument to rb_str_subpat. (rb_str_subpat_set): accept capture name. (rb_str_aset): follow above change. (rb_str_partition): ditto. (rb_str_aset_m): pass the 2nd argument to rb_str_subpat_set. * include/ruby/intern.h (rb_reg_backref_number): declared. * re.c (rb_reg_backref_number): defined. [ruby-core:21057] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22959 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 16 ++++++++++++++++ NEWS | 4 ++++ include/ruby/intern.h | 1 + re.c | 5 +++++ string.c | 24 +++++++++++++++--------- test/ruby/test_regexp.rb | 6 ++++++ 6 files changed, 47 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index f4d758f2a7..2ee3078c87 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +Sun Mar 15 02:53:13 2009 Tanaka Akira + + * string.c (rb_str_subpat): accept capture name. + (rb_str_aref): follow above change. + (rb_str_aref_m): pass the 2nd argument to rb_str_subpat. + (rb_str_subpat_set): accept capture name. + (rb_str_aset): follow above change. + (rb_str_partition): ditto. + (rb_str_aset_m): pass the 2nd argument to rb_str_subpat_set. + + * include/ruby/intern.h (rb_reg_backref_number): declared. + + * re.c (rb_reg_backref_number): defined. + + [ruby-core:21057] + Sun Mar 15 02:09:31 2009 Nobuyoshi Nakada * proc.c (bmcall): should not uninitialized variable. a patch from diff --git a/NEWS b/NEWS index c518957bee..419a8af9f1 100644 --- a/NEWS +++ b/NEWS @@ -38,6 +38,10 @@ with all sufficient information, see the ChangeLog file. * extended methods: * Process.spawn accepts [:child, FD] for a redirect target. + * String + * extended methods: + * string[regexp, name] supported. + * rss * 0.2.4 -> 0.2.5 diff --git a/include/ruby/intern.h b/include/ruby/intern.h index 1a034508ea..ddb1b03229 100644 --- a/include/ruby/intern.h +++ b/include/ruby/intern.h @@ -518,6 +518,7 @@ int rb_memcicmp(const void*,const void*,long); void rb_match_busy(VALUE); VALUE rb_reg_nth_defined(int, VALUE); VALUE rb_reg_nth_match(int, VALUE); +int rb_reg_backref_number(VALUE match, VALUE backref); VALUE rb_reg_last_match(VALUE); VALUE rb_reg_match_pre(VALUE); VALUE rb_reg_match_post(VALUE); diff --git a/re.c b/re.c index 5f1accff30..d48d3f3329 100644 --- a/re.c +++ b/re.c @@ -1008,6 +1008,11 @@ match_backref_number(VALUE match, VALUE backref) return num; } +int +rb_reg_backref_number(VALUE match, VALUE backref) +{ + return match_backref_number(match, backref); +} /* * call-seq: diff --git a/string.c b/string.c index 063965ae03..0e8f2678e8 100644 --- a/string.c +++ b/string.c @@ -3024,10 +3024,12 @@ rb_str_upto(int argc, VALUE *argv, VALUE beg) } static VALUE -rb_str_subpat(VALUE str, VALUE re, int nth) +rb_str_subpat(VALUE str, VALUE re, VALUE backref) { if (rb_reg_search(re, str, 0, 0) >= 0) { - return rb_reg_nth_match(nth, rb_backref_get()); + VALUE match = rb_backref_get(); + int nth = rb_reg_backref_number(match, backref); + return rb_reg_nth_match(nth, match); } return Qnil; } @@ -3047,7 +3049,7 @@ rb_str_aref(VALUE str, VALUE indx) return str; case T_REGEXP: - return rb_str_subpat(str, indx, 0); + return rb_str_subpat(str, indx, INT2FIX(0)); case T_STRING: if (rb_str_index(str, indx, 0) != -1) @@ -3091,6 +3093,7 @@ rb_str_aref(VALUE str, VALUE indx) * str.slice(range) => new_str or nil * str.slice(regexp) => new_str or nil * str.slice(regexp, fixnum) => new_str or nil + * str.slice(regexp, capname) => new_str or nil * str.slice(other_str) => new_str or nil * * Element Reference---If passed a single Fixnum, returns a @@ -3103,7 +3106,7 @@ rb_str_aref(VALUE str, VALUE indx) * is negative, or the beginning of the range is greater than the end. * * If a Regexp is supplied, the matching portion of str is - * returned. If a numeric parameter follows the regular expression, that + * returned. If a numeric or name parameter follows the regular expression, that * component of the MatchData is returned instead. If a * String is given, that string is returned if it occurs in * str. In both cases, nil is returned if there is no @@ -3130,7 +3133,7 @@ rb_str_aref_m(int argc, VALUE *argv, VALUE str) { if (argc == 2) { if (TYPE(argv[0]) == T_REGEXP) { - return rb_str_subpat(str, argv[0], NUM2INT(argv[1])); + return rb_str_subpat(str, argv[0], argv[1]); } return rb_str_substr(str, NUM2LONG(argv[0]), NUM2LONG(argv[1])); } @@ -3251,8 +3254,9 @@ rb_str_update(VALUE str, long beg, long len, VALUE val) } static void -rb_str_subpat_set(VALUE str, VALUE re, int nth, VALUE val) +rb_str_subpat_set(VALUE str, VALUE re, VALUE backref, VALUE val) { + int nth; VALUE match; long start, end, len; rb_encoding *enc; @@ -3262,6 +3266,7 @@ rb_str_subpat_set(VALUE str, VALUE re, int nth, VALUE val) rb_raise(rb_eIndexError, "regexp not matched"); } match = rb_backref_get(); + nth = rb_reg_backref_number(match, backref); regs = RMATCH_REGS(match); if (nth >= regs->num_regs) { out_of_range: @@ -3299,7 +3304,7 @@ rb_str_aset(VALUE str, VALUE indx, VALUE val) return val; case T_REGEXP: - rb_str_subpat_set(str, indx, 0, val); + rb_str_subpat_set(str, indx, INT2FIX(0), val); return val; case T_STRING: @@ -3332,6 +3337,7 @@ rb_str_aset(VALUE str, VALUE indx, VALUE val) * str[range] = aString * str[regexp] = new_str * str[regexp, fixnum] = new_str + * str[regexp, name] = new_str * str[other_str] = new_str * * Element Assignment---Replaces some or all of the content of str. The @@ -3354,7 +3360,7 @@ rb_str_aset_m(int argc, VALUE *argv, VALUE str) { if (argc == 3) { if (TYPE(argv[0]) == T_REGEXP) { - rb_str_subpat_set(str, argv[0], NUM2INT(argv[1]), argv[2]); + rb_str_subpat_set(str, argv[0], argv[1], argv[2]); } else { rb_str_splice(str, NUM2LONG(argv[0]), NUM2LONG(argv[1]), argv[2]); @@ -6760,7 +6766,7 @@ rb_str_partition(VALUE str, VALUE sep) return rb_ary_new3(3, str, rb_str_new(0,0),rb_str_new(0,0)); } if (regex) { - sep = rb_str_subpat(str, sep, 0); + sep = rb_str_subpat(str, sep, INT2FIX(0)); if (pos == 0 && RSTRING_LEN(sep) == 0) goto failed; } return rb_ary_new3(3, rb_str_subseq(str, 0, pos), diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb index d6441c9573..8b7b6c053e 100644 --- a/test/ruby/test_regexp.rb +++ b/test/ruby/test_regexp.rb @@ -104,6 +104,12 @@ class TestRegexp < Test::Unit::TestCase assert_equal({}, /(.)(.)/.named_captures) assert_equal("a[b]c", "abc".sub(/(?[bc])/, "[\\k]")) + + assert_equal("o", "foo"[/(?o)/, "bar"]) + + s = "foo" + s[/(?o)/, "bar"] = "baz" + assert_equal("fbazo", s) end def test_assign_named_capture -- cgit v1.2.3