From f6117f5a1b8e5aa426b959c0fe5571de626070dc Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Sun, 4 Apr 2021 14:07:14 -0600 Subject: keep track of pattern stem to correctly populate `$*` --- src/makefile/inference_rules.rs | 2 +- src/makefile/input.rs | 1 + src/makefile/mod.rs | 27 ++++++++++++++++++--------- src/makefile/target.rs | 1 + 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/makefile/inference_rules.rs b/src/makefile/inference_rules.rs index 86e5598..57756c9 100644 --- a/src/makefile/inference_rules.rs +++ b/src/makefile/inference_rules.rs @@ -23,7 +23,7 @@ impl InferenceRule { } } - fn first_match<'s, 't: 's>(&'s self, target_name: &'t str) -> Result>> { + pub fn first_match<'s, 't: 's>(&'s self, target_name: &'t str) -> Result>> { self.products .iter() .map(|pattern| r#match(pattern, target_name)) diff --git a/src/makefile/input.rs b/src/makefile/input.rs index 6ee5392..b02cdb6 100644 --- a/src/makefile/input.rs +++ b/src/makefile/input.rs @@ -446,6 +446,7 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> { name: target.into(), prerequisites: prerequisites.clone(), commands: commands.clone(), + stem: None, already_updated: Cell::new(false), }; self.targets.insert(target.into(), new_target); diff --git a/src/makefile/mod.rs b/src/makefile/mod.rs index ce30623..cda5559 100644 --- a/src/makefile/mod.rs +++ b/src/makefile/mod.rs @@ -180,6 +180,9 @@ impl<'a> Makefile<'a> { name: name.into(), prerequisites: prereqs, commands: rule.commands.clone(), + stem: rule + .first_match(name)? + .and_then(|x| x.get(0).map(|x| x.as_str().to_owned())), already_updated: Cell::new(false), }); break; @@ -231,6 +234,7 @@ impl<'a> Makefile<'a> { name: name.into(), prerequisites: vec![], commands, + stem: None, already_updated: Cell::new(false), }); } else { @@ -240,6 +244,7 @@ impl<'a> Makefile<'a> { name: name.into(), prerequisites: vec![], commands: vec![], + stem: None, already_updated: Cell::new(true), }); } @@ -269,15 +274,15 @@ impl<'a> Makefile<'a> { fn expand_macros(&self, text: &TokenString, target: Option<&Target>) -> Result { let target = target.cloned(); - let lookup_internal = move |name: &str| { + let lookup_internal = move |macro_name: &str| { let target = target .as_ref() .ok_or_else(|| eyre!("internal macro but no current target!"))?; - let macro_pieces = if name.starts_with('@') { + let macro_pieces = if macro_name.starts_with('@') { // The $@ shall evaluate to the full target name of the // current target. vec![target.name.clone()] - } else if name.starts_with('?') { + } else if macro_name.starts_with('?') { // The $? macro shall evaluate to the list of prerequisites // that are newer than the current target. target @@ -291,22 +296,25 @@ impl<'a> Makefile<'a> { }) .cloned() .collect() - } else if name.starts_with('<') { + } else if macro_name.starts_with('<') { // In an inference rule, the $< macro shall evaluate to the // filename whose existence allowed the inference rule to be // chosen for the target. In the .DEFAULT rule, the $< macro // shall evaluate to the current target name. // TODO make that actually be the case (rn exists_but_inferring_anyway might fuck that up) vec![target.prerequisites.get(0).cloned().unwrap_or_default()] - } else if name.starts_with('*') { + } else if macro_name.starts_with('*') { // The $* macro shall evaluate to the current target name with - // its suffix deleted. - vec![Path::new(name).with_extension("").to_string_lossy().into()] + // its suffix deleted. (GNUism: the match stem) + vec![Path::new(target.stem.as_ref().unwrap_or(&target.name)) + .with_extension("") + .to_string_lossy() + .into()] } else { unreachable!() }; - let macro_pieces = if name.ends_with('D') { + let macro_pieces = if macro_name.ends_with('D') { macro_pieces .into_iter() .map(|x| { @@ -316,7 +324,7 @@ impl<'a> Makefile<'a> { .map(|x| x.to_string_lossy().into()) }) .collect::>()? - } else if name.ends_with('F') { + } else if macro_name.ends_with('F') { macro_pieces .into_iter() .map(|x| { @@ -433,6 +441,7 @@ fn builtin_targets() -> Vec { .map(String::from) .collect(), commands: vec![], + stem: None, already_updated: Cell::new(false), }] } diff --git a/src/makefile/target.rs b/src/makefile/target.rs index 1c382d0..506bde8 100644 --- a/src/makefile/target.rs +++ b/src/makefile/target.rs @@ -14,6 +14,7 @@ pub struct Target { pub name: String, pub prerequisites: Vec, pub commands: Vec, + pub stem: Option, pub already_updated: Cell, } -- cgit v1.2.3