diff --git a/crates/bashkit/src/parser/lexer.rs b/crates/bashkit/src/parser/lexer.rs index 57f9f6aa..bcaa6bb8 100644 --- a/crates/bashkit/src/parser/lexer.rs +++ b/crates/bashkit/src/parser/lexer.rs @@ -954,6 +954,19 @@ impl<'a> Lexer<'a> { self.advance(); } } + Some('$') => { + // Check for $'...' ANSI-C quoting in continuation + let mut lookahead = self.chars.clone(); + lookahead.next(); // skip $ + if lookahead.next() == Some('\'') { + self.advance(); // consume $ + self.advance(); // consume opening ' + content.push_str(&self.read_dollar_single_quoted_content()); + } else { + content.push('$'); + self.advance(); + } + } Some(ch) if self.is_word_char(ch) => { content.push(ch); self.advance(); diff --git a/crates/bashkit/tests/spec_cases/bash/quote.test.sh b/crates/bashkit/tests/spec_cases/bash/quote.test.sh index 67060f21..a28ce6d1 100644 --- a/crates/bashkit/tests/spec_cases/bash/quote.test.sh +++ b/crates/bashkit/tests/spec_cases/bash/quote.test.sh @@ -274,3 +274,60 @@ echo 'say "hi"' ### expect say "hi" ### end + +### quote_ansi_c_concat_func_arg +# Issue #862: $'\n' concatenated in function argument position +show() { printf '%q\n' "$1"; } +show "a"$'\n'"b" +### expect +$'a\nb' +### end + +### quote_ansi_c_tab_concat_func_arg +# $'\t' concatenated in function argument position +show() { printf '%q\n' "$1"; } +show "a"$'\t'"b" +### expect +$'a\tb' +### end + +### quote_ansi_c_sole_arg +# $'\n' as sole function argument +show() { printf '%q\n' "$1"; } +show $'\n' +### expect +$'\n' +### end + +### quote_ansi_c_at_start +# $'\n' at start of concatenation +show() { printf '%q\n' "$1"; } +show $'\n'"after" +### expect +$'\nafter' +### end + +### quote_ansi_c_at_end +# $'\n' at end of concatenation +show() { printf '%q\n' "$1"; } +show "before"$'\n' +### expect +$'before\n' +### end + +### quote_ansi_c_multiple_segments +# Multiple ANSI-C segments concatenated +show() { printf '%q\n' "$1"; } +show "a"$'\n'"b"$'\t'"c" +### expect +$'a\nb\tc' +### end + +### quote_ansi_c_via_variable_baseline +# Baseline: ANSI-C via variable works +show() { printf '%q\n' "$1"; } +x="a"$'\n'"b" +show "${x}" +### expect +$'a\nb' +### end