From: Chet Ramey Date: Mon, 28 Aug 2023 16:16:01 +0000 (-0400) Subject: documentation updates for arrayname[0]; update trace/debug order for some compound... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f4683835d896effb5bbbf6b43719519d86e4b0a9;p=thirdparty%2Fbash.git documentation updates for arrayname[0]; update trace/debug order for some compound commands --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 5d0480a7a..00331f909 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -7516,4 +7516,20 @@ parse.y subst.c - function_substitute: unwind-protect eof_encountered so ignoreeof doesn't keep getting reset to 0 if PS1 includes a ${ ...;} command. + From a report by Grisha Levit + + 8/25 + ---- +doc/{bash.1,bashref.texi} + - clarify the cases where arrayname[@] doesn't refer to all the + elements of an associative array (the unset builtin and test/[/[[ -v + for now) + Inspired by https://savannah.gnu.org/support/index.php?110924 + + 8/28 + ---- +execute_cmd.c + - execute_for_command,execute_select_command,execute_arith_command, + execute_case_command: fix up order in which BASH_COMMAND is set, + the DEBUG trap is run, and PS4 is printed. From a report by Grisha Levit diff --git a/doc/bash.1 b/doc/bash.1 index 592fc082d..eee584573 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -2864,7 +2864,9 @@ Any element of an array may be referenced using ${\fIname\fP[\fIsubscript\fP]}. The braces are required to avoid conflicts with pathname expansion. If \fIsubscript\fP is \fB@\fP or \fB*\fP, the word expands to -all members of \fIname\fP. These subscripts differ only when the +all members of \fIname\fP, +unless noted in the description of a builtin or word expansion. +These subscripts differ only when the word appears within double quotes. If the word is double-quoted, ${\fIname\fP[*]} expands to a single word with the value of each array member separated by the first @@ -4978,6 +4980,12 @@ builtin below. True if the shell variable .I varname is set (has been assigned a value). +If \fIvarname\fP is an indexed +array variable name subscripted by \fI@\fP or \fI*\fP, +this returns true if the array has any set elements. +If \fIvarname\fP is an associative +array variable name subscripted by \fI@\fP or \fI*\fP, +this returns true if an element with that key is set. .TP .B \-R \fIvarname\fP True if the shell variable diff --git a/doc/bashref.texi b/doc/bashref.texi index 0c4c19bb4..1e970d4be 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -1759,7 +1759,7 @@ When @samp{+=} is applied to an array variable using compound assignment (@pxref{Arrays}), the variable's value is not unset (as it is when using @samp{=}), and new values are appended to the array beginning at one greater than the array's -maximum index (for indexed arrays), or added as additional key-value pairs +maximum index (for indexed arrays), or added as additional key-value pairs in an associative array. When applied to a string-valued variable, @var{value} is expanded and appended to the variable's value. @@ -7664,6 +7664,12 @@ option to the @code{set} builtin (@pxref{The Set Builtin}). @item -v @var{varname} True if the shell variable @var{varname} is set (has been assigned a value). +If @var{varname} is an indexed +array variable name subscripted by @samp{@@} or @samp{*}, +this returns true if the array has any set elements. +If @var{varname} is an associative +array variable name subscripted by @samp{@@} or @samp{*}, +this returns true if an element with that key is set. @item -R @var{varname} True if the shell variable @var{varname} is set and is a name reference. @@ -7983,7 +7989,9 @@ Any element of an array may be referenced using The braces are required to avoid conflicts with the shell's filename expansion operators. If the @var{subscript} is @samp{@@} or @samp{*}, the word expands to all members -of the array @var{name}. These subscripts differ only when the word +of the array @var{name}, unless otherwise noted in the description of a +builtin or word expansion. +These subscripts differ only when the word appears within double quotes. If the word is double-quoted, @code{$@{@var{name}[*]@}} expands to a single word with diff --git a/doc/version.texi b/doc/version.texi index 2475f5a12..57a71f7f6 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -2,10 +2,10 @@ Copyright (C) 1988-2023 Free Software Foundation, Inc. @end ignore -@set LASTCHANGE Tue Aug 15 16:02:41 EDT 2023 +@set LASTCHANGE Fri Aug 25 11:58:00 EDT 2023 @set EDITION 5.3 @set VERSION 5.3 -@set UPDATED 15 August 2023 +@set UPDATED 25 August 2023 @set UPDATED-MONTH August 2023 diff --git a/examples/loadables/cut.c b/examples/loadables/cut.c index ee51d9b9d..49d3547c2 100644 --- a/examples/loadables/cut.c +++ b/examples/loadables/cut.c @@ -503,22 +503,13 @@ cut_internal (int which, WORD_LIST *list) } if (array_name) - { - v = find_or_make_array_variable (array_name, 1); - if (v == 0 || readonly_p (v) || noassign_p (v)) - { - if (v && readonly_p (v)) - err_readonly (array_name); - return (EXECUTION_FAILURE); - } - else if (array_p (v) == 0) + { + v = builtin_find_indexed_array (array_name, 1); + if (v == 0) { - builtin_error ("%s: not an indexed array", array_name); + free (poslist); return (EXECUTION_FAILURE); } - if (invisible_p (v)) - VUNSETATTR (v, att_invisible); - array_flush (array_cell (v)); } op.flags = cutflags; @@ -542,6 +533,7 @@ cut_internal (int which, WORD_LIST *list) else rval = cutfile (v, list, &op); + free (poslist); return (rval); } diff --git a/examples/loadables/finfo.c b/examples/loadables/finfo.c index 64a9e9108..e5910c93a 100644 --- a/examples/loadables/finfo.c +++ b/examples/loadables/finfo.c @@ -53,7 +53,6 @@ extern int errno; extern char **make_builtin_argv (WORD_LIST *, int *); -static int octal(char *); static struct stat *getstat(char *); static int printinfo(char *); static int getperm(int); @@ -95,17 +94,6 @@ static int pmask; #define OPTIONS "acdgiflmnopsuACGMP:U" -static int -octal(char *s) -{ - int r; - - r = *s - '0'; - while (*++s >= '0' && *s <= '7') - r = (r * 8) + (*s - '0'); - return r; -} - static int finfo_main(int argc, char **argv) { @@ -136,7 +124,14 @@ finfo_main(int argc, char **argv) case 'n': flags |= OPT_NLINK; break; case 'o': flags |= OPT_OPERM; break; case 'p': flags |= OPT_PERM; break; - case 'P': flags |= OPT_PMASK; pmask = octal(sh_optarg); break; + case 'P': + flags |= OPT_PMASK; + pmask = octal(sh_optarg); + if (pmask < 0) { + builtin_error ("invalid mode: %s", sh_optarg); + return(1); + } + break; case 's': flags |= OPT_SIZE; break; case 'u': flags |= OPT_UID; break; case 'U': flags |= OPT_UID|OPT_ASCII; break; diff --git a/execute_cmd.c b/execute_cmd.c index ae5d313c6..2c99493bc 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -2954,9 +2954,6 @@ execute_for_command (FOR_COM *for_command) command_string_index = 0; print_for_command_head (for_command); - if (echo_command_at_execute) - xtrace_print_for_command_head (for_command); - /* Save this command unless it's a trap command and we're not running a debug trap. */ if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0) @@ -2973,6 +2970,9 @@ execute_for_command (FOR_COM *for_command) continue; #endif + if (echo_command_at_execute) + xtrace_print_for_command_head (for_command); + this_command_name = (char *)NULL; /* XXX - special ksh93 for command index variable handling */ v = find_variable_last_nameref (identifier, 1); @@ -3088,9 +3088,6 @@ eval_arith_for_expr (WORD_LIST *l, int *okp) if (new) { - if (echo_command_at_execute) - xtrace_print_arith_cmd (new); - command_string_index = 0; print_arith_command (new); if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0) @@ -3100,23 +3097,25 @@ eval_arith_for_expr (WORD_LIST *l, int *okp) } r = run_debug_trap (); +#if defined (DEBUGGER) /* In debugging mode, if the DEBUG trap returns a non-zero status, we skip the command. */ - eflag = (shell_compatibility_level > 51) ? 0 : EXP_EXPANDED; - this_command_name = "(("; /* )) for expression error messages */ - -#if defined (DEBUGGER) - if (debugging_mode == 0 || r == EXECUTION_SUCCESS) - expresult = evalexp (new->word->word, eflag, okp); - else + if (debugging_mode && r != EXECUTION_SUCCESS) { expresult = 0; if (okp) *okp = 1; + return (expresult); } -#else - expresult = evalexp (new->word->word, eflag, okp); #endif + + if (echo_command_at_execute) + xtrace_print_arith_cmd (new); + + eflag = (shell_compatibility_level > 51) ? 0 : EXP_EXPANDED; + this_command_name = "(("; /* )) for expression error messages */ + + expresult = evalexp (new->word->word, eflag, okp); dispose_words (new); } else @@ -3425,9 +3424,6 @@ execute_select_command (SELECT_COM *select_command) command_string_index = 0; print_select_command_head (select_command); - if (echo_command_at_execute) - xtrace_print_select_command_head (select_command); - #if 0 if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0))) #else @@ -3446,6 +3442,9 @@ execute_select_command (SELECT_COM *select_command) return (EXECUTION_SUCCESS); #endif + if (echo_command_at_execute) + xtrace_print_select_command_head (select_command); + this_command_name = (char *)0; loop_level++; interrupt_execution++; @@ -3565,9 +3564,6 @@ execute_case_command (CASE_COM *case_command) command_string_index = 0; print_case_command_head (case_command); - if (echo_command_at_execute) - xtrace_print_case_command_head (case_command); - #if 0 if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0))) #else @@ -3589,6 +3585,9 @@ execute_case_command (CASE_COM *case_command) } #endif + if (echo_command_at_execute) + xtrace_print_case_command_head (case_command); + /* Use the same expansions (the ones POSIX specifies) as the patterns; dequote the resulting string (as POSIX specifies) since the quotes in patterns are handled specially below. We have to do it in this order