aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/makefile/macro.rs60
-rw-r--r--src/makefile/mod.rs5
2 files changed, 53 insertions, 12 deletions
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(&macro_value, |c: &regex::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(&macro_value, |c: &regex::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(())
+ }
}
diff --git a/src/makefile/mod.rs b/src/makefile/mod.rs
index 8c50f41..1d4873e 100644
--- a/src/makefile/mod.rs
+++ b/src/makefile/mod.rs
@@ -203,7 +203,7 @@ impl<'a> Makefile<'a> {
.filter(|rule| rule.matches(name).unwrap_or(false));
for rule in inference_rule_candidates {
log::trace!(
- "{:>58} considering rule to build {:?} from {:?}",
+ "{} considering rule to build {:?} from {:?}",
name,
&rule.products,
&rule.prerequisites
@@ -211,7 +211,6 @@ impl<'a> Makefile<'a> {
// whose prerequisite file ($*.s2) exists.
let prereq_paths = rule
.prereqs(name)?
- .inspect(|x| log::trace!("{:>58} prereq {}", name, x))
.map(|prereq_path_name| {
if name == prereq_path_name || banned_names.contains(&&*prereq_path_name) {
// we can't build this based on itself! fuck outta here
@@ -250,7 +249,7 @@ impl<'a> Makefile<'a> {
})
.collect::<Option<Vec<String>>>();
if let Some(prereqs) = prereq_paths {
- log::trace!("oh {} is a {:#?}", name, rule);
+ log::trace!("oh {} is a {}", name, rule);
new_target = Some(Target {
name: name.into(),
prerequisites: prereqs,