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 *);
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)
{
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);
#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;
}
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;
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);
}
#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;
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;
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;
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);
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 */
#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);
}
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;
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;
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);
}
#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;
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;
}
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;
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 */
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 */
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)
--- /dev/null
+# 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