From ceb2ee16c46515dbd46267c2c93f5cb8f8d7ea47 Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Wed, 14 Apr 2021 15:45:45 -0600 Subject: use full pattern matching for $(x:y%z=z%a) macro substitution --- src/makefile/macro.rs | 60 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 9 deletions(-) (limited to 'src/makefile/macro.rs') diff --git a/src/makefile/macro.rs b/src/makefile/macro.rs index af7e354..9b52206 100644 --- a/src/makefile/macro.rs +++ b/src/makefile/macro.rs @@ -6,6 +6,7 @@ use std::fmt; use std::rc::Rc; use eyre::{bail, Result, WrapErr}; +#[cfg(not(feature = "full"))] use regex::Regex; #[cfg(feature = "full")] @@ -238,15 +239,40 @@ impl<'parent, 'lookup> Set<'parent, 'lookup> { let macro_value = match replacement { Some((subst1, subst2)) => { let subst1 = self.expand(subst1)?; - let subst1_suffix = regex::escape(&subst1); - let subst1_suffix = Regex::new(&format!(r"{}(\s|$)", subst1_suffix)) - .context("formed invalid regex somehow")?; - let subst2 = self.expand(subst2)?; - subst1_suffix - .replace_all(¯o_value, |c: ®ex::Captures| { - format!("{}{}", subst2, c.get(1).unwrap().as_str()) - }) - .to_string() + #[cfg(feature = "full")] + { + let (subst1, subst2) = if subst1.contains('%') { + (subst1, subst2.clone()) + } else { + let mut real_subst2 = TokenString::text("%"); + real_subst2.extend(subst2.clone()); + (format!("%{}", subst1), real_subst2) + }; + let args = [ + TokenString::text(subst1), + subst2, + TokenString::text(macro_value), + ]; + functions::expand_call( + "patsubst", + &args, + self, + Some(Rc::clone(&self.to_eval)), + )? + } + #[cfg(not(feature = "full"))] + { + let subst1_suffix = regex::escape(&subst1); + let subst1_suffix = + Regex::new(&format!(r"{}(\s|$)", subst1_suffix)) + .context("formed invalid regex somehow")?; + let subst2 = self.expand(subst2)?; + subst1_suffix + .replace_all(¯o_value, |c: ®ex::Captures| { + format!("{}{}", subst2, c.get(1).unwrap().as_str()) + }) + .to_string() + } } None => macro_value, }; @@ -421,4 +447,20 @@ mod test { assert_eq!(macros.expand(&"$(oof:;=?)".parse()?)?, "bruh? swag? yeet?"); Ok(()) } + + #[test] + #[cfg(feature = "full")] + fn hell_subst() -> R { + let mut macros = Set::new(); + macros.set( + "m".to_owned(), + Macro { + source: ItemSource::FunctionCall, + text: TokenString::text("conf"), + eagerly_expanded: false, + }, + ); + assert_eq!(macros.expand(&"$(m:%=%-objs)".parse()?)?, "conf-objs"); + Ok(()) + } } -- cgit v1.2.3