aboutsummaryrefslogtreecommitdiff
path: root/src/makefile/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/makefile/mod.rs')
-rw-r--r--src/makefile/mod.rs54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/makefile/mod.rs b/src/makefile/mod.rs
index 2f73c70..0d4cded 100644
--- a/src/makefile/mod.rs
+++ b/src/makefile/mod.rs
@@ -13,11 +13,13 @@ use regex::Regex;
use crate::args::Args;
mod command_line;
+mod conditional;
mod inference_rules;
mod target;
mod token;
use command_line::CommandLine;
+use conditional::{ConditionalLine, ConditionalState};
use inference_rules::InferenceRule;
use target::Target;
use token::{tokenize, Token, TokenString};
@@ -151,6 +153,7 @@ impl<'a> Makefile<'a> {
pub(crate) fn and_read(&mut self, source: impl BufRead) {
let mut lines_iter = source.lines().enumerate().peekable();
+ let mut conditional_stack: Vec<ConditionalState> = vec![];
while let Some((line_number, line)) = lines_iter.next() {
// TODO handle I/O errors at all
let mut line = line.expect("failed to read line of makefile!");
@@ -170,6 +173,14 @@ impl<'a> Makefile<'a> {
}
let line = COMMENT.replace(&line, "").into_owned();
+ // skip lines if we need to
+ if conditional_stack
+ .last()
+ .map_or(false, ConditionalState::skipping)
+ {
+ continue;
+ }
+
// handle include lines
if let Some(line) = line.strip_prefix("include ") {
// remove extra leading space
@@ -181,6 +192,14 @@ impl<'a> Makefile<'a> {
for field in fields {
self.and_read_file(field);
}
+ } else if let Some(line) = ConditionalLine::from(&line, |t| self.expand_macros(t, None))
+ {
+ line.action(
+ conditional_stack.last(),
+ |name| self.macros.contains_key(name),
+ |t| self.expand_macros(t, None),
+ )
+ .apply_to(&mut conditional_stack);
} else if line.trim().is_empty() {
// handle blank lines
continue;
@@ -728,3 +747,38 @@ fn builtin_targets() -> Vec<Target> {
already_updated: Cell::new(false),
}]
}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ use std::io::Cursor;
+
+ fn empty_makefile(args: &Args) -> Makefile {
+ Makefile {
+ inference_rules: vec![],
+ macros: HashMap::new(),
+ targets: RefCell::new(HashMap::new()),
+ first_non_special_target: None,
+ args,
+ }
+ }
+
+ #[test]
+ fn basic_conditionals() {
+ let file = "
+ifeq (1,1)
+worked = yes
+else ifeq (2,2)
+worked = no
+endif
+ ";
+ let args = Args::empty();
+ let mut makefile = empty_makefile(&args);
+ makefile.and_read(Cursor::new(file));
+ assert_eq!(
+ makefile.expand_macros(&"$(worked)".parse().unwrap(), None),
+ "yes"
+ );
+ }
+}