diff options
Diffstat (limited to 'src/makefile/functions.rs')
-rw-r--r-- | src/makefile/functions.rs | 27 |
1 files changed, 27 insertions, 0 deletions
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<String> { + 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::<Result<Vec<_>>>()?; + Ok(words.join(" ")) + } + pub fn strip(macros: &MacroSet, text: &TokenString) -> Result<String> { let text = macros.expand(text)?; // TODO don't allocate this vec |