From 1479b2b9a2d5d00e2799a05c3af3bef1508a3e80 Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Tue, 6 Apr 2021 16:28:24 -0600 Subject: implement function `patsubst` --- src/makefile/functions.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/makefile/functions.rs b/src/makefile/functions.rs index e6efd1c..2192d26 100644 --- a/src/makefile/functions.rs +++ b/src/makefile/functions.rs @@ -20,6 +20,10 @@ pub fn expand_call( assert_eq!(args.len(), 3); text::subst(macros, &args[0], &args[1], &args[2]) } + "patsubst" => { + assert_eq!(args.len(), 3); + text::patsubst(macros, &args[0], &args[1], &args[2]) + } "strip" => { assert_eq!(args.len(), 1); text::strip(macros, &args[0]) @@ -148,6 +152,29 @@ mod text { Ok(text.replace(&from, &to)) } + pub fn patsubst( + macros: &MacroSet, + from: &TokenString, + to: &TokenString, + text: &TokenString, + ) -> Result { + let from = macros.expand(from)?; + let to = macros.expand(to)?; + let text = macros.expand(text)?; + let words = text + .split_whitespace() + .map(|word| { + let pattern_match = r#match(&from, word)?.and_then(|x| x.get(1)); + Ok(if let Some(pm) = pattern_match { + to.replace('%', pm.as_str()) + } else { + word.to_owned() + }) + }) + .collect::>>()?; + Ok(words.join(" ")) + } + pub fn strip(macros: &MacroSet, text: &TokenString) -> Result { let text = macros.expand(text)?; // TODO don't allocate this vec -- cgit v1.2.3