mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-14 23:50:49 +02:00
changes to make builtins that perform assignments work better with arbitrary associative array keys
This commit is contained in:
+4
-6
@@ -990,10 +990,7 @@ builtin_bind_variable (name, value, flags)
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
/* Callers are responsible for calling this with array references that have
|
||||
already undergone valid_array_reference checks.
|
||||
Affected builtins: read, printf
|
||||
To make this *really* work, needs additional downstream support, starting
|
||||
with assign_array_element and array_variable_name. */
|
||||
already undergone valid_array_reference checks (read, printf). */
|
||||
vflags = assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0;
|
||||
bindflags = flags | (assoc_expand_once ? ASS_NOEXPAND : 0) | ASS_ALLOWALLSUB;
|
||||
if (flags & ASS_NOEXPAND)
|
||||
@@ -1016,13 +1013,14 @@ builtin_bind_variable (name, value, flags)
|
||||
}
|
||||
|
||||
SHELL_VAR *
|
||||
builtin_bind_var_to_int (name, val)
|
||||
builtin_bind_var_to_int (name, val, flags)
|
||||
char *name;
|
||||
intmax_t val;
|
||||
int flags;
|
||||
{
|
||||
SHELL_VAR *v;
|
||||
|
||||
v = bind_var_to_int (name, val, ASS_ALLOWALLSUB);
|
||||
v = bind_var_to_int (name, val, flags|ASS_ALLOWALLSUB);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
+16
-1
@@ -232,7 +232,7 @@ extern sh_builtin_func_t *this_shell_builtin;
|
||||
extern sh_builtin_func_t *last_shell_builtin;
|
||||
|
||||
extern SHELL_VAR *builtin_bind_variable PARAMS((char *, char *, int));
|
||||
extern SHELL_VAR *builtin_bind_var_to_int PARAMS((char *, intmax_t));
|
||||
extern SHELL_VAR *builtin_bind_var_to_int PARAMS((char *, intmax_t, int));
|
||||
extern int builtin_unbind_variable PARAMS((const char *));
|
||||
|
||||
extern int builtin_arrayref_flags PARAMS((WORD_DESC *, int));
|
||||
@@ -263,4 +263,19 @@ extern int source_uses_path;
|
||||
/* variables from wait.def */
|
||||
extern int wait_intr_flag;
|
||||
|
||||
/* common code to set flags for valid_array_reference and builtin_bind_variable */
|
||||
#if defined (ARRAY_VARS)
|
||||
#define SET_VFLAGS(wordflags, vflags, bindflags) \
|
||||
do { \
|
||||
vflags = assoc_expand_once ? VA_NOEXPAND : 0; \
|
||||
bindflags = assoc_expand_once ? ASS_NOEXPAND : 0; \
|
||||
if (assoc_expand_once && (wordflags & W_ARRAYREF)) \
|
||||
vflags |= VA_ONEWORD|VA_NOEXPAND; \
|
||||
if (vflags & VA_NOEXPAND) \
|
||||
bindflags |= ASS_NOEXPAND; \
|
||||
if (vflags & VA_ONEWORD) \
|
||||
bindflags |= ASS_ONEWORD; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#endif /* !__COMMON_H */
|
||||
|
||||
+4
-4
@@ -151,7 +151,7 @@ extern int errno;
|
||||
if (vflag) \
|
||||
{ \
|
||||
SHELL_VAR *v; \
|
||||
v = builtin_bind_variable (vname, vbuf, 0); \
|
||||
v = builtin_bind_variable (vname, vbuf, bindflags); \
|
||||
stupidly_hack_special_variables (vname); \
|
||||
if (v == 0 || readonly_p (v) || noassign_p (v)) \
|
||||
return (EXECUTION_FAILURE); \
|
||||
@@ -232,6 +232,7 @@ static int conversion_error;
|
||||
|
||||
/* printf -v var support */
|
||||
static int vflag = 0;
|
||||
static int bindflags = 0;
|
||||
static char *vbuf, *vname;
|
||||
static size_t vbsize;
|
||||
static int vblen;
|
||||
@@ -266,10 +267,9 @@ printf_builtin (list)
|
||||
{
|
||||
case 'v':
|
||||
vname = list_optarg;
|
||||
bindflags = 0;
|
||||
#if defined (ARRAY_VARS)
|
||||
arrayflags = assoc_expand_once ? VA_NOEXPAND : 0;
|
||||
if (assoc_expand_once && (list_optflags & W_ARRAYREF))
|
||||
arrayflags |= VA_ONEWORD|VA_NOEXPAND;
|
||||
SET_VFLAGS (list_optflags, arrayflags, bindflags);
|
||||
retval = legal_identifier (vname) || valid_array_reference (vname, arrayflags);
|
||||
#else
|
||||
retval = legal_identifier (vname);
|
||||
|
||||
+3
-17
@@ -190,20 +190,6 @@ read_builtin_timeout (fd)
|
||||
: shtimer_select (read_timeout));
|
||||
}
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
#define SET_VFLAGS(wordflags) \
|
||||
do { \
|
||||
vflags = assoc_expand_once ? VA_NOEXPAND : 0; \
|
||||
bindflags = assoc_expand_once ? ASS_NOEXPAND : 0; \
|
||||
if (assoc_expand_once && (wordflags & W_ARRAYREF)) \
|
||||
vflags |= VA_ONEWORD|VA_NOEXPAND; \
|
||||
if (vflags & VA_NOEXPAND) \
|
||||
bindflags |= ASS_NOEXPAND; \
|
||||
if (vflags & VA_ONEWORD) \
|
||||
bindflags |= ASS_ONEWORD; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/* Read the value of the shell variables whose names follow.
|
||||
The reading is done from the current input stream, whatever
|
||||
that may be. Successive words of the input line are assigned
|
||||
@@ -378,7 +364,7 @@ read_builtin (list)
|
||||
variable names is a valid identifier, and bail early if so. */
|
||||
#if defined (ARRAY_VARS)
|
||||
if (list)
|
||||
SET_VFLAGS (list->word->flags);
|
||||
SET_VFLAGS (list->word->flags, vflags, bindflags);
|
||||
if (list && legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word, vflags) == 0)
|
||||
#else
|
||||
bindflags = 0;
|
||||
@@ -969,7 +955,7 @@ assign_vars:
|
||||
{
|
||||
varname = list->word->word;
|
||||
#if defined (ARRAY_VARS)
|
||||
SET_VFLAGS (list->word->flags);
|
||||
SET_VFLAGS (list->word->flags, vflags, bindflags);
|
||||
if (legal_identifier (varname) == 0 && valid_array_reference (varname, vflags) == 0)
|
||||
#else
|
||||
if (legal_identifier (varname) == 0)
|
||||
@@ -1018,7 +1004,7 @@ assign_vars:
|
||||
|
||||
/* Now assign the rest of the line to the last variable argument. */
|
||||
#if defined (ARRAY_VARS)
|
||||
SET_VFLAGS (list->word->flags);
|
||||
SET_VFLAGS (list->word->flags, vflags, bindflags);
|
||||
if (legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word, vflags) == 0)
|
||||
#else
|
||||
if (legal_identifier (list->word->word) == 0)
|
||||
|
||||
+7
-11
@@ -111,7 +111,7 @@ int
|
||||
wait_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int status, code, opt, nflag;
|
||||
int status, code, opt, nflag, vflags, bindflags;
|
||||
volatile int wflags;
|
||||
char *vname;
|
||||
SHELL_VAR *pidvar;
|
||||
@@ -119,7 +119,7 @@ wait_builtin (list)
|
||||
|
||||
USE_VAR(list);
|
||||
|
||||
nflag = wflags = 0;
|
||||
nflag = wflags = vflags = 0;
|
||||
vname = NULL;
|
||||
pidvar = (SHELL_VAR *)NULL;
|
||||
reset_internal_getopt ();
|
||||
@@ -136,6 +136,7 @@ wait_builtin (list)
|
||||
break;
|
||||
case 'p':
|
||||
vname = list_optarg;
|
||||
vflags = list_optflags;
|
||||
break;
|
||||
#endif
|
||||
CASE_HELPOPT;
|
||||
@@ -152,15 +153,10 @@ wait_builtin (list)
|
||||
#if defined (ARRAY_VARS)
|
||||
int arrayflags;
|
||||
|
||||
#if 0
|
||||
arrayflags = assoc_expand_once ? VA_NOEXPAND : 0;
|
||||
if (assoc_expand_once && (list_optflags & W_ARRAYREF))
|
||||
arrayflags |= VA_ONEWORD|VA_NOEXPAND;
|
||||
#else
|
||||
arrayflags = 0; /* not yet without builtin_bind_var_to_int support */
|
||||
#endif
|
||||
SET_VFLAGS (vflags, arrayflags, bindflags);
|
||||
if (legal_identifier (vname) == 0 && valid_array_reference (vname, arrayflags) == 0)
|
||||
#else
|
||||
bindflags = 0;
|
||||
if (legal_identifier (vname) == 0)
|
||||
#endif
|
||||
{
|
||||
@@ -225,7 +221,7 @@ wait_builtin (list)
|
||||
|
||||
status = wait_for_any_job (wflags, &pstat);
|
||||
if (vname && status >= 0)
|
||||
builtin_bind_var_to_int (vname, pstat.pid);
|
||||
builtin_bind_var_to_int (vname, pstat.pid, bindflags);
|
||||
|
||||
if (status < 0)
|
||||
status = 127;
|
||||
@@ -241,7 +237,7 @@ wait_builtin (list)
|
||||
{
|
||||
wait_for_background_pids (&pstat);
|
||||
if (vname)
|
||||
builtin_bind_var_to_int (vname, pstat.pid);
|
||||
builtin_bind_var_to_int (vname, pstat.pid, bindflags);
|
||||
WAIT_RETURN (EXECUTION_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user