From 89a87698ed39188fee792cc3488bffed2ff525cf Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Sat, 3 Apr 2021 12:26:33 -0600 Subject: implement `eval` --- src/makefile/input.rs | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'src/makefile/input.rs') diff --git a/src/makefile/input.rs b/src/makefile/input.rs index 918ce0a..f269fa4 100644 --- a/src/makefile/input.rs +++ b/src/makefile/input.rs @@ -2,7 +2,7 @@ use std::cell::Cell; use std::collections::HashMap; use std::error::Error as StdError; use std::fs::File; -use std::io::{BufRead, BufReader, Error as IoError, Lines}; +use std::io::{BufRead, BufReader, Cursor, Error as IoError, Lines}; use std::iter::Peekable; use std::path::Path; @@ -181,7 +181,10 @@ impl<'a, R: BufRead> MakefileReader<'a, R> { // POSIX says we only have to handle a single filename, but GNU make // handles arbitrarily many filenames, and it's not like that's more work for field in fields { - self.extend(MakefileReader::read_file(self.args, field)?); + self.extend( + MakefileReader::read_file(self.args, field) + .with_context(|| format!("while including {}", field))?, + ); } continue; } @@ -202,7 +205,18 @@ impl<'a, R: BufRead> MakefileReader<'a, R> { // before we actually test it, see if it's only visible after expanding macros let (line_tokens, line_type) = if let LineType::Unknown = line_type { - let line_tokens = TokenString::text(self.expand_macros(&line_tokens)?); + let line_tokens = TokenString::text(self.expand_macros(&line_tokens)?.trim()); + // and let's eval whatever bullshit needs evaling + #[cfg(feature = "full")] + { + let eval = self.macros.to_eval.take(); + for eval in eval { + self.extend( + MakefileReader::read(self.args, Cursor::new(eval)) + .context("while evaling")?, + ); + } + } let line_type = LineType::of(&line_tokens); (line_tokens, line_type) } else { @@ -499,8 +513,6 @@ impl<'a, R: BufRead> MakefileReader<'a, R> { #[cfg(test)] mod test { - use std::io::Cursor; - use super::*; type R = Result<()>; @@ -545,7 +557,7 @@ endef } #[test] - #[ignore = "I still haven't implemented `eval` or %-based macro substitution."] + #[cfg(feature = "full")] fn eval() -> R { // This, for the record, is a terrible misfeature. // If you need this, you probably shouldn't be using Make. @@ -574,10 +586,10 @@ endef $(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog)))) $(PROGRAMS): - $(LINK.o) $^ $(LDLIBS) -o $@ +\t$(LINK.o) $^ $(LDLIBS) -o $@ clean: - rm -f $(ALL_OBJS) $(PROGRAMS) +\trm -f $(ALL_OBJS) $(PROGRAMS) "; let args = Args::empty(); -- cgit v1.2.3