aboutsummaryrefslogtreecommitdiff
path: root/src/makefile/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/makefile/mod.rs')
-rw-r--r--src/makefile/mod.rs81
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,
+ )
}
}