- win32_isatty: win32-specific changes from GDB. Patch submitted by
Tom Tromey <tom@tromey.com>, originally from Eli Zaretskii
<eliz@gnu.org>
+
+ 10/1
+ ----
+lib/readline/vi_mode.c
+ - rl_vi_start_inserting: start an undo group so we can grab the text
+ inserted here as a single unit, avoiding any insert coalescing
+ performed by rl_insert_text. Report and fix from Richard Todd
+ <richard.w.todd@outlook.com>
+
+ 10/3
+ ----
+subst.c
+ - parameter_brace_transform: if we're asked to display the attributes
+ of an unset variable, check that the variable exists even if
+ get_var_and_type returns NULL (it checks invisible_p). Requested by
+ Michal Pesa <pesathem@gmail.com>
+
+lib/readline/kill.c
+ - _rl_bracketed_text: new function, collects the text pasted in
+ bracketed paste mode and consumes the bracketed paste end marker;
+ returns the pasted text and its length
+ - rl_bracketed_paste_begin: call _rl_bracketed_text to collect the
+ text
+
+lib/readline/isearch.c
+ - _rl_isearch_dispatch: set cxt->lastc to -7 if the input resolves to
+ rl_bracketed_paste_begin
+ - _rl_isearch_dispatch: if cxt->lastc == -7, call _rl_bracketed_text
+ to collect the pasted text and add it to the accumulating search
+ string. Only works if ESC is not one of the isearch terminators.
+ Fixes issue reported in Debian bug report 891780,
+ https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=891780
+
+ 10/5
+ ----
+variables.c
+ - push_posix_tempvar_internal: new function, body of push_func_var
+ with additional argument saying whether it's being called from a
+ function or (special) builtin code path
+ - push_builtin_var: new function, calls push_posix_tempvar_internal
+ with second argument indicating builtin code path
+ - push_func_var: now a stub that calls push_posix_tempvar_internal
+ with second argument indicating function code path
+ - pop_scope: if called from a special builtin, call push_builtin_var
+ instead of push_func_var to do the right variable propagation
+
+builtins/shopt.def
+ - progcomp_alias: uncomment, make available to users
+
+doc/{bash.1,bashref.texi},lib/readline/doc/rluser.texi
+ - progcomp_alias: document shopt option, describe its use in
+ the section on programmable completion
+
+trap.c
+ - decode_signal: handle SIGRTMIN+n at runtime, with the `SIG' prefix
+ or without, case-insensitively if requested, and return SIGRTMIN+n.
+ These values could be different than what was available at compile
+ time. Report and patch from Rasmus Villemoes <rv@rasumsvillemoes.dk>
SHELL_VAR *entry;
t = mbschr (name, '['); /* ] */
+ isassoc = 0;
if (t)
{
*t = '\0';
r = legal_identifier (name);
- isassoc = (entry = find_variable (name)) && assoc_p (entry);
+ if (flags & VA_NOEXPAND) /* Don't waste a lookup if we don't need one */
+ isassoc = (entry = find_variable (name)) && assoc_p (entry);
*t = '[';
if (r == 0)
return 0;
exp = (char *)xmalloc (len);
strncpy (exp, s, len - 1);
exp[len - 1] = '\0';
-#if 0 /* XXX - not yet -- maybe bash-5.0 */
+#if 0 /* XXX - not yet -- maybe bash-5.1 */
if ((flags & AV_NOEXPAND) == 0)
t = expand_arith_string (exp, Q_DOUBLE_QUOTES|Q_ARITH|Q_ARRAYSUB); /* XXX - Q_ARRAYSUB for future use */
else
free (temp);
}
else /* ${name[@]} or unquoted ${name[*]} */
- /* XXX - bash-4.4/bash-5.0 test AV_ASSIGNRHS and pass PF_ASSIGNRHS */
retval = string_list_dollar_at (l, quoted, (flags & AV_ASSIGNRHS) ? PF_ASSIGNRHS : 0);
dispose_words (l);
var = find_variable_noref (name);
#endif
- if (var /* && invisible_p (var) == 0 */) /* XXX bash-4.4/bash-5.0 */
+ if (var /* && invisible_p (var) == 0 */)
{
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
return (0);
{ "nullglob", &allow_null_glob_expansion, (shopt_set_func_t *)NULL },
#if defined (PROGRAMMABLE_COMPLETION)
{ "progcomp", &prog_completion_enabled, (shopt_set_func_t *)NULL },
-# if 0 /* bash-5.0-beta */
+# if defined (ALIAS)
{ "progcomp_alias", &progcomp_alias, (shopt_set_func_t *)NULL },
# endif
#endif
.\" Case Western Reserve University
.\" chet.ramey@case.edu
.\"
-.\" Last Change: Sat Sep 29 13:38:24 EDT 2018
+.\" Last Change: Fri Oct 5 14:53:12 EDT 2018
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
-.TH BASH 1 "2018 September 29" "GNU Bash 5.0"
+.TH BASH 1 "2018 October 5" "GNU Bash 5.0"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
find a compspec for the portion following the final slash.
If those searches do not result in a compspec, any compspec defined with
the \fB\-D\fP option to \fBcomplete\fP is used as the default.
+If there is no default compspec, \fBbash\fP attempts alias expansion
+on the command word as a final resort, and attempts to find a compspec
+for the command word from any successful expansion.
.PP
Once a compspec has been found, it is used to generate the list of
matching words.
\fBProgrammable Completion\fP above) are enabled.
This option is enabled by default.
.TP 8
+.B progcomp_alias
+If set, and programmable completion is enabled, \fBbash\fP treats a command
+name that doesn't have any completions as a possible alias and attempts
+alias expansion. If it has an alias, \fBbash\fP attempts programmable
+completion using the command word resulting from the expanded alias.
+.TP 8
.B promptvars
If set, prompt strings undergo
parameter expansion, command substitution, arithmetic
(@pxref{Programmable Completion}) are enabled.
This option is enabled by default.
+@item progcomp_alias
+If set, and programmable completion is enabled, Bash treats a command
+name that doesn't have any completions as a possible alias and attempts
+alias expansion. If it has an alias, Bash attempts programmable
+completion using the command word resulting from the expanded alias.
+
@item promptvars
If set, prompt strings undergo
parameter expansion, command substitution, arithmetic
Copyright (C) 1988-2018 Free Software Foundation, Inc.
@end ignore
-@set LASTCHANGE Sat Sep 29 13:41:44 EDT 2018
+@set LASTCHANGE Fri Oct 5 14:52:51 EDT 2018
@set EDITION 5.0
@set VERSION 5.0
-@set UPDATED 29 September 2018
-@set UPDATED-MONTH September 2018
+@set UPDATED 5 October 2018
+@set UPDATED-MONTH October 2018
int funcnest = 0;
int funcnest_max = 0;
-int evalnest = 0; /* bash-4.4/bash-5.0 */
+int evalnest = 0;
int evalnest_max = EVALNEST_MAX;
int sourcenest = 0;
async_redirect_stdin ();
#if 0
- /* bash-5.0 */
+ /* XXX - TAG: bash-5.1 */
if (user_subshell && command->type == cm_subshell)
optimize_subshell_command (command->value.Subshell->command);
#endif
invert = (command->flags & CMD_INVERT_RETURN) != 0;
- /* XXX - expand coproc name without splitting -- bash-5.0 */
- /* could make this dependent on a shopt option */
+ /* expand name without splitting - could make this dependent on a shopt option */
name = expand_string_unsplit_to_string (command->value.Coproc->name, 0);
- /* Optional check -- bash-5.0. */
+ /* Optional check -- could be relaxed */
if (legal_identifier (name) == 0)
{
internal_error (_("`%s': not a valid identifier"), name);
close (rpipe[1]);
close (wpipe[0]);
- /* XXX - run Coproc->name through word expansion above -- bash-5.0 */
cp = coproc_alloc (command->value.Coproc->name, coproc_pid);
cp->c_rfd = rpipe[0];
cp->c_wfd = wpipe[1];
{
s = job_signal_status (job);
- /* XXX - bash-5.0 */
/* If we are non-interactive, but job control is enabled, and the job
died due to SIGINT, pretend we got the SIGINT */
if (job_control && IS_JOBCONTROL (job) && WIFSIGNALED (s) && WTERMSIG (s) == SIGINT)
}
/* Call a SIGCHLD trap handler for each child that exits, if one is set. */
- /* XXX - bash-5.0 removes test for job_control */
if (children_exited &&
(signal_is_trapped (SIGCHLD) || trap_list[SIGCHLD] == (char *)IMPOSSIBLE_TRAP_HANDLER) &&
trap_list[SIGCHLD] != (char *)IGNORE_SIG)
find a compspec for the portion following the final slash.
If those searches do not result in a compspec, any compspec defined with
the @option{-D} option to @code{complete} is used as the default.
+If there is no default compspec, Bash attempts alias expansion
+on the command word as a final resort, and attempts to find a compspec
+for the command word from any successful expansion
Once a compspec has been found, it is used to generate the list of
matching words.
_rl_isearch_dispatch (_rl_search_cxt *cxt, int c)
{
int n, wstart, wlen, limit, cval, incr;
+ char *paste;
+ size_t pastelen;
+ int j;
rl_command_func_t *f;
f = (rl_command_func_t *)NULL;
cxt->lastc = -5;
else if (c == CTRL ('Y') || f == rl_yank) /* XXX */
cxt->lastc = -6;
+ else if (f == rl_bracketed_paste_begin)
+ cxt->lastc = -7;
}
/* If we changed the keymap earlier while translating a key sequence into
cxt->search_string[cxt->search_string_index] = '\0';
break;
+ case -7: /* bracketed paste */
+ paste = _rl_bracketed_text (&pastelen);
+ if (paste == 0 || *paste == 0)
+ {
+ free (paste);
+ break;
+ }
+ if (cxt->search_string_index + pastelen + 1 >= cxt->search_string_size)
+ {
+ cxt->search_string_size += pastelen + 2;
+ cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
+ }
+ strcpy (cxt->search_string + cxt->search_string_index, paste);
+ cxt->search_string_index += pastelen;
+ free (paste);
+ break;
+
/* Add character to search string and continue search. */
default:
#if defined (HANDLE_MULTIBYTE)
`bracketed paste' sequence, read the rest of the pasted input until the
closing sequence and insert the pasted text as a single unit without
interpretation. */
-int
-rl_bracketed_paste_begin (int count, int key)
+char *
+_rl_bracketed_text (size_t *lenp)
{
- int retval, c;
+ int c;
size_t len, cap;
char *buf;
- retval = 0;
len = 0;
buf = xmalloc (cap = 64);
+ buf[0] = '\0';
RL_SETSTATE (RL_STATE_MOREINPUT);
while ((c = rl_read_key ()) >= 0)
if (len == cap)
buf = xrealloc (buf, cap + 1);
buf[len] = '\0';
- retval = rl_insert_text (buf) == len ? 0 : 1;
}
+ if (lenp)
+ *lenp = len;
+ return (buf);
+}
+
+int
+rl_bracketed_paste_begin (int count, int key)
+{
+ int retval, c;
+ size_t len, cap;
+ char *buf;
+
+ buf = _rl_bracketed_text (&len);
+ retval = rl_insert_text (buf) == len ? 0 : 1;
+
xfree (buf);
return (retval);
}
#define BRACK_PASTE_INIT "\033[?2004h"
#define BRACK_PASTE_FINI "\033[?2004l\r"
+extern char *_rl_bracketed_text PARAMS((size_t *));
+
/* macro.c */
extern void _rl_with_macro_input PARAMS((char *));
extern int _rl_peek_macro_key PARAMS((void));
rl_vi_start_inserting (int key, int repeat, int sign)
{
_rl_vi_set_last (key, repeat, sign);
+ rl_begin_undo_group (); /* ensure inserts aren't concatenated */
rl_vi_insertion_mode (1, key);
}
return (IN);
}
- /* bash-5.0: leaving above code intact for now, but it should eventually be
+ /* XXX - leaving above code intact for now, but it should eventually be
removed in favor of this clause. */
/* Posix grammar rule 6 */
if (expecting_in_token && (last_read_token == WORD || last_read_token == '\n') &&
int prog_completion_enabled = 1;
-#ifdef ALIAS /* bash-5.0-beta */
+#ifdef ALIAS
int progcomp_alias = 0; /* unavailable to user code for now */
#endif
if (sig == SIGCHLD)
act.sa_flags |= SA_RESTART; /* XXX */
#endif
- /* XXX - bash-5.0 */
/* Let's see if we can keep SIGWINCH from interrupting interruptible system
calls, like open(2)/read(2)/write(2) */
#if defined (SIGWINCH)
}
#if defined (ARRAY_VARS)
- /* XXX - bash-5.0 */
if (c == LBRACK && dolbrace_state == DOLBRACE_PARAM)
{
si = skipsubscript (string, i, 0);
# if !defined (__GNUC__)
sep = (char *)xmalloc (MB_CUR_MAX + 1);
# endif /* !__GNUC__ */
- /* XXX - bash-4.4/bash-5.0 testing PF_ASSIGNRHS */
+ /* XXX - testing PF_ASSIGNRHS to make sure positional parameters are
+ separated with a space even when word splitting will not occur. */
if (flags & PF_ASSIGNRHS)
{
sep[0] = ' ';
sep[1] = '\0';
}
#else /* !HANDLE_MULTIBYTE */
- /* XXX - bash-4.4/bash-5.0 test PF_ASSIGNRHS */
+ /* XXX - PF_ASSIGNRHS means no word splitting, so we want positional
+ parameters separated by a space. */
sep[0] = ((flags & PF_ASSIGNRHS) || ifs == 0 || *ifs == 0) ? ' ' : *ifs;
sep[1] = '\0';
#endif /* !HANDLE_MULTIBYTE */
{
/* Only treat as double quoted if array variable */
if (var && (array_p (var) || assoc_p (var)))
- /* XXX - bash-4.4/bash-5.0 pass AV_ASSIGNRHS */
temp = array_value (name, quoted|Q_DOUBLE_QUOTES, AV_ASSIGNRHS, &atype, &ind);
else
temp = array_value (name, quoted, 0, &atype, &ind);
#if 1
if ((vtype == VT_ARRAYVAR || vtype == VT_POSPARMS) && *e2p < 0)
#else
- /* XXX - bash-5.0 */
+ /* XXX - TAG: bash-5.1 */
if (vtype == VT_ARRAYVAR && *e2p < 0)
#endif
{
return &expand_param_error;
}
+ /* If we are asked to display the attributes of an unset variable, V will
+ be NULL after the call to get_var_and_type. Double-check here. */
+ if (xc == 'a' && vtype == VT_VARIABLE && varname && v == 0)
+ v = find_variable (varname);
+
temp1 = (char *)NULL; /* shut up gcc */
switch (vtype & ~VT_STARSUB)
{
case '<':
case '>':
{
- /* bash-4.4/bash-5.0
- XXX - technically this should only be expanded at the start
+ /* XXX - technically this should only be expanded at the start
of a word */
if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (word->flags & (W_DQUOTE|W_NOPROCSUB)) || posixly_correct)
{
word->flags |= W_ITILDE;
#endif
- /* XXX - bash-4.4/bash-5.0 */
if (word->flags & W_ASSIGNARG)
word->flags |= W_ASSIGNRHS; /* affects $@ */
tword = alloc_word_desc ();
tword->word = temp;
- /* XXX - bash-4.4/bash-5.0 */
if (word->flags & W_ASSIGNARG)
- tword->flags |= word->flags & (W_ASSIGNARG|W_ASSIGNRHS); /* affects $@ */
+ tword->flags |= word->flags & (W_ASSIGNARG|W_ASSIGNRHS); /* affects $@ */
if (word->flags & W_COMPLETE)
tword->flags |= W_COMPLETE; /* for command substitutions */
if (word->flags & W_NOCOMSUB)
-BUILD_DIR=/usr/local/build/bash/bash-current
+BUILD_DIR=/usr/local/build/chet/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
a b c d e
5
a5b
+i
+declare -i foo
+A
+declare -A foo
abcxxxdef
abcådef
ḅć
echo ${@}
echo ${#@}
echo a${#@}b
+
+# new feature in bash-5.0: display attributes of even unset variables
+unset -v foo
+
+declare -i foo
+echo ${foo@a}
+
+declare -p foo
+
+unset foo
+declare -A foo
+echo ${foo@a}
+
+declare -p foo
shopt -u lastpipe
shopt -u lithist
shopt -u localvar_inherit
+shopt -u localvar_unset
shopt -u login_shell
shopt -u mailwarn
shopt -u no_empty_cmd_completion
shopt -u nocasematch
shopt -u nullglob
shopt -s progcomp
+shopt -u progcomp_alias
shopt -s promptvars
shopt -u restricted_shell
shopt -u shift_verbose
shopt -u lastpipe
shopt -u lithist
shopt -u localvar_inherit
+shopt -u localvar_unset
shopt -u login_shell
shopt -u mailwarn
shopt -u no_empty_cmd_completion
shopt -u nocaseglob
shopt -u nocasematch
shopt -u nullglob
+shopt -u progcomp_alias
shopt -u restricted_shell
shopt -u shift_verbose
shopt -u xpg_echo
lastpipe off
lithist off
localvar_inherit off
+localvar_unset off
login_shell off
mailwarn off
no_empty_cmd_completion off
nocaseglob off
nocasematch off
nullglob off
+progcomp_alias off
restricted_shell off
shift_verbose off
xpg_echo off
if (legal_number (string, &sig))
return ((sig >= 0 && sig < NSIG) ? (int)sig : NO_SIG);
+#if defined (SIGRTMIN) && defined (SIGRTMAX)
+ if (STREQN (string, "SIGRTMIN+", 9) || ((flags & DSIG_NOCASE) && strncasecmp (string, "SIGRTMIN+", 9) == 0))
+ {
+ if (legal_number (string+9, &sig) && sig >= 0 && sig <= SIGRTMAX - SIGRTMIN)
+ return (SIGRTMIN + sig);
+ else
+ return NO_SIG;
+ }
+ else if (STREQN (string, "RTMIN+", 6) || ((flags & DSIG_NOCASE) && strncasecmp (string, "RTMIN+", 6) == 0))
+ {
+ if (legal_number (string+6, &sig) && sig >= 0 && sig <= SIGRTMAX - SIGRTMIN)
+ return (SIGRTMIN + sig);
+ else
+ return NO_SIG;
+ }
+#endif /* SIGRTMIN && SIGRTMAX */
+
/* A leading `SIG' may be omitted. */
for (sig = 0; sig < BASH_NSIG; sig++)
{
static int set_context __P((SHELL_VAR *));
static void push_func_var __P((PTR_T));
+static void push_builtin_var __P((PTR_T));
static void push_exported_var __P((PTR_T));
+static inline void push_posix_tempvar_internal __P((SHELL_VAR *, int));
+
static inline int find_special_var __P((const char *));
static void
{
internal_warning (_("%s: circular name reference"), orig->name);
#if 1
- /* XXX - provisional change - bash-5.0 - circular refs go to
+ /* XXX - provisional change - circular refs go to
global scope for resolution, without namerefs. */
if (variable_context && v->context)
return (find_global_variable_noref (v->name));
array_needs_making = 1;
-#if 0
- sv_ifs ("IFS"); /* XXX here for now -- check setifs in assign_in_env */
-#endif
for (i = 0; i < tvlist_ind; i++)
stupidly_hack_special_variables (tempvar_list[i]);
functions no longer behave like assignment statements preceding
special builtins, and do not persist in the current shell environment.
This is austin group interp #654, though nobody implements it yet. */
+#if 0 /* XXX - TAG: bash-5.1 */
+ posix_func_behavior = 0;
+#else
posix_func_behavior = posixly_correct;
+#endif
vc = new_var_context (name, flags);
/* Posix interp 1009, temporary assignments preceding function calls modify
/* This can be called from one of two code paths:
1. pop_scope, which implements the posix rules for propagating variable
- assignments preceding special builtins to the surrounding scope.
+ assignments preceding special builtins to the surrounding scope
+ (push_builtin_var);
2. pop_var_context, which is called from pop_context and implements the
posix rules for propagating variable assignments preceding function
- calls to the surrounding scope.
+ calls to the surrounding scope (push_func_var).
It takes variables out of a temporary environment hash table. We take the
variable in data.
*/
-static void
-push_func_var (data)
- PTR_T data;
+
+static inline void
+push_posix_tempvar_internal (var, isbltin)
+ SHELL_VAR *var;
+ int isbltin;
{
- SHELL_VAR *var, *v;
+ SHELL_VAR *v;
int posix_var_behavior;
- var = (SHELL_VAR *)data;
/* As of IEEE Std 1003.1-2017, assignment statements preceding shell
functions no longer behave like assignment statements preceding
special builtins, and do not persist in the current shell environment.
This is austin group interp #654, though nobody implements it yet. */
- posix_var_behavior = posixly_correct;
+#if 0 /* XXX - TAG: bash-5.1 */
+ posix_var_behavior = posixly_correct && isbltin;
+#else
+ posix_var_behavior = posixly_correct;
+#endif
if (local_p (var) && STREQ (var->name, "-"))
set_current_options (value_cell (var));
dispose_variable (var);
}
+static void
+push_func_var (data)
+ PTR_T data;
+{
+ SHELL_VAR *var;
+
+ var = (SHELL_VAR *)data;
+ push_posix_tempvar_internal (var, 0);
+}
+
+static void
+push_builtin_var (data)
+ PTR_T data;
+{
+ SHELL_VAR *var;
+
+ var = (SHELL_VAR *)data;
+ push_posix_tempvar_internal (var, 1);
+}
+
/* Pop the top context off of VCXT and dispose of it, returning the rest of
the stack. */
void
special builtin (if IS_SPECIAL != 0) or exported variables that are the
result of a builtin like `source' or `command' that can operate on the
variables in its temporary environment. In the first case, we call
- push_func_var, which does the right thing (for now) */
+ push_builtin_var, which does the right thing. */
void
pop_scope (is_special)
int is_special;
if (vcxt->table)
{
if (is_special)
- hash_flush (vcxt->table, push_func_var);
+ hash_flush (vcxt->table, push_builtin_var);
else
hash_flush (vcxt->table, push_exported_var);
hash_dispose (vcxt->table);