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 <grishalevit@gmail.com>
+
+ 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 <grishalevit@gmail.com>
${\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
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
(@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.
@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.
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
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
}
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;
else
rval = cutfile (v, list, &op);
+ free (poslist);
return (rval);
}
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);
#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)
{
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;
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)
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);
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)
}
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
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
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++;
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
}
#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