mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-22 13:27:58 +02:00
fix expansion of $* and $@ in contexts where word splitting is not performed to be more consistent across different word expansions; fix pathname canonicalization when setting $BASH
This commit is contained in:
@@ -12253,3 +12253,32 @@ sig.c
|
||||
doc/bash.1,doc/bashref.texi
|
||||
- fix some options typeset in the wrong font
|
||||
Report and patch from Grisha Levit <grishalevit@gmail.com>
|
||||
|
||||
subst.c
|
||||
- list_remove_pattern,parameter_list_remove_pattern,array_remove_pattern,
|
||||
parameter_brace_remove_pattern: take an additional PFLAGS argument
|
||||
from the PFLAGS passed to parameter_brace_expand
|
||||
- list_remove_pattern: pass PFLAGS to string_list_pos_params so it can
|
||||
get the right expansion of `@' and `*'
|
||||
Report by Emanuele Torre <torreemanuele6@gmail.com>
|
||||
|
||||
11/18
|
||||
-----
|
||||
variables.c
|
||||
- get_bash_name: only call sh_canonpath on the directory portion of
|
||||
the full pathname to the current executable; it only works on
|
||||
directories. Then glue the return value and the trailing component
|
||||
together to get the full pathname
|
||||
Report from Stan Marsh <gazelle@xmission.com>
|
||||
|
||||
11/20
|
||||
-----
|
||||
subst.c
|
||||
- parameter_list_transform,array_transform,list_transform: add an
|
||||
extra PFLAGS argument, passed down from parameter_brace_transform
|
||||
- list_transform,array_transform: pass PFLAGS to string_list_pos_params
|
||||
so it can get the right expansion of `@' and `*'
|
||||
This makes all the quoted and unquoted expansions of `@' consistent
|
||||
when they are expanded in a context that will not perform word
|
||||
splitting
|
||||
Report by Emanuele Torre <torreemanuele6@gmail.com>
|
||||
|
||||
@@ -1204,6 +1204,7 @@ tests/exp10.sub f
|
||||
tests/exp11.sub f
|
||||
tests/exp12.sub f
|
||||
tests/exp13.sub f
|
||||
tests/exp14.sub f
|
||||
tests/exportfunc.tests f
|
||||
tests/exportfunc.right f
|
||||
tests/exportfunc1.sub f
|
||||
|
||||
+3
-1
@@ -135,7 +135,7 @@ help_builtin (WORD_LIST *list)
|
||||
|
||||
globpat = glob_pattern_p (pattern);
|
||||
if (globpat)
|
||||
printf (_("Shell commands matching pattern '%s':\n\n"), pattern);
|
||||
printf (_("Shell commands matching pattern '%s':\n"), pattern);
|
||||
|
||||
for (pass = 1, this_found = 0; pass < 3; pass++)
|
||||
{
|
||||
@@ -153,6 +153,8 @@ help_builtin (WORD_LIST *list)
|
||||
|
||||
if (m)
|
||||
{
|
||||
if (globpat && this_found == 0)
|
||||
putchar ('\n');
|
||||
this_found = 1;
|
||||
match_found++;
|
||||
if (dflag)
|
||||
|
||||
@@ -299,23 +299,23 @@ static int match_pattern (char *, char *, int, char **, char **);
|
||||
static int getpatspec (int, const char *);
|
||||
static char *getpattern (char *, int, int);
|
||||
static char *variable_remove_pattern (char *, char *, int, int);
|
||||
static char *list_remove_pattern (WORD_LIST *, char *, int, int, int);
|
||||
static char *parameter_list_remove_pattern (int, char *, int, int);
|
||||
static char *list_remove_pattern (WORD_LIST *, char *, int, int, int, int);
|
||||
static char *parameter_list_remove_pattern (int, char *, int, int, int);
|
||||
#ifdef ARRAY_VARS
|
||||
static char *array_remove_pattern (SHELL_VAR *, char *, int, int, int);
|
||||
static char *array_remove_pattern (SHELL_VAR *, char *, int, int, int, int);
|
||||
#endif
|
||||
static char *parameter_brace_remove_pattern (char *, char *, array_eltstate_t *, char *, int, int, int);
|
||||
static char *parameter_brace_remove_pattern (char *, char *, array_eltstate_t *, char *, int, int, int, int);
|
||||
|
||||
static char *string_var_assignment (SHELL_VAR *, char *);
|
||||
#if defined (ARRAY_VARS)
|
||||
static char *array_var_assignment (SHELL_VAR *, int, int, int);
|
||||
#endif
|
||||
static char *pos_params_assignment (WORD_LIST *, int, int);
|
||||
static char *pos_params_assignment (WORD_LIST *, int, int, int);
|
||||
static char *string_transform (int, SHELL_VAR *, char *);
|
||||
static char *list_transform (int, SHELL_VAR *, WORD_LIST *, int, int);
|
||||
static char *parameter_list_transform (int, int, int);
|
||||
static char *list_transform (int, SHELL_VAR *, WORD_LIST *, int, int, int);
|
||||
static char *parameter_list_transform (int, int, int, int);
|
||||
#if defined ARRAY_VARS
|
||||
static char *array_transform (int, SHELL_VAR *, int, int);
|
||||
static char *array_transform (int, SHELL_VAR *, int, int, int);
|
||||
#endif
|
||||
static char *parameter_brace_transform (char *, char *, array_eltstate_t *, char *, int, int, int, int);
|
||||
static int valid_parameter_transform (const char *);
|
||||
@@ -3045,6 +3045,7 @@ string_list_dollar_at (WORD_LIST *list, int quoted, int flags)
|
||||
string_list as appropriate. */
|
||||
/* This needs to fully understand the additional contexts where word
|
||||
splitting does not occur (W_ASSIGNRHS, etc.) */
|
||||
/* XXX - does this need to handle (pflags & PF_NOSPLIT2)? */
|
||||
char *
|
||||
string_list_pos_params (int pchar, WORD_LIST *list, int quoted, int pflags)
|
||||
{
|
||||
@@ -3086,9 +3087,18 @@ string_list_pos_params (int pchar, WORD_LIST *list, int quoted, int pflags)
|
||||
else if (pchar == '@' && quoted == 0 && ifs_is_null) /* XXX */
|
||||
ret = string_list_dollar_at (list, quoted, 0); /* Posix interp 888 */
|
||||
else if (pchar == '@' && quoted == 0 && (pflags & PF_ASSIGNRHS))
|
||||
/* XXX - param_expand uses quoted|Q_DOUBLE_QUOTES for this case, but
|
||||
that quotes the escapes. We could use string_list_internal with " "
|
||||
as the second argument. */
|
||||
ret = string_list_dollar_at (list, quoted, pflags); /* Posix interp 888 */
|
||||
else if (pchar == '@')
|
||||
#if 0
|
||||
/* XXX - param_expand uses string_list_dollar_at() for this case. */
|
||||
/* string_list_dollar_at quotes CTLESC, even if quoted == 0 */
|
||||
ret = string_list_dollar_at (list, quoted, 0);
|
||||
#else
|
||||
ret = string_list_dollar_star (list, quoted, 0);
|
||||
#endif
|
||||
else
|
||||
ret = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (list) : list);
|
||||
|
||||
@@ -5777,7 +5787,7 @@ variable_remove_pattern (char *value, char *pattern, int patspec, int quoted)
|
||||
#endif
|
||||
|
||||
static char *
|
||||
list_remove_pattern (WORD_LIST *list, char *pattern, int patspec, int itype, int quoted)
|
||||
list_remove_pattern (WORD_LIST *list, char *pattern, int patspec, int itype, int quoted, int pflags)
|
||||
{
|
||||
WORD_LIST *new, *l;
|
||||
WORD_DESC *w;
|
||||
@@ -5792,14 +5802,14 @@ list_remove_pattern (WORD_LIST *list, char *pattern, int patspec, int itype, int
|
||||
}
|
||||
|
||||
l = REVERSE_LIST (new, WORD_LIST *);
|
||||
tword = string_list_pos_params (itype, l, quoted, 0);
|
||||
tword = string_list_pos_params (itype, l, quoted, pflags);
|
||||
dispose_words (l);
|
||||
|
||||
return (tword);
|
||||
}
|
||||
|
||||
static char *
|
||||
parameter_list_remove_pattern (int itype, char *pattern, int patspec, int quoted)
|
||||
parameter_list_remove_pattern (int itype, char *pattern, int patspec, int quoted, int pflags)
|
||||
{
|
||||
char *ret;
|
||||
WORD_LIST *list;
|
||||
@@ -5807,7 +5817,7 @@ parameter_list_remove_pattern (int itype, char *pattern, int patspec, int quoted
|
||||
list = list_rest_of_args ();
|
||||
if (list == 0)
|
||||
return ((char *)NULL);
|
||||
ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
|
||||
ret = list_remove_pattern (list, pattern, patspec, itype, quoted, pflags);
|
||||
dispose_words (list);
|
||||
return (ret);
|
||||
}
|
||||
@@ -5815,7 +5825,7 @@ parameter_list_remove_pattern (int itype, char *pattern, int patspec, int quoted
|
||||
#if defined (ARRAY_VARS)
|
||||
/* STARSUB is so we can figure out how it's indexed */
|
||||
static char *
|
||||
array_remove_pattern (SHELL_VAR *var, char *pattern, int patspec, int starsub, int quoted)
|
||||
array_remove_pattern (SHELL_VAR *var, char *pattern, int patspec, int starsub, int quoted, int pflags)
|
||||
{
|
||||
ARRAY *a;
|
||||
HASH_TABLE *h;
|
||||
@@ -5834,7 +5844,7 @@ array_remove_pattern (SHELL_VAR *var, char *pattern, int patspec, int starsub, i
|
||||
list = a ? array_to_word_list (a) : (h ? assoc_to_word_list (h) : 0);
|
||||
if (list == 0)
|
||||
return ((char *)NULL);
|
||||
ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
|
||||
ret = list_remove_pattern (list, pattern, patspec, itype, quoted, pflags);
|
||||
dispose_words (list);
|
||||
|
||||
return ret;
|
||||
@@ -5844,7 +5854,7 @@ array_remove_pattern (SHELL_VAR *var, char *pattern, int patspec, int starsub, i
|
||||
static char *
|
||||
parameter_brace_remove_pattern (char *varname, char *value,
|
||||
array_eltstate_t *estatep, char *patstr,
|
||||
int rtype, int quoted, int flags)
|
||||
int rtype, int quoted, int pflags, int flags)
|
||||
{
|
||||
int vtype, patspec, starsub;
|
||||
char *temp1, *val, *pattern, *oname;
|
||||
@@ -5894,7 +5904,7 @@ parameter_brace_remove_pattern (char *varname, char *value,
|
||||
break;
|
||||
#if defined (ARRAY_VARS)
|
||||
case VT_ARRAYVAR:
|
||||
temp1 = array_remove_pattern (v, pattern, patspec, starsub, quoted);
|
||||
temp1 = array_remove_pattern (v, pattern, patspec, starsub, quoted, pflags);
|
||||
if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
|
||||
{
|
||||
val = quote_escapes (temp1);
|
||||
@@ -5904,7 +5914,7 @@ parameter_brace_remove_pattern (char *varname, char *value,
|
||||
break;
|
||||
#endif
|
||||
case VT_POSPARMS:
|
||||
temp1 = parameter_list_remove_pattern (varname[0], pattern, patspec, quoted);
|
||||
temp1 = parameter_list_remove_pattern (varname[0], pattern, patspec, quoted, pflags);
|
||||
if (temp1 && quoted == 0 && ifs_is_null)
|
||||
{
|
||||
/* Posix interp 888 */
|
||||
@@ -8783,12 +8793,12 @@ array_var_assignment (SHELL_VAR *v, int itype, int quoted, int atype)
|
||||
#endif
|
||||
|
||||
static char *
|
||||
pos_params_assignment (WORD_LIST *list, int itype, int quoted)
|
||||
pos_params_assignment (WORD_LIST *list, int itype, int quoted, int pflags)
|
||||
{
|
||||
char *temp, *ret;
|
||||
|
||||
/* first, we transform the list to quote each word. */
|
||||
temp = list_transform ('Q', (SHELL_VAR *)0, list, itype, quoted);
|
||||
temp = list_transform ('Q', (SHELL_VAR *)0, list, itype, quoted, 0);
|
||||
ret = (char *)xmalloc (strlen (temp) + 8);
|
||||
strcpy (ret, "set -- ");
|
||||
strcpy (ret + 7, temp);
|
||||
@@ -8848,7 +8858,7 @@ string_transform (int xc, SHELL_VAR *v, char *s)
|
||||
}
|
||||
|
||||
static char *
|
||||
list_transform (int xc, SHELL_VAR *v, WORD_LIST *list, int itype, int quoted)
|
||||
list_transform (int xc, SHELL_VAR *v, WORD_LIST *list, int itype, int quoted, int pflags)
|
||||
{
|
||||
WORD_LIST *new, *l;
|
||||
WORD_DESC *w;
|
||||
@@ -8870,14 +8880,14 @@ list_transform (int xc, SHELL_VAR *v, WORD_LIST *list, int itype, int quoted)
|
||||
if (itype == '*' && expand_no_split_dollar_star && ifs_is_null)
|
||||
qflags |= Q_DOUBLE_QUOTES; /* Posix interp 888 */
|
||||
|
||||
tword = string_list_pos_params (itype, l, qflags, 0);
|
||||
tword = string_list_pos_params (itype, l, qflags, pflags);
|
||||
dispose_words (l);
|
||||
|
||||
return (tword);
|
||||
}
|
||||
|
||||
static char *
|
||||
parameter_list_transform (int xc, int itype, int quoted)
|
||||
parameter_list_transform (int xc, int itype, int quoted, int pflags)
|
||||
{
|
||||
char *ret;
|
||||
WORD_LIST *list;
|
||||
@@ -8886,9 +8896,9 @@ parameter_list_transform (int xc, int itype, int quoted)
|
||||
if (list == 0)
|
||||
return ((char *)NULL);
|
||||
if (xc == 'A')
|
||||
ret = pos_params_assignment (list, itype, quoted);
|
||||
ret = pos_params_assignment (list, itype, quoted, pflags);
|
||||
else
|
||||
ret = list_transform (xc, (SHELL_VAR *)0, list, itype, quoted);
|
||||
ret = list_transform (xc, (SHELL_VAR *)0, list, itype, quoted, pflags);
|
||||
dispose_words (list);
|
||||
return (ret);
|
||||
}
|
||||
@@ -8896,7 +8906,7 @@ parameter_list_transform (int xc, int itype, int quoted)
|
||||
#if defined (ARRAY_VARS)
|
||||
/* STARSUB so we can figure out how it's indexed */
|
||||
static char *
|
||||
array_transform (int xc, SHELL_VAR *var, int starsub, int quoted)
|
||||
array_transform (int xc, SHELL_VAR *var, int starsub, int quoted, int pflags)
|
||||
{
|
||||
ARRAY *a;
|
||||
HASH_TABLE *h;
|
||||
@@ -8939,7 +8949,7 @@ array_transform (int xc, SHELL_VAR *var, int starsub, int quoted)
|
||||
if (itype == '*' && expand_no_split_dollar_star && ifs_is_null)
|
||||
qflags |= Q_DOUBLE_QUOTES; /* Posix interp 888 */
|
||||
|
||||
ret = string_list_pos_params (itype, list, qflags, 0);
|
||||
ret = string_list_pos_params (itype, list, qflags, pflags);
|
||||
dispose_words (list);
|
||||
return ret;
|
||||
}
|
||||
@@ -8947,7 +8957,7 @@ array_transform (int xc, SHELL_VAR *var, int starsub, int quoted)
|
||||
list = a ? array_to_word_list (a) : (h ? assoc_to_word_list (h) : 0);
|
||||
if (list == 0)
|
||||
return ((char *)NULL);
|
||||
ret = list_transform (xc, v, list, itype, quoted);
|
||||
ret = list_transform (xc, v, list, itype, quoted, pflags);
|
||||
dispose_words (list);
|
||||
|
||||
return ret;
|
||||
@@ -9035,7 +9045,7 @@ parameter_brace_transform (char *varname, char *value, array_eltstate_t *estatep
|
||||
break;
|
||||
#if defined (ARRAY_VARS)
|
||||
case VT_ARRAYVAR:
|
||||
temp1 = array_transform (xc, v, starsub, quoted);
|
||||
temp1 = array_transform (xc, v, starsub, quoted, pflags);
|
||||
if (temp1 && quoted == 0 && ifs_is_null)
|
||||
{
|
||||
/* Posix interp 888 */
|
||||
@@ -9049,7 +9059,7 @@ parameter_brace_transform (char *varname, char *value, array_eltstate_t *estatep
|
||||
break;
|
||||
#endif
|
||||
case VT_POSPARMS:
|
||||
temp1 = parameter_list_transform (xc, varname[0], quoted);
|
||||
temp1 = parameter_list_transform (xc, varname[0], quoted, pflags);
|
||||
if (temp1 && quoted == 0 && ifs_is_null)
|
||||
{
|
||||
/* Posix interp 888 */
|
||||
@@ -10391,7 +10401,7 @@ bad_substitution:
|
||||
FREE (value);
|
||||
break;
|
||||
}
|
||||
temp1 = parameter_brace_remove_pattern (name, temp, &es, value, c, quoted, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
|
||||
temp1 = parameter_brace_remove_pattern (name, temp, &es, value, c, quoted, pflags, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
|
||||
free (temp);
|
||||
free (value);
|
||||
#if defined (ARRAY_VARS)
|
||||
|
||||
+2
-1
@@ -12,7 +12,8 @@ rm -f ${BASH_TSTOUT}
|
||||
|
||||
if [ -t 1 ]; then
|
||||
if type -P tput >/dev/null; then
|
||||
CSTART=$(tput setaf 15 setab 1) CEND=$(tput sgr0)
|
||||
# CSTART=$(tput setaf 15 setab 1) CEND=$(tput sgr0)
|
||||
CSTART=$(tput bold ; tput setab 9 ; tput setaf 7) CEND=$(tput sgr0)
|
||||
else
|
||||
# can't rely on having $'...' or printf understanding \e
|
||||
# bright red background, white foreground text
|
||||
|
||||
@@ -12,7 +12,8 @@ rm -f ${BASH_TSTOUT}
|
||||
|
||||
if [ -t 1 ]; then
|
||||
if type -P tput >/dev/null; then
|
||||
CSTART=$(tput setaf 15 setab 1) CEND=$(tput sgr0)
|
||||
# CSTART=$(tput setaf 15 setab 1) CEND=$(tput sgr0)
|
||||
CSTART=$(tput bold ; tput setab 9 ; tput setaf 7) CEND=$(tput sgr0)
|
||||
else
|
||||
# can't rely on having $'...' or printf understanding \e
|
||||
# bright red background, white foreground text
|
||||
|
||||
@@ -354,7 +354,7 @@ found
|
||||
./builtins9.sub: line 52: hash: /: Is a directory
|
||||
builtin hash -p /nosuchfile cat
|
||||
builtins10.sub
|
||||
./builtins10.sub: line 17: help: -x: invalid option
|
||||
./builtins10.sub: line 19: help: -x: invalid option
|
||||
help: usage: help [-dms] [pattern ...]
|
||||
These shell commands are defined internally. Type `help' to see this list.
|
||||
Type `help name' to find out more about the function `name'.
|
||||
@@ -495,7 +495,9 @@ A star (*) next to a name means that the command is disabled.
|
||||
getopts optstring name [arg ...] while COMMANDS; do COMMANDS-2; done
|
||||
hash [-lr] [-p pathname] [-dt] [name > { COMMANDS ; }
|
||||
help [-dms] [pattern ...]
|
||||
./builtins10.sub: line 39: help: no help topics match 'bash'. Try 'help help', 'man -k bash', or 'info bash'.
|
||||
./builtins10.sub: line 41: help: no help topics match 'bash'. Try 'help help', 'man -k bash', or 'info bash'.
|
||||
Shell commands matching pattern 'ad*x':
|
||||
./builtins10.sub: line 44: help: no help topics match 'ad*x'.
|
||||
builtins11.sub
|
||||
unlimited
|
||||
unlimited
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#
|
||||
# have to run through sed or grep to filter out version information
|
||||
|
||||
COLUMNS=80
|
||||
|
||||
# let's exercise print-help
|
||||
help -x
|
||||
|
||||
@@ -37,3 +39,6 @@ help -- | sed 1d
|
||||
|
||||
# maybe sometime in the future this will do something
|
||||
help -- bash
|
||||
|
||||
# Tinkering with format for pattern output
|
||||
help 'ad*x'
|
||||
|
||||
@@ -446,3 +446,31 @@ declare -i a="7"
|
||||
declare -- a="42"
|
||||
FOO
|
||||
declare -u A="FOO"
|
||||
exp14.sub
|
||||
!Q= <a b c> <a:b:c>
|
||||
Q= <a b c> <a:b:c>
|
||||
!Q= <a b c> <a:b:c>
|
||||
Q= <a b c> <a:b:c>
|
||||
!Q- <a b c> <a:b:c>
|
||||
Q- <a b c> <a:b:c>
|
||||
!Q? <a b c> <a:b:c>
|
||||
Q? <a b c> <a:b:c>
|
||||
!Q+ <a b c> <a:b:c>
|
||||
Q+ <a b c> <a:b:c>
|
||||
+Q+ <a b c> <a:b:c>
|
||||
!Q: <a b c> <a:b:c>
|
||||
Q: <a:b:c> <a:b:c>
|
||||
!Q# <a b c> <a:b:c>
|
||||
Q# <a:b:c> <a:b:c>
|
||||
!Q% <a b c> <a:b:c>
|
||||
Q% <a:b:c> <a:b:c>
|
||||
!Q/ <x x x> <x:x:x>
|
||||
Q/ <x:x:x> <x:x:x>
|
||||
!Q^ <A B C> <A:B:C>
|
||||
Q^ <A:B:C> <A:B:C>
|
||||
!Q, <a b c> <a:b:c>
|
||||
Q, <a:b:c> <a:b:c>
|
||||
!Q@Q <'a' 'b' 'c'> <'a':'b':'c'>
|
||||
Q@Q <'a':'b':'c'> <'a':'b':'c'>
|
||||
!Q@A <set -- 'a':'b':'c'> <set -- 'a':'b':'c'>
|
||||
Q@A <set -- 'a':'b':'c'> <set -- 'a':'b':'c'>
|
||||
|
||||
@@ -430,3 +430,4 @@ test_runsub ./exp10.sub
|
||||
test_runsub ./exp11.sub
|
||||
test_runsub ./exp12.sub
|
||||
test_runsub ./exp13.sub
|
||||
test_runsub ./exp14.sub
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
#
|
||||
# tests for quoted and unquoted expansions of $@/$* in contexts without
|
||||
# word splitting
|
||||
|
||||
set -- a b c
|
||||
OIFS="$IFS"
|
||||
|
||||
IFS=:; o=$@ s=$*; printf '!Q= <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
IFS=:; o="$@" s="$*"; printf ' Q= <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
IFS=:; o=${@} s=${*}; printf '!Q= <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
IFS=:; o="${@}" s="${*}"; printf 'Q= <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
IFS=:; o=${@-x} s=${*-x}; printf '!Q- <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
IFS=:; o="${@-x}" s="${*-x}"; printf ' Q- <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
IFS=:; o=${@?x} s=${*?x}; printf '!Q? <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
IFS=:; o="${@?x}" s="${*?x}"; printf ' Q? <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
IFS=:; o=${@+$@} s=${*+$*}; printf '!Q+ <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
IFS=:; o="${@+$@}" s="${*+$*}"; printf ' Q+ <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
IFS=:; o=${@+"$@"} s=${*+"$*"}; printf '+Q+ <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
|
||||
# positional parameter substring expansion
|
||||
IFS=:; o=${@:1} s=${*:1}; printf '!Q: <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
IFS=:; o="${@:1}" s="${*:1}"; printf 'Q: <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
|
||||
set -- aa bb cc
|
||||
|
||||
# positional parameter pattern removal
|
||||
IFS=:; o=${@#?} s=${*#?}; printf '!Q# <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
IFS=:; o="${@#?}" s="${*#?}"; printf 'Q# <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
|
||||
IFS=:; o=${@%?} s=${*%?}; printf '!Q%% <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
IFS=:; o="${@%?}" s="${*%?}"; printf 'Q%% <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
|
||||
set -- a b c
|
||||
|
||||
# positional parameter pattern substitution
|
||||
IFS=:; o=${@/?/x} s=${*/?/x}; printf '!Q/ <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
IFS=:; o="${@/?/x}" s="${*/?/x}"; printf 'Q/ <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
|
||||
# positional parameter case modification
|
||||
IFS=:; o=${@^[abc]} s=${*^[abc]}; printf '!Q^ <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
IFS=:; o="${@^[abc]}" s="${*^[abc]}"; printf 'Q^ <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
|
||||
set -- A B C
|
||||
|
||||
IFS=:; o=${@,[ABC]} s=${*,[ABC]}; printf '!Q, <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
IFS=:; o="${@,[ABC]}" s="${*,[ABC]}"; printf 'Q, <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
|
||||
set -- a b c
|
||||
|
||||
# positional parameter transformation -- quoting
|
||||
IFS=:; o=${@@Q} s=${*@Q}; printf '!Q@Q <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
IFS=:; o="${@@Q}" s="${*@Q}"; printf 'Q@Q <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
|
||||
# positional parameter transformation -- assignment
|
||||
IFS=:; o=${@@A} s=${*@A}; printf '!Q@A <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
IFS=:; o="${@@A}" s="${*@A}"; printf 'Q@A <%s> <%s>\n' "$o" "$s" ; IFS=$OIFS
|
||||
+2
-1
@@ -63,7 +63,8 @@ echo Any output from any test, unless otherwise noted, indicates a possible anom
|
||||
# keep track of passed and failed tests and report them
|
||||
if [ -t 1 ]; then
|
||||
if type -P tput >/dev/null; then
|
||||
CSTART=$(tput setaf 15 setab 1) CEND=$(tput sgr0)
|
||||
# CSTART=$(tput bold ; tput setaf 15 ; tput setab 1) CEND=$(tput sgr0)
|
||||
CSTART=$(tput bold ; tput setab 9 ; tput setaf 7) CEND=$(tput sgr0)
|
||||
else
|
||||
# can't rely on having $'...' or printf understanding \e
|
||||
# bright red background, white foreground text
|
||||
|
||||
+14
-1
@@ -820,11 +820,24 @@ get_bash_name (void)
|
||||
tname = make_absolute (shell_name, get_string_value ("PWD"));
|
||||
if (*shell_name == '.')
|
||||
{
|
||||
char *x, *fp;
|
||||
|
||||
x = strrchr (tname, '/');
|
||||
*x = 0;
|
||||
name = sh_canonpath (tname, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
|
||||
*x++ = '/';
|
||||
if (name == 0)
|
||||
name = tname;
|
||||
else
|
||||
free (tname);
|
||||
{
|
||||
fp = sh_makepath (name, x, 0);
|
||||
free (tname);
|
||||
if (fp)
|
||||
{
|
||||
free (name);
|
||||
name = fp;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
name = tname;
|
||||
|
||||
Reference in New Issue
Block a user