(command.CommandList children: [ (command.Simple blame_tok: <Id.Lit_Colon ':'> more_env: [] words: [ {<Id.Lit_Colon ':'>} { (BracedVarSub left: <Id.Left_DollarBrace '${'> token: <Id.VSub_Name TEST_SH> var_name: TEST_SH suffix_op: (suffix_op.Unary op:<Id.VTest_ColonEquals _> arg_word:{(DQ <'/bin/sh'>)}) right: <Id.Right_DollarBrace '}'> ) } ] redirects: [] do_fork: T ) (command.ShFunction name_tok: <check> name: check body: (BraceGroup left: <Id.Lit_LBrace '{'> children: [ (command.If if_kw: <Id.KW_If if> arms: [ (IfArm keyword: <Id.KW_If if> cond: (condition.Shell commands: [ (command.Simple blame_tok: <Id.Lit_LBracket '['> more_env: [] words: [ {<Id.Lit_LBracket '['>} {(DQ ($ Id.VSub_Number 1))} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_Number 2))} {<Id.Lit_RBracket ']'>} ] redirects: [] do_fork: T ) ] ) then_kw: <Id.KW_Then then> action: [ (command.Simple blame_tok: <atf_fail> more_env: [] words: [ {<atf_fail>} { (DQ <'expected ['> ($ Id.VSub_Number 2) <'], found ['> ($ Id.VSub_Number 1) <']'> ) } ] redirects: [ (Redir op: <Id.Redir_GreatAnd '1>&'> loc: (redir_loc.Fd fd:1) arg: {<2>} ) ] do_fork: T ) ] spids: [103 121] ) ] else_action: [] fi_kw: <Id.KW_Fi fi> redirects: [] ) ] redirects: [] right: <Id.Lit_RBrace '}'> ) ) (command.Simple blame_tok: <atf_test_case> more_env: [] words: [{<atf_test_case>} {<all>}] redirects: [] do_fork: T ) (command.ShFunction name_tok: <all_head> name: all_head body: (BraceGroup left: <Id.Lit_LBrace '{'> children: [ (command.Simple blame_tok: <atf_set> more_env: [] words: [{<atf_set>} {(DQ <descr>)} {(DQ <'Basic checks for variable quoting'>)}] redirects: [] do_fork: T ) ] redirects: [] right: <Id.Lit_RBrace '}'> ) ) (command.ShFunction name_tok: <all_body> name: all_body body: (BraceGroup left: <Id.Lit_LBrace '{'> children: [ (command.Simple blame_tok: <cat> more_env: [] words: [{<cat>}] redirects: [ (Redir op: <Id.Redir_DLessDash '<<-'> loc: (redir_loc.Fd fd:0) arg: (redir_param.HereDoc here_begin: {(SQ <EOF>)} here_end_tok: <Id.Undefined_Tok ''> stdin_parts: [ <'T=0\n'> <'check() {\n'> <'T=$((${T} + 1))\n'> <'\n'> <'if [ "$1" != "$2" ]\n'> <'then\n'> <'printf \'%s\\n\' "T${T}: expected [$2], found [$1]"\n'> <'exit 1\n'> <'fi\n'> <'}\n'> <'\n'> <'#1\n'> <'foo=\'${a:-foo}\'\n'> <'check "$foo" \'${a:-foo}\'\n'> <'#2\n'> <'foo="${a:-foo}"\n'> <'check "$foo" "foo"\n'> <'#3\n'> <'foo=${a:-"\'{}\'"}\t\n'> <'check "$foo" "\'{}\'"\n'> <'#4\n'> <'foo=${a:-${b:-"\'{}\'"}}\n'> <'check "$foo" "\'{}\'"\n'> <'#5\n'> <'# ${ } The \' are inside ".." so are literal (not quotes).\n'> <'foo="${a-\'}\'}"\n'> <'check "$foo" "\'\'}"\n'> <'#6\n'> <'# The rules for quoting in ${var-word} expressions are somewhat\n'> <'# weird, in the following there is not one quoted string being\n'> <'# assigned to foo (with internally quoted sub-strings), rather\n'> <'# it is a mixed quoted/unquoted string, with parts that are\n'> <'# quoted, separated by 2 unquoted sections...\n'> <'# qqqqqqqqqq uuuuuuuuuu qq uuuu qqqq\n'> <'foo="${a:-${b:-"${c:-${d:-"x}"}}y}"}}z}"\n'> <'# " z*"\n'> <'# ${a:- }\n'> <'# ${b:- }\n'> <'# " y*"\n'> <'# ${c:- }\n'> <'# ${d:- }\n'> <'# "x*"\n'> <'check "$foo" "x}y}z}"\n'> <'#7\n'> <'# And believe it or not, this is the one that gives\n'> <'# most problems, with 3 different observed outputs...\n'> <'# qqqqq qq q\t\tis one interpretation\n'> <'# qqqqq QQQQ q\t\tis another (most common)\n'> <'#\t\t\t(the third is syntax error...)\n'> <'foo="${a:-"\'{}\'"}"\n'> <'check "$foo" "\'{}\'"\n'> <'\n'> ] ) ) (Redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<script.sh>} ) ] do_fork: T ) (command.ShAssignment left: <Id.Lit_VarLike 'OUT='> pairs: [ (AssignPair left: <Id.Lit_VarLike 'OUT='> lhs: (sh_lhs_expr.Name left:<Id.Lit_VarLike 'OUT='> name:OUT) op: assign_op.Equal rhs: { (CommandSub left_token: <Id.Left_DollarParen '$('> child: (command.Simple blame_tok: <Id.Left_DollarBrace '${'> more_env: [] words: [{(${ Id.VSub_Name TEST_SH)} {<script.sh>}] redirects: [ (Redir op: <Id.Redir_GreatAnd '2>&'> loc: (redir_loc.Fd fd:2) arg: {<1>} ) ] do_fork: T ) right: <Id.Eof_RParen _> ) } ) ] redirects: [] ) (command.If if_kw: <Id.KW_If if> arms: [ (IfArm keyword: <Id.KW_If if> cond: (condition.Shell commands: [ (command.Simple blame_tok: <Id.Lit_LBracket '['> more_env: [] words: [ {<Id.Lit_LBracket '['>} {($ Id.VSub_QMark '?')} {<-ne>} {<0>} {<Id.Lit_RBracket ']'>} ] redirects: [] do_fork: T ) ] ) then_kw: <Id.KW_Then then> action: [ (command.Simple blame_tok: <atf_fail> more_env: [] words: [{<atf_fail>} {(DQ (${ Id.VSub_Name OUT))}] redirects: [] do_fork: T ) ] spids: [255 268] ) (IfArm keyword: <Id.KW_Elif elif> cond: (condition.Shell commands: [ (command.Simple blame_tok: <Id.Lit_LBracket '['> more_env: [] words: [ {<Id.Lit_LBracket '['>} {<-n>} {(DQ (${ Id.VSub_Name OUT))} {<Id.Lit_RBracket ']'>} ] redirects: [] do_fork: T ) ] ) then_kw: <Id.KW_Then then> action: [ (command.Simple blame_tok: <atf_fail> more_env: [] words: [ {<atf_fail>} {(DQ <'script.sh unexpectedly said: '> (${ Id.VSub_Name OUT))} ] redirects: [] do_fork: T ) ] spids: [280 295] ) ] else_action: [] fi_kw: <Id.KW_Fi fi> redirects: [] ) ] redirects: [] right: <Id.Lit_RBrace '}'> ) ) (command.Simple blame_tok: <atf_test_case> more_env: [] words: [{<atf_test_case>} {<nested_quotes_multiword>}] redirects: [] do_fork: T ) (command.ShFunction name_tok: <nested_quotes_multiword_head> name: nested_quotes_multiword_head body: (BraceGroup left: <Id.Lit_LBrace '{'> children: [ (command.Simple blame_tok: <atf_set> more_env: [] words: [ {<atf_set>} {(DQ <descr>)} {(DQ <'Tests that having nested quoting in a multi-word'>)} {(DQ <'string works (PR bin/43597)'>)} ] redirects: [] do_fork: T ) ] redirects: [] right: <Id.Lit_RBrace '}'> ) ) (command.ShFunction name_tok: <nested_quotes_multiword_body> name: nested_quotes_multiword_body body: (BraceGroup left: <Id.Lit_LBrace '{'> children: [ (command.Simple blame_tok: <atf_check> more_env: [] words: [ {<atf_check>} {<-s>} {<eq> <Id.Lit_Colon ':'> <0>} {<-o>} {<match> <Id.Lit_Colon ':'> (DQ <'first-word second-word'>)} {<-e>} {<empty>} {(${ Id.VSub_Name TEST_SH)} {<-c>} {(SQ <'echo "${foo:="first-word"} second-word"'>)} ] redirects: [] do_fork: T ) ] redirects: [] right: <Id.Lit_RBrace '}'> ) ) (command.Simple blame_tok: <atf_test_case> more_env: [] words: [{<atf_test_case>} {<default_assignment_with_arith>}] redirects: [] do_fork: T ) (command.ShFunction name_tok: <default_assignment_with_arith_head> name: default_assignment_with_arith_head body: (BraceGroup left: <Id.Lit_LBrace '{'> children: [ (command.Simple blame_tok: <atf_set> more_env: [] words: [ {<atf_set>} {(DQ <descr>)} {(DQ <'Tests default variable assignment with arithmetic'>)} {(DQ <'string works (PR bin/50827)'>)} ] redirects: [] do_fork: T ) ] redirects: [] right: <Id.Lit_RBrace '}'> ) ) (command.ShFunction name_tok: <default_assignment_with_arith_body> name: default_assignment_with_arith_body body: (BraceGroup left: <Id.Lit_LBrace '{'> children: [ (command.Simple blame_tok: <atf_check> more_env: [] words: [ {<atf_check>} {<-s>} {<eq> <Id.Lit_Colon ':'> <0>} {<-o>} {<empty>} {<-e>} {<empty>} {(${ Id.VSub_Name TEST_SH)} {<-c>} {(SQ <': "${x=$((1))}"'>)} ] redirects: [] do_fork: T ) (command.Simple blame_tok: <atf_check> more_env: [] words: [ {<atf_check>} {<-s>} {<eq> <Id.Lit_Colon ':'> <0>} {<-o>} {<match> <Id.Lit_Colon ':'> <1>} {<-e>} {<empty>} {(${ Id.VSub_Name TEST_SH)} {<-c>} {(SQ <'echo "${x=$((1))}"'>)} ] redirects: [] do_fork: T ) ] redirects: [] right: <Id.Lit_RBrace '}'> ) ) (command.ShFunction name_tok: <atf_init_test_cases> name: atf_init_test_cases body: (BraceGroup left: <Id.Lit_LBrace '{'> children: [ (command.Simple blame_tok: <atf_add_test_case> more_env: [] words: [{<atf_add_test_case>} {<all>}] redirects: [] do_fork: T ) (command.Simple blame_tok: <atf_add_test_case> more_env: [] words: [{<atf_add_test_case>} {<nested_quotes_multiword>}] redirects: [] do_fork: T ) (command.Simple blame_tok: <atf_add_test_case> more_env: [] words: [{<atf_add_test_case>} {<default_assignment_with_arith>}] redirects: [] do_fork: T ) ] redirects: [] right: <Id.Lit_RBrace '}'> ) ) ] )