===== CASE: FOO=1 break ===== FOO=1 break ^~~~ [ -c flag ]:1: Control flow shouldn't have environment bindings ===== CASE: break 1 2 ===== break 1 2 ^ [ -c flag ]:1: Unexpected argument to 'break' ===== CASE: x"y"() { echo hi; } ===== x"y"() { echo hi; } ^ [ -c flag ]:1: Invalid function name ===== CASE: function x"y" { echo hi; } ===== function x"y" { echo hi; } ^ [ -c flag ]:1: Invalid KSH-style function name ===== CASE: } ===== } ^ [ -c flag ]:1: Unexpected right brace ===== CASE: case foo in *) echo ===== case foo in *) echo ^ [ -c flag ]:1: Expected ;; or esac ===== CASE: ls foo| ===== ls foo| ^ [ -c flag ]:1: Unexpected EOF while parsing command ===== CASE: ls foo&& ===== ls foo&& ^ [ -c flag ]:1: Unexpected EOF while parsing command ===== CASE: foo() ===== foo() ^ [ -c flag ]:1: Unexpected word while parsing compound command ===== CASE: break >out ===== (command.ControlFlow token:) ===== CASE: break >out ===== break >out ^~~~~ [ -c flag ]:1: Control flow shouldn't have redirects ===== CASE: [ ( x ] ===== [ ( x ] ^ [ -c flag ]:1: Syntax error in expression (near Id.Op_RBracket) ===== CASE: PYTHONPATH=. FOO=(1 2) python ===== PYTHONPATH=. FOO=(1 2) python ^~~~ [ -c flag ]:1: Environment bindings can't contain array literals ===== CASE: PYTHONPATH+=1 python ===== PYTHONPATH+=1 python ^~~~~~~~~~~~ [ -c flag ]:1: Expected = in environment binding, got += ===== CASE: echo line 2 echo $( echo ===== echo $( echo ^ [ -c flag ]:3: Invalid word while parsing command list ===== CASE: echo line 2 echo ` echo ===== echo ` echo ^ [ -c flag ]:3: Unexpected EOF while looking for closing backtick ===== CASE: echo line 2 echo ` echo \` ===== echo ` echo \` ^ [ -c flag ]:3: Unexpected EOF while looking for closing backtick ===== CASE: echo line 2 echo ` echo \`unclosed ` ===== echo ` echo \`unclosed ` ^ [ backticks in [ -c flag ] ]:3: Unexpected EOF while looking for closing backtick ===== CASE: echo < << ===== echo < << ^~ [ -c flag ]:1: Invalid token after redirect operator ===== CASE: echo $( echo > >> ) ===== echo $( echo > >> ) ^~ [ -c flag ]:1: Invalid token after redirect operator ===== CASE: cat < right: {} ) cond: (arith_expr.Binary op_id:Id.Arith_Less left: right:{}) update: (arith_expr.UnaryAssign op_id:Id.Node_PostDPlus child:) body: (command.DoGroup children: [ (command.Sentence child: (C {} {($ Id.VSub_DollarName '$x')}) terminator: ) ] ) ) ===== CASE: for ((; x<5; x++)); do echo $x; done ===== (command.ForExpr cond: (arith_expr.Binary op_id:Id.Arith_Less left: right:{}) update: (arith_expr.UnaryAssign op_id:Id.Node_PostDPlus child:) body: (command.DoGroup children: [ (command.Sentence child: (C {} {($ Id.VSub_DollarName '$x')}) terminator: ) ] ) ) ===== CASE: for ((; ; x++)); do echo $x; done ===== (command.ForExpr update: (arith_expr.UnaryAssign op_id:Id.Node_PostDPlus child:) body: (command.DoGroup children: [ (command.Sentence child: (C {} {($ Id.VSub_DollarName '$x')}) terminator: ) ] ) ) ===== CASE: for ((; ;)); do echo $x; done ===== (command.ForExpr body: (command.DoGroup children: [ (command.Sentence child: (C {} {($ Id.VSub_DollarName '$x')}) terminator: ) ] ) ) ===== CASE: for ((x=0; x<5; x++ b)); do echo $x; done ===== for ((x=0; x<5; x++ b)); do echo $x; done ^ [ -c flag ]:1: Unexpected token after arithmetic expression (Id.Word_Compound != Id.Arith_RParen) ===== CASE: for ((x=0 b; x<5; x++)); do echo $x; done ===== for ((x=0 b; x<5; x++)); do echo $x; done ^ [ -c flag ]:1: Expected ; here ===== CASE: for ((x=0; x<5 b; x++)); do echo $x; done ===== for ((x=0; x<5 b; x++)); do echo $x; done ^ [ -c flag ]:1: Expected ; here ===== CASE: ${a:1+2 b} ===== ${a:1+2 b} ^ [ -c flag ]:1: Expected : or } in slice ===== CASE: ${a:1+2:3+4 b} ===== ${a:1+2:3+4 b} ^ [ -c flag ]:1: Unexpected token after arithmetic expression (Id.Word_Compound != Id.Arith_RBrace) ===== CASE: ${a[1+2 b]} ===== ${a[1+2 b]} ^ [ -c flag ]:1: Unexpected token after arithmetic expression (Id.Word_Compound != Id.Arith_RBracket) ===== CASE: $(( 1 + + )) ===== $(( 1 + + )) ^ [ -c flag ]:1: Token can't be used in prefix position ===== CASE: $(( 1 2 )) ===== $(( 1 2 )) ^ [ -c flag ]:1: Unexpected token after arithmetic expression (Id.Word_Compound != Id.Arith_RParen) ===== CASE: $(( - ; )) ===== $(( - ; )) ^ [ -c flag ]:1: Token can't be used in prefix position ===== CASE: $(( ` )) ===== $(( ` )) ^ [ -c flag ]:1: Unexpected EOF while looking for closing backtick ===== CASE: $(( $ )) ===== $(( $ )) ^ [ -c flag ]:1: Unexpected token while parsing arithmetic: '$' ===== CASE: $(( ${var} = fd )) ===== $(( ${var} = fd )) ^ [ -c flag ]:1: Left-hand side of this assignment is invalid ===== CASE: $(( x+1 = 42 )) ===== $(( x+1 = 42 )) ^ [ -c flag ]:1: Left-hand side of this assignment is invalid ===== CASE: $(( (x+42)++ )) ===== $(( (x+42)++ )) ^~ [ -c flag ]:1: Left-hand side of this assignment is invalid ===== CASE: $(( ++(x+42) )) ===== $(( ++(x+42) )) ^~ [ -c flag ]:1: Left-hand side of this assignment is invalid ===== CASE: $(( 1 = foo )) ===== $(( 1 = foo )) ^ [ -c flag ]:1: Left-hand side of this assignment is invalid ===== CASE: $(( 1++ )) ===== $(( 1++ )) ^~ [ -c flag ]:1: Left-hand side of this assignment is invalid ===== CASE: $(( ++1 )) ===== $(( ++1 )) ^~ [ -c flag ]:1: Left-hand side of this assignment is invalid ===== CASE: [[ a b ]] ===== [[ a b ]] ^ [ -c flag ]:1: Expected ]] ===== CASE: [[ a "a"$(echo hi)"b" ]] ===== [[ a "a"$(echo hi)"b" ]] ^ [ -c flag ]:1: Expected ]] ===== CASE: [[ a == ]] ===== [[ a == ]] ^ [ -c flag ]:1: Expected ]] ===== CASE: [[ ( 1 == 2 - ]] ===== [[ ( 1 == 2 - ]] ^ [ -c flag ]:1: Expected ), got (compound_word parts:[(Token id:Id.Lit_Chars span_id:10 val:-)]) ===== CASE: [[ == ]] ===== [[ == ]] ^~ [ -c flag ]:1: Unexpected token in boolean expression (Id.BoolBinary_GlobDEqual) ===== CASE: [[ ) ]] ===== [[ ) ]] ^ [ -c flag ]:1: Unexpected token in boolean expression (Id.Op_RParen) ===== CASE: [[ ( ]] ===== [[ ( ]] ^~ [ -c flag ]:1: Unexpected token in boolean expression (Id.Lit_DRightBracket) ===== CASE: [[ ;;; ]] ===== [[ ;;; ]] ^~ [ -c flag ]:1: Unexpected token in boolean expression (Id.Op_DSemi) ===== CASE: [[ ===== [[ ^ [ -c flag ]:1: Unexpected token in boolean expression (Id.Eof_Real) ===== CASE: [ x -a y f ] ===== [ x -a y f ] ^ [ -c flag ]:1: (test) Unexpected trailing word 'f' ===== CASE: test x -a y f ===== test x -a y f ^ [ -c flag ]:1: (test) Unexpected trailing word 'f' ===== CASE: [ x ===== [ x ^ [ -c flag ]:1: missing closing ] ===== CASE: [ x x ] ===== [ x x ] ^ [ -c flag ]:1: (test) Expected unary operator, got 'x' (2 args) ===== CASE: [ x x "a b" ] ===== [ x x "a b" ] ^ [ -c flag ]:1: (test) Expected binary operator, got 'x' (3 args) ===== CASE: [ -t xxx ] ===== [ -t xxx ] ^~~ [ -c flag ]:1: (test) Invalid file descriptor 'xxx' ===== CASE: [ \( x -a -y -a z ] ===== [??? no location ???] (test) Expected ), got EOF ===== CASE: printf % ===== % ^ [ printf word at line 1 of [ -c flag ] ]:1: Expected a printf format character ===== CASE: printf [%Z] ===== [%Z] ^ [ printf word at line 1 of [ -c flag ] ]:1: Invalid printf format character ===== CASE: printf -v "-invalid-" %s foo ===== -invalid- ^ [ dynamic place word at ? ]:1: Unexpected end of input printf -v "-invalid-" %s foo ^~~~~~ [ -c flag ]:1: 'printf' got invalid place expression ===== CASE: shift 1 2 ===== shift 1 2 ^~~~~ [ -c flag ]:1: 'shift' got too many arguments ===== CASE: shift zzz ===== shift zzz ^~~~~ [ -c flag ]:1: 'shift' Invalid shift argument 'zzz' ===== CASE: pushd x y ===== pushd x y ^ [ -c flag ]:1: 'pushd' got too many arguments ===== CASE: pwd -x ===== pwd -x ^~ [ -c flag ]:1: 'pwd' doesn't accept flag -x ===== CASE: pp x foo a-x ===== pp x foo a-x ^ [ -c flag ]:1: 'pp' got invalid action 'x' ===== CASE: wait zzz ===== wait zzz ^~~ [ -c flag ]:1: 'wait' expected PID or jobspec, got 'zzz' ===== CASE: wait %jobspec-not-supported ===== wait %jobspec-not-supported ^ [ -c flag ]:1: 'wait' doesn't support bash-style jobspecs (got '%jobspec-not-supported') ===== CASE: unset invalid-var-name ===== unset invalid-var-name ^~~~~ [ -c flag ]:1: fatal: Invalid place to modify ===== CASE: getopts hc: invalid-var-name ===== getopts hc: invalid-var-name ^~~~~~~~~~~~~~~~ [ -c flag ]:1: 'getopts' got invalid variable name 'invalid-var-name' ===== CASE: read -x ===== read -x ^~ [ -c flag ]:1: 'read' doesn't accept flag -x ===== CASE: builtin read -x ===== builtin read -x ^~ [ -c flag ]:1: 'read' doesn't accept flag -x ===== CASE: read -n ===== read -n ^~ [ -c flag ]:1: 'read' expected argument to '-n' ===== CASE: read -n x ===== read -n x ^ [ -c flag ]:1: 'read' expected integer after -n, got 'x' ===== CASE: set -o errexit +o oops ===== set -o errexit +o oops ^~~ [ -c flag ]:1: 'set' got invalid option 'oops' osh usage error: got invalid argument 'x' to '-ast-format', expected one of: text|abbrev-text|html|abbrev-html|oheap|none oil: got invalid option 'oops' ===== CASE: echo {1..3..-1} ===== echo {1..3..-1} ^~~~~~~~ [ -c flag ]:1: Invalid step -1 for ascending integer range ===== CASE: echo {1..3..0} ===== echo {1..3..0} ^~~~~~~ [ -c flag ]:1: Step can't be 0 ===== CASE: echo {3..1..1} ===== echo {3..1..1} ^~~~~~~ [ -c flag ]:1: Invalid step 1 for descending integer range ===== CASE: echo {3..1..0} ===== echo {3..1..0} ^~~~~~~ [ -c flag ]:1: Step can't be 0 ===== CASE: echo {a..Z} ===== echo {a..Z} ^~~~ [ -c flag ]:1: Mismatched cases in character range ===== CASE: echo {a..z..0} ===== echo {a..z..0} ^~~~~~~ [ -c flag ]:1: Step can't be 0 ===== CASE: echo {a..z..-1} ===== echo {a..z..-1} ^~~~~~~~ [ -c flag ]:1: Invalid step -1 for ascending character range ===== CASE: echo {z..a..1} ===== echo {z..a..1} ^~~~~~~ [ -c flag ]:1: Invalid step 1 for descending character range ===== CASE: var x = 1 + ===== var x = 1 + ^ [ -c flag ]:1: Syntax error in expression (near Id.Eof_Real) ===== CASE: var x = * ===== var x = * ^ [ -c flag ]:1: Syntax error in expression (near Id.Arith_Star) ===== CASE: var x = @($(cat <out { echo hi } ===== >out { echo hi } ^ [ -c flag ]:1: Unexpected typed args ===== CASE: a=1 b=2 { echo hi } ===== a=1 b=2 { echo hi } ^~ [ -c flag ]:1: Use const or var/setvar to assign in Oil (parse_sh_assign) ===== CASE: break { echo hi } ===== break { echo hi } ^ [ -c flag ]:1: Unexpected typed args ===== CASE: cd / { echo hi } cd / ===== cd / { echo hi } cd / ^~ [ -c flag ]:1: Invalid word while parsing command line ===== CASE: if test -f foo{ echo hi } ===== if test -f foo{ echo hi } ^~~ [ -c flag ]:1: Word has unbalanced { }. Maybe add a space or quote it like \{ ===== CASE: var x = / ! / ===== var x = / ! / ^ [ -c flag ]:1: Syntax error in expression (near Id.Arith_Slash) ===== CASE: var x = / ![a-z] / ===== (command.VarDecl keyword: lhs: [(name_type name:)] rhs: (expr.RegexLiteral left: regex: (re.CharClassLiteral negated: T terms: [(class_literal_term.Range start: end:)] ) ) ) ===== CASE: var x = / !d / ===== (command.VarDecl keyword: lhs: [(name_type name:)] rhs: (expr.RegexLiteral left: regex:(perl_class negated:(Id.Expr_Bang) name:d)) ) ===== CASE: var x = / !! / ===== var x = / !! / ^ [ -c flag ]:1: Syntax error in expression (near Id.Arith_Slash) ===== CASE: var x = /[a-zA-Z]/ ===== var x = /[a-zA-Z]/ ^ [ -c flag ]:1: Syntax error in expression (near Id.Arith_Minus) ===== CASE: var x = /[a-z0-9]/ ===== var x = /[a-z0-9]/ ^ [ -c flag ]:1: Syntax error in expression (near Id.Arith_Minus) ===== CASE: var x = /[a-zz]/ ===== var x = /[a-zz]/ ^~ [ -c flag ]:1: Range start/end shouldn't have more than one character ===== CASE: var x = /['ab'-'z']/ ===== var x = /['ab'-'z']/ ^ [ -c flag ]:1: Range start/end shouldn't have more than one character ===== CASE: var x = /[$a-${z}]/ ===== var x = /[$a-${z}]/ ^ [ -c flag ]:1: Syntax error in expression (near Id.Arith_Minus) ===== CASE: var x = /[abc]/ ===== var x = /[abc]/ ^~~ [ -c flag ]:1: 'abc' isn't a character class ===== CASE: var x = /[% _]/ ===== var x = /[% _]/ ^ [ -c flag ]:1: Syntax error in expression (near Id.Arith_Percent) ===== CASE: proc f[] { echo hi } ===== proc f[] { echo hi } ^~ [ -c flag ]:1: Invalid proc name 'f[' ===== CASE: proc : { echo hi } ===== proc : { echo hi } ^ [ -c flag ]:1: Invalid proc name ':' ===== CASE: proc foo::bar { echo hi } ===== proc foo::bar { echo hi } ^~ [ -c flag ]:1: Syntax error in expression (near Id.Expr_DColon) ===== CASE: json write (x) ===== (command.Simple words:[{} {}] typed_args:(ArgList positional:[(Var x)]) do_fork:T) ===== CASE: echo $(json write (x)) ===== (C {} { (command_sub left_token: child: (command.Simple words: [{} {}] typed_args: (ArgList positional:[(Var x)]) do_fork: T ) ) } ) ===== CASE: var result = $(json write (x)) ===== (command.VarDecl keyword: lhs: [(name_type name:)] rhs: (command_sub left_token: child: (command.Simple words: [{} {}] typed_args: (ArgList positional:[(Var x)]) do_fork: T ) ) ) ===== CASE: json write (x, y); echo hi ===== (command.CommandList children: [ (command.Sentence child: (command.Simple words: [{} {}] typed_args: (ArgList positional:[(Var x) (Var y)]) do_fork: T ) terminator: ) (C {} {}) ] ) ===== CASE: json write (x, name = "value") echo hi ===== (command.CommandList children: [ (command.Simple words: [{} {}] typed_args: (ArgList positional: [(Var x)] named: [(named_arg name: value:(DQ ))] ) do_fork: T ) (C {} {}) ] ) ===== CASE: json write (x) { echo hi } ===== (command.Simple words: [{} {}] typed_args: (ArgList positional:[(Var x)]) block: (BraceGroup children:[(C {} {})]) do_fork: T ) ===== CASE: json write (x) { echo hi } ===== (command.Simple words: [{} {}] typed_args: (ArgList positional:[(Var x)]) block: (BraceGroup children:[(C {} {})]) do_fork: T ) ===== CASE: json write ( x, y, z ) ===== (command.Simple words: [{} {}] typed_args: (ArgList positional:[(Var x) (Var y) (Var z)]) do_fork: T ) ===== CASE: json write () ===== json write () ^ [ -c flag ]:1: Empty arg list not allowed ===== CASE: json write ( ) ===== json write ( ) ^ [ -c flag ]:1: Empty arg list not allowed ===== CASE: json write(x) ===== json write(x) ^ [ -c flag ]:1: Space required before ( ===== CASE: json write() ===== json write() ^ [ -c flag ]:1: Space required before ( ===== CASE: f(x) ===== f(x) ^ [ -c flag ]:1: Space required before ( ===== CASE: = 5 mod 3 ===== = 5 mod 3 ^~~ [ -c flag ]:1: Syntax error in expression (near Id.Expr_Name) ===== CASE: = >>= ===== = >>= ^~~ [ -c flag ]:1: Syntax error in expression (near Id.Arith_DGreatEqual) ===== CASE: = %( ===== = %( ^ [ -c flag ]:1: Unexpected token in array literal: '' ===== CASE: = 42, ===== = 42, ^ [ -c flag ]:1: Write singleton tuples with tup(), not a trailing comma ===== CASE: = (42,) ===== = (42,) ^ [ -c flag ]:1: Write singleton tuples with tup(), not a trailing comma ===== CASE: =a ===== =a ^ [ -c flag ]:1: =word isn't allowed. Hint: either quote it or add a space after = to pretty print an expression ===== CASE: if (5 == 5) { echo yes } ===== if (5 == 5) { echo yes } ^~ [ -c flag ]:1: Use === to be exact, or ~== to convert types ===== CASE: name=val ===== name=val ^~~~~ [ -c flag ]:2: Use const or var/setvar to assign in Oil (parse_sh_assign) ===== CASE: name = val ===== name = val ^ [ -c flag ]:2: Unexpected = (Hint: use const/var/setvar, or quote it) ===== CASE: rule { x = 42 } ===== x = 42 ^ [ -c flag ]:3: Unexpected = (Hint: use const/var/setvar, or quote it) ===== CASE: RULE { x = 42 } ===== x = 42 ^ [ -c flag ]:3: Unexpected = (Hint: use const/var/setvar, or quote it) ===== CASE: Rule { x = 42 } ===== (command.Simple words: [{}] block: (BraceGroup children: [(command.VarDecl lhs:[(name_type name:)] rhs:(Const Id.Expr_DecInt 42))] ) do_fork: T ) ===== CASE: Rule X Y { x = 42 } ===== (command.Simple words: [{} {} {}] block: (BraceGroup children: [(command.VarDecl lhs:[(name_type name:)] rhs:(Const Id.Expr_DecInt 42))] ) do_fork: T ) ===== CASE: RULe { # inconsistent but OK x = 42 } ===== (command.Simple words: [{}] block: (BraceGroup children: [(command.VarDecl lhs:[(name_type name:)] rhs:(Const Id.Expr_DecInt 42))] ) do_fork: T ) ===== CASE: hay eval :result { Rule { foo = 42 } bar = 43 # parse error here } ===== bar = 43 # parse error here ^ [ -c flag ]:8: Unexpected = (Hint: use const/var/setvar, or quote it) ===== CASE: hay define TASK TASK build { foo = 42 } ===== foo = 42 ^ [ -c flag ]:5: Unexpected = (Hint: use const/var/setvar, or quote it) ===== CASE: hay define Package/TASK Package libc { TASK build { foo = 42 } } ===== foo = 42 ^ [ -c flag ]:6: Unexpected = (Hint: use const/var/setvar, or quote it) ===== CASE: echo $'\u{03bc' ===== (C {} { (single_quoted left: tokens: [ ] multiline: F ) } ) ===== CASE: +O parse_backslash -n -c echo parse_backslash $'\u{03bc' ===== echo parse_backslash $'\u{03bc' ^ [ -c flag ]:1: Invalid char escape in C-style string literal ===== CASE: const bad = $'\u{03bc' ===== const bad = $'\u{03bc' ^ [ -c flag ]:1: Invalid char escape in C-style string literal ===== CASE: echo $'\z' ===== (C {} { (single_quoted left: tokens: [ ] multiline: F ) } ) ===== CASE: const bad = $'\z' ===== const bad = $'\z' ^ [ -c flag ]:1: Invalid char escape in C-style string literal ===== CASE: echo $'\101' ===== (C {} { (single_quoted left: tokens: [] multiline: F ) } ) ===== CASE: const bad = $'\101' ===== const bad = $'\101' ^~~~ [ -c flag ]:1: Use \xhh or \u{...} instead of octal escapes in Oil strings ===== CASE: const bad = c'\xf' ===== const bad = c'\xf' ^ [ -c flag ]:1: Syntax error in expression (near Id.Left_SingleQuote) ===== CASE: echo "\z" ===== (C {} {(DQ )}) ===== CASE: +O parse_backslash -n -c echo parse_backslash "\z" ===== echo parse_backslash "\z" ^ [ -c flag ]:1: Invalid char escape in double quoted string ===== CASE: echo "\z" ===== echo "\z" ^ [ -c flag ]:1: Invalid char escape in double quoted string ===== CASE: const bad = "\z" ===== const bad = "\z" ^ [ -c flag ]:1: Invalid char escape in double quoted string ===== CASE: echo "\u1234" ===== (C {} {(DQ )}) ===== CASE: echo "\u1234" ===== echo "\u1234" ^ [ -c flag ]:1: Invalid char escape in double quoted string ===== CASE: const bad = "\u1234" ===== const bad = "\u1234" ^ [ -c flag ]:1: Invalid char escape in double quoted string ===== CASE: echo "`echo hi`" ===== (C {} {(DQ (command_sub left_token: child:(C {} {})))}) ===== CASE: echo "`echo hi`" ===== echo "`echo hi`" ^ [ -c flag ]:1: Use $(cmd) instead of backticks (parse_backticks) ===== CASE: const bad = "`echo hi`" ===== const bad = "`echo hi`" ^ [ -c flag ]:1: Invalid backtick: use $(cmd) or \` in Oil strings ===== CASE: setvar x = "\z" ===== setvar x = "\z" ^ [ -c flag ]:1: Invalid char escape in double quoted string ===== CASE: ===== osh usage error: expected argument to '-c' ===== CASE: echo `echo hi` ===== (C {} {(command_sub left_token: child:(C {} {}))}) ===== CASE: echo "foo = `echo hi`" ===== (C {} {(DQ <'foo = '> (command_sub left_token: child:(C {} {})))}) ===== CASE: +O parse_backticks -n -c echo `echo hi` ===== echo `echo hi` ^ [ -c flag ]:1: Use $(cmd) instead of backticks (parse_backticks) ===== CASE: +O parse_backticks -n -c echo "foo = `echo hi`" ===== echo "foo = `echo hi`" ^ [ -c flag ]:1: Use $(cmd) instead of backticks (parse_backticks) ===== CASE: echo $ ===== (C {} {}) ===== CASE: +O parse_dollar -n -c echo $ ===== echo $ ^ [ -c flag ]:1: Literal $ should be quoted like \$ ===== CASE: echo $ ===== echo $ ^ [ -c flag ]:1: Literal $ should be quoted like \$ ===== CASE: echo $: ===== (C {} { }) ===== CASE: +O parse_dollar -n -c echo $: ===== echo $: ^ [ -c flag ]:1: Literal $ should be quoted like \$ ===== CASE: echo $: ===== echo $: ^ [ -c flag ]:1: Literal $ should be quoted like \$ ===== CASE: echo "$" ===== (C {} {(DQ )}) ===== CASE: +O parse_dollar -n -c echo "$" ===== echo "$" ^ [ -c flag ]:1: Literal $ should be quoted like \$ ===== CASE: echo "$" ===== echo "$" ^ [ -c flag ]:1: Literal $ should be quoted like \$ ===== CASE: echo "$:" ===== (C {} {(DQ <':'>)}) ===== CASE: +O parse_dollar -n -c echo "$:" ===== echo "$:" ^ [ -c flag ]:1: Literal $ should be quoted like \$ ===== CASE: echo "$:" ===== echo "$:" ^ [ -c flag ]:1: Literal $ should be quoted like \$ ===== CASE: echo ${x:-$} ===== (C {} { (braced_var_sub token: suffix_op: (suffix_op.Unary tok: arg_word:{}) ) } ) ===== CASE: +O parse_dollar -n -c echo ${x:-$} ===== echo ${x:-$} ^ [ -c flag ]:1: Literal $ should be quoted like \$ ===== CASE: echo ${x:-$} ===== echo ${x:-$} ^ [ -c flag ]:1: Literal $ should be quoted like \$ ===== CASE: echo ${x:-$:} ===== (C {} { (braced_var_sub token: suffix_op: (suffix_op.Unary tok: arg_word:{ <':'>}) ) } ) ===== CASE: +O parse_dollar -n -c echo ${x:-$:} ===== echo ${x:-$:} ^ [ -c flag ]:1: Literal $ should be quoted like \$ ===== CASE: echo ${x:-$:} ===== echo ${x:-$:} ^ [ -c flag ]:1: Literal $ should be quoted like \$ ===== CASE: echo "${x:-$}" ===== (C {} { (DQ (braced_var_sub token: suffix_op: (suffix_op.Unary tok: arg_word:{}) ) ) } ) ===== CASE: +O parse_dollar -n -c echo "${x:-$}" ===== echo "${x:-$}" ^ [ -c flag ]:1: Literal $ should be quoted like \$ ===== CASE: echo "${x:-$}" ===== echo "${x:-$}" ^ [ -c flag ]:1: Literal $ should be quoted like \$ ===== CASE: echo "${x:-$:}" ===== (C {} { (DQ (braced_var_sub token: suffix_op: (suffix_op.Unary tok: arg_word: { <':'>} ) ) ) } ) ===== CASE: +O parse_dollar -n -c echo "${x:-$:}" ===== echo "${x:-$:}" ^ [ -c flag ]:1: Literal $ should be quoted like \$ ===== CASE: echo "${x:-$:}" ===== echo "${x:-$:}" ^ [ -c flag ]:1: Literal $ should be quoted like \$ ===== CASE: echo \( ===== (C {} {(word_part.EscapedLiteral token:)}) ===== CASE: echo \; ===== (C {} {(word_part.EscapedLiteral token:)}) ===== CASE: echo ~ ===== (C {} {(word_part.TildeSub token:)}) ===== CASE: echo \! ===== (C {} {(word_part.EscapedLiteral token:)}) ===== CASE: echo \% ===== (C {} {(word_part.EscapedLiteral token:)}) ===== CASE: echo \# ===== (C {} {(word_part.EscapedLiteral token:)}) ===== CASE: echo \. ===== echo \. ^~ [ -c flag ]:1: Invalid char escape (parse_backslash) ===== CASE: echo \- ===== echo \- ^~ [ -c flag ]:1: Invalid char escape (parse_backslash) ===== CASE: echo \/ ===== echo \/ ^~ [ -c flag ]:1: Invalid char escape (parse_backslash) ===== CASE: echo \a ===== echo \a ^~ [ -c flag ]:1: Invalid char escape (parse_backslash) ===== CASE: echo \Z ===== echo \Z ^~ [ -c flag ]:1: Invalid char escape (parse_backslash) ===== CASE: echo \0 ===== echo \0 ^~ [ -c flag ]:1: Invalid char escape (parse_backslash) ===== CASE: echo \9 ===== echo \9 ^~ [ -c flag ]:1: Invalid char escape (parse_backslash) ===== CASE: echo \. \- \/ \a \Z \0 \9 ===== (C {} {(word_part.EscapedLiteral token:)} {(word_part.EscapedLiteral token:)} {(word_part.EscapedLiteral token:)} {(word_part.EscapedLiteral token:)} {(word_part.EscapedLiteral token:)} {(word_part.EscapedLiteral token:)} {(word_part.EscapedLiteral token:)} ) ===== CASE: ((1 > 0 && 43 > 42)) ===== (command.DParen child: (arith_expr.Binary op_id: Id.Arith_DAmp left: (arith_expr.Binary op_id:Id.Arith_Great left:{} right:{}) right: (arith_expr.Binary op_id: Id.Arith_Great left: {} right: {} ) ) ) ===== CASE: ((1 > 0 && 43 > 42)) ===== ((1 > 0 && 43 > 42)) ^~ [ -c flag ]:1: You may want a space between parens (parse_dparen) ===== CASE: if ((1 > 0 && 43 > 42)); then echo yes; fi ===== (command.If arms: [ (if_arm cond: (condition.Shell commands: [ (command.Sentence child: (command.DParen child: (arith_expr.Binary op_id: Id.Arith_DAmp left: (arith_expr.Binary op_id: Id.Arith_Great left: {} right: {} ) right: (arith_expr.Binary op_id: Id.Arith_Great left: {} right: {} ) ) ) terminator: ) ] ) action: [(command.Sentence child:(C {} {}) terminator:)] spids: [0 20] ) ] ) ===== CASE: if ((1 > 0 && 43 > 42)); then echo yes; fi ===== if ((1 > 0 && 43 > 42)); then echo yes; fi ^~ [ -c flag ]:1: You may want a space between parens (parse_dparen) ===== CASE: for ((x = 1; x < 5; ++x)); do echo $x; done ===== (command.ForExpr init: (arith_expr.BinaryAssign op_id: Id.Arith_Equal left: right: {} ) cond: (arith_expr.Binary op_id:Id.Arith_Less left: right:{}) update: (arith_expr.UnaryAssign op_id:Id.Arith_DPlus child:) body: (command.DoGroup children: [ (command.Sentence child: (C {} {($ Id.VSub_DollarName '$x')}) terminator: ) ] ) ) ===== CASE: for ((x = 1; x < 5; ++x)); do echo $x; done ===== for ((x = 1; x < 5; ++x)); do echo $x; done ^~ [ -c flag ]:1: Bash for loops aren't allowed (parse_dparen) ===== CASE: if (1 > 0 and 43 > 42) { echo yes } ===== (command.If arms: [ (if_arm cond: (condition.Oil e: (expr.Binary op: left: (expr.Compare left: (Const Id.Expr_DecInt 1) ops: [(Id.Arith_Great)] comparators: [(Const Id.Expr_DecInt 0)] ) right: (expr.Compare left: (Const Id.Expr_DecInt 43) ops: [(Id.Arith_Great)] comparators: [(Const Id.Expr_DecInt 42)] ) ) ) action: [(C {} {})] spids: [0] ) ] ) ===== CASE: if ( (1 > 0 and 43 > 42) ) { echo yes } ===== (command.If arms: [ (if_arm cond: (condition.Oil e: (expr.Binary op: left: (expr.Compare left: (Const Id.Expr_DecInt 1) ops: [(Id.Arith_Great)] comparators: [(Const Id.Expr_DecInt 0)] ) right: (expr.Compare left: (Const Id.Expr_DecInt 43) ops: [(Id.Arith_Great)] comparators: [(Const Id.Expr_DecInt 42)] ) ) ) action: [(C {} {})] spids: [0] ) ] ) ===== CASE: = ===== = ^ [ -c flag ]:1: Syntax error in expression (near Id.Eof_Real) ===== CASE: _ ===== _ ^ [ -c flag ]:1: Syntax error in expression (near Id.Eof_Real) ===== CASE: const d = { name: 42 } ===== const d = { name: ^ [ -c flag ]:1: Syntax error in expression (near Id.Op_Newline) ===== CASE: proc p { echo 1; proc f { echo f }; echo 2 } ===== proc p { echo 1; proc f { echo f }; echo 2 } ^~~~ [ -c flag ]:1: procs and shell functions can't be nested ===== CASE: proc p { echo 1; +weird() { echo f; }; echo 2 } ===== proc p { echo 1; +weird() { echo f; }; echo 2 } ^ [ -c flag ]:1: procs and shell functions can't be nested ===== CASE: proc p { echo 1; function f { echo f; }; echo 2 } ===== proc p { echo 1; function f { echo f; }; echo 2 } ^~~~~~~~ [ -c flag ]:1: procs and shell functions can't be nested ===== CASE: f() { echo 1; proc inner { echo inner; }; echo 2; } ===== f() { echo 1; proc inner { echo inner; }; echo 2; } ^~~~ [ -c flag ]:1: procs and shell functions can't be nested ===== CASE: f() { echo 1; g() { echo g; }; echo 2; } ===== (command.ShFunction name: f body: (BraceGroup children: [ (command.Sentence child:(C {} {<1>}) terminator:) (command.Sentence child: (command.ShFunction name: g body: (BraceGroup children: [(command.Sentence child:(C {} {}) terminator:)] ) ) terminator: ) (command.Sentence child:(C {} {<2>}) terminator:) ] ) ) ===== CASE: proc p() { shopt --unset errexit { false hi } } ===== (command.Proc name:

sig: (proc_sig.Closed) body: (BraceGroup children: [ (command.Simple words: [{} {<--unset>} {}] block: (BraceGroup children:[(C {} {})]) do_fork: T ) ] ) ) ===== CASE: proc p(x) { echo hi var x = 2 # Cannot redeclare param } ===== var x = 2 # Cannot redeclare param ^ [ -c flag ]:4: 'x' was already declared ===== CASE: proc p { var x = 1 echo hi var x = 2 # Cannot redeclare local } ===== var x = 2 # Cannot redeclare local ^ [ -c flag ]:5: 'x' was already declared ===== CASE: proc p { var x = 1 echo hi const x = 2 # Cannot redeclare local } ===== const x = 2 # Cannot redeclare local ^ [ -c flag ]:5: 'x' was already declared ===== CASE: proc p(x, :out) { var out = 2 # Cannot redeclare out param } ===== var out = 2 # Cannot redeclare out param ^~~ [ -c flag ]:3: 'out' was already declared ===== CASE: proc p { var out = 2 # Cannot redeclare out param cd /tmp { var out = 3 } } ===== var out = 3 ^~~ [ -c flag ]:5: 'out' was already declared ===== CASE: var x = 1 proc p { echo hi var x = 2 } proc p2 { var x = 3 } ===== (command.CommandList children: [ (command.VarDecl keyword: lhs: [(name_type name:)] rhs: (Const Id.Expr_DecInt 1) ) (command.Proc name:

sig: (proc_sig.Open) body: (BraceGroup children: [ (C {} {}) (command.VarDecl keyword: lhs: [(name_type name:)] rhs: (Const Id.Expr_DecInt 2) ) ] ) ) (command.Proc name: sig: (proc_sig.Open) body: (BraceGroup children: [ (command.VarDecl keyword: lhs: [(name_type name:)] rhs: (Const Id.Expr_DecInt 3) ) ] ) ) ] ) ===== CASE: proc p(x) { var y = 1 setvar L = "L" # ERROR: not declared } ===== setvar L = "L" # ERROR: not declared ^ [ -c flag ]:4: 'L' hasn't been declared ===== CASE: proc p(x) { const c = 123 setvar c = 42 # ERROR: cannot modify constant } ===== setvar c = 42 # ERROR: cannot modify constant ^ [ -c flag ]:4: Can't modify constant 'c' ===== CASE: proc p(x) { setvar x = "X" # is mutating params allowed? I guess why not. } ===== (command.Proc name:

sig: (proc_sig.Closed untyped:[(UntypedParam name:)]) body: (BraceGroup children: [ (command.PlaceMutation keyword: lhs: [(place_expr.Var name:)] op: rhs: (DQ ) ) ] ) ) ===== CASE: case $foo { (*.py) echo "python" ;; } ===== (command.Case to_match: {($ Id.VSub_DollarName '$foo')} arms: [ (case_arm pat_list: [{ <.py>}] action: [(C {} {(DQ )})] spids: [9 12 20 -1] ) ] ) ===== CASE: case "foo" { (*.py) echo "python" ;; } ===== (command.Case to_match: {(DQ )} arms: [ (case_arm pat_list: [{ <.py>}] action: [(C {} {(DQ )})] spids: [11 14 22 -1] ) ] ) ===== CASE: case foo { (*.py) echo "python" ;; } ===== case foo { ^~~ [ -c flag ]:2: This is a constant string. You may want a variable like $x (parse_bare_word) ===== CASE: case $x { (*.py) echo "python" ;; *.sh) echo "shell" ;; } ===== *.sh) echo "shell" ;; ^ [ -c flag ]:4: Expected left paren (parse_sloppy_case) ===== CASE: for x in (obj) { echo $x } ===== (command.ForEach iter_names: [x] iterable: (for_iter.Oil e:(Var obj) blame:) body: (BraceGroup children:[(C {} {($ Id.VSub_DollarName '$x')})]) ) ===== CASE: for x in (obj); do echo $x done ===== for x in (obj); do ^ [ -c flag ]:2: Expected { after iterable expression ===== CASE: for x, y in SPAM EGGS; do echo $x done ===== (command.ForEach iter_names: [x y] iterable: (for_iter.Words words:[{} {}]) body: (command.DoGroup children:[(C {} {($ Id.VSub_DollarName '$x')})]) ) ===== CASE: for x-y in SPAM EGGS; do echo $x done ===== for x-y in SPAM EGGS; do ^~~ [ -c flag ]:2: Invalid loop variable name 'x-y' ===== CASE: for x, y, z in SPAM EGGS; do echo $x done ===== for x, y, z in SPAM EGGS; do ^~~ [ -c flag ]:2: Expected at most 2 loop variables ===== CASE: for w, x, y, z in SPAM EGGS; do echo $x done ===== for w, x, y, z in SPAM EGGS; do ^ [ -c flag ]:2: Unexpected word after 3 loop variables ===== CASE: for x, y in SPAM EGGS do echo $x done ===== (command.ForEach iter_names: [x y] iterable: (for_iter.Words words:[{} {}]) body: (command.DoGroup children:[(C {} {($ Id.VSub_DollarName '$x')})]) ) ===== CASE: for const in (x) { echo $var } ===== (command.ForEach iter_names: [const] iterable: (for_iter.Oil e:(Var x) blame:) body: (BraceGroup children:[(C {} {($ Id.VSub_DollarName '$var')})]) ) ===== CASE: for x in bare { echo $x } ===== for x in bare { ^~~~ [ -c flag ]:2: Surround this word with either parens or quotes (parse_bare_word) ===== CASE: for x in a b { echo $x } ===== (command.ForEach iter_names: [x] iterable: (for_iter.Words words:[{} {}]) body: (BraceGroup children:[(C {} {($ Id.VSub_DollarName '$x')})]) ) ===== CASE: for x in *.py { echo $x } ===== (command.ForEach iter_names: [x] iterable: (for_iter.Words words:[{ <.py>}]) body: (BraceGroup children:[(C {} {($ Id.VSub_DollarName '$x')})]) ) ===== CASE: for x in "quoted" { echo $x } ===== (command.ForEach iter_names: [x] iterable: (for_iter.Words words:[{(DQ )}]) body: (BraceGroup children:[(C {} {($ Id.VSub_DollarName '$x')})]) ) ===== CASE: var snippets = [{status: 42}] for snippet in (snippets) { if (snippet["status"] === 0) { echo hi } # The $ causes a wierd error if ($snippet["status"] === 0) { echo hi } } ===== if ($snippet["status"] === 0) { ^~~~~~~~ [ -c flag ]:9: In expressions, remove $ and use `snippet`, or sometimes "$snippet" ===== CASE: var content = [ 1, 2, 4 ] var count = 0 # The $ causes a weird error while (count < $len(content)) { setvar count += 1 } ===== while (count < $len(content)) { ^~~~ [ -c flag ]:6: In expressions, remove $ and use `len`, or sometimes "$len" ===== CASE: for x in & ===== for x in & ^ [ -c flag ]:1: Invalid word in for loop ===== CASE: for (( i=0; i<10; i++ )) ls ===== for (( i=0; i<10; i++ )) ls ^~ [ -c flag ]:1: Invalid word after for expression ===== CASE: for ( i=0; i<10; i++ ) ===== for ( i=0; i<10; i++ ) ^ [ -c flag ]:1: Expected loop variable (a constant word) ===== CASE: for $x in 1 2 3; do echo $i; done ===== for $x in 1 2 3; do echo $i; done ^~ [ -c flag ]:1: Expected loop variable (a constant word) ===== CASE: for x.y in 1 2 3; do echo $i; done ===== for x.y in 1 2 3; do echo $i; done ^~~ [ -c flag ]:1: Invalid loop variable name 'x.y' ===== CASE: for x in 1 2 3; & ===== for x in 1 2 3; & ^ [ -c flag ]:1: Expected word type Id.KW_Do, got Id.Op_Amp ===== CASE: for foo BAD ===== for foo BAD ^ [ -c flag ]:1: Expected loop variable (a constant word) ===== CASE: for var in x; do echo $var; done ===== (command.ForEach iter_names: [var] iterable: (for_iter.Words words:[{}]) body: (command.DoGroup children: [ (command.Sentence child: (C {} {($ Id.VSub_DollarName '$var')}) terminator: ) ] ) ) ===== CASE: echo @ ===== echo @ ^ [ -c flag ]:1: Literal @ starting a word must be quoted (parse_at_all) ===== CASE: echo @@ ===== echo @@ ^ [ -c flag ]:1: Literal @ starting a word must be quoted (parse_at_all) ===== CASE: echo @{foo} ===== echo @{foo} ^ [ -c flag ]:1: Literal @ starting a word must be quoted (parse_at_all) ===== CASE: echo @/foo/ ===== echo @/foo/ ^ [ -c flag ]:1: Literal @ starting a word must be quoted (parse_at_all) ===== CASE: echo @"foo" ===== echo @"foo" ^ [ -c flag ]:1: Literal @ starting a word must be quoted (parse_at_all) ===== CASE: write -- $f(x) ===== (C {} {<-->} {(word_part.FuncCall name: args:(ArgList positional:[(Var x)]))} ) ===== CASE: write -- $f(x) ===== (C {} {<-->} {(word_part.FuncCall name: args:(ArgList positional:[(Var x)]))} ) ===== CASE: write -- @sorted(x) ===== write -- @sorted(x) ^ [ -c flag ]:1: Unexpected left paren (might need a space before it) ===== CASE: write -- @sorted(x) ===== (C {} {<-->} {(word_part.FuncCall name: args:(ArgList positional:[(Var x)]))} ) ===== CASE: f() { write -- @sorted(x) } ===== write -- @sorted(x) ^ [ -c flag ]:3: Unexpected left paren (might need a space before it) ===== CASE: f() { write -- @sorted(x) } ===== (command.ShFunction name: f body: (BraceGroup children: [ (C {} {<-->} {(word_part.FuncCall name: args:(ArgList positional:[(Var x)]))} ) ] ) ) ===== CASE: f() { write -- @sorted (( z )) } ===== write -- @sorted (( z )) ^~ [ -c flag ]:3: Invalid word while parsing command list ===== CASE: code="printf % x" eval $code ===== % ^ [ printf word at line 1 of [ eval word at line 3 of [ -c flag ] ] ]:1: Expected a printf format character ---------------------- ===== CASE: test/parse-errors/01-bad-func.sh ===== foo (,) ^ 'test/parse-errors/01-bad-func.sh':15: Syntax error in expression (near Id.Arith_Comma) ===== CASE: test/parse-errors/02-bad-func.sh ===== foo() ^ 'test/parse-errors/02-bad-func.sh':3: Unexpected word while parsing compound command ===== CASE: test/parse-errors/05-unterminated-single.sh ===== A B echo 'C ^ 'test/parse-errors/05-unterminated-single.sh':5: Unexpected EOF in single-quoted string that began here ===== CASE: test/parse-errors/06-unterminated-double-long.sh ===== A B echo 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 " ^ 'test/parse-errors/06-unterminated-double-long.sh':9: Unexpected EOF reading double-quoted string that began here ===== CASE: test/parse-errors/06-unterminated-double.sh ===== A B echo "0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 ^ 'test/parse-errors/06-unterminated-double.sh':6: Unexpected EOF reading double-quoted string that began here ===== CASE: test/parse-errors/07-unterminated-here-doc-2.sh ===== cat << "$@" ^ 'test/parse-errors/07-unterminated-here-doc-2.sh':2: Invalid here doc delimiter ===== CASE: test/parse-errors/07-unterminated-here-doc.sh ===== cat <