Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion crates/bashkit/src/parser/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,10 @@ impl<'a> Lexer<'a> {
self.advance();
if let Some(next) = self.peek_char() {
match next {
'\n' => {
// \<newline> is line continuation: discard both
self.advance();
}
'"' | '\\' | '$' | '`' => {
word.push(next);
self.advance();
Expand Down Expand Up @@ -578,7 +582,11 @@ impl<'a> Lexer<'a> {
if let Some(next) = self.peek_char() {
// Handle escape sequences
match next {
'"' | '\\' | '$' | '`' | '\n' => {
'\n' => {
// \<newline> is line continuation: discard both
self.advance();
}
'"' | '\\' | '$' | '`' => {
content.push(next);
self.advance();
}
Expand Down
40 changes: 40 additions & 0 deletions crates/bashkit/tests/spec_cases/bash/variables.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -408,3 +408,43 @@ x=hello; echo ${x@A}
### expect
x='hello'
### end

### var_line_continuation_dquote
# Backslash-newline inside double quotes is line continuation
echo "hel\
lo"
### expect
hello
### end

### var_line_continuation_dquote_var
# Line continuation in double-quoted variable assignment
x="abc\
def"; echo "$x"
### expect
abcdef
### end

### var_line_continuation_dquote_multi
# Multiple line continuations
echo "one\
two\
three"
### expect
onetwothree
### end

### var_line_continuation_unquoted
# Backslash-newline in unquoted context
echo hel\
lo
### expect
hello
### end

### var_line_continuation_preserves_other_escapes
# Backslash before non-newline in double quotes is preserved
echo "hello\tworld"
### expect
hello\tworld
### end
8 changes: 4 additions & 4 deletions specs/009-implementation-status.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,16 @@ Bashkit implements IEEE 1003.1-2024 Shell Command Language. See

## Spec Test Coverage

**Total spec test cases:** 1194 (1189 pass, 5 skip)
**Total spec test cases:** 1199 (1194 pass, 5 skip)

| Category | Cases | In CI | Pass | Skip | Notes |
|----------|-------|-------|------|------|-------|
| Bash (core) | 833 | Yes | 828 | 5 | `bash_spec_tests` in CI |
| Bash (core) | 838 | Yes | 833 | 5 | `bash_spec_tests` in CI |
| AWK | 96 | Yes | 96 | 0 | loops, arrays, -v, ternary, field assign, getline, %.6g |
| Grep | 76 | Yes | 76 | 0 | -z, -r, -a, -b, -H, -h, -f, -P, --include, --exclude, binary detect |
| Sed | 75 | Yes | 75 | 0 | hold space, change, regex ranges, -E |
| JQ | 114 | Yes | 114 | 0 | reduce, walk, regex funcs, --arg/--argjson, combined flags, input/inputs, env |
| **Total** | **1194** | **Yes** | **1189** | **5** | |
| **Total** | **1199** | **Yes** | **1194** | **5** | |

### Bash Spec Tests Breakdown

Expand Down Expand Up @@ -156,7 +156,7 @@ Bashkit implements IEEE 1003.1-2024 Shell Command Language. See
| test-operators.test.sh | 17 | file/string tests |
| time.test.sh | 11 | Wall-clock only (user/sys always 0) |
| timeout.test.sh | 17 | |
| variables.test.sh | 58 | includes special vars, prefix env, PIPESTATUS, trap EXIT, `${var@Q}` |
| variables.test.sh | 63 | includes special vars, prefix env, PIPESTATUS, trap EXIT, `${var@Q}`, `\<newline>` line continuation |
| wc.test.sh | 35 | word count (5 skipped) |
| type.test.sh | 15 | `type`, `which`, `hash` builtins |
| declare.test.sh | 10 | `declare`/`typeset`, `-i`, `-r`, `-x`, `-a`, `-p` |
Expand Down
Loading