diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-08-17 06:03:41 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-08-17 06:03:41 +0900 |
| commit | c81e9f89d9e4388f36a4427bbaa95eced659d2ce (patch) | |
| tree | cd35eedf6741347e791e6909ec604b89d5e0cff7 /crates/shirabe-php-shim/src/preg.rs | |
| parent | ea39e2301824435d45db88f95867dbe692aaf21e (diff) | |
| download | php-shirabe-c81e9f89d9e4388f36a4427bbaa95eced659d2ce.tar.gz php-shirabe-c81e9f89d9e4388f36a4427bbaa95eced659d2ce.tar.zst php-shirabe-c81e9f89d9e4388f36a4427bbaa95eced659d2ce.zip | |
refactor(preg): split the PREG_UNMATCHED_AS_NULL preg_* by flag
preg_match2() and preg_match_all_offset_capture() each become a pair over
a shared private impl, and their flags arguments are gone: no caller passed
anything but 0 or PREG_UNMATCHED_AS_NULL. Preg::match5()/is_match5() lose
their own flags argument for the same reason -- both call sites passed 0,
and the value had nowhere left to go -- so they are renumbered to
match4()/is_match4(). PREG_UNMATCHED_AS_NULL itself is now unreferenced.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe-php-shim/src/preg.rs')
| -rw-r--r-- | crates/shirabe-php-shim/src/preg.rs | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/crates/shirabe-php-shim/src/preg.rs b/crates/shirabe-php-shim/src/preg.rs index 1156129a..0d6a3231 100644 --- a/crates/shirabe-php-shim/src/preg.rs +++ b/crates/shirabe-php-shim/src/preg.rs @@ -1,8 +1,6 @@ use indexmap::IndexMap; use std::sync::{Arc, LazyLock, Mutex}; -pub const PREG_UNMATCHED_AS_NULL: i64 = 512; - #[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] pub enum CaptureKey { ByIndex(usize), @@ -51,18 +49,35 @@ pub fn preg_match( } } -// Returns whether the pattern matched. Unmatched groups are reported as None -// (PREG_UNMATCHED_AS_NULL). +// Returns whether the pattern matched, reporting the groups as single_match_map() does. pub fn preg_match2( pattern: impl PregPattern, subject: &str, matches: &mut indexmap::IndexMap<CaptureKey, Option<String>>, - flags: i64, offset: usize, ) -> bool { + preg_match2_impl(pattern, subject, matches, offset, false) +} + +// PREG_UNMATCHED_AS_NULL counterpart of preg_match2(). +pub fn preg_match2_unmatched_as_null( + pattern: impl PregPattern, + subject: &str, + matches: &mut indexmap::IndexMap<CaptureKey, Option<String>>, + offset: usize, +) -> bool { + preg_match2_impl(pattern, subject, matches, offset, true) +} + +fn preg_match2_impl( + pattern: impl PregPattern, + subject: &str, + matches: &mut indexmap::IndexMap<CaptureKey, Option<String>>, + offset: usize, + unmatched_as_null: bool, +) -> bool { let __resolved = pattern.resolve(); let (re, anchored) = __resolved.parts(); - let unmatched_as_null = flags & PREG_UNMATCHED_AS_NULL != 0; // An anchored (`A`) pattern must match starting exactly at `offset`; the `regex` crate cannot // anchor a `captures_at` search, so search the sub-slice beginning at `offset` and require the // match to start at its head. @@ -155,15 +170,33 @@ pub fn preg_match_all_set_order( count } +// A non-participating group is reported at offset -1, holding "". pub fn preg_match_all_offset_capture( pattern: impl PregPattern, subject: &str, matches: &mut indexmap::IndexMap<CaptureKey, Vec<(Option<String>, i64)>>, - flags: i64, +) -> usize { + preg_match_all_offset_capture_impl(pattern, subject, matches, false) +} + +// PREG_UNMATCHED_AS_NULL counterpart of preg_match_all_offset_capture(): a +// non-participating group holds null instead of "". +pub fn preg_match_all_offset_capture_unmatched_as_null( + pattern: impl PregPattern, + subject: &str, + matches: &mut indexmap::IndexMap<CaptureKey, Vec<(Option<String>, i64)>>, +) -> usize { + preg_match_all_offset_capture_impl(pattern, subject, matches, true) +} + +fn preg_match_all_offset_capture_impl( + pattern: impl PregPattern, + subject: &str, + matches: &mut indexmap::IndexMap<CaptureKey, Vec<(Option<String>, i64)>>, + unmatched_as_null: bool, ) -> usize { let __resolved = pattern.resolve(); let (re, _anchored) = __resolved.parts(); - let unmatched_as_null = flags & PREG_UNMATCHED_AS_NULL != 0; let group_count = re.captures_len(); let names: Vec<Option<&str>> = re.capture_names().collect(); @@ -172,8 +205,6 @@ pub fn preg_match_all_offset_capture( for caps in re.captures_iter(subject) { count += 1; for (g, column) in groups.iter_mut().enumerate() { - // A non-participating group is reported at offset -1, holding "" or, - // with PREG_UNMATCHED_AS_NULL, null. let entry = match caps.get(g) { Some(m) => (Some(m.as_str().to_string()), m.start() as i64), None if unmatched_as_null => (None, -1), |
