commit bash-20200417 snapshot

This commit is contained in:
Chet Ramey
2020-04-20 10:11:53 -04:00
parent 96a2ec128b
commit 3235014e5b
20 changed files with 216 additions and 132 deletions
+67
View File
@@ -8009,3 +8009,70 @@ examples/loadables/cut.c
- lcut: new builtin that does what cut does but on a string supplied
as an argument (only one string for now)
4/17
----
jobs.h
- FORK_SYNC,FORK_ASYNC,FORK_NOJOB: new flag values for the second
argument to make_child
jobs.c
- make_child: now takes a set of flags as the second argument
execute_cmd.c
- make_child: change callers to pass FORK_ASYNC instead of a non-zero
value as the second argument
subst.c
- make_child: change callers to pass FORK_ASYNC instead of a non-zero
value as the second argument
doc/{bash.1,bashref.texi}
- document that the words in a compound array assignment undergo all
the shell word expansions, including filename generation and word
splitting. From a report from E. Choroba <choroba@matfyz.cz>
4/18
----
subst.c
- command_substitute: use JOB_CONTROL instead of INTERACTIVE in the
test to determine whether or not to give the terminal back to
pipeline_pgrp
jobs.c
- make_child: if FORK_NOTERM is set in the flags argument, don't call
give_terminal_to
{jobs,nojobs}.c,jobs.h
- wait_for: now takes a second argument, a flags word
{execute_cmd,subst}.c
- wait_for: change all callers to add second argument to wait_for
jobs.c
- wait_for: if JWAIT_NOTERM is set in the flags argument, don't call
give_terminal_to
4/19
----
subst.c
- command_substitute: block SIGINT around call to read_comsub, so we
let any interrupts affect the command substitution. Fixes issue
reported by DALECKI Léo <leo.dalecki@ntymail.com>
hashcmd.h
- FILENAME_HASH_BUCKETS: increase to 256
assoc.h
- ASSOC_HASH_BUCKETS: new define, set to 1024
variables.c
- make_new_assoc_variable,make_local_assoc_variable: call assoc_create
with ASSOC_HASH_BUCKETS as argument. This changes the hash function
and how the array keys are ordered (which is not guaranteed)
builtins/read.def
- read_builtin: in posix mode, or if the read call returns -1/EINTR,
don't call run_pending_traps until the read command returns. This
allows a trap action to see the same exit status that the read
builtin would return when it exits on a signal (e.g., SIGINT == 130).
From a suggestion by <gentoo_eshoes@tutanota.com>
+22 -20
View File
@@ -1,7 +1,7 @@
/* assoc.h -- definitions for the interface exported by assoc.c that allows
the rest of the shell to manipulate associative array variables. */
/* Copyright (C) 2008,2009 Free Software Foundation, Inc.
/* Copyright (C) 2008,2009-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -25,6 +25,8 @@
#include "stdc.h"
#include "hashlib.h"
#define ASSOC_HASH_BUCKETS 1024
#define assoc_empty(h) ((h)->nentries == 0)
#define assoc_num_elements(h) ((h)->nentries)
@@ -34,30 +36,30 @@
#define assoc_walk(h, f) (hash_walk((h), (f))
extern void assoc_dispose __P((HASH_TABLE *));
extern void assoc_flush __P((HASH_TABLE *));
extern void assoc_dispose PARAMS((HASH_TABLE *));
extern void assoc_flush PARAMS((HASH_TABLE *));
extern int assoc_insert __P((HASH_TABLE *, char *, char *));
extern PTR_T assoc_replace __P((HASH_TABLE *, char *, char *));
extern void assoc_remove __P((HASH_TABLE *, char *));
extern int assoc_insert PARAMS((HASH_TABLE *, char *, char *));
extern PTR_T assoc_replace PARAMS((HASH_TABLE *, char *, char *));
extern void assoc_remove PARAMS((HASH_TABLE *, char *));
extern char *assoc_reference __P((HASH_TABLE *, char *));
extern char *assoc_reference PARAMS((HASH_TABLE *, char *));
extern char *assoc_subrange __P((HASH_TABLE *, arrayind_t, arrayind_t, int, int, int));
extern char *assoc_patsub __P((HASH_TABLE *, char *, char *, int));
extern char *assoc_modcase __P((HASH_TABLE *, char *, int, int));
extern char *assoc_subrange PARAMS((HASH_TABLE *, arrayind_t, arrayind_t, int, int, int));
extern char *assoc_patsub PARAMS((HASH_TABLE *, char *, char *, int));
extern char *assoc_modcase PARAMS((HASH_TABLE *, char *, int, int));
extern HASH_TABLE *assoc_quote __P((HASH_TABLE *));
extern HASH_TABLE *assoc_quote_escapes __P((HASH_TABLE *));
extern HASH_TABLE *assoc_dequote __P((HASH_TABLE *));
extern HASH_TABLE *assoc_dequote_escapes __P((HASH_TABLE *));
extern HASH_TABLE *assoc_remove_quoted_nulls __P((HASH_TABLE *));
extern HASH_TABLE *assoc_quote PARAMS((HASH_TABLE *));
extern HASH_TABLE *assoc_quote_escapes PARAMS((HASH_TABLE *));
extern HASH_TABLE *assoc_dequote PARAMS((HASH_TABLE *));
extern HASH_TABLE *assoc_dequote_escapes PARAMS((HASH_TABLE *));
extern HASH_TABLE *assoc_remove_quoted_nulls PARAMS((HASH_TABLE *));
extern char *assoc_to_kvpair __P((HASH_TABLE *, int));
extern char *assoc_to_assign __P((HASH_TABLE *, int));
extern char *assoc_to_kvpair PARAMS((HASH_TABLE *, int));
extern char *assoc_to_assign PARAMS((HASH_TABLE *, int));
extern WORD_LIST *assoc_to_word_list __P((HASH_TABLE *));
extern WORD_LIST *assoc_keys_to_word_list __P((HASH_TABLE *));
extern WORD_LIST *assoc_to_word_list PARAMS((HASH_TABLE *));
extern WORD_LIST *assoc_keys_to_word_list PARAMS((HASH_TABLE *));
extern char *assoc_to_string __P((HASH_TABLE *, char *, int));
extern char *assoc_to_string PARAMS((HASH_TABLE *, char *, int));
#endif /* _ASSOC_H_ */
+2
View File
@@ -624,7 +624,9 @@ read_builtin (list)
lastsig = LASTSIG();
if (lastsig == 0)
lastsig = trapped_signal_received;
#if 0
run_pending_traps (); /* because interrupt_immediately is not set */
#endif
}
else
lastsig = 0;
+6 -2
View File
@@ -5,12 +5,12 @@
.\" Case Western Reserve University
.\" chet.ramey@case.edu
.\"
.\" Last Change: Thu Apr 9 11:50:30 EDT 2020
.\" Last Change: Fri Apr 17 16:30:01 EDT 2020
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
.TH BASH 1 "2020 April 9" "GNU Bash 5.0"
.TH BASH 1 "2020 April 17" "GNU Bash 5.0"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -2682,6 +2682,10 @@ Arrays are assigned to using compound assignments of the form
\fIname\fP=\fB(\fPvalue\fI1\fP ... value\fIn\fP\fB)\fP, where each
\fIvalue\fP may be of the form [\fIsubscript\fP]=\fIstring\fP.
Indexed array assignments do not require anything but \fIstring\fP.
Each \fIvalue\fP in the list is expanded using all the shell expansions
described below under
.SM
.BR EXPANSION .
When assigning to indexed arrays, if the optional brackets and subscript
are supplied, that index is assigned to;
otherwise the index of the element assigned is the last index assigned
+3
View File
@@ -7312,6 +7312,9 @@ the optional subscript is supplied, that index is assigned to;
otherwise the index of the element assigned is the last index assigned
to by the statement plus one. Indexing starts at zero.
Each @var{value} in the list undergoes all the shell expansions
described above (@pxref{Shell Expansions}).
When assigning to an associative array, the words in a compound assignment
may be either assignment statements, for which the subscript is required,
or a list of words that is interpreted as a sequence of alternating keys
+2 -2
View File
@@ -2,10 +2,10 @@
Copyright (C) 1988-2020 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Thu Apr 9 11:58:06 EDT 2020
@set LASTCHANGE Fri Apr 17 16:30:16 EDT 2020
@set EDITION 5.0
@set VERSION 5.0
@set UPDATED 9 April 2020
@set UPDATED 17 April 2020
@set UPDATED-MONTH April 2020
+20 -16
View File
@@ -556,7 +556,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
int pipe_in, pipe_out;
struct fd_bitmap *fds_to_close;
{
int exec_result, user_subshell, invert, ignore_return, was_error_trap;
int exec_result, user_subshell, invert, ignore_return, was_error_trap, fork_flags;
REDIRECT *my_undo_list, *exec_undo_list;
char *tcmd;
volatile int save_line_number;
@@ -627,7 +627,8 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
line_number_for_err_trap = line_number = command->value.Subshell->line; /* XXX - save value? */
/* Otherwise we defer setting line_number */
tcmd = make_command_string (command);
paren_pid = make_child (p = savestring (tcmd), asynchronous);
fork_flags = asynchronous ? FORK_ASYNC : 0;
paren_pid = make_child (p = savestring (tcmd), fork_flags);
if (user_subshell && signal_is_trapped (ERROR_TRAP) &&
signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0)
@@ -684,7 +685,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
invert = (command->flags & CMD_INVERT_RETURN) != 0;
ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
exec_result = wait_for (paren_pid);
exec_result = wait_for (paren_pid, 0);
/* If we have to, invert the return value. */
if (invert)
@@ -865,7 +866,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
the function to be waited for twice. This also causes
subshells forked to execute builtin commands (e.g., in
pipelines) to be waited for twice. */
exec_result = wait_for (last_made_pid);
exec_result = wait_for (last_made_pid, 0);
}
}
@@ -1103,10 +1104,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
last_command_exit_value = exec_result;
run_pending_traps ();
#if 0
if (running_trap == 0)
#endif
currently_executing_command = (COMMAND *)NULL;
currently_executing_command = (COMMAND *)NULL;
return (last_command_exit_value);
}
@@ -2367,7 +2365,7 @@ execute_coproc (command, pipe_in, pipe_out, fds_to_close)
BLOCK_SIGNAL (SIGCHLD, set, oset);
coproc_pid = make_child (p = savestring (tcmd), 1);
coproc_pid = make_child (p = savestring (tcmd), FORK_ASYNC);
if (coproc_pid == 0)
{
@@ -2590,12 +2588,12 @@ execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close)
if (INVALID_JOB (lastpipe_jid) == 0)
{
append_process (savestring (the_printed_command_except_trap), dollar_dollar_pid, exec_result, lastpipe_jid);
lstdin = wait_for (lastpid);
lstdin = wait_for (lastpid, 0);
}
else
lstdin = wait_for_single_pid (lastpid, 0); /* checks bgpids list */
#else
lstdin = wait_for (lastpid);
lstdin = wait_for (lastpid, 0);
#endif
#if defined (JOB_CONTROL)
@@ -3986,7 +3984,7 @@ execute_null_command (redirects, pipe_in, pipe_out, async)
int pipe_in, pipe_out, async;
{
int r;
int forcefork;
int forcefork, fork_flags;
REDIRECT *rd;
for (forcefork = 0, rd = redirects; rd; rd = rd->next)
@@ -4000,7 +3998,8 @@ execute_null_command (redirects, pipe_in, pipe_out, async)
{
/* We have a null command, but we really want a subshell to take
care of it. Just fork, do piping and redirections, and exit. */
if (make_child ((char *)NULL, async) == 0)
fork_flags = async ? FORK_ASYNC : 0;
if (make_child ((char *)NULL, fork_flags) == 0)
{
/* Cancel traps, in trap.c. */
restore_original_signals (); /* XXX */
@@ -4168,6 +4167,7 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
WORD_LIST *words, *lastword;
char *command_line, *lastarg, *temp;
int first_word_quoted, result, builtin_is_special, already_forked, dofork;
int fork_flags;
pid_t old_last_async_pid;
sh_builtin_func_t *builtin;
SHELL_VAR *func;
@@ -4244,7 +4244,8 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
/* Don't let a DEBUG trap overwrite the command string to be saved with
the process/job associated with this child. */
if (make_child (p = savestring (the_printed_command_except_trap), async) == 0)
fork_flags = async ? FORK_ASYNC : 0;
if (make_child (p = savestring (the_printed_command_except_trap), fork_flags) == 0)
{
already_forked = 1;
simple_command->flags |= CMD_NO_FORK;
@@ -5331,7 +5332,7 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
int cmdflags;
{
char *pathname, *command, **args, *p;
int nofork, stdpath, result;
int nofork, stdpath, result, fork_flags;
pid_t pid;
SHELL_VAR *hookf;
WORD_LIST *wl;
@@ -5380,7 +5381,10 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
if (nofork && pipe_in == NO_PIPE && pipe_out == NO_PIPE)
pid = 0;
else
pid = make_child (p = savestring (command_line), async);
{
fork_flags = async ? FORK_ASYNC : 0;
pid = make_child (p = savestring (command_line), fork_flags);
}
if (pid == 0)
{
+7 -7
View File
@@ -1,6 +1,6 @@
/* hashcmd.h - Common defines for hashing filenames. */
/* Copyright (C) 1993-2009 Free Software Foundation, Inc.
/* Copyright (C) 1993-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -21,7 +21,7 @@
#include "stdc.h"
#include "hashlib.h"
#define FILENAME_HASH_BUCKETS 64 /* must be power of two */
#define FILENAME_HASH_BUCKETS 256 /* must be power of two */
extern HASH_TABLE *hashed_filenames;
@@ -35,9 +35,9 @@ typedef struct _pathdata {
#define pathdata(x) ((PATH_DATA *)(x)->data)
extern void phash_create __P((void));
extern void phash_flush __P((void));
extern void phash_create PARAMS((void));
extern void phash_flush PARAMS((void));
extern void phash_insert __P((char *, char *, int, int));
extern int phash_remove __P((const char *));
extern char *phash_search __P((const char *));
extern void phash_insert PARAMS((char *, char *, int, int));
extern int phash_remove PARAMS((const char *));
extern char *phash_search PARAMS((const char *));
+9 -8
View File
@@ -1079,7 +1079,7 @@ procsub_waitpid (pid)
return -1;
if (p->running == PS_DONE)
return (p->status);
r = wait_for (p->pid);
r = wait_for (p->pid, 0);
return (r); /* defer removing until later */
}
@@ -1093,7 +1093,7 @@ procsub_waitall ()
{
if (p->running == PS_DONE)
continue;
r = wait_for (p->pid);
r = wait_for (p->pid, 0);
}
}
@@ -2252,7 +2252,7 @@ make_child (command, flags)
In this case, we don't want to give the terminal to the
shell's process group (we could be in the middle of a
pipeline, for example). */
if (async_p == 0 && pipeline_pgrp != shell_pgrp && ((subshell_environment&(SUBSHELL_ASYNC|SUBSHELL_PIPE)) == 0) && running_in_background == 0)
if ((flags & FORK_NOTERM) == 0 && async_p == 0 && pipeline_pgrp != shell_pgrp && ((subshell_environment&(SUBSHELL_ASYNC|SUBSHELL_PIPE)) == 0) && running_in_background == 0)
give_terminal_to (pipeline_pgrp, 0);
#if defined (PGRP_PIPE)
@@ -2609,7 +2609,7 @@ wait_for_single_pid (pid, flags)
alive = 0;
do
{
r = wait_for (pid);
r = wait_for (pid, 0);
if ((flags & JWAIT_FORCE) == 0)
break;
@@ -2899,8 +2899,9 @@ job_exit_signal (job)
the jobs table. Returns -1 if waitchld() returns -1, indicating
that there are no unwaited-for child processes. */
int
wait_for (pid)
wait_for (pid, flags)
pid_t pid;
int flags;
{
int job, termination_state, r;
WAIT s;
@@ -3235,7 +3236,7 @@ wait_for_job (job, flags, ps)
do
{
r = wait_for (pid);
r = wait_for (pid, 0);
if (r == -1 && errno == ECHILD)
mark_all_jobs_as_dead ();
@@ -3331,7 +3332,7 @@ return_job:
CHECK_WAIT_INTR;
errno = 0;
r = wait_for (ANY_PID); /* special sentinel value for wait_for */
r = wait_for (ANY_PID, 0); /* special sentinel value for wait_for */
if (r == -1 && errno == ECHILD)
mark_all_jobs_as_dead ();
@@ -3642,7 +3643,7 @@ start_job (job, foreground)
pid = find_last_pid (job, 0);
UNBLOCK_CHILD (oset);
st = wait_for (pid);
st = wait_for (pid, 0);
shell_tty_info = save_stty;
set_tty_state ();
return (st);
+13 -9
View File
@@ -38,11 +38,14 @@
/* I looked it up. For pretty_print_job (). The real answer is 24. */
#define LONGEST_SIGNAL_DESC 24
/* Defines for the wait_for functions and for the wait builtin to use */
#define JWAIT_PERROR 0x01
#define JWAIT_FORCE 0x02
#define JWAIT_NOWAIT 0x04 /* don't waitpid(), just return status if already exited */
#define JWAIT_WAITING 0x08 /* wait for jobs marked J_WAITING only */
/* Defines for the wait_for_* functions and for the wait builtin to use */
#define JWAIT_PERROR (1 << 0)
#define JWAIT_FORCE (1 << 1)
#define JWAIT_NOWAIT (1 << 2) /* don't waitpid(), just return status if already exited */
#define JWAIT_WAITING (1 << 3) /* wait for jobs marked J_WAITING only */
/* flags for wait_for */
#define JWAIT_NOTERM (1 << 8) /* wait_for doesn't give terminal away */
/* The max time to sleep while retrying fork() on EAGAIN failure */
#define FORKSLEEP_MAX 16
@@ -197,9 +200,10 @@ struct procchain {
#define ANY_PID (pid_t)-1
/* flags for make_child () */
#define FORK_SYNC 0
#define FORK_ASYNC 1
#define FORK_NOJOB 2
#define FORK_SYNC 0 /* normal synchronous process */
#define FORK_ASYNC 1 /* background process */
#define FORK_NOJOB 2 /* don't put process in separate pgrp */
#define FORK_NOTERM 4 /* don't give terminal to any pgrp */
/* System calls. */
#if !defined (HAVE_UNISTD_H)
@@ -276,7 +280,7 @@ extern int job_exit_signal PARAMS((int));
extern int wait_for_single_pid PARAMS((pid_t, int));
extern void wait_for_background_pids PARAMS((struct procstat *));
extern int wait_for PARAMS((pid_t));
extern int wait_for PARAMS((pid_t, int));
extern int wait_for_job PARAMS((int, int, struct procstat *));
extern int wait_for_any_job PARAMS((int, struct procstat *));
+2 -1
View File
@@ -823,8 +823,9 @@ j_strsignal (s)
/* Wait for pid (one of our children) to terminate. This is called only
by the execution code in execute_cmd.c. */
int
wait_for (pid)
wait_for (pid, flags)
pid_t pid;
int flags;
{
int return_val, pstatus;
pid_t got_pid;
+14 -18
View File
@@ -5555,7 +5555,7 @@ wait_procsubs ()
{
if (fifo_list[i].proc != (pid_t)-1 && fifo_list[i].proc > 0)
{
r = wait_for (fifo_list[i].proc);
r = wait_for (fifo_list[i].proc, 0);
save_proc_status (fifo_list[i].proc, r);
fifo_list[i].proc = (pid_t)-1;
}
@@ -5793,7 +5793,7 @@ wait_procsubs ()
{
if (dev_fd_list[i] != (pid_t)-1 && dev_fd_list[i] > 0)
{
r = wait_for (dev_fd_list[i]);
r = wait_for (dev_fd_list[i], 0);
save_proc_status (dev_fd_list[i], r);
dev_fd_list[i] = (pid_t)-1;
}
@@ -5901,7 +5901,7 @@ process_substitute (string, open_for_read_in_child)
save_pipeline (1);
#endif /* JOB_CONTROL */
pid = make_child ((char *)NULL, 1);
pid = make_child ((char *)NULL, FORK_ASYNC);
if (pid == 0)
{
interactive = 0;
@@ -6141,8 +6141,7 @@ read_comsub (fd, quoted, flags, rflag)
mb_cur_max = MB_CUR_MAX;
nullbyte = 0;
/* Read the output of the command through the pipe. This may need to be
changed to understand multibyte characters in the future. */
/* Read the output of the command through the pipe. */
while (1)
{
if (fd < 0)
@@ -6206,16 +6205,6 @@ read_comsub (fd, quoted, flags, rflag)
#endif
istring[istring_index++] = c;
#if 0
#if defined (__CYGWIN__)
if (c == '\n' && istring_index > 1 && istring[istring_index - 2] == '\r')
{
istring_index--;
istring[istring_index - 1] = '\n';
}
#endif
#endif
}
if (istring)
@@ -6267,8 +6256,9 @@ command_substitute (string, quoted, flags)
{
pid_t pid, old_pid, old_pipeline_pgrp, old_async_pid;
char *istring, *s;
int result, fildes[2], function_value, pflags, rc, tflag;
int result, fildes[2], function_value, pflags, rc, tflag, fork_flags;
WORD_DESC *ret;
sigset_t set, oset;
istring = (char *)NULL;
@@ -6323,7 +6313,8 @@ command_substitute (string, quoted, flags)
#endif /* JOB_CONTROL */
old_async_pid = last_asynchronous_pid;
pid = make_child ((char *)NULL, subshell_environment&SUBSHELL_ASYNC);
fork_flags = (subshell_environment&SUBSHELL_ASYNC) ? FORK_ASYNC : 0;
pid = make_child ((char *)NULL, fork_flags);
last_asynchronous_pid = old_async_pid;
if (pid == 0)
@@ -6486,14 +6477,19 @@ command_substitute (string, quoted, flags)
dummyfd = fildes[0];
add_unwind_protect (close, dummyfd);
/* Block SIGINT while we're reading from the pipe. If the child
process gets a SIGINT, it will either handle it or die, and the
read will return. */
BLOCK_SIGNAL (SIGINT, set, oset);
tflag = 0;
istring = read_comsub (fildes[0], quoted, flags, &tflag);
close (fildes[0]);
discard_unwind_frame ("read-comsub");
UNBLOCK_SIGNAL (oset);
current_command_subst_pid = pid;
last_command_exit_value = wait_for (pid);
last_command_exit_value = wait_for (pid, 0);
last_command_subst_pid = pid;
last_made_pid = old_pid;
+1 -1
View File
@@ -1,4 +1,4 @@
BUILD_DIR=/usr/local/build/chet/bash/bash-current
BUILD_DIR=/usr/local/build/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
+2 -2
View File
@@ -17,8 +17,8 @@
16
./appendop.tests: line 97: x: readonly variable
declare -A foo=([two]="baz" [three]="quux" [one]="bar" )
declare -A foo=([two]="baz" [0]="zero" [three]="quux" [one]="bar" )
declare -A foo=([two]="baz" [0]="zero" [three]="quux" [four]="four" [one]="bar" )
declare -A foo=([0]="zero" [two]="baz" [three]="quux" [one]="bar" )
declare -A foo=([four]="four" [0]="zero" [two]="baz" [three]="quux" [one]="bar" )
declare -ai iarr=([0]="3" [1]="2" [2]="3")
declare -ai iarr=([0]="3" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6")
25 25
+4 -4
View File
@@ -349,10 +349,10 @@ version[agent]
version.agent
version[agent]
version.agent
version[agent] foo[bar]
version.agent bowl
foo foobar] foo[bar]
bbb bleh bleh
foo[bar] version[agent]
bowl version.agent
foobar] foo foo[bar]
bleh bbb bleh
ab]
bar
1
+36 -36
View File
@@ -6,14 +6,14 @@ declare -A BASH_CMDS=()
declare -A fluff=([foo]="one" [bar]="two" )
declare -A fluff=([foo]="one" [bar]="two" )
declare -A fluff=([bar]="two" )
declare -A fluff=([bar]="newval" [qux]="assigned" )
declare -A fluff=([qux]="assigned" [bar]="newval" )
./assoc.tests: line 39: chaff: four: must use subscript when assigning associative array
declare -A BASH_ALIASES=()
declare -A BASH_CMDS=()
declare -Ai chaff=([zero]="5" [one]="10" )
declare -Ar waste=([lineno]="41" [source]="./assoc.tests" [version]="4.0-devel" [pid]="42134" )
declare -A wheat=([two]="b" [three]="c" [zero]="0" [one]="a" )
declare -A chaff=(["hello world"]="flip" [zero]="5" [one]="10" )
declare -Ai chaff=([one]="10" [zero]="5" )
declare -Ar waste=([pid]="42134" [lineno]="41" [source]="./assoc.tests" [version]="4.0-devel" )
declare -A wheat=([two]="b" [three]="c" [one]="a" [zero]="0" )
declare -A chaff=(["hello world"]="flip" [one]="10" [zero]="5" )
./assoc.tests: line 51: waste: readonly variable
./assoc.tests: line 52: unset: waste: cannot unset: readonly variable
./assoc.tests: line 53: chaff[*]: bad array subscript
@@ -35,11 +35,11 @@ argv[1] = <multiple words flip a>
./assoc.tests: line 71: declare: chaff: cannot destroy array variables in this way
./assoc.tests: line 73: chaff[*]: bad array subscript
./assoc.tests: line 74: [*]=12: invalid associative array key
declare -A wheat=(["foo bar"]="qux qix" [six]="6" )
declare -A wheat=([six]="6" ["foo bar"]="qux qix" )
argv[1] = <qux>
argv[2] = <qix>
argv[1] = <qux qix>
declare -A wheat=(["foo bar"]="qux qix" [six]="6" )
declare -A wheat=([six]="6" ["foo bar"]="qux qix" )
argv[1] = <2>
argv[1] = <7>
argv[1] = <qux>
@@ -48,16 +48,16 @@ argv[3] = <blat>
argv[1] = <qux qix blat>
argv[1] = <16>
argv[1] = <16>
argv[1] = <flix>
argv[2] = <6>
argv[1] = <foo>
argv[2] = <bar>
argv[3] = <six>
argv[1] = <foo bar>
argv[2] = <six>
argv[1] = <6>
argv[2] = <flix>
argv[1] = <six>
argv[2] = <foo>
argv[3] = <bar>
argv[1] = <six>
argv[2] = <foo bar>
8
/sbin /usr/bin /bin /usr/ucb /usr/local/bin . /usr/sbin /bin
sbin bin bin ucb bin . sbin bin
/usr/local/bin /bin . /usr/bin /usr/ucb /usr/sbin /bin /sbin
bin bin . bin ucb sbin bin sbin
bin
/ / / / / / /
/
@@ -66,27 +66,27 @@ argv[1] = </>
argv[1] = <sbin>
argv[1] = </>
8
/sbin /usr/bin /bin /usr/ucb /usr/local/bin . /usr/sbin /bin
sbin bin bin ucb bin . sbin bin
/usr/local/bin /bin . /usr/bin /usr/ucb /usr/sbin /bin /sbin
bin bin . bin ucb sbin bin sbin
/ / / / / / /
8
4 -- /bin
^sbin ^usr^bin ^bin ^usr^ucb ^usr^local^bin . ^usr^sbin ^bin
^sbin ^usr^bin ^bin ^usr^ucb ^usr^local^bin . ^usr^sbin ^bin
\sbin \usr/bin \bin \usr/ucb \usr/local/bin . \usr/sbin \bin
\sbin \usr\bin \bin \usr\ucb \usr\local\bin . \usr\sbin \bin
\sbin \usr\bin \bin \usr\ucb \usr\local\bin . \usr\sbin \bin
^usr^local^bin ^bin . ^usr^bin ^usr^ucb ^usr^sbin ^bin ^sbin
^usr^local^bin ^bin . ^usr^bin ^usr^ucb ^usr^sbin ^bin ^sbin
\usr/local/bin \bin . \usr/bin \usr/ucb \usr/sbin \bin \sbin
\usr\local\bin \bin . \usr\bin \usr\ucb \usr\sbin \bin \sbin
\usr\local\bin \bin . \usr\bin \usr\ucb \usr\sbin \bin \sbin
([a]=1)
foo qux
/usr/sbin/foo /usr/local/bin/qux
hits command
0 /sbin/blat
0 /usr/sbin/foo
0 /bin/sh
0 /sbin/blat
0 /usr/local/bin/qux
blat foo sh qux
/sbin/blat /usr/sbin/foo /bin/sh /usr/local/bin/qux
foo sh blat qux
/usr/sbin/foo /bin/sh /sbin/blat /usr/local/bin/qux
foo qux
argv[1] = </usr/sbin/foo>
@@ -104,10 +104,10 @@ argv[4] = </usr/local/bin/qux -l>
outside: outside
declare -A BASH_ALIASES=()
declare -A BASH_CMDS=()
declare -A afoo=(["foo bar"]="foo quux" [six]="six" )
declare -A afoo=([six]="six" ["foo bar"]="foo quux" )
argv[1] = <inside:>
argv[2] = <foo quux>
argv[3] = <six>
argv[2] = <six>
argv[3] = <foo quux>
outside 2: outside
argv[1] = </barq//fooq>
argv[1] = <>
@@ -138,11 +138,11 @@ abc
def
def
./assoc5.sub: line 26: declare: `myarray[foo[bar]=bleh': not a valid identifier
bleh def abc
myarray=([foo]="bleh" ["]"]="def" ["a]=test1;#a"]="123" ["a]a"]="abc" )
def bleh abc
myarray=(["]"]="def" [foo]="bleh" ["a]a"]="abc" ["a]=test1;#a"]="123" )
123
myarray=([foo]="bleh" ["]"]="def" ["a]=test2;#a"]="def" ["a]=test1;#a"]="123" ["a]a"]="abc" )
myarray=(["]"]="def" ["a]=test2;#a"]="def" [foo]="bleh" ["a]a"]="abc" ["a]=test1;#a"]="123" )
bar"bie
doll
declare -A foo=(["bar\"bie"]="doll" )
@@ -234,11 +234,11 @@ main: declare -- a="42"
declare -A a=([3]="" [1]="2" )
declare -A foo=([d]="4" [c]="3" [b]="2" [a]="1" )
foo=( d "4" c "3" b "2" a "1" )
declare -A foo=(["spa ces"]="2" ["\\"]="5" ["@"]="3" ["holy hell this works"]="4" ["a b"]="1" )
foo=( echo "spa ces" "2" "\\" "5" "@" "3" "holy hell this works" "4" "a b" "1" )
declare -A foo=(["\\"]="5" ["@"]="3" ["holy hell this works"]="4" ["a b"]="1" ["spa ces"]="2" )
foo=( echo "\\" "5" "@" "3" "holy hell this works" "4" "a b" "1" "spa ces" "2" )
./assoc11.sub: line 34: "": bad array subscript
declare -A foo=(["foo[bar"]="bleh" [";"]="semicolon" ["]"]="def" [a=b]="assignment" ["a]a"]="abc" )
foo=( "foo[bar" "bleh" ";" "semicolon" "]" "def" a=b "assignment" "a]a" "abc" )
declare -A foo=([";"]="semicolon" ["]"]="def" [a=b]="assignment" ["a]a"]="abc" ["foo[bar"]="bleh" )
foo=( ";" "semicolon" "]" "def" a=b "assignment" "a]a" "abc" "foo[bar" "bleh" )
declare -A foo=(["'"]="squote" ["\""]="dquote" ["\\"]="bslash" ["\`"]="backquote" )
foo=( "'" "squote" "\"" "dquote" "\\" "bslash" "\`" "backquote" )
declare -A foo=(["bar]bie"]="doll" ["a]=test1;#a"]="123" ["bar\"bie"]="doll" )
+1 -1
View File
@@ -635,7 +635,7 @@ declare -r x='ab '\''cd'\'' ef'
set -- 'ab' 'cd ef' '' 'gh'
declare -a A=([0]="ab" [1]="cd ef" [2]="" [3]="gh")
declare -a B=()
declare -A A=([two]="b c" [three]="" [four]="de" [one]="1" )
declare -A A=([four]="de" [two]="b c" [three]="" [one]="1" )
r
a
A
+1 -1
View File
@@ -44,8 +44,8 @@ builtin is a shell builtin
bash is hashed (/tmp/bash)
file
hits command
3 /tmp/bash
1 /bin/sh
3 /tmp/bash
f is a function
f ()
{
+1 -1
View File
@@ -133,7 +133,7 @@ after func: x = outside
./varenv11.sub: line 18: qux: readonly variable
declare -A foo=([zero]="zero" [one]="one" )
declare -a bar=([0]="zero" [1]="one")
declare -A foo=([zero]="zero" [one]="one" )
declare -A foo=([one]="one" [zero]="zero" )
declare -a bar=([0]="zero" [1]="one")
./varenv11.sub: line 42: a: readonly variable
foo=abc
+3 -3
View File
@@ -3015,7 +3015,7 @@ make_new_assoc_variable (name)
HASH_TABLE *hash;
entry = make_new_variable (name, global_variables->table);
hash = assoc_create (0);
hash = assoc_create (ASSOC_HASH_BUCKETS);
var_setassoc (entry, hash);
VSETATTR (entry, att_assoc);
@@ -3047,7 +3047,7 @@ make_local_assoc_variable (name, flags)
internal_warning ("%s: cannot inherit value from incompatible type", name);
VUNSETATTR (var, att_array);
dispose_variable_value (var);
hash = assoc_create (0);
hash = assoc_create (ASSOC_HASH_BUCKETS);
var_setassoc (var, hash);
}
else if (localvar_inherit)
@@ -3055,7 +3055,7 @@ make_local_assoc_variable (name, flags)
else
{
dispose_variable_value (var);
hash = assoc_create (0);
hash = assoc_create (ASSOC_HASH_BUCKETS);
var_setassoc (var, hash);
}