From 5752b61d8649f0b4128721753dc1b38669efdb9c Mon Sep 17 00:00:00 2001 From: nobu Date: Thu, 27 Mar 2014 09:58:12 +0000 Subject: string.c: search by rb_str_index * re.c (match_regexp): set regexp for MatchData from string. * re.c (rb_backref_set_string): create MatchData from string and set backref. * string.c (rb_pat_search, rb_str_sub, rb_str_sub_bang, str_gsub), (scan_once, rb_str_scan, rb_str_partition): use rb_str_index instead of rb_reg_search() when pattern is a String. based on the patch by Sam Rawlins [Fixes GH-579] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45451 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- re.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) (limited to 're.c') diff --git a/re.c b/re.c index 54ba47c199..5927e9e9f3 100644 --- a/re.c +++ b/re.c @@ -1017,8 +1017,15 @@ match_init_copy(VALUE obj, VALUE orig) static VALUE match_regexp(VALUE match) { + VALUE regexp; match_check(match); - return RMATCH(match)->regexp; + regexp = RMATCH(match)->regexp; + if (NIL_P(regexp)) { + VALUE str = rb_reg_nth_match(0, match); + regexp = rb_reg_regcomp(rb_reg_quote(str)); + RMATCH(match)->regexp = regexp; + } + return regexp; } /* @@ -1216,6 +1223,31 @@ rb_match_busy(VALUE match) FL_SET(match, MATCH_BUSY); } +static void +match_set_string(VALUE m, VALUE string, long pos, long len) +{ + struct RMatch *match = (struct RMatch *)m; + struct rmatch *rmatch = match->rmatch; + + match->str = string; + match->regexp = Qnil; + onig_region_resize(&rmatch->regs, 1); + rmatch->regs.beg[0] = pos; + rmatch->regs.end[0] = pos + len; + rmatch->char_offset_updated = 0; +} + +void +rb_backref_set_string(VALUE string, long pos, long len) +{ + VALUE match = rb_backref_get(); + if (NIL_P(match) || FL_TEST(match, MATCH_BUSY)) { + match = match_alloc(rb_cMatch); + } + match_set_string(match, string, pos, len); + rb_backref_set(match); +} + /* * call-seq: * rxp.fixed_encoding? -> true or false @@ -1909,6 +1941,10 @@ match_inspect(VALUE match) if (regexp == 0) { return rb_sprintf("#<%"PRIsVALUE":%p>", cname, (void*)match); } + else if (NIL_P(regexp)) { + return rb_sprintf("#<%"PRIsVALUE": %"PRIsVALUE">", + cname, rb_reg_nth_match(0, match)); + } names = ALLOCA_N(struct backref_name_tag, num_regs); MEMZERO(names, struct backref_name_tag, num_regs); -- cgit v1.2.3