diff --git a/crates/kernel/src/vm/bf_list_sets.rs b/crates/kernel/src/vm/bf_list_sets.rs index 8223a308..0bdafc4b 100644 --- a/crates/kernel/src/vm/bf_list_sets.rs +++ b/crates/kernel/src/vm/bf_list_sets.rs @@ -2,7 +2,7 @@ use std::ops::BitOr; use std::sync::Arc; use async_trait::async_trait; -use onig::{SearchOptions, SyntaxOperator}; +use onig::{Region, SearchOptions, SyntaxOperator}; use moor_compiler::builtins::offset_for_builtin; use moor_values::var::error::Error; @@ -202,7 +202,7 @@ fn translate_pattern(pattern: &str) -> Option { type Span = (isize, isize); type MatchSpans = (Span, Vec); -fn onig_match( +fn perform_regex_match( pattern: &str, subject: &str, case_matters: bool, @@ -227,28 +227,24 @@ fn onig_match( let regex = onig::Regex::with_options(translated_pattern.as_str(), options, &syntax) .map_err(|_| E_INVARG)?; - let (start_pos, end_pos) = if reverse { + let (search_start, search_end) = if reverse { (subject.len(), 0) } else { (0, subject.len()) }; + let mut region = Region::new(); - let Some(start) = regex.search_with_options( + let Some(_) = regex.search_with_options( subject, - start_pos, - end_pos, + search_start, + search_end, SearchOptions::SEARCH_OPTION_NONE, - None, + Some(&mut region), ) else { return Ok(None); }; - - let Some(captures) = regex.captures(subject) else { - return Ok(None); - }; - // Overall span - let Some((_, end)) = captures.pos(0) else { + let Some((start, end)) = region.pos(0) else { return Ok(None); }; @@ -257,18 +253,16 @@ fn onig_match( // MOO match() returns 9 subpatterns, no more, no less. So we start with a Vec of 9 // (-1, -1) pairs and then fill that in with the captured groups, if any. let mut match_vec = vec![(0, -1); 9]; - for (i, capture) in captures.iter_pos().enumerate() { - if i == 0 { - continue; + for i in 1..=8 { + if let Some((start, end)) = region.pos(i) { + match_vec[i - 1] = ((start + 1) as isize, end as isize); } - let Some((start, end)) = capture else { - continue; - }; - match_vec[i - 1] = (start as isize + 1, end as isize); } + Ok(Some((overall, match_vec))) } +/// Common code for both match and rmatch. fn do_re_match<'a>(bf_args: &mut BfCallState<'a>, reverse: bool) -> Result { if bf_args.args.len() < 2 || bf_args.args.len() > 3 { return Err(E_INVARG); @@ -289,7 +283,7 @@ fn do_re_match<'a>(bf_args: &mut BfCallState<'a>, reverse: bool) -> Result