mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-27 07:43:07 +02:00
commit bash-20161216 snapshot
This commit is contained in:
@@ -12749,3 +12749,73 @@ arrayfunc.c
|
||||
expand_assignment_string_to_string; just use the unexpanded subscript
|
||||
to produce the key [THIS IS A WORK IN PROGRESS]
|
||||
|
||||
12/14
|
||||
-----
|
||||
subst.h
|
||||
- ASS_NOEXPAND: assignment flag that inhibits expansion of associative
|
||||
array subscripts
|
||||
|
||||
variables.c
|
||||
- bind_int_variable: takes new flags arg; flags are taken from the
|
||||
ASS_ set of assignment flags, changed callers (bashline.c, expr.c,
|
||||
pcomplete.c)
|
||||
- bind_int_variable: if flags includes ASS_NOEXPAND, pass 1 as flag to
|
||||
valid_array_reference and array_variable_part to pass along to
|
||||
skipsubscript, so we don't try to skip over quoted strings in the
|
||||
subscript
|
||||
- bind_int_variable: pass flags along to assign_array_element
|
||||
|
||||
variables.h
|
||||
- bind_int_variable: updated extern declaration with new flags arg
|
||||
|
||||
expr.c
|
||||
- expr_bind_variable: if the assoc_expand_once option is enabled, and
|
||||
the flags to evalexp indicate that we have already run the expression
|
||||
through word expansion, pass ASS_NOEXPAND as flag to bind_int_variable
|
||||
|
||||
arrayfunc.c
|
||||
- assign_array_element: if flags includes ASS_NOEXPAND, pass 1 as flag
|
||||
to array_variable_name to pass along to skipsubscript
|
||||
- assign_array_element: if flags includes ASS_NOEXPAND, don't run an
|
||||
associative array subscript through word expansion, just use as-is
|
||||
|
||||
subst.c
|
||||
- param_expand: call evalexp with EXP_EXPANDED flag for arithmetic
|
||||
substitution because the string has already been expanded with
|
||||
expand_arith_string
|
||||
|
||||
12/15
|
||||
-----
|
||||
builtins/read.def
|
||||
- read_builtin: use value of assoc_expand_once for valid_array_reference
|
||||
as with other uses
|
||||
- bind_read_variable: if assoc_expand_once is set, pass ASS_NOEXPAND
|
||||
to assign_array_element
|
||||
|
||||
general.c
|
||||
- assignment: instead of checking whether flags == 0 to allow a `[',
|
||||
explicitly check for (flags&1) to disallow it. This leaves the door
|
||||
open for additional flag values
|
||||
|
||||
builtins/printf.def
|
||||
- printf_builtin: use value of assoc_expand_once for
|
||||
valid_array_reference as with other uses
|
||||
- bind_printf_variable: if assoc_expand_once is set, pass ASS_NOEXPAND
|
||||
to assign_array_element
|
||||
|
||||
12/16
|
||||
-----
|
||||
builtins/history.def
|
||||
- change history -d option to handle negative arguments; negative
|
||||
arguments offset from the end of the history list (last_position + 1
|
||||
so history -d -1 deletes the history -d command that just got
|
||||
added). Original patch from Piotr Grzybowski <narsil.pl@gmail.com>
|
||||
|
||||
doc/bash.1,lib/readline/doc/hsuser.texi
|
||||
- documented new behavior of negative offsets for `history -d'
|
||||
|
||||
12/17
|
||||
-----
|
||||
lib/readline/history.c
|
||||
- remove_history: use memmove to move the history list around instead
|
||||
of a loop that copies pointers one at a time, similar to add_history
|
||||
|
||||
@@ -864,6 +864,7 @@ tests/assoc5.sub f
|
||||
tests/assoc6.sub f
|
||||
tests/assoc7.sub f
|
||||
tests/assoc8.sub f
|
||||
tests/assoc9.sub f
|
||||
tests/attr.tests f
|
||||
tests/attr.right f
|
||||
tests/attr1.sub f
|
||||
|
||||
+7
-3
@@ -276,7 +276,8 @@ bind_assoc_variable (entry, name, key, value, flags)
|
||||
}
|
||||
|
||||
/* Parse NAME, a lhs of an assignment statement of the form v[s], and
|
||||
assign VALUE to that array element by calling bind_array_variable(). */
|
||||
assign VALUE to that array element by calling bind_array_variable().
|
||||
Flags are ASS_ assignment flags */
|
||||
SHELL_VAR *
|
||||
assign_array_element (name, value, flags)
|
||||
char *name, *value;
|
||||
@@ -286,7 +287,7 @@ assign_array_element (name, value, flags)
|
||||
int sublen;
|
||||
SHELL_VAR *entry, *nv;
|
||||
|
||||
vname = array_variable_name (name, 0, &sub, &sublen);
|
||||
vname = array_variable_name (name, (flags & ASS_NOEXPAND) != 0, &sub, &sublen);
|
||||
|
||||
if (vname == 0)
|
||||
return ((SHELL_VAR *)NULL);
|
||||
@@ -321,7 +322,10 @@ assign_array_element_internal (entry, name, vname, sub, sublen, value, flags)
|
||||
if (entry && assoc_p (entry))
|
||||
{
|
||||
sub[sublen-1] = '\0';
|
||||
akey = expand_assignment_string_to_string (sub, 0); /* [ */
|
||||
if ((flags & ASS_NOEXPAND) == 0)
|
||||
akey = expand_assignment_string_to_string (sub, 0); /* [ */
|
||||
else
|
||||
akey = savestring (sub);
|
||||
sub[sublen-1] = ']';
|
||||
if (akey == 0 || *akey == 0)
|
||||
{
|
||||
|
||||
+1
-1
@@ -4137,7 +4137,7 @@ bash_execute_unix_command (count, key)
|
||||
VSETATTR (v, att_exported);
|
||||
l = v ? value_cell (v) : 0;
|
||||
value = inttostr (rl_point, ibuf, sizeof (ibuf));
|
||||
v = bind_int_variable ("READLINE_POINT", value);
|
||||
v = bind_int_variable ("READLINE_POINT", value, 0);
|
||||
if (v)
|
||||
VSETATTR (v, att_exported);
|
||||
array_needs_making = 1;
|
||||
|
||||
@@ -295,6 +295,7 @@ declare_internal (list, local_var)
|
||||
{
|
||||
char *value, *name, *oldname;
|
||||
int offset, aflags, wflags, created_var, namelen;
|
||||
int assoc_noexpand;
|
||||
#if defined (ARRAY_VARS)
|
||||
int making_array_special, compound_array_assign, simple_array_assign;
|
||||
int var_exists, array_exists, creating_array, array_subscript_assignment;
|
||||
@@ -302,7 +303,8 @@ declare_internal (list, local_var)
|
||||
|
||||
name = savestring (list->word->word);
|
||||
wflags = list->word->flags;
|
||||
offset = assignment (name, 0);
|
||||
assoc_noexpand = assoc_expand_once && (wflags & W_ASSIGNMENT);
|
||||
offset = assignment (name, assoc_noexpand ? 2 : 0);
|
||||
aflags = 0;
|
||||
created_var = 0;
|
||||
|
||||
@@ -828,10 +830,13 @@ restart_new_var_name:
|
||||
assign_array_var_from_string (var, value, aflags|ASS_FORCE);
|
||||
else if (simple_array_assign && subscript_start)
|
||||
{
|
||||
int local_aflags;
|
||||
/* declare [-aA] name[N]=value */
|
||||
*subscript_start = '['; /* ] */
|
||||
/* XXX - problem here with appending */
|
||||
var = assign_array_element (name, value, aflags&ASS_APPEND); /* XXX - not aflags */
|
||||
local_aflags = aflags&ASS_APPEND;
|
||||
local_aflags |= assoc_noexpand ? ASS_NOEXPAND : 0;
|
||||
var = assign_array_element (name, value, local_aflags); /* XXX - not aflags */
|
||||
*subscript_start = '\0';
|
||||
if (var == 0) /* some kind of assignment error */
|
||||
{
|
||||
|
||||
+23
-6
@@ -31,7 +31,8 @@ entry with a `*'. An argument of N lists only the last N entries.
|
||||
|
||||
Options:
|
||||
-c clear the history list by deleting all of the entries
|
||||
-d offset delete the history entry at position OFFSET.
|
||||
-d offset delete the history entry at position OFFSET. Negative
|
||||
offsets count back from the end of the history list
|
||||
|
||||
-a append history lines from this session to the history file
|
||||
-n read all history lines not already read from the history file
|
||||
@@ -104,7 +105,7 @@ int
|
||||
history_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int flags, opt, result, old_history_lines, obase;
|
||||
int flags, opt, result, old_history_lines, obase, ind;
|
||||
char *filename, *delete_arg;
|
||||
intmax_t delete_offset;
|
||||
|
||||
@@ -180,14 +181,30 @@ history_builtin (list)
|
||||
#endif
|
||||
else if (flags & DFLAG)
|
||||
{
|
||||
if ((legal_number (delete_arg, &delete_offset) == 0)
|
||||
|| (delete_offset < history_base)
|
||||
|| (delete_offset > (history_base + history_length)))
|
||||
if (legal_number (delete_arg, &delete_offset) == 0)
|
||||
{
|
||||
sh_erange (delete_arg, _("history position"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
opt = delete_offset;
|
||||
/* check for negative offsets, count back from end of list */
|
||||
if (delete_arg[0] == '-' && delete_offset < 0)
|
||||
{
|
||||
ind = history_length + delete_offset;
|
||||
if (ind < history_base)
|
||||
{
|
||||
sh_erange (delete_arg, _("history position"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
opt = ind + 1; /* so history -d -1 deletes last history entry */
|
||||
}
|
||||
else if ((delete_offset < history_base) || (delete_offset > (history_base + history_length)))
|
||||
{
|
||||
sh_erange (delete_arg, _("history position"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
else
|
||||
opt = delete_offset;
|
||||
|
||||
result = bash_delete_histent (opt - history_base);
|
||||
/* Since remove_history changes history_length, this can happen if
|
||||
we delete the last history entry. */
|
||||
|
||||
+3
-3
@@ -258,7 +258,7 @@ printf_builtin (list)
|
||||
case 'v':
|
||||
vname = list_optarg;
|
||||
#if defined (ARRAY_VARS)
|
||||
if (legal_identifier (vname) || valid_array_reference (vname, 0))
|
||||
if (legal_identifier (vname) || valid_array_reference (vname, assoc_expand_once))
|
||||
#else
|
||||
if (legal_identifier (vname))
|
||||
#endif
|
||||
@@ -1270,10 +1270,10 @@ bind_printf_variable (name, value, flags)
|
||||
SHELL_VAR *v;
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
if (valid_array_reference (name, 0) == 0)
|
||||
if (valid_array_reference (name, assoc_expand_once) == 0)
|
||||
v = bind_variable (name, value, flags);
|
||||
else
|
||||
v = assign_array_element (name, value, flags);
|
||||
v = assign_array_element (name, value, flags | (assoc_expand_once ? ASS_NOEXPAND : 0));
|
||||
#else /* !ARRAY_VARS */
|
||||
v = bind_variable (name, value, flags);
|
||||
#endif /* !ARRAY_VARS */
|
||||
|
||||
+5
-5
@@ -337,7 +337,7 @@ read_builtin (list)
|
||||
/* Convenience: check early whether or not the first of possibly several
|
||||
variable names is a valid identifier, and bail early if so. */
|
||||
#if defined (ARRAY_VARS)
|
||||
if (list && legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word, 0) == 0)
|
||||
if (list && legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word, assoc_expand_once) == 0)
|
||||
#else
|
||||
if (list && legal_identifier (list->word->word) == 0)
|
||||
#endif
|
||||
@@ -816,7 +816,7 @@ assign_vars:
|
||||
{
|
||||
varname = list->word->word;
|
||||
#if defined (ARRAY_VARS)
|
||||
if (legal_identifier (varname) == 0 && valid_array_reference (varname, 0) == 0)
|
||||
if (legal_identifier (varname) == 0 && valid_array_reference (varname, assoc_expand_once) == 0)
|
||||
#else
|
||||
if (legal_identifier (varname) == 0)
|
||||
#endif
|
||||
@@ -864,7 +864,7 @@ assign_vars:
|
||||
|
||||
/* Now assign the rest of the line to the last variable argument. */
|
||||
#if defined (ARRAY_VARS)
|
||||
if (legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word, 0) == 0)
|
||||
if (legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word, assoc_expand_once) == 0)
|
||||
#else
|
||||
if (legal_identifier (list->word->word) == 0)
|
||||
#endif
|
||||
@@ -927,10 +927,10 @@ bind_read_variable (name, value)
|
||||
SHELL_VAR *v;
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
if (valid_array_reference (name, 0) == 0)
|
||||
if (valid_array_reference (name, assoc_expand_once) == 0)
|
||||
v = bind_variable (name, value, 0);
|
||||
else
|
||||
v = assign_array_element (name, value, 0);
|
||||
v = assign_array_element (name, value, assoc_expand_once ? ASS_NOEXPAND : 0);
|
||||
#else /* !ARRAY_VARS */
|
||||
v = bind_variable (name, value, 0);
|
||||
#endif /* !ARRAY_VARS */
|
||||
|
||||
+1
-1
@@ -859,7 +859,7 @@ unset_builtin (list)
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
unset_array = 0;
|
||||
if (!unset_function && nameref == 0 && valid_array_reference (name, 1)) /* XXX valid array reference second arg was 0 */
|
||||
if (!unset_function && nameref == 0 && valid_array_reference (name, assoc_expand_once)) /* XXX valid array reference second arg was 0 */
|
||||
{
|
||||
t = strchr (name, '[');
|
||||
*t++ = '\0';
|
||||
|
||||
+6
-2
@@ -5,12 +5,12 @@
|
||||
.\" Case Western Reserve University
|
||||
.\" chet.ramey@case.edu
|
||||
.\"
|
||||
.\" Last Change: Wed Nov 30 10:05:42 PST 2016
|
||||
.\" Last Change: Fri Dec 16 11:45:56 EST 2016
|
||||
.\"
|
||||
.\" bash_builtins, strip all but Built-Ins section
|
||||
.if \n(zZ=1 .ig zZ
|
||||
.if \n(zY=1 .ig zY
|
||||
.TH BASH 1 "2016 November 30" "GNU Bash 4.4"
|
||||
.TH BASH 1 "2016 December 16" "GNU Bash 4.4"
|
||||
.\"
|
||||
.\" There's some problem with having a `@'
|
||||
.\" in a tagged paragraph with the BSD man macros.
|
||||
@@ -8468,6 +8468,10 @@ Clear the history list by deleting all the entries.
|
||||
.TP
|
||||
\fB\-d\fP \fIoffset\fP
|
||||
Delete the history entry at position \fIoffset\fP.
|
||||
If \fIoffset\fP is negative, it is interpreted as relative to one greater
|
||||
than the last history position, so negative indices count back from the
|
||||
end of the history, and an index of \-1 refers to the current
|
||||
\fBhistory -d\fP command.
|
||||
.TP
|
||||
.B \-a
|
||||
Append the ``new'' history lines to the history file.
|
||||
|
||||
+2
-2
@@ -2,10 +2,10 @@
|
||||
Copyright (C) 1988-2016 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set LASTCHANGE Mon Dec 12 12:26:16 EST 2016
|
||||
@set LASTCHANGE Fri Dec 16 11:45:56 EST 2016
|
||||
|
||||
@set EDITION 4.4
|
||||
@set VERSION 4.4
|
||||
|
||||
@set UPDATED 12 December 2016
|
||||
@set UPDATED 16 December 2016
|
||||
@set UPDATED-MONTH December 2016
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
#include "bashintl.h"
|
||||
|
||||
#include "shell.h"
|
||||
#include "subst.h"
|
||||
#include "typemax.h" /* INTMAX_MAX, INTMAX_MIN */
|
||||
|
||||
/* Because of the $((...)) construct, expressions may include newlines.
|
||||
@@ -317,8 +318,10 @@ expr_bind_variable (lhs, rhs)
|
||||
char *lhs, *rhs;
|
||||
{
|
||||
SHELL_VAR *v;
|
||||
int aflags;
|
||||
|
||||
v = bind_int_variable (lhs, rhs);
|
||||
aflags = (assoc_expand_once && already_expanded) ? ASS_NOEXPAND : 0;
|
||||
v = bind_int_variable (lhs, rhs, aflags);
|
||||
if (v && (readonly_p (v) || noassign_p (v)))
|
||||
sh_longjmp (evalbuf, 1); /* variable assignment error */
|
||||
stupidly_hack_special_variables (lhs);
|
||||
@@ -1150,10 +1153,11 @@ expr_streval (tok, e, lvalue)
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
ind = -1;
|
||||
/* Second argument of 0 to get_array_value means that we don't allow
|
||||
references like array[@]. In this case, get_array_value is just
|
||||
like get_variable_value in that it does not return newly-allocated
|
||||
memory or quote the results. */
|
||||
/* If the second argument to get_array_value doesn't include AV_ALLOWALL,
|
||||
we don't allow references like array[@]. In this case, get_array_value
|
||||
is just like get_variable_value in that it does not return newly-allocated
|
||||
memory or quote the results. AFLAG is set above and is either AV_NOEXPAND
|
||||
or 0. */
|
||||
value = (e == ']') ? get_array_value (tok, aflag, (int *)NULL, &ind) : get_variable_value (v);
|
||||
#else
|
||||
value = get_variable_value (v);
|
||||
|
||||
@@ -349,7 +349,8 @@ legal_alias_name (string, flags)
|
||||
}
|
||||
|
||||
/* Returns non-zero if STRING is an assignment statement. The returned value
|
||||
is the index of the `=' sign. */
|
||||
is the index of the `=' sign. If FLAGS&1 we are expecting a compound assignment
|
||||
and don't want an array subscript before the `='. */
|
||||
int
|
||||
assignment (string, flags)
|
||||
const char *string;
|
||||
@@ -361,7 +362,7 @@ assignment (string, flags)
|
||||
c = string[indx = 0];
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
if ((legal_variable_starter (c) == 0) && (flags == 0 || c != '[')) /* ] */
|
||||
if ((legal_variable_starter (c) == 0) && ((flags&1) == 0 || c != '[')) /* ] */
|
||||
#else
|
||||
if (legal_variable_starter (c) == 0)
|
||||
#endif
|
||||
@@ -377,7 +378,7 @@ assignment (string, flags)
|
||||
#if defined (ARRAY_VARS)
|
||||
if (c == '[')
|
||||
{
|
||||
newi = skipsubscript (string, indx, 0);
|
||||
newi = skipsubscript (string, indx, (flags & 2) ? 1 : 0);
|
||||
if (string[newi++] != ']')
|
||||
return (0);
|
||||
if (string[newi] == '+' && string[newi+1] == '=')
|
||||
|
||||
@@ -198,8 +198,12 @@ with the other options to replace the history list completely.
|
||||
|
||||
@item -d @var{offset}
|
||||
Delete the history entry at position @var{offset}.
|
||||
@var{offset} should be specified as it appears when the history is
|
||||
displayed.
|
||||
If @var{offset} is positive, it should be specified as it appears when
|
||||
the history is displayed.
|
||||
If @var{offset} is negative, it is interpreted as relative to one greater
|
||||
than the last history position, so negative indices count back from the
|
||||
end of the history, and an index of @samp{-1} refers to the current
|
||||
@code{history -d} command.
|
||||
|
||||
@item -a
|
||||
Append the new history lines to the history file.
|
||||
|
||||
@@ -498,14 +498,27 @@ remove_history (which)
|
||||
{
|
||||
HIST_ENTRY *return_value;
|
||||
register int i;
|
||||
#if 1
|
||||
int nentries;
|
||||
HIST_ENTRY **start, **end;
|
||||
#endif
|
||||
|
||||
if (which < 0 || which >= history_length || history_length == 0 || the_history == 0)
|
||||
return ((HIST_ENTRY *)NULL);
|
||||
|
||||
return_value = the_history[which];
|
||||
|
||||
#if 1
|
||||
/* Copy the rest of the entries, moving down one slot. Copy includes
|
||||
trailing NULL. */
|
||||
nentries = history_length - which;
|
||||
start = the_history + which;
|
||||
end = start + 1;
|
||||
memmove (start, end, nentries * sizeof (HIST_ENTRY *));
|
||||
#else
|
||||
for (i = which; i < history_length; i++)
|
||||
the_history[i] = the_history[i + 1];
|
||||
#endif
|
||||
|
||||
history_length--;
|
||||
|
||||
|
||||
+4
-4
@@ -993,17 +993,17 @@ bind_compfunc_variables (line, ind, lwords, cw, exported)
|
||||
llen = MB_STRLEN (line);
|
||||
line[ind] = c;
|
||||
value = inttostr (llen, ibuf, sizeof(ibuf));
|
||||
v = bind_int_variable ("COMP_POINT", value);
|
||||
v = bind_int_variable ("COMP_POINT", value, 0);
|
||||
if (v && exported)
|
||||
VSETATTR(v, att_exported);
|
||||
|
||||
value = inttostr (rl_completion_type, ibuf, sizeof (ibuf));
|
||||
v = bind_int_variable ("COMP_TYPE", value);
|
||||
v = bind_int_variable ("COMP_TYPE", value, 0);
|
||||
if (v && exported)
|
||||
VSETATTR(v, att_exported);
|
||||
|
||||
value = inttostr (rl_completion_invoking_key, ibuf, sizeof (ibuf));
|
||||
v = bind_int_variable ("COMP_KEY", value);
|
||||
v = bind_int_variable ("COMP_KEY", value, 0);
|
||||
if (v && exported)
|
||||
VSETATTR(v, att_exported);
|
||||
|
||||
@@ -1014,7 +1014,7 @@ bind_compfunc_variables (line, ind, lwords, cw, exported)
|
||||
#ifdef ARRAY_VARS
|
||||
v = bind_comp_words (lwords);
|
||||
value = inttostr (cw, ibuf, sizeof(ibuf));
|
||||
bind_int_variable ("COMP_CWORD", value);
|
||||
bind_int_variable ("COMP_CWORD", value, 0);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
||||
@@ -8963,7 +8963,7 @@ arithsub:
|
||||
/* No error messages. */
|
||||
savecmd = this_command_name;
|
||||
this_command_name = (char *)NULL;
|
||||
number = evalexp (temp1, 0, &expok);
|
||||
number = evalexp (temp1, EXP_EXPANDED, &expok);
|
||||
this_command_name = savecmd;
|
||||
free (temp);
|
||||
free (temp1);
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#define ASS_NAMEREF 0x0010 /* assigning to nameref variable */
|
||||
#define ASS_FORCE 0x0020 /* force assignment even to readonly variable */
|
||||
#define ASS_CHKLOCAL 0x0040 /* check local variable before assignment */
|
||||
#define ASS_NOEXPAND 0x0080 /* don't expand associative array subscripts */
|
||||
|
||||
/* Flags for the string extraction functions. */
|
||||
#define SX_NOALLOC 0x0001 /* just skip; don't return substring */
|
||||
|
||||
@@ -195,3 +195,23 @@ declare -A assoc=([0]="assoc" )
|
||||
assoc
|
||||
declare -A assoc=([two]="twoless" [three]="three" [one]="onemore" )
|
||||
declare -Ar assoc=([two]="twoless" [three]="three" [one]="onemore" )
|
||||
declare -A b=(["\""]="" [")"]="" ["\\"]="" ["]"]="" ["\`"]="" )
|
||||
declare -A b=(["]"]="" ["\`"]="" )
|
||||
declare -A dict=(["\""]="1" ["'"]="3" ["\\"]="4" ["\`"]="2" )
|
||||
./assoc9.sub: line 23: unset: `dict["]': not a valid identifier
|
||||
./assoc9.sub: line 23: unset: `dict[']': not a valid identifier
|
||||
./assoc9.sub: line 23: unset: `dict[\]': not a valid identifier
|
||||
./assoc9.sub: line 23: unset: `dict[`]': not a valid identifier
|
||||
declare -A dict=(["\""]="1" ["'"]="3" ["\\"]="4" ["\`"]="2" )
|
||||
declare -A dict=(["\""]="1" ["'"]="3" ["\\"]="4" ["\`"]="2" )
|
||||
declare -A dict=()
|
||||
4
|
||||
4
|
||||
a[$b]= 5
|
||||
declare -A a=(["80's"]="Depeche Mode" )
|
||||
./assoc9.sub: line 71: read: `a[80's]': not a valid identifier
|
||||
declare -A a
|
||||
declare -A a=(["80's"]="Depeche Mode" )
|
||||
./assoc9.sub: line 83: printf: `a[80's]': not a valid identifier
|
||||
declare -A a
|
||||
declare -A a=(["80's"]="Depeche Mode" )
|
||||
|
||||
@@ -207,3 +207,6 @@ readonly -A assoc
|
||||
declare -p assoc
|
||||
|
||||
${THIS_SH} ./assoc8.sub
|
||||
|
||||
# new shopt option to prevent multiple expansion of assoc array subscripts
|
||||
${THIS_SH} ./assoc9.sub
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
typeset -A a=( [\\]= [\"]= [\)]= ) b
|
||||
for x in "${!a[@]}"; do b[$x]=; done
|
||||
b+=([\`]= [\]]=)
|
||||
typeset -p b
|
||||
for x in "${!a[@]}"; do
|
||||
unset -v 'b[$x]'
|
||||
done
|
||||
typeset -p b
|
||||
|
||||
unset -v a b
|
||||
|
||||
loaddict()
|
||||
{
|
||||
dict['"']=1
|
||||
dict['`']=2
|
||||
dict["'"]=3
|
||||
dict['\']=4
|
||||
declare -p dict
|
||||
}
|
||||
|
||||
del()
|
||||
{
|
||||
unset -v dict["$1"];
|
||||
}
|
||||
|
||||
declare -A dict
|
||||
loaddict
|
||||
for k in "${!dict[@]}"; do del "$k"; done
|
||||
declare -p dict
|
||||
|
||||
unset 'dict[@]'
|
||||
|
||||
shopt -s assoc_expand_once
|
||||
declare -A dict
|
||||
loaddict
|
||||
for k in "${!dict[@]}"; do del "$k"; done
|
||||
declare -p dict
|
||||
|
||||
unset a b dict
|
||||
|
||||
typeset -A a
|
||||
b="80's"
|
||||
|
||||
((++a[$b]))
|
||||
|
||||
((++a["$b"]))
|
||||
[[ $((++a[$b])) ]]
|
||||
[[ $((++a["$b"])) ]]
|
||||
echo ${a["$b"]}
|
||||
echo ${a[$b]}
|
||||
|
||||
let "++a[$b]"
|
||||
|
||||
echo 'a[$b]=' "${a[$b]}"
|
||||
|
||||
unset a b
|
||||
|
||||
declare -A a
|
||||
b="80's"
|
||||
|
||||
: ${a[$b]:='Depeche Mode'}
|
||||
|
||||
declare -p a
|
||||
|
||||
unset a b
|
||||
shopt -u assoc_expand_once
|
||||
|
||||
typeset -A a
|
||||
b="80's"
|
||||
|
||||
read a[$b] <<<"Depeche Mode"
|
||||
typeset -p a
|
||||
|
||||
shopt -s assoc_expand_once
|
||||
read a[$b] <<<"Depeche Mode"
|
||||
typeset -p a
|
||||
|
||||
unset a
|
||||
shopt -u assoc_expand_once
|
||||
|
||||
typeset -A a
|
||||
|
||||
printf -v a[$b] "%s" "Depeche Mode"
|
||||
typeset -p a
|
||||
|
||||
shopt -s assoc_expand_once
|
||||
|
||||
printf -v a[$b] "%s" "Depeche Mode"
|
||||
typeset -p a
|
||||
+7
-6
@@ -3076,18 +3076,19 @@ bind_variable_value (var, value, aflags)
|
||||
variable we set here, then turn it back on after binding as necessary. */
|
||||
|
||||
SHELL_VAR *
|
||||
bind_int_variable (lhs, rhs)
|
||||
bind_int_variable (lhs, rhs, flags)
|
||||
char *lhs, *rhs;
|
||||
int flags;
|
||||
{
|
||||
register SHELL_VAR *v;
|
||||
int isint, isarr, implicitarray;
|
||||
|
||||
isint = isarr = implicitarray = 0;
|
||||
#if defined (ARRAY_VARS)
|
||||
if (valid_array_reference (lhs, 0))
|
||||
if (valid_array_reference (lhs, (flags & ASS_NOEXPAND) != 0))
|
||||
{
|
||||
isarr = 1;
|
||||
v = array_variable_part (lhs, 0, (char **)0, (int *)0);
|
||||
v = array_variable_part (lhs, (flags & ASS_NOEXPAND) != 0, (char **)0, (int *)0);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -3105,9 +3106,9 @@ bind_int_variable (lhs, rhs)
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
if (isarr)
|
||||
v = assign_array_element (lhs, rhs, 0);
|
||||
v = assign_array_element (lhs, rhs, flags);
|
||||
else if (implicitarray)
|
||||
v = bind_array_variable (lhs, 0, rhs, 0);
|
||||
v = bind_array_variable (lhs, 0, rhs, 0); /* XXX - check on flags */
|
||||
else
|
||||
#endif
|
||||
v = bind_variable (lhs, rhs, 0); /* why not use bind_variable_value? */
|
||||
@@ -3133,7 +3134,7 @@ bind_var_to_int (var, val)
|
||||
char ibuf[INT_STRLEN_BOUND (intmax_t) + 1], *p;
|
||||
|
||||
p = fmtulong (val, 10, ibuf, sizeof (ibuf), 0);
|
||||
return (bind_int_variable (var, p));
|
||||
return (bind_int_variable (var, p, 0));
|
||||
}
|
||||
|
||||
/* Do a function binding to a variable. You pass the name and
|
||||
|
||||
+1
-1
@@ -296,7 +296,7 @@ extern char *sh_get_env_value __P((const char *));
|
||||
extern char *make_variable_value __P((SHELL_VAR *, char *, int));
|
||||
|
||||
extern SHELL_VAR *bind_variable_value __P((SHELL_VAR *, char *, int));
|
||||
extern SHELL_VAR *bind_int_variable __P((char *, char *));
|
||||
extern SHELL_VAR *bind_int_variable __P((char *, char *, int));
|
||||
extern SHELL_VAR *bind_var_to_int __P((char *, intmax_t));
|
||||
|
||||
extern int assign_in_env __P((WORD_DESC *, int));
|
||||
|
||||
Reference in New Issue
Block a user