From 2ef3a7c21e90a2f1a75e877e756730c8ec2634a7 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 23 Mar 2026 09:36:21 +0900 Subject: [PATCH] mruby-regexp: extract exec_match() to consolidate match methods Regexp#match and Regexp#=~ shared most of their logic (get pattern, execute, create MatchData, set globals). Extracted into exec_match() internal function. Regexp#=~ now calls exec_match() and reads the match position from the returned MatchData. Co-authored-by: Claude --- mrbgems/mruby-regexp/src/regexp.c | 52 ++++++++++++++----------------- 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/mrbgems/mruby-regexp/src/regexp.c b/mrbgems/mruby-regexp/src/regexp.c index 7b34ac075..15039781b 100644 --- a/mrbgems/mruby-regexp/src/regexp.c +++ b/mrbgems/mruby-regexp/src/regexp.c @@ -187,18 +187,13 @@ create_matchdata(mrb_state *mrb, mrb_value regexp, mrb_value str, int *captures, return obj; } -/* - * Regexp#match(str, pos=0) - */ +/* Internal: execute match and create MatchData. + Returns MatchData on match, nil on no match. + Sets $~ and $1-$9 globals. */ static mrb_value -regexp_match(mrb_state *mrb, mrb_value self) +exec_match(mrb_state *mrb, mrb_value self, mrb_value str, mrb_int pos) { - mrb_value str; - mrb_int pos = 0; - mrb_regexp_pattern *pat; - - mrb_get_args(mrb, "S|i", &str, &pos); - pat = DATA_GET_PTR(mrb, self, ®exp_type, mrb_regexp_pattern); + mrb_regexp_pattern *pat = DATA_GET_PTR(mrb, self, ®exp_type, mrb_regexp_pattern); if (!pat) mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized Regexp"); int captures[RE_MAX_CAPTURES * 2]; @@ -210,10 +205,21 @@ regexp_match(mrb_state *mrb, mrb_value self) clear_match_globals(mrb); return mrb_nil_value(); } - return create_matchdata(mrb, self, str, captures, pat->num_captures * 2); } +/* + * Regexp#match(str, pos=0) + */ +static mrb_value +regexp_match(mrb_state *mrb, mrb_value self) +{ + mrb_value str; + mrb_int pos = 0; + mrb_get_args(mrb, "S|i", &str, &pos); + return exec_match(mrb, self, str, pos); +} + /* * Regexp#match?(str, pos=0) */ @@ -222,10 +228,9 @@ regexp_match_p(mrb_state *mrb, mrb_value self) { mrb_value str; mrb_int pos = 0; - mrb_regexp_pattern *pat; - mrb_get_args(mrb, "S|i", &str, &pos); - pat = DATA_GET_PTR(mrb, self, ®exp_type, mrb_regexp_pattern); + + mrb_regexp_pattern *pat = DATA_GET_PTR(mrb, self, ®exp_type, mrb_regexp_pattern); if (!pat) mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized Regexp"); int ncap = re_exec(mrb, pat, RSTRING_PTR(str), RSTRING_LEN(str), pos, NULL, 0); @@ -239,26 +244,15 @@ static mrb_value regexp_match_op(mrb_state *mrb, mrb_value self) { mrb_value str; - mrb_regexp_pattern *pat; - mrb_get_args(mrb, "o", &str); if (mrb_nil_p(str)) return mrb_nil_value(); mrb_ensure_string_type(mrb, str); - pat = DATA_GET_PTR(mrb, self, ®exp_type, mrb_regexp_pattern); - if (!pat) mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized Regexp"); + mrb_value md = exec_match(mrb, self, str, 0); + if (mrb_nil_p(md)) return mrb_nil_value(); - int captures[RE_MAX_CAPTURES * 2]; - memset(captures, -1, sizeof(captures)); - int ncap = re_exec(mrb, pat, RSTRING_PTR(str), RSTRING_LEN(str), 0, - captures, pat->num_captures * 2); - - if (ncap == 0) { - clear_match_globals(mrb); - return mrb_nil_value(); - } - create_matchdata(mrb, self, str, captures, pat->num_captures * 2); - return mrb_int_value(mrb, captures[0]); + mrb_match_data *m = DATA_GET_PTR(mrb, md, &matchdata_type, mrb_match_data); + return mrb_int_value(mrb, m->captures[0]); } /*