diff options
| author | Chet Ramey <chet.ramey@case.edu> | 2016-08-03 15:37:14 -0400 |
|---|---|---|
| committer | Chet Ramey <chet.ramey@case.edu> | 2016-08-03 15:37:14 -0400 |
| commit | 13eae87b0c5dbc31a7d352ce17c6817bb79b9226 (patch) | |
| tree | b726557a01cd177f62906d911221f823cbfcecf0 | |
| parent | 7fa3190622e31ed9abffb0d81144b538de8b17ba (diff) | |
| download | bash-13eae87b0c5dbc31a7d352ce17c6817bb79b9226.tar.gz | |
commit bash-20160722 snapshot
| -rw-r--r-- | CWRU/CWRU.chlog | 67 | ||||
| -rw-r--r-- | MANIFEST | 2 | ||||
| -rw-r--r-- | arrayfunc.c | 3 | ||||
| -rw-r--r-- | arrayfunc.h | 2 | ||||
| -rw-r--r-- | command.h | 7 | ||||
| -rw-r--r-- | general.c | 2 | ||||
| -rw-r--r-- | lib/readline/bind.c | 4 | ||||
| -rw-r--r-- | lib/readline/display.c | 10 | ||||
| -rw-r--r-- | lib/readline/doc/rltech.texi | 2 | ||||
| -rw-r--r-- | subst.c | 60 | ||||
| -rwxr-xr-x | tests/dollar-at-star | 5 | ||||
| -rw-r--r-- | tests/dollar-at-star8.sub | 14 | ||||
| -rw-r--r-- | tests/dollar.right | 5 | ||||
| -rw-r--r-- | tests/exp.right | 100 | ||||
| -rw-r--r-- | tests/exp.tests | 1 | ||||
| -rw-r--r-- | tests/exp9.sub | 69 |
16 files changed, 319 insertions, 34 deletions
diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 0bd8d47..6d9871f 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -11303,7 +11303,7 @@ execute_cmd.c 6/23 ---- -execute_cmd.c +subst.c - param_expand: when expanding $* in a context where splitting is not desired (pflags & PF_ASSIGNRHS), make sure to quote the word and the included separators. Reported by Dan Douglas <ormaaj@gmail.com> @@ -11404,3 +11404,68 @@ execute_cmd.c - execute_arith_for_command,execute_arith_command,execute_simple_command, execute_cond_command: make sure line_number doesn't go < 0 when adjusting it by function_line_number + + 7/23 + ---- +subst.c,command.h + - move the PF_ constants to command.h so other files can see them, now + that PF_ASSIGNRHS has meaning to string_list_dollar_at + +arrayfunc.h + - AV_ASSIGNRHS: new flag, indicate that ${a[@]} is being expanded on + the RHS of an assignment statement + +arrayfunc.c + - array_value_internal: if AV_ASSIGNRHS passed for ${a[@]}, pass + PF_ASSIGNRHS to string_list_dollar_at to support args separated by + spaces even if $IFS does not have the default value. Reported by + Dan Douglas <ormaaj@gmail.com> + +subst.c + - string_list_dollar_at: if FLAGS argument includes PF_ASSIGNRHS, obey + rules for $@ on the RHS of an assignment statement: expand to + postitional parameters separated by spaces no matter what the first + character of $IFS is. Reported by Dan Douglas <ormaaj@gmail.com> + - parameter_brace_expand_word: pass AV_ASSIGNRHS as flags value to + array_value if PF_ASSIGNRHS is set and we are expanding an array + variable subscripted by @ or * + - param_expand: pass pflags to string_list_dollar_at in case it contains + PF_ASSIGNRHS + - expand_word_internal: if we have an assignment statement argument to + a declaration builtin (W_ASSIGNARG), turn on W_ASSIGNRHS when we see + the `=' to enable special $@ behavior + - expand_word_internal: if W_ASSIGNARG enabled in word flags, pass that + flag and W_ASSIGNRHS to recursive call to expand_word_internal when + expanding double-quoted string; handles "$@" when IFS is not the + default value and word splitting will not be performed + +subst.c + - expand_word_internal: change case that handles '' (single-quoted + empty string) to only discard it if we will not be performing word + splitting (W_NOSPLIT|W_NOSPLIT2), since we need to add a quoted null + argument if the subsequent characters will cause word splitting. + This is how "" (double-quoted empty string) is handled after a bug + fix back in August 2010. Reported by Grisha Levit + <grishalevit@gmail.com>, fix for Posix interp 888 + + 7/27 + ---- +subst.c + - param_expand: change fix from 6/23 (expanding $* in a context where + word splitting is not performed) to make sure that $* expands to + something before trying to quote the string. Bug and fix from + Andreas Schwab <schwab@suse.de> + +lib/readline/bind.c + - _rl_get_string_variable_value: fix a cut-and-paste error that caused + the emacs mode string to be displayed for both vi insert and command + mode strings. Report and fix from Steve Jones <sjml@slohj.org> + + 7/28 + ---- +lib/readline/display.c + - update_line: we can't use PROMPT_ENDING_INDEX unless we're testing + against _rl_last_c_pos; if we are testing buffer indices, we need to + use prompt_last_invisible directly. Fixes mode string redisplay issue + with short prompt strings reported by Steve Jones <sjml@slohj.org> + @@ -924,6 +924,7 @@ tests/dollar-at-star4.sub f tests/dollar-at-star5.sub f tests/dollar-at-star6.sub f tests/dollar-at-star7.sub f +tests/dollar-at-star8.sub f tests/dollar-at1.sub f tests/dollar-at2.sub f tests/dollar-at3.sub f @@ -975,6 +976,7 @@ tests/exp5.sub f tests/exp6.sub f tests/exp7.sub f tests/exp8.sub f +tests/exp9.sub f tests/exportfunc.tests f tests/exportfunc.right f tests/exportfunc1.sub f diff --git a/arrayfunc.c b/arrayfunc.c index fb87112..c65229e 100644 --- a/arrayfunc.c +++ b/arrayfunc.c @@ -1087,7 +1087,8 @@ array_value_internal (s, quoted, flags, rtype, indp) free (temp); } else /* ${name[@]} or unquoted ${name[*]} */ - retval = string_list_dollar_at (l, quoted, 0); /* XXX - leak here */ + /* XXX - bash-4.4/bash-5.0 test AV_ASSIGNRHS and pass PF_ASSIGNRHS */ + retval = string_list_dollar_at (l, quoted, (flags & AV_ASSIGNRHS) ? PF_ASSIGNRHS : 0); /* XXX - leak here */ dispose_words (l); } diff --git a/arrayfunc.h b/arrayfunc.h index 3a29a59..2811f45 100644 --- a/arrayfunc.h +++ b/arrayfunc.h @@ -30,6 +30,7 @@ #define AV_QUOTED 0x002 #define AV_USEIND 0x004 #define AV_USEVAL 0x008 /* XXX - should move this */ +#define AV_ASSIGNRHS 0x010 /* no splitting, special case ${a[@]} */ extern SHELL_VAR *convert_var_to_array __P((SHELL_VAR *)); extern SHELL_VAR *convert_var_to_assoc __P((SHELL_VAR *)); @@ -72,6 +73,7 @@ extern SHELL_VAR *array_variable_part __P((char *, char **, int *)); #define AV_ALLOWALL 0 #define AV_QUOTED 0 #define AV_USEIND 0 +#define AV_ASSIGNRHS 0 #endif @@ -101,6 +101,13 @@ enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select, #define W_ASSNGLOBAL 0x2000000 /* word is a global assignment to declare (declare/typeset -g) */ #define W_NOBRACE 0x4000000 /* Don't perform brace expansion */ +/* Flags for the `pflags' argument to param_expand() and various + parameter_brace_expand_xxx functions; also used for string_list_dollar_at */ +#define PF_NOCOMSUB 0x01 /* Do not perform command substitution */ +#define PF_IGNUNBOUND 0x02 /* ignore unbound vars even if -u set */ +#define PF_NOSPLIT2 0x04 /* same as W_NOSPLIT2 */ +#define PF_ASSIGNRHS 0x08 /* same as W_ASSIGNRHS */ + /* Possible values for subshell_environment */ #define SUBSHELL_ASYNC 0x01 /* subshell caused by `command &' */ #define SUBSHELL_PAREN 0x02 /* subshell caused by ( ... ) */ @@ -265,7 +265,7 @@ check_selfref (name, value, flags) #if defined (ARRAY_VARS) if (valid_array_reference (value, 0)) { - t = array_variable_name (value, (int *)NULL, (int *)NULL); + t = array_variable_name (value, (char **)NULL, (int *)NULL); if (t && STREQ (name, t)) { free (t); diff --git a/lib/readline/bind.c b/lib/readline/bind.c index 3dbc1ce..f1098c4 100644 --- a/lib/readline/bind.c +++ b/lib/readline/bind.c @@ -2591,9 +2591,9 @@ _rl_get_string_variable_value (name) else if (_rl_stricmp (name, "emacs-mode-string") == 0) return (_rl_emacs_mode_str ? _rl_emacs_mode_str : RL_EMACS_MODESTR_DEFAULT); else if (_rl_stricmp (name, "vi-cmd-mode-string") == 0) - return (_rl_emacs_mode_str ? _rl_emacs_mode_str : RL_VI_CMD_MODESTR_DEFAULT); + return (_rl_vi_cmd_mode_str ? _rl_vi_cmd_mode_str : RL_VI_CMD_MODESTR_DEFAULT); else if (_rl_stricmp (name, "vi-ins-mode-string") == 0) - return (_rl_emacs_mode_str ? _rl_emacs_mode_str : RL_VI_INS_MODESTR_DEFAULT); + return (_rl_vi_ins_mode_str ? _rl_vi_ins_mode_str : RL_VI_INS_MODESTR_DEFAULT); else return (0); } diff --git a/lib/readline/display.c b/lib/readline/display.c index cd9b89f..41fb053 100644 --- a/lib/readline/display.c +++ b/lib/readline/display.c @@ -119,6 +119,8 @@ static int _rl_col_width PARAMS((const char *, int, int, int)); buffer index in others. This macro is used when deciding whether the current cursor position is in the middle of a prompt string containing invisible characters. XXX - might need to take `modmark' into account. */ +/* XXX - only valid when tested against _rl_last_c_pos; buffer indices need + to use prompt_last_invisible directly. */ #define PROMPT_ENDING_INDEX \ ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1) @@ -1674,10 +1676,10 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) if (lendiff > nmax) lendiff = nmax; od = ofd - old; /* index of first difference in visible line */ - nd = nfd - new; + nd = nfd - new; /* nd, od are buffer indexes */ if (current_line == 0 && !_rl_horizontal_scroll_mode && _rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 && - (((od > 0 || nd > 0) && (od < PROMPT_ENDING_INDEX || nd < PROMPT_ENDING_INDEX)) || + (((od > 0 || nd > 0) && (od <= prompt_last_invisible || nd <= prompt_last_invisible)) || ((od >= lendiff) && _rl_last_c_pos < PROMPT_ENDING_INDEX))) { #if defined (__MSDOS__) @@ -1702,7 +1704,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) was within the prompt, see if we need to recompute where the lines differ. Check whether where we are now is past the last place where the old and new lines are the same and short-circuit now if we are. */ - if ((od < PROMPT_ENDING_INDEX || nd < PROMPT_ENDING_INDEX) && + if ((od <= prompt_last_invisible || nd <= prompt_last_invisible) && omax == nmax && lendiff > (ols-old) && lendiff > (nls-new)) return; @@ -1714,7 +1716,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) first difference, but you don't know the number of invisible characters in that case. This needs a lot of work to be efficient. */ - if ((od < PROMPT_ENDING_INDEX || nd < PROMPT_ENDING_INDEX)) + if ((od <= prompt_last_invisible || nd <= prompt_last_invisible)) { nfd = new + lendiff; /* number of characters we output above */ nd = lendiff; diff --git a/lib/readline/doc/rltech.texi b/lib/readline/doc/rltech.texi index adf7ee4..b8ce90f 100644 --- a/lib/readline/doc/rltech.texi +++ b/lib/readline/doc/rltech.texi @@ -1531,7 +1531,7 @@ main (int c, char **v) @{ rl_resize_terminal (); sigwinch_received = 0; - }@ + @} if (r < 0) continue; @@ -90,12 +90,6 @@ extern int errno; #define ST_SQUOTE 0x04 /* unused yet */ #define ST_DQUOTE 0x08 /* unused yet */ -/* Flags for the `pflags' argument to param_expand() */ -#define PF_NOCOMSUB 0x01 /* Do not perform command substitution */ -#define PF_IGNUNBOUND 0x02 /* ignore unbound vars even if -u set */ -#define PF_NOSPLIT2 0x04 /* same as W_NOSPLIT2 */ -#define PF_ASSIGNRHS 0x08 /* same as W_ASSIGNRHS */ - /* These defs make it easier to use the editor. */ #define LBRACE '{' #define RBRACE '}' @@ -2515,7 +2509,13 @@ string_list_dollar_star (list) <space><tab><newline>, IFS characters in the words in the list should also be split. If IFS is null, and the word is not quoted, we need to quote the words in the list to preserve the positional parameters - exactly. */ + exactly. + Valid values for the FLAGS argument are the PF_ flags in command.h, + the only one we care about is PF_ASSIGNRHS. $@ is supposed to expand + to the positional parameters separated by spaces no matter what IFS is + set to if in a context where word splitting is not performed. The only + one that we didn't handle before is assignment statement arguments to + declaration builtins like `declare'. */ char * string_list_dollar_at (list, quoted, flags) WORD_LIST *list; @@ -2541,7 +2541,13 @@ string_list_dollar_at (list, quoted, flags) # if !defined (__GNUC__) sep = (char *)xmalloc (MB_CUR_MAX + 1); # endif /* !__GNUC__ */ - if (ifs && *ifs) + /* XXX - bash-4.4/bash-5.0 testing PF_ASSIGNRHS */ + if (flags & PF_ASSIGNRHS) + { + sep[0] = ' '; + sep[1] = '\0'; + } + else if (ifs && *ifs) { if (ifs_firstc_len == 1) { @@ -2560,7 +2566,8 @@ string_list_dollar_at (list, quoted, flags) sep[1] = '\0'; } #else - sep[0] = (ifs == 0 || *ifs == 0) ? ' ' : *ifs; + /* XXX - bash-4.4/bash-5.0 test PF_ASSIGNRHS */ + sep[0] = ((flags & PF_ASSIGNRHS) || ifs == 0 || *ifs == 0) ? ' ' : *ifs; sep[1] = '\0'; #endif @@ -6427,7 +6434,8 @@ expand_arrayref: { /* Only treat as double quoted if array variable */ if (var && (array_p (var) || assoc_p (var))) - temp = array_value (name, quoted|Q_DOUBLE_QUOTES, 0, &atype, &ind); + /* XXX - bash-4.4/bash-5.0 pass AV_ASSIGNRHS */ + temp = array_value (name, quoted|Q_DOUBLE_QUOTES, AV_ASSIGNRHS, &atype, &ind); else temp = array_value (name, quoted, 0, &atype, &ind); } @@ -8575,7 +8583,7 @@ param_expand (string, sindex, quoted, expanded_something, /* If we're not quoted but we still don't want word splitting, make we quote the IFS characters to protect them from splitting (e.g., when $@ is in the string as well). */ - else if (quoted == 0 && ifs_is_set && (pflags & PF_ASSIGNRHS)) + else if (temp && quoted == 0 && ifs_is_set && (pflags & PF_ASSIGNRHS)) { temp1 = quote_string (temp); free (temp); @@ -8637,7 +8645,8 @@ param_expand (string, sindex, quoted, expanded_something, performed? Even when IFS is not the default, posix seems to imply that we behave like unquoted $* ? Maybe we should use PF_NOSPLIT2 here. */ - temp = string_list_dollar_at (list, (pflags & PF_ASSIGNRHS) ? (quoted|Q_DOUBLE_QUOTES) : quoted, 0); + /* XXX - bash-4.4/bash-5.0 passing PFLAGS */ + temp = string_list_dollar_at (list, (pflags & PF_ASSIGNRHS) ? (quoted|Q_DOUBLE_QUOTES) : quoted, pflags); tflag |= W_DOLLARAT; dispose_words (list); @@ -9115,11 +9124,11 @@ add_string: string[sindex+1] == '~') word->flags |= W_ITILDE; #endif -#if 0 - /* XXX - bash-5.0 */ + + /* XXX - bash-4.4/bash-5.0 */ if (word->flags & W_ASSIGNARG) - word->flags |= W_ASSIGNRHS; -#endif + word->flags |= W_ASSIGNRHS; /* affects $@ */ + if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c)) goto add_ifs_character; else @@ -9351,11 +9360,11 @@ add_twochars: { tword = alloc_word_desc (); tword->word = temp; -#if 0 - /* XXX - bash-5.0 */ + + /* XXX - bash-4.4/bash-5.0 */ if (word->flags & W_ASSIGNARG) - tword->flags |= word->flags & (W_ASSIGNARG|W_ASSIGNRHS); -#endif + tword->flags |= word->flags & (W_ASSIGNARG|W_ASSIGNRHS); /* affects $@ */ + temp = (char *)NULL; temp_has_dollar_at = 0; /* XXX */ @@ -9379,7 +9388,7 @@ add_twochars: /* "$@" (a double-quoted dollar-at) expands into nothing, not even a NULL word, when there are no positional parameters. */ - if (list == 0 && has_dollar_at) + if (list == 0 && temp_has_dollar_at) /* XXX - was has_dollar_at */ { quoted_dollar_at++; break; @@ -9399,7 +9408,7 @@ add_twochars: if (list && list->word && (list->word->flags & W_HASQUOTEDNULL)) had_quoted_null = 1; /* XXX */ - if (has_dollar_at) + if (temp_has_dollar_at) /* XXX - was has_dollar_at */ { quoted_dollar_at++; if (contains_dollar_at) @@ -9511,8 +9520,9 @@ add_twochars: remove_quoted_escapes (temp); /* ??? */ /* We do not want to add quoted nulls to strings that are only - partially quoted; such nulls are discarded. */ - if (temp == 0 && (quoted_state == PARTIALLY_QUOTED)) + partially quoted; such nulls are discarded. See above for the + exception, which is when the string is going to be split. */ + if (temp == 0 && (quoted_state == PARTIALLY_QUOTED) && (word->flags & (W_NOSPLIT|W_NOSPLIT2))) continue; /* If we have a quoted null expansion, add a quoted NULL to istring. */ @@ -9614,6 +9624,8 @@ finished_with_string: /* According to sh, ksh, and Posix.2, if a word expands into nothing and a double-quoted "$@" appears anywhere in it, then the entire word is removed. */ + /* XXX - exception appears to be that quoted null strings result in + null arguments */ else if (quoted_state == UNQUOTED || quoted_dollar_at) list = (WORD_LIST *)NULL; #if 0 diff --git a/tests/dollar-at-star b/tests/dollar-at-star index 6b34abf..2d2a1b6 100755 --- a/tests/dollar-at-star +++ b/tests/dollar-at-star @@ -220,6 +220,11 @@ ${THIS_SH} ./dollar-at-star5.sub ${THIS_SH} ./dollar-at-star6.sub ${THIS_SH} ./dollar-at-star7.sub +# tests for expansions of $@ and ${a[@]} (vs. $* and ${a[*]}) on the RHS of +# assignment statements with non-default IFS: $@ expands to args or array +# members separated by spaces +${THIS_SH} ./dollar-at-star8.sub + # tests for special expansion of "$*" and "${array[*]}" when used with other # expansions -- bugs through bash-2.05b ${THIS_SH} ./dollar-star1.sub diff --git a/tests/dollar-at-star8.sub b/tests/dollar-at-star8.sub new file mode 100644 index 0000000..7e1b688 --- /dev/null +++ b/tests/dollar-at-star8.sub @@ -0,0 +1,14 @@ +function f { + typeset -a a + a=("$@") + typeset IFS=, + typeset a1="${a[@]} ${a[*]} $@ $* ${@} ${*}" + typeset a2=${a[@]}\ ${a[*]}\ $@\ $*\ ${@}\ ${*} a3 a4 + a3="${a[@]} ${a[*]} $@ $* ${@} ${*}" + a4=${a[@]}\ ${a[*]}\ $@\ $*\ ${@}\ ${*} + unset -v IFS + printf '%s\n' "a1=$a1" "a2=$a2" "a3=$a3" "a4=$a4" +} + +echo +f a b c diff --git a/tests/dollar.right b/tests/dollar.right index 8d21b6d..1e48c24 100644 --- a/tests/dollar.right +++ b/tests/dollar.right @@ -294,6 +294,11 @@ argv[3] = <'c'> |is| |a| |test| + +a1=a b c a,b,c a b c a,b,c a b c a,b,c +a2=a b c a,b,c a b c a,b,c a b c a,b,c +a3=a b c a,b,c a b c a,b,c a b c a,b,c +a4=a b c a,b,c a b c a,b,c a b c a,b,c xa|xb|xc xa|xb|xc a|b|c diff --git a/tests/exp.right b/tests/exp.right index 5e6d6cb..11b49ff 100644 --- a/tests/exp.right +++ b/tests/exp.right @@ -234,3 +234,103 @@ declare -a array=([0]=$'x\001y\177z') argv[1] = <x^Ay^?z> declare -a array=([0]=$'x\001y\177z') declare -A array=([$'x\001y\177z']=$'a\242b\002c' ) +abc +def +ghi +jkl +abc def ghi jkl +xxabc +def +ghi +jklyy +xxabc def ghi jklyy +abc +def +ghi +jkl +abc +def ghi +jkl +abc +def ghi +jkl +abc +def ghi +jkl +xxabc +def +ghi +jklyy +xxabc +def ghi +jklyy +abc +def +ghi +jklabc +def +ghi +jkl +abc +def ghi +jklabc +def ghi +jkl +abc:def ghi:jkl +abc:def ghi:jkl +abc:def ghi:jkl +abc +def ghi +jkl +abc:def ghi:jkl +abc:def ghi:jkl +abc +def ghi +jkl +var=abc:def ghi:jkl +abc:def ghi:jkl +var=abc:def ghi:jkl +abcdef ghijkl +abcdef ghijkl +abcdef ghijkl +abcdef ghijkl +abcdef ghijkl +abcdef ghijkl +abcdef ghijkl +var=abcdef ghijkl +abcdef ghijkl +var=abcdef ghijkl +abc +def ghi +jkl +abc def ghi jkl +abc def ghi jkl +abc def ghi jkl +abc +def +ghi +jkl +abc def ghi jkl +abc def ghi jkl +abc +def +ghi +jkl +var=abc def ghi jkl +abc def ghi jkl +var=abc def ghi jkl +abc +def ghi +jkl +[foo] +[] +[foo] +[] +[foo] +[foo] +[foo] +[] +[foo] +[] +[foo] +[] diff --git a/tests/exp.tests b/tests/exp.tests index e6e2bc5..b446d63 100644 --- a/tests/exp.tests +++ b/tests/exp.tests @@ -404,3 +404,4 @@ ${THIS_SH} ./exp5.sub ${THIS_SH} ./exp6.sub ${THIS_SH} ./exp7.sub ${THIS_SH} ./exp8.sub +${THIS_SH} ./exp9.sub diff --git a/tests/exp9.sub b/tests/exp9.sub new file mode 100644 index 0000000..a0399c7 --- /dev/null +++ b/tests/exp9.sub @@ -0,0 +1,69 @@ +# expansion test cases from Posix interp 888 + +set "abc" "def ghi" "jkl" +unset novar +IFS=' ' # a space +printf '%s\n' $* +printf '%s\n' "$*" +printf '%s\n' xx$*yy +printf '%s\n' "xx$*yy" +printf '%s\n' $@ +printf '%s\n' "$@" +printf '%s\n' ${1+"$@"} +printf '%s\n' ${novar-"$@"} +printf '%s\n' xx$@yy +printf '%s\n' "xx$@yy" +printf '%s\n' $@$@ +printf '%s\n' "$@$@" +IFS=':' +printf '%s\n' "$*" +var=$*; printf '%s\n' "$var" +var="$*"; printf '%s\n' "$var" +unset var +printf '%s\n' ${var-$*} +printf '%s\n' "${var-$*}" +printf '%s\n' ${var-"$*"} +printf '%s\n' ${var=$*} +printf 'var=%s\n' "$var" +unset var +printf '%s\n' "${var=$*}" +printf 'var=%s\n' "$var" + +IFS='' # null +printf '%s\n' "$*" +var=$*; printf '%s\n' "$var" +var="$*"; printf '%s\n' "$var" +unset var +printf '%s\n' ${var-$*} +printf '%s\n' "${var-$*}" +printf '%s\n' ${var-"$*"} +printf '%s\n' ${var=$*} +printf 'var=%s\n' "$var" +unset var +printf '%s\n' "${var=$*}" +printf 'var=%s\n' "$var" +printf '%s\n' "$@" + +unset IFS +printf '%s\n' "$*" +var=$*; printf '%s\n' "$var" +var="$*"; printf '%s\n' "$var" +unset var +printf '%s\n' ${var-$*} +printf '%s\n' "${var-$*}" +printf '%s\n' ${var-"$*"} +printf '%s\n' ${var=$*} +printf 'var=%s\n' "$var" +unset var +printf '%s\n' "${var=$*}" +printf 'var=%s\n' "$var" +printf '%s\n' "$@" + +set -- +printf '[%s]\n' foo "$*" +printf '[%s]\n' foo "$novar$*$(echo)" +printf '[%s]\n' foo $@ +printf '[%s]\n' foo "$@" +printf '[%s]\n' foo ''$@ +printf '[%s]\n' foo ''"$@" +printf '[%s]\n' foo ''"$novar$@$(echo)" |
