From 457bcbfd1116f0b3330f9b409395beabffe6ca18 Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Wed, 14 Apr 2021 11:51:38 -0600 Subject: keep track of sources for inference rules too --- src/makefile/functions.rs | 17 ++++++++--------- src/makefile/inference_rules.rs | 18 ++++++++++++++++-- src/makefile/input.rs | 30 +++++++++++++++++++++++++----- src/makefile/macro.rs | 31 ++++++++++++++----------------- src/makefile/mod.rs | 33 +++++++++++++++++++++++---------- 5 files changed, 86 insertions(+), 43 deletions(-) diff --git a/src/makefile/functions.rs b/src/makefile/functions.rs index feb0e54..295e50f 100644 --- a/src/makefile/functions.rs +++ b/src/makefile/functions.rs @@ -6,8 +6,9 @@ use std::rc::Rc; use eyre::{bail, Result, WrapErr}; use super::pattern::r#match; -use super::r#macro::{Macro, Set as MacroSet, Source as MacroSource}; +use super::r#macro::{Macro, Set as MacroSet}; use super::token::TokenString; +use super::ItemSource; pub fn expand_call( name: &str, @@ -471,7 +472,7 @@ pub fn foreach( macros.set( var.clone(), Macro { - source: MacroSource::File, + source: ItemSource::FunctionCall, text: TokenString::text(word), #[cfg(feature = "full")] eagerly_expanded: false, @@ -495,7 +496,7 @@ pub fn call<'a>(macros: &MacroSet, args: impl Iterator) macros.set( i.to_string(), Macro { - source: MacroSource::File, + source: ItemSource::FunctionCall, text: TokenString::text(x), #[cfg(feature = "full")] eagerly_expanded: false, @@ -552,8 +553,6 @@ pub fn shell(macros: &MacroSet, command: &TokenString) -> Result { mod test { use super::*; - use crate::makefile::r#macro::{Set as MacroSet, Source as MacroSource}; - type R = Result<()>; fn call(name: &str, args: &[TokenString], macros: &MacroSet) -> Result { @@ -663,7 +662,7 @@ mod test { macros.set( "test1".to_owned(), Macro { - source: MacroSource::File, + source: ItemSource::Builtin, text: TokenString::text("something"), #[cfg(feature = "full")] eagerly_expanded: false, @@ -672,7 +671,7 @@ mod test { macros.set( "test2".to_owned(), Macro { - source: MacroSource::File, + source: ItemSource::Builtin, text: TokenString::text(""), #[cfg(feature = "full")] eagerly_expanded: false, @@ -764,7 +763,7 @@ mod test { macros.set( "test".to_owned(), Macro { - source: MacroSource::File, + source: ItemSource::Builtin, text: "worked for $(item).".parse()?, #[cfg(feature = "full")] eagerly_expanded: false, @@ -791,7 +790,7 @@ mod test { macros.set( "reverse".to_owned(), Macro { - source: MacroSource::File, + source: ItemSource::Builtin, text: "$(2) $(1)".parse()?, #[cfg(feature = "full")] eagerly_expanded: false, diff --git a/src/makefile/inference_rules.rs b/src/makefile/inference_rules.rs index 397e651..368d72b 100644 --- a/src/makefile/inference_rules.rs +++ b/src/makefile/inference_rules.rs @@ -5,9 +5,11 @@ use regex::Captures; use super::command_line::CommandLine; use super::pattern::r#match; +use super::ItemSource; #[derive(PartialEq, Eq, Clone, Debug)] pub struct InferenceRule { + pub source: ItemSource, pub products: Vec, pub prerequisites: Vec, pub commands: Vec, @@ -15,8 +17,14 @@ pub struct InferenceRule { impl InferenceRule { /// s1 is the product, s2 is the prereq - pub fn new_suffix(s1: String, s2: String, commands: Vec) -> Self { + pub fn new_suffix( + source: ItemSource, + s1: String, + s2: String, + commands: Vec, + ) -> Self { Self { + source, products: vec![format!("%{}", s1)], prerequisites: vec![format!("%{}", s2)], commands, @@ -72,7 +80,12 @@ mod test { #[test] fn suffix_match() -> R { - let rule = InferenceRule::new_suffix(".o".to_owned(), ".c".to_owned(), vec![]); + let rule = InferenceRule::new_suffix( + ItemSource::Builtin, + ".o".to_owned(), + ".c".to_owned(), + vec![], + ); assert!(rule.matches("foo.o")?); assert!(rule.matches("dir/foo.o")?); Ok(()) @@ -83,6 +96,7 @@ mod test { fn percent_match() -> R { // thanks, SPDX License List let rule = InferenceRule { + source: ItemSource::Builtin, products: vec!["licenseListPublisher-%.jar-valid".to_owned()], prerequisites: vec![ "licenseListPublisher-%.jar.asc".to_owned(), diff --git a/src/makefile/input.rs b/src/makefile/input.rs index 5a937f5..0e0506a 100644 --- a/src/makefile/input.rs +++ b/src/makefile/input.rs @@ -18,9 +18,10 @@ use super::conditional::{Line as ConditionalLine, State as ConditionalState}; use super::inference_rules::InferenceRule; #[cfg(feature = "full")] use super::r#macro::ExportConfig; -use super::r#macro::{Macro, Set as MacroSet, Source as MacroSource}; +use super::r#macro::{Macro, Set as MacroSet}; use super::target::Target; use super::token::{tokenize, Token, TokenString}; +use super::ItemSource; enum LineType { Rule, @@ -194,7 +195,7 @@ impl<'a, 'parent> MakefileReader<'a, 'parent, BufReader> { macros.set( "MAKEFILE_LIST".to_owned(), Macro { - source: MacroSource::Builtin, + source: ItemSource::Builtin, text: TokenString::text(path.as_ref().to_string_lossy()), #[cfg(feature = "full")] eagerly_expanded: false, @@ -651,6 +652,10 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> { #[cfg(feature = "full")] if is_pattern { let new_rule = InferenceRule { + source: ItemSource::File { + name: self.file_name.clone(), + line: line_number, + }, products: targets.into_iter().map(|x| x.to_owned()).collect(), prerequisites, commands, @@ -703,6 +708,10 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> { if let Some(inference_match) = inference_match { let new_rule = InferenceRule::new_suffix( + ItemSource::File { + name: self.file_name.clone(), + line: line_number, + }, inference_match.s1.to_owned(), inference_match.s2.to_owned(), commands, @@ -816,18 +825,26 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> { match self.macros.get(name) { // We always let command line or MAKEFLAGS macros override macros from the file. Some(Macro { - source: MacroSource::CommandLineOrMakeflags, + source: ItemSource::CommandLineOrMakeflags, .. }) => return Ok(()), // We let environment variables override macros from the file only if the command-line argument to do that was given Some(Macro { - source: MacroSource::Environment, + source: ItemSource::Environment, .. }) if self.args.environment_overrides => return Ok(()), Some(_) if skip_if_defined => return Ok(()), _ => {} } + log::trace!( + "{}:{}: setting macro {} to {}", + &self.file_name, + line_number, + name, + &value + ); + let value = match self.macros.pop(name) { Some(mut old_value) if append => { #[cfg(feature = "full")] @@ -843,7 +860,10 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> { old_value } _ => Macro { - source: MacroSource::File, + source: ItemSource::File { + name: self.file_name.clone(), + line: line_number, + }, text: value, #[cfg(feature = "full")] eagerly_expanded: expand_value, diff --git a/src/makefile/macro.rs b/src/makefile/macro.rs index fc3be51..2dfd84f 100644 --- a/src/makefile/macro.rs +++ b/src/makefile/macro.rs @@ -11,18 +11,11 @@ use regex::Regex; #[cfg(feature = "full")] use super::functions; use super::token::{Token, TokenString}; - -#[derive(Debug, Clone)] -pub enum Source { - File, - CommandLineOrMakeflags, - Environment, - Builtin, -} +use super::ItemSource; #[derive(Debug, Clone)] pub struct Macro { - pub source: Source, + pub source: ItemSource, pub text: TokenString, #[cfg(feature = "full")] pub eagerly_expanded: bool, @@ -121,7 +114,7 @@ impl<'parent, 'lookup> Set<'parent, 'lookup> { self.data.insert( k.into(), Macro { - source: Source::Builtin, + source: ItemSource::Builtin, text: v, #[cfg(feature = "full")] eagerly_expanded: false, @@ -136,7 +129,7 @@ impl<'parent, 'lookup> Set<'parent, 'lookup> { self.data.insert( k, Macro { - source: Source::Environment, + source: ItemSource::Environment, text: TokenString::text(v), #[cfg(feature = "full")] eagerly_expanded: false, @@ -277,23 +270,27 @@ impl<'parent, 'lookup> Set<'parent, 'lookup> { match self.data.get(name) { None => self.parent.map_or("undefined", |p| p.origin(name)), Some(Macro { - source: Source::Builtin, + source: ItemSource::Builtin, .. }) => "default", Some(Macro { - source: Source::Environment, + source: ItemSource::Environment, .. }) => "environment", // TODO figure out when to return "environment override" Some(Macro { - source: Source::File, + source: ItemSource::File { .. }, .. }) => "file", Some(Macro { - source: Source::CommandLineOrMakeflags, + source: ItemSource::CommandLineOrMakeflags, .. }) => "command line", - // TODO handle override and automatic + // TODO handle override + Some(Macro { + source: ItemSource::FunctionCall, + .. + }) => "automatic", } } @@ -416,7 +413,7 @@ mod test { macros.set( "oof".to_owned(), Macro { - source: Source::File, + source: ItemSource::Builtin, text: TokenString::text("bruh; swag; yeet;"), #[cfg(feature = "full")] eagerly_expanded: false, diff --git a/src/makefile/mod.rs b/src/makefile/mod.rs index eb06939..228a170 100644 --- a/src/makefile/mod.rs +++ b/src/makefile/mod.rs @@ -7,6 +7,14 @@ use std::rc::Rc; use eyre::{bail, eyre, Result, WrapErr}; +use command_line::CommandLine; +use inference_rules::InferenceRule; +use input::FinishedMakefileReader; +pub use input::MakefileReader; +use r#macro::{Macro, Set as MacroSet}; +use target::Target; +use token::TokenString; + use crate::args::Args; mod command_line; @@ -21,13 +29,14 @@ mod pattern; mod target; mod token; -use command_line::CommandLine; -use inference_rules::InferenceRule; -use input::FinishedMakefileReader; -pub use input::MakefileReader; -use r#macro::{Macro, Set as MacroSet, Source as MacroSource}; -use target::Target; -use token::TokenString; +#[derive(Debug, Clone, Eq, PartialEq)] +pub enum ItemSource { + File { name: String, line: usize }, + CommandLineOrMakeflags, + Environment, + Builtin, + FunctionCall, +} pub struct Makefile<'a> { inference_rules: Vec, @@ -63,7 +72,7 @@ impl<'a> Makefile<'a> { macros.set( name.into(), Macro { - source: MacroSource::CommandLineOrMakeflags, + source: ItemSource::CommandLineOrMakeflags, text: TokenString::text(value), #[cfg(feature = "full")] eagerly_expanded: false, @@ -78,7 +87,7 @@ impl<'a> Makefile<'a> { macros.set( "MAKECMDGOALS".to_owned(), Macro { - source: MacroSource::Builtin, + source: ItemSource::Builtin, text: TokenString::text(make_cmd_goals.join(" ")), #[cfg(feature = "full")] eagerly_expanded: false, @@ -89,7 +98,7 @@ impl<'a> Makefile<'a> { macros.set( "CURDIR".to_owned(), Macro { - source: MacroSource::Builtin, + source: ItemSource::Builtin, text: TokenString::text(curdir.to_string_lossy()), #[cfg(feature = "full")] eagerly_expanded: false, @@ -229,6 +238,7 @@ impl<'a> Makefile<'a> { }) .collect::>>(); if let Some(prereqs) = prereq_paths { + log::trace!("oh {} is a {:#?}", name, rule); new_target = Some(Target { name: name.into(), prerequisites: prereqs, @@ -264,6 +274,7 @@ impl<'a> Makefile<'a> { false }; if !self.targets.borrow().contains_key(name) || exists_but_infer_anyway { + log::trace!("trying to infer for {}", name); self.infer_target(name, vec![], vec![])?; } @@ -429,6 +440,7 @@ fn builtin_inference_rules() -> Vec { $($cmd:literal)+)+} => { vec![$( InferenceRule::new_suffix( + ItemSource::Builtin, prepend_dot!($($second)?).into(), concat!(".", stringify!($first)).into(), vec![$(CommandLine::from($cmd.parse().unwrap())),+], @@ -501,6 +513,7 @@ mod test { fn stem() -> R { let args = Args::empty(); let rule = InferenceRule { + source: ItemSource::Builtin, products: vec!["this-is-a-%-case".to_owned()], prerequisites: vec![], commands: vec![], -- cgit v1.2.3