Skip to content

Commit

Permalink
parser: fix escaped characters in raw lines with continuation
Browse files Browse the repository at this point in the history
  • Loading branch information
erikgrinaker committed Jun 29, 2024
1 parent cac20be commit 85a363b
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 21 deletions.
32 changes: 16 additions & 16 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::command::{Argument, Block, Command};
use nom::branch::alt;
use nom::bytes::complete::{escaped_transform, is_not, tag, take, take_while_m_n};
use nom::character::complete::{
alphanumeric1, anychar, char, line_ending, none_of, not_line_ending, one_of, space0, space1,
alphanumeric1, anychar, char, line_ending, not_line_ending, one_of, space0, space1,
};
use nom::combinator::{consumed, eof, map_res, opt, peek, recognize, value, verify};
use nom::error::ErrorKind;
Expand Down Expand Up @@ -258,20 +258,20 @@ fn comment(input: Span) -> IResult<Span> {
recognize(preceded(alt((tag("//"), tag("#"))), not_line_ending))(input)
}

/// Parses a line with \ line continuation escapes.
fn line_continuation(input: Span) -> IResult<String> {
// Special case a blank line.
let (input, maybe_newline) = opt(line_ending)(input)?;
if maybe_newline.is_some() {
return Ok((input, "".to_string()));
}
/// Parses a raw line with optional \ line continuation escapes. Naïve but
/// sufficient implementation that e.g. doesn't support \\ escapes.
fn line_continuation(mut input: Span) -> IResult<String> {
let mut result = String::new();
loop {
let (i, line) = terminated(not_line_ending, line_ending)(input)?;
input = i;
result.push_str(line.as_ref());

terminated(
escaped_transform(
none_of("\\\n"),
'\\',
alt((value("\\", tag("\\")), value("\n", line_ending))),
),
line_ending,
)(input)
if line.ends_with('\\') {
// Remove \ and continue.
result.pop();
continue;
}
return Ok((input, result));
}
}
9 changes: 4 additions & 5 deletions tests/scripts/commands
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,15 @@ Error: Command { name: "command arg", args: [], prefix: None, tags: {}, silent:
Command { name: "command arg", args: [], prefix: None, tags: {"tag"}, silent: false, fail: false, line_number: 79 }
prefix: Error: Command { name: "command arg", args: [], prefix: Some("prefix"), tags: {"tag"}, silent: false, fail: true, line_number: 80 }

# > respects \ line continuation, unless escaped.
# > respects \ line continuation, but it can't be escaped by \\.
> a very \
long line \
with line \
continuation
---
Command { name: "a very \nlong line \nwith line \ncontinuation", args: [], prefix: None, tags: {}, silent: false, fail: false, line_number: 88 }
Command { name: "a very long line with line continuation", args: [], prefix: None, tags: {}, silent: false, fail: false, line_number: 88 }

> a line ending with \\
> a line with \n ending with \\
another line
---
Command { name: "a line ending with \\", args: [], prefix: None, tags: {}, silent: false, fail: false, line_number: 95 }
Command { name: "another", args: [Argument { key: None, value: "line" }], prefix: None, tags: {}, silent: false, fail: false, line_number: 96 }
Command { name: "a line with \\n ending with \\another line", args: [], prefix: None, tags: {}, silent: false, fail: false, line_number: 95 }

0 comments on commit 85a363b

Please # to comment.