diff options
Diffstat (limited to 'src/makefile/mod.rs')
-rw-r--r-- | src/makefile/mod.rs | 81 |
1 files changed, 9 insertions, 72 deletions
diff --git a/src/makefile/mod.rs b/src/makefile/mod.rs index 8fd7113..9255ebf 100644 --- a/src/makefile/mod.rs +++ b/src/makefile/mod.rs @@ -11,6 +11,7 @@ use command_line::CommandLine; use inference_rules::InferenceRule; use input::FinishedMakefileReader; pub use input::MakefileReader; +use lookup_internal::LookupInternal; use r#macro::{Macro, Set as MacroSet}; use target::{DynamicTargetSet, Target}; use token::TokenString; @@ -28,6 +29,7 @@ mod eval_context; mod functions; mod inference_rules; mod input; +mod lookup_internal; mod r#macro; mod pattern; mod target; @@ -347,78 +349,13 @@ impl<'a> Makefile<'a> { } fn expand_macros(&self, text: &TokenString, target: Option<&Target>) -> Result<String> { - let target = target.cloned(); - 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 macro_name.starts_with('@') { - // The $@ shall evaluate to the full target name of the - // current target. - vec![target.name.clone()] - } else if macro_name.starts_with('?') { - // The $? macro shall evaluate to the list of prerequisites - // that are newer than the current target. - target - .prerequisites - .iter() - .filter(|prereq| { - self.get_target(prereq) - .ok() - .and_then(|prereq| prereq.borrow().newer_than(target)) - .unwrap_or(false) - }) - .cloned() - .collect() - } 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.first().cloned().unwrap_or_default()] - } else if macro_name.starts_with('*') { - // The $* macro shall evaluate to the current target name with - // its suffix deleted. (GNUism: the match stem) - vec![target.stem.as_ref().unwrap_or(&target.name).to_owned()] - } else if macro_name.starts_with('^') { - target.prerequisites.clone() - } else { - unreachable!() - }; - - let macro_pieces = if macro_name.ends_with('D') { - macro_pieces - .into_iter() - .map(|x| { - Path::new(&x) - .parent() - .ok_or_else(|| eyre!("no parent")) - .map(|x| x.to_string_lossy().into()) - }) - .collect::<Result<_, _>>()? - } else if macro_name.ends_with('F') { - macro_pieces - .into_iter() - .map(|x| { - Path::new(&x) - .file_name() - .ok_or_else(|| eyre!("no filename")) - .map(|x| x.to_string_lossy().into()) - }) - .collect::<Result<_, _>>()? - } else { - macro_pieces - }; - - Ok(macro_pieces.join(" ")) - }; - - self.macros.with_lookup(&lookup_internal).expand( - text, - #[cfg(feature = "full")] - NO_EVAL, - ) + self.macros + .with_lookup(LookupInternal::new(target, &|name| self.get_target(name))) + .expand( + text, + #[cfg(feature = "full")] + NO_EVAL, + ) } } |