diff options
Diffstat (limited to 'src/makefile/input.rs')
-rw-r--r-- | src/makefile/input.rs | 64 |
1 files changed, 33 insertions, 31 deletions
diff --git a/src/makefile/input.rs b/src/makefile/input.rs index ed1140e..f1d4f70 100644 --- a/src/makefile/input.rs +++ b/src/makefile/input.rs @@ -2,8 +2,6 @@ use std::cell::{Cell, RefCell}; use std::collections::HashMap; use std::error::Error as StdError; use std::fs::File; -#[cfg(feature = "full")] -use std::io::Cursor; use std::io::{BufRead, BufReader, Error as IoError, ErrorKind as IoErrorKind, Lines}; use std::iter::Peekable; use std::path::Path; @@ -18,6 +16,7 @@ use crate::args::Args; use super::command_line::CommandLine; #[cfg(feature = "full")] use super::conditional::{Line as ConditionalLine, State as ConditionalState}; +use super::eval_context::DeferredEvalContext; use super::inference_rules::InferenceRule; #[cfg(feature = "full")] use super::r#macro::ExportConfig; @@ -97,10 +96,10 @@ fn inference_match<'a>( ) -> Option<InferenceMatch<'a>> { lazy_static! { static ref INFERENCE_RULE: Regex = #[allow(clippy::unwrap_used)] - Regex::new(r"^(?P<s2>(\.[^/.]+)?)(?P<s1>\.[^/.]+)$") + Regex::new(r"^(?P<s2>(\.[^/.]+)?)(?P<s1>\.[^/.]+)$") .unwrap(); static ref SPECIAL_TARGET: Regex = #[allow(clippy::unwrap_used)] - Regex::new(r"^\.[A-Z]+$").unwrap(); + Regex::new(r"^\.[A-Z]+$").unwrap(); } let inference_match = INFERENCE_RULE.captures(targets[0]); @@ -192,13 +191,13 @@ pub struct MakefileReader<'a, 'parent, R: BufRead> { built_in_targets: HashMap<String, Target>, pub first_non_special_target: Option<String>, pub failed_includes: Vec<String>, - args: &'a Args, + pub args: &'a Args, lines_iter: Peekable<LineNumbers<String, IoError, Lines<R>>>, // join with escaped_newline_replacement to get the actual line pending_line: Option<(usize, Vec<String>)>, #[cfg(feature = "full")] conditional_stack: Vec<ConditionalState>, - file_names: Rc<RefCell<Vec<String>>>, + pub file_names: Rc<RefCell<Vec<String>>>, } impl<'a, 'parent> MakefileReader<'a, 'parent, BufReader<File>> { @@ -311,24 +310,6 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> { .wrap_err_with(|| format!("while parsing line {}", line_number))? .trim(), ); - // and let's eval whatever bullshit needs evaling - #[cfg(feature = "full")] - { - let eval = self.macros.to_eval.take(); - for eval in eval { - let child_macros = self.macros.with_overlay(); - let child = MakefileReader::read( - self.args, - child_macros, - Cursor::new(eval), - "<eval>", - Rc::clone(&self.file_names), - ) - .context("while evaling")? - .finish(); - self.extend(child); - } - } let line_type = LineType::of(&line_tokens); (line_tokens, line_type) } else { @@ -471,15 +452,19 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> { Err(err) => return Some((line_number, Err(err))), }; if let Some(line) = cond_line { + let mut deferred_eval_context = DeferredEvalContext::new(self); let action = line .action( self.conditional_stack.last(), |name| self.macros.is_defined(name), - |t| self.expand_macros(t), + |t| self.expand_macros_deferred_eval(t, &mut deferred_eval_context), ) .wrap_err_with(|| { format!("while applying conditional on line {}", line_number) }); + for child in deferred_eval_context { + self.extend(child); + } let action = match action { Ok(x) => x, Err(err) => return Some((line_number, Err(err))), @@ -609,6 +594,7 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> { log::error!("rule-specific macros are not implemented yet"); return Ok(()); } + let mut deferred_eval_context = DeferredEvalContext::new(self); let prerequisites = self .macros .with_lookup(&|macro_name: &str| { @@ -644,7 +630,10 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> { Ok(macro_pieces.join(" ")) }) - .expand(&prerequisites)?; + .expand(&prerequisites, Some(&mut deferred_eval_context))?; + for child in deferred_eval_context { + self.extend(child); + } let prerequisites = prerequisites .split_whitespace() .map(|x| x.into()) @@ -913,9 +902,22 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> { Ok(name.to_owned()) } - fn expand_macros(&self, text: &TokenString) -> Result<String> { + fn expand_macros(&mut self, text: &TokenString) -> Result<String> { + let mut deferred_eval_context = DeferredEvalContext::new(self); + let result = self.expand_macros_deferred_eval(text, &mut deferred_eval_context); + for child in deferred_eval_context { + self.extend(child); + } + result + } + + fn expand_macros_deferred_eval( + &self, + text: &TokenString, + deferred_eval_context: &mut DeferredEvalContext<R>, + ) -> Result<String> { self.macros - .expand(text) + .expand(text, Some(deferred_eval_context)) .wrap_err_with(|| format!("while expanding \"{}\"", text)) } @@ -1006,7 +1008,7 @@ worked = perhaps endif "; let args = Args::empty(); - let makefile = MakefileReader::read( + let mut makefile = MakefileReader::read( &args, MacroSet::new(), Cursor::new(file), @@ -1052,7 +1054,7 @@ baz endef "; let args = Args::empty(); - let makefile = MakefileReader::read( + let mut makefile = MakefileReader::read( &args, MacroSet::new(), Cursor::new(file), @@ -1080,7 +1082,7 @@ endif FOO = bar "; let args = Args::empty(); - let makefile = MakefileReader::read( + let mut makefile = MakefileReader::read( &args, MacroSet::new(), Cursor::new(file), |