aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/shirabe-pcre/src/preg.rs5
-rw-r--r--crates/shirabe-php-shim/src/preg.rs46
-rw-r--r--crates/shirabe-symfony-console/src/formatter/output_formatter.rs33
3 files changed, 31 insertions, 53 deletions
diff --git a/crates/shirabe-pcre/src/preg.rs b/crates/shirabe-pcre/src/preg.rs
index 822609a9..8fb0c2e8 100644
--- a/crates/shirabe-pcre/src/preg.rs
+++ b/crates/shirabe-pcre/src/preg.rs
@@ -15,7 +15,7 @@ use indexmap::IndexMap;
pub use shirabe_php_shim::CaptureKey;
use shirabe_php_shim::{
PREG_OFFSET_CAPTURE, PREG_SET_ORDER, PREG_SPLIT_OFFSET_CAPTURE, PREG_UNMATCHED_AS_NULL,
- PregPattern, preg_grep, preg_match_all_offset_capture2, preg_match_all2, preg_match2,
+ PregPattern, preg_grep, preg_match_all_offset_capture, preg_match_all2, preg_match2,
preg_replace_callback, preg_replace2, preg_split2,
};
@@ -89,7 +89,8 @@ impl Preg {
matches: Option<&mut IndexMap<CaptureKey, Vec<(Option<String>, i64)>>>,
) -> usize {
let mut internal: IndexMap<CaptureKey, Vec<(Option<String>, i64)>> = IndexMap::new();
- let result = preg_match_all_offset_capture2(pattern, subject, &mut internal);
+ let result =
+ preg_match_all_offset_capture(pattern, subject, &mut internal, PREG_UNMATCHED_AS_NULL);
if let Some(out) = matches {
*out = internal;
diff --git a/crates/shirabe-php-shim/src/preg.rs b/crates/shirabe-php-shim/src/preg.rs
index 40eb25fb..c762cb95 100644
--- a/crates/shirabe-php-shim/src/preg.rs
+++ b/crates/shirabe-php-shim/src/preg.rs
@@ -15,17 +15,6 @@ pub enum CaptureKey {
ByName(String),
}
-#[derive(Debug, Default)]
-pub struct PregOffsetCaptureMatches {
- groups: Vec<Vec<(String, usize)>>,
-}
-
-impl PregOffsetCaptureMatches {
- pub fn group(&self, i: usize) -> &[(String, usize)] {
- &self.groups[i]
- }
-}
-
pub fn preg_quote(str: &str, delimiter: Option<char>) -> String {
// Regex pattern compatibility:
// PHP's preg_quote escapes `<` and `>` (PCRE treats `\<`/`\>` as literals), but the `regex`
@@ -171,38 +160,12 @@ pub fn preg_match_all_set_order(
pub fn preg_match_all_offset_capture(
pattern: impl PregPattern,
subject: &str,
- matches: &mut PregOffsetCaptureMatches,
-) -> usize {
- let __resolved = pattern.resolve();
- let (re, _anchored) = __resolved.parts();
- let group_count = re.captures_len();
- matches.groups = vec![Vec::new(); group_count];
-
- let mut count = 0;
- for caps in re.captures_iter(subject) {
- count += 1;
- for g in 0..group_count {
- // PHP stores ["", -1] for non-participating groups under
- // PREG_OFFSET_CAPTURE; the unsigned offset here approximates -1 as 0,
- // which callers must not rely on for absent groups.
- let entry = caps
- .get(g)
- .map(|m| (m.as_str().to_string(), m.start()))
- .unwrap_or_else(|| (String::new(), 0));
- matches.groups[g].push(entry);
- }
- }
-
- count
-}
-
-pub fn preg_match_all_offset_capture2(
- pattern: impl PregPattern,
- subject: &str,
matches: &mut indexmap::IndexMap<CaptureKey, Vec<(Option<String>, i64)>>,
+ flags: i64,
) -> 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();
@@ -211,9 +174,12 @@ pub fn preg_match_all_offset_capture2(
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 => (None, -1),
+ None if unmatched_as_null => (None, -1),
+ None => (Some(String::new()), -1),
};
column.push(entry);
}
diff --git a/crates/shirabe-symfony-console/src/formatter/output_formatter.rs b/crates/shirabe-symfony-console/src/formatter/output_formatter.rs
index 4943e65b..6ce96875 100644
--- a/crates/shirabe-symfony-console/src/formatter/output_formatter.rs
+++ b/crates/shirabe-symfony-console/src/formatter/output_formatter.rs
@@ -7,8 +7,8 @@ use crate::formatter::output_formatter_style_interface::OutputFormatterStyleInte
use crate::formatter::output_formatter_style_stack::OutputFormatterStyleStack;
use crate::formatter::wrappable_output_formatter_interface::WrappableOutputFormatterInterface;
use shirabe_php_shim::{
- php_regex, preg_match, preg_match_all, preg_match_all_offset_capture, preg_match_all_set_order,
- preg_replace,
+ CaptureKey, php_regex, preg_match, preg_match_all, preg_match_all_offset_capture,
+ preg_match_all_set_order, preg_replace,
};
use shirabe_symfony_string::b;
@@ -290,16 +290,24 @@ impl WrappableOutputFormatterInterface for OutputFormatter {
let open_tag_regex = "[a-z](?:[^\\\\<>]* | \\\\.)*";
let close_tag_regex = "[a-z][^<>]*";
let mut current_line_length: i64 = 0;
- let mut matches: shirabe_php_shim::PregOffsetCaptureMatches = Default::default();
+ let mut matches: indexmap::IndexMap<CaptureKey, Vec<(Option<String>, i64)>> =
+ indexmap::IndexMap::new();
preg_match_all_offset_capture(
format!("#<(({open_tag_regex}) | /({close_tag_regex})?)>#ix"),
message,
&mut matches,
+ 0,
);
- let count = matches.group(0).len();
- for i in 0..count {
- let (text, pos) = matches.group(0)[i].clone();
- let pos = pos as i64;
+ let full_matches = matches
+ .get(&CaptureKey::ByIndex(0))
+ .cloned()
+ .unwrap_or_default();
+ for (i, match_) in full_matches.iter().enumerate() {
+ let pos = match_.1;
+ let text = match_
+ .0
+ .clone()
+ .expect("group 0 participates whenever the pattern matches");
if pos != 0 && shirabe_php_shim::byte_at(message, (pos - 1) as usize) == b'\\' {
continue;
@@ -315,12 +323,15 @@ impl WrappableOutputFormatterInterface for OutputFormatter {
// opening tag?
let open = shirabe_php_shim::byte_at(&text, 1) != b'/';
let tag = if open {
- matches.group(1)[i].0.clone()
+ matches[&CaptureKey::ByIndex(1)][i]
+ .0
+ .clone()
+ .expect("group 1 participates whenever the pattern matches")
} else {
matches
- .group(3)
- .get(i)
- .map(|m| m.0.clone())
+ .get(&CaptureKey::ByIndex(3))
+ .and_then(|group| group.get(i))
+ .and_then(|m| m.0.clone())
.unwrap_or_default()
};