diff options
author | Melody Horn <melody@boringcactus.com> | 2021-04-04 15:17:12 -0600 |
---|---|---|
committer | Melody Horn <melody@boringcactus.com> | 2021-04-04 15:17:12 -0600 |
commit | 050a3b166123be17c8dfdbd47e1b439040101884 (patch) | |
tree | 412642ec257792972868d8638ef023a1caf32682 | |
parent | 8d990bbdcb51a97b3f9430f57f947507b138b488 (diff) | |
download | makers-050a3b166123be17c8dfdbd47e1b439040101884.tar.gz makers-050a3b166123be17c8dfdbd47e1b439040101884.zip |
don't assume something's an inference rule unless it's on the suffix list
-rw-r--r-- | src/makefile/input.rs | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/src/makefile/input.rs b/src/makefile/input.rs index b02cdb6..5afecc6 100644 --- a/src/makefile/input.rs +++ b/src/makefile/input.rs @@ -63,10 +63,16 @@ impl LineType { } } +#[derive(Debug)] +struct InferenceMatch<'a> { + s1: &'a str, + s2: &'a str, +} + fn inference_match<'a>( targets: &[&'a str], prerequisites: &[String], -) -> Option<regex::Captures<'a>> { +) -> Option<InferenceMatch<'a>> { lazy_static! { static ref INFERENCE_RULE: Regex = Regex::new(r"^(?P<s2>(\.[^/.]+)?)(?P<s1>\.[^/.]+)$").unwrap(); @@ -81,7 +87,10 @@ fn inference_match<'a>( && inference_match.is_some() && special_target_match.is_none(); if inference_rule { - inference_match + inference_match.map(|x| InferenceMatch { + s1: x.name("s1").unwrap().as_str(), + s2: x.name("s2").unwrap().as_str(), + }) } else { None } @@ -343,6 +352,15 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> { } } + fn special_target_has_prereq(&self, target: &str, name: &str) -> bool { + match self.targets.get(target) { + Some(target) => { + target.prerequisites.is_empty() || target.prerequisites.iter().any(|e| e == name) + } + None => false, + } + } + fn read_rule(&mut self, line_tokens: &TokenString, line_number: usize) -> Result<()> { let (targets, not_targets) = line_tokens .split_once(':') @@ -407,10 +425,23 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> { return Ok(()); } + // don't interpret things like `.tmp: ; mkdir -p $@` as single-suffix rules + let inference_match = inference_match.and_then(|inference| { + if (inference.s1.is_empty() + || self.special_target_has_prereq(".SUFFIXES", inference.s1)) + && (inference.s2.is_empty() + || self.special_target_has_prereq(".SUFFIXES", inference.s2)) + { + Some(inference) + } else { + None + } + }); + if let Some(inference_match) = inference_match { let new_rule = InferenceRule::new_suffix( - inference_match.name("s1").unwrap().as_str().to_owned(), - inference_match.name("s2").unwrap().as_str().to_owned(), + inference_match.s1.to_owned(), + inference_match.s2.to_owned(), commands, ); log::trace!( |