Skip to content

Commit

Permalink
Ignore leading byte order mark in source files
Browse files Browse the repository at this point in the history
  • Loading branch information
casey committed Nov 5, 2021
1 parent f3abb95 commit 910badc
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ impl<'src> Lexer<'src> {
'@' => self.lex_single(At),
'[' => self.lex_delimiter(BracketL),
'\n' | '\r' => self.lex_eol(),
'\u{feff}' => self.lex_single(ByteOrderMark),
']' => self.lex_delimiter(BracketR),
'`' | '"' | '\'' => self.lex_string(),
'{' => self.lex_delimiter(BraceL),
Expand Down Expand Up @@ -926,6 +927,7 @@ mod tests {
BraceR => "}",
BracketL => "[",
BracketR => "]",
ByteOrderMark => "\u{feff}",
Colon => ":",
ColonEquals => ":=",
Comma => ",",
Expand Down
9 changes: 8 additions & 1 deletion src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,12 @@ impl<'tokens, 'src> Parser<'tokens, 'src> {
/// `Parser::next`
fn unexpected_token(&self) -> CompileResult<'src, CompileError<'src>> {
self.error(CompileErrorKind::UnexpectedToken {
expected: self.expected.iter().cloned().collect::<Vec<TokenKind>>(),
expected: self
.expected
.iter()
.cloned()
.filter(|kind| *kind != ByteOrderMark)
.collect::<Vec<TokenKind>>(),
found: self.next()?.kind,
})
}
Expand Down Expand Up @@ -302,6 +307,8 @@ impl<'tokens, 'src> Parser<'tokens, 'src> {

let mut eol_since_last_comment = false;

self.accept(ByteOrderMark)?;

loop {
let next = self.next()?;

Expand Down
4 changes: 3 additions & 1 deletion src/token_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub(crate) enum TokenKind {
BraceR,
BracketL,
BracketR,
ByteOrderMark,
Colon,
ColonEquals,
Comma,
Expand Down Expand Up @@ -51,6 +52,7 @@ impl Display for TokenKind {
BraceR => "'}'",
BracketL => "'['",
BracketR => "']'",
ByteOrderMark => "byte order mark",
Colon => "':'",
ColonEquals => "':='",
Comma => "','",
Expand All @@ -61,6 +63,7 @@ impl Display for TokenKind {
Eol => "end of line",
Equals => "'='",
EqualsEquals => "'=='",
EqualsTilde => "'=~'",
Identifier => "identifier",
Indent => "indent",
InterpolationEnd => "'}}'",
Expand All @@ -70,7 +73,6 @@ impl Display for TokenKind {
Plus => "'+'",
StringToken => "string",
Text => "command text",
EqualsTilde => "'=~'",
Unspecified => "unspecified",
Whitespace => "whitespace",
}
Expand Down
52 changes: 52 additions & 0 deletions tests/byte_order_mark.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use crate::common::*;

#[test]
fn ignore_leading_byte_order_mark() {
Test::new()
.justfile(
"
\u{feff}foo:
echo bar
",
)
.stderr("echo bar\n")
.stdout("bar\n")
.run();
}

#[test]
fn non_leading_byte_order_mark_produces_error() {
Test::new()
.justfile(
"
foo:
echo bar
\u{feff}
",
)
.stderr(
"
error: Expected \'@\', comment, end of file, end of line, or identifier, but found byte order mark
|
3 | \u{feff}
| ^
")
.status(EXIT_FAILURE)
.run();
}

#[test]
fn dont_mention_byte_order_mark_in_errors() {
Test::new()
.justfile("{")
.stderr(
"
error: Expected '@', comment, end of file, end of line, or identifier, but found '{'
|
1 | {
| ^
",
)
.status(EXIT_FAILURE)
.run();
}
1 change: 1 addition & 0 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod test;

mod assert_stdout;
mod assert_success;
mod byte_order_mark;
mod changelog;
mod choose;
mod command;
Expand Down

0 comments on commit 910badc

Please sign in to comment.