aboutsummaryrefslogtreecommitdiff
path: root/src/makefile/input.rs
diff options
context:
space:
mode:
authorMelody Horn <melody@boringcactus.com>2024-11-10 21:20:34 -0700
committerMelody Horn <melody@boringcactus.com>2024-11-10 21:20:34 -0700
commitfca10b517b448b4023ad8c3225e59dcefd4004e4 (patch)
tree7507e959d1f690044945dd6fcf34b5fef3385b14 /src/makefile/input.rs
parentf945ff33f9312a534ae52f1c763b4150ae41dcf6 (diff)
downloadmakers-fca10b517b448b4023ad8c3225e59dcefd4004e4.tar.gz
makers-fca10b517b448b4023ad8c3225e59dcefd4004e4.zip
overhaul eval architecture
Diffstat (limited to 'src/makefile/input.rs')
-rw-r--r--src/makefile/input.rs64
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),