diff options
| author | Melody Horn <melody@boringcactus.com> | 2021-04-03 18:27:36 -0600 | 
|---|---|---|
| committer | Melody Horn <melody@boringcactus.com> | 2021-04-03 18:27:36 -0600 | 
| commit | e84322e5c45c5bc44a228e7912b5d50d7e91b841 (patch) | |
| tree | a7f19ffbce12eb2b58fbafa7115cbdf1a49117cf /src | |
| parent | 13b90ab94dd884be95207e3004c65657db815ffa (diff) | |
| download | makers-e84322e5c45c5bc44a228e7912b5d50d7e91b841.tar.gz makers-e84322e5c45c5bc44a228e7912b5d50d7e91b841.zip | |
finally fix newlines & peeking
until something else breaks, at least
Diffstat (limited to 'src')
| -rw-r--r-- | src/makefile/input.rs | 45 | 
1 files changed, 37 insertions, 8 deletions
| diff --git a/src/makefile/input.rs b/src/makefile/input.rs index 3a3508f..7c699f1 100644 --- a/src/makefile/input.rs +++ b/src/makefile/input.rs @@ -140,6 +140,8 @@ pub struct MakefileReader<'a, 'parent, R: BufRead> {      pub first_non_special_target: Option<String>,      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>,  } @@ -167,6 +169,7 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> {              first_non_special_target: None,              args,              lines_iter: source.lines().line_numbered().peekable(), +            pending_line: None,              #[cfg(feature = "full")]              conditional_stack: Vec::new(),          }; @@ -175,7 +178,7 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> {      }      fn read_all(&mut self) -> Result<()> { -        while let Some((line_number, line)) = self.next_line(" ") { +        while let Some((line_number, line)) = self.next_line(" ", false) {              let line = line?;              // handle include lines @@ -253,7 +256,14 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> {      fn next_line(          &mut self,          escaped_newline_replacement: &'static str, +        peeking: bool,      ) -> Option<(usize, Result<String>)> { +        if let Some((line_number, line)) = self.pending_line.take() { +            if peeking { +                self.pending_line = Some((line_number, line.clone())); +            } +            return Some((line_number, Ok(line.join(escaped_newline_replacement)))); +        }          while let Some((line_number, line)) = self.lines_iter.next() {              let mut line = match line {                  Ok(x) => x, @@ -261,17 +271,18 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> {              };              // handle escaped newlines -            while line.ends_with('\\') { -                line.pop(); -                line.push_str(escaped_newline_replacement); +            let mut line_pieces = vec![line]; +            while line_pieces.last().map_or(false, |p| p.ends_with('\\')) { +                line_pieces.last_mut().map(|x| x.pop());                  if let Some((n, x)) = self.lines_iter.next() {                      let x = match x {                          Ok(x) => x,                          Err(err) => return Some((n, Err(err))),                      }; -                    line.push_str(x.trim_start()) +                    line_pieces.push(x.trim_start().to_string());                  }              } +            line = line_pieces.join(escaped_newline_replacement);              // handle comments              lazy_static! { @@ -310,6 +321,9 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> {                  }              } +            if peeking { +                self.pending_line = Some((line_number, line_pieces)); +            }              return Some((line_number, Ok(line)));          }          None @@ -322,8 +336,8 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> {          escaped_newline_replacement: &'static str,          predicate: impl FnOnce(&(usize, Result<String>)) -> bool,      ) -> Option<(usize, Result<String>)> { -        if predicate(self.lines_iter.peek()?) { -            self.next_line(escaped_newline_replacement) +        if predicate(&self.next_line(escaped_newline_replacement, true)?) { +            self.next_line(escaped_newline_replacement, false)          } else {              None          } @@ -446,7 +460,7 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> {              }              let mut value = TokenString::empty();              // TODO what should be done with escaped newlines -            while let Some((_, line)) = self.next_line(" ") { +            while let Some((_, line)) = self.next_line(" ", false) {                  let line = line?;                  if line == "endef" {                      break; @@ -596,6 +610,21 @@ endif      #[cfg(feature = "full")]      #[test] +    fn condition_in_rule() -> R { +        let file = " +a: +ifeq (1,1) +\tfoo +endif +        "; +        let args = Args::empty(); +        let makefile = MakefileReader::read(&args, MacroSet::new(), Cursor::new(file))?; +        assert_eq!(makefile.targets["a"].commands.len(), 1); +        Ok(()) +    } + +    #[cfg(feature = "full")] +    #[test]      fn define_syntax() -> R {          let file = "  define foo = |