doc/bashref.texi
- bash posix mode: add description of alias expansion and command
substitution parsing and execution
+
+ 2/4
+ ---
+lib/readline/rltty.c
+ - rl_deprep_terminal: set _rl_last_c_pos to 0 after outputting
+ BRACK_PASTE_FINI, since the last character in that is \r. Partially
+ address issue raised by Markus Schwarzenberg <markus.schwarzenberg@freenet.de>
+ in https://lists.gnu.org/archive/html/bug-bash/2022-02/msg00056.html
+
+ 2/5
+ ---
+doc/{bash.1,bashref.texi}
+ - minor typo fixes from Helge Kreutzmann <debian@helgefjell.de>
+
+ 2/7
+ ---
+{arrayfunc,variables}.c
+ - ARRAY_EXPORT: changes to encode array and assoc variables using a
+ scheme similar to shell functions so we can export arrays and
+ differentiate them from scalar variables and differentiate array
+ and assoc variables. Still not enabled by default.
+
+variables.c
+ - mk_env_string: third argument is now the variable's attributes or 0,
+ with all the attributes we can export arrays
+
+lib/readline/bind.c
+ - active-region-start-color,active-region-end-color: new bindable
+ string variables, one to set the active region color (instead of
+ standout mode) and one to turn it off (instead of the "se" terminal
+ capability). They set _rl_active_region_start_color and
+ _rl_active_region_end_color variables via functions
+
+lib/readline/display.c
+ - putc_face: if setting standout mode, check for both the start color
+ and end color variables and output the start color string. If turning
+ off standout mode (normal face), output the end color string. Both
+ varibables must be set
+
+lib/readline/{readline.c,rlprivate.h}
+ - declarations for _rl_active_region_start_color and
+ _rl_active_region_end_color
+
+ 2/8
+ ---
+bashline.c
+ - initialize_readline: add bindable name `vi-edit-and-execute-command'
+
+shell.c
+ - subshell_exit: make sure to set last_command_exit_value before
+ calling the exit trap. Fixes bug reported by Greg Edwards
+ <gedwards@ddn.com>
entry = assign_array_element_internal (entry, name, vname, sub, sublen, value, flags, estatep);
+#if ARRAY_EXPORT
+ if (entry && exported_p (entry))
+ {
+ INVALIDATE_EXPORTSTR (entry);
+ array_needs_making = 1;
+ }
+#endif
+
free (vname);
return entry;
}
rl_add_defun ("display-shell-version", display_shell_version, -1);
rl_add_defun ("edit-and-execute-command", emacs_edit_and_execute_command, -1);
+#if defined (VI_MODE)
+ rl_add_defun ("vi-edit-and-execute-command", vi_edit_and_execute_command, -1);
+#endif
#if defined (BRACE_COMPLETION)
rl_add_defun ("complete-into-braces", bash_brace_completion, -1);
.\" Case Western Reserve University
.\" chet.ramey@case.edu
.\"
-.\" Last Change: Mon Jan 17 17:27:05 EST 2022
+.\" Last Change: Sat Feb 5 18:20:32 EST 2022
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
-.TH BASH 1 "2022 January 17" "GNU Bash 5.2"
+.TH BASH 1 "2022 February 5" "GNU Bash 5.2"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
append to or add to the variable's previous value.
This includes arguments to builtin commands such as \fBdeclare\fP that
accept assignment statements (\fIdeclaration\fP commands).
-When += is applied to a variable for which the \fIinteger\fP attribute has been
+When += is applied to a variable for which the \fBinteger\fP attribute has been
set, \fIvalue\fP is evaluated as an arithmetic expression and added to the
variable's current value, which is also evaluated.
When += is applied to an array variable using compound assignment (see
The value is used to set the shell's compatibility level.
See
.SM
-.B SHELL COMPATIBILITY MODE
+.B "SHELL COMPATIBILITY MODE"
below for a description of the various compatibility
levels and their effects.
The value may be a decimal number (e.g., 4.2) or an integer (e.g., 42)
The valid values correspond to the compatibility levels
described below under
.SM
-.BR BSHELL COMPATIBILITY MODE .
+.BR "SHELL COMPATIBILITY MODE" .
For example, 4.2 and 42 are valid values that correspond
to the \fBcompat42\fP \fBshopt\fP option
and set the compatibility level to 42.
127. Otherwise, the return status is the exit status of the last
process or job waited for.
.SH "SHELL COMPATIBILITY MODE"
-Bash-4.0 introduced the concept of a `shell compatibility level', specified
-as a set of options to the shopt builtin
+Bash-4.0 introduced the concept of a \fIshell compatibility level\fP,
+specified as a set of options to the shopt builtin (
.BR compat31 ,
.BR compat32 ,
.BR compat40 ,
@cindex Compatibility Level
@cindex Compatibility Mode
-Bash-4.0 introduced the concept of a `shell compatibility level', specified
-as a set of options to the shopt builtin
+Bash-4.0 introduced the concept of a @dfn{shell compatibility level},
+specified as a set of options to the shopt builtin
(@code{compat31},
@code{compat32},
@code{compat40},
Copyright (C) 1988-2022 Free Software Foundation, Inc.
@end ignore
-@set LASTCHANGE Tue Feb 1 13:25:53 EST 2022
+@set LASTCHANGE Sat Feb 5 18:20:58 EST 2022
@set EDITION 5.2
@set VERSION 5.2
-@set UPDATED 1 February 2022
+@set UPDATED 5 February 2022
@set UPDATED-MONTH February 2022
#define V_INT 2
/* Forward declarations */
+static int sv_region_start_color (const char *);
+static int sv_region_end_color (const char *);
static int sv_bell_style (const char *);
static int sv_combegin (const char *);
static int sv_dispprefix (const char *);
int flags;
_rl_sv_func_t *set_func;
} string_varlist[] = {
+ { "active-region-end-color", V_STRING, sv_region_end_color },
+ { "active-region-start-color", V_STRING, sv_region_start_color },
{ "bell-style", V_STRING, sv_bell_style },
{ "comment-begin", V_STRING, sv_combegin },
{ "completion-display-width", V_INT, sv_compwidth },
return 0;
}
+static int
+sv_region_start_color (const char *value)
+{
+ int len;
+
+ free (_rl_active_region_start_color);
+ if (value && *value)
+ {
+ _rl_active_region_start_color = (char *)xmalloc (2 * strlen (value) + 1);
+ rl_translate_keyseq (value, _rl_active_region_start_color, &len);
+ _rl_active_region_start_color[len] = '\0';
+ }
+ else
+ _rl_active_region_start_color = NULL;
+ return 0;
+}
+
+static int
+sv_region_end_color (const char *value)
+{
+ int len;
+
+ free (_rl_active_region_end_color);
+ if (value && *value)
+ {
+ _rl_active_region_end_color = (char *)xmalloc (2 * strlen (value) + 1);
+ rl_translate_keyseq (value, _rl_active_region_end_color, &len);
+ _rl_active_region_end_color[len] = '\0';
+ }
+ else
+ _rl_active_region_end_color = NULL;
+ return 0;
+}
+
static int
sv_bell_style (const char *value)
{
if (face != FACE_NORMAL && face != FACE_STANDOUT)
return;
if (face == FACE_STANDOUT && cf == FACE_NORMAL)
- _rl_standout_on ();
+ {
+ if (_rl_active_region_start_color && _rl_active_region_end_color)
+ tputs (_rl_active_region_start_color, 1, _rl_output_character_function);
+ else
+ _rl_standout_on ();
+ }
if (face == FACE_NORMAL && cf == FACE_STANDOUT)
- _rl_standout_off ();
+ {
+ if (_rl_active_region_start_color && _rl_active_region_end_color)
+ tputs (_rl_active_region_end_color, 1, _rl_output_character_function);
+ else
+ _rl_standout_off ();
+ }
*cur_face = face;
}
if (c != EOF)
int _rl_enable_bracketed_paste = BRACKETED_PASTE_DEFAULT;
int _rl_enable_active_region = BRACKETED_PASTE_DEFAULT;
+char *_rl_active_region_start_color = NULL;
+char *_rl_active_region_end_color = NULL;
+
/* **************************************************************** */
/* */
/* Top Level Functions */
extern int _rl_show_mode_in_prompt;
extern int _rl_enable_bracketed_paste;
extern int _rl_enable_active_region;
+extern char *_rl_active_region_start_color;
+extern char *_rl_active_region_end_color;
extern char *_rl_comment_begin;
extern unsigned char _rl_parsing_conditionalized_out;
extern Keymap _rl_keymap;
if (terminal_prepped & TPX_BRACKPASTE)
{
fprintf (rl_outstream, BRACK_PASTE_FINI);
+ /* Since the last character in BRACK_PASTE_FINI is \r */
+ _rl_last_c_pos = 0;
if (_rl_eof_found && (RL_ISSTATE (RL_STATE_TIMEOUT) == 0))
fprintf (rl_outstream, "\n");
else if (_rl_echoing_p == 0)
/* Do trap[0] if defined. Allow it to override the exit status
passed to us. */
+ last_command_exit_value = s;
if (signal_is_trapped (0))
s = run_exit_trap ();
#define BASHFUNC_SUFFIX "%%"
#define BASHFUNC_SUFFLEN 2 /* == strlen(BASHFUNC_SUFFIX) */
+#if ARRAY_EXPORT
+#define BASHARRAY_PREFIX "BASH_ARRAY_"
+#define BASHARRAY_PREFLEN 11
+#define BASHARRAY_SUFFIX "%%"
+#define BASHARRAY_SUFFLEN 2
+
+#define BASHASSOC_PREFIX "BASH_ASSOC_"
+#define BASHASSOC_PREFLEN 11
+#define BASHASSOC_SUFFIX "%%" /* needs to be the same as BASHARRAY_SUFFIX */
+#define BASHASSOC_SUFFLEN 2
+#endif
+
/* flags for find_variable_internal */
#define FV_FORCETEMPENV 0x01
#if defined (ARRAY_VARS)
# if ARRAY_EXPORT
/* Array variables may not yet be exported. */
- if (*string == '(' && string[1] == '[' && string[strlen (string) - 1] == ')')
+ if (STREQN (BASHARRAY_PREFIX, name, BASHARRAY_PREFLEN) &&
+ STREQN (BASHARRAY_SUFFIX, name + char_index - BASHARRAY_SUFFLEN, BASHARRAY_SUFFLEN) &&
+ *string == '(' && string[1] == '[' && string[strlen (string) - 1] == ')')
{
+ size_t namelen;
+ char *tname; /* desired imported array variable name */
+
+ namelen = char_index - BASHARRAY_PREFLEN - BASHARRAY_SUFFLEN;
+
+ tname = name + BASHARRAY_PREFLEN; /* start of variable name */
+ tname[namelen] = '\0'; /* now tname == varname */
+
string_length = 1;
temp_string = extract_array_assignment_list (string, &string_length);
- temp_var = assign_array_from_string (name, temp_string, 0);
+ temp_var = assign_array_from_string (tname, temp_string, 0);
FREE (temp_string);
- VSETATTR (temp_var, (att_exported | att_imported));
- array_needs_making = 1;
+ if (temp_var)
+ {
+ VSETATTR (temp_var, (att_exported | att_imported));
+ array_needs_making = 1;
+ }
+ }
+ else if (STREQN (BASHASSOC_PREFIX, name, BASHASSOC_PREFLEN) &&
+ STREQN (BASHASSOC_SUFFIX, name + char_index - BASHASSOC_SUFFLEN, BASHASSOC_SUFFLEN) &&
+ *string == '(' && string[1] == '[' && string[strlen (string) - 1] == ')')
+ {
+ size_t namelen;
+ char *tname; /* desired imported assoc variable name */
+
+ namelen = char_index - BASHASSOC_PREFLEN - BASHASSOC_SUFFLEN;
+
+ tname = name + BASHASSOC_PREFLEN; /* start of variable name */
+ tname[namelen] = '\0'; /* now tname == varname */
+
+ /* need to make sure it exists as an associative array first */
+ temp_var = find_or_make_array_variable (tname, 2);
+ if (temp_var)
+ {
+ string_length = 1;
+ temp_string = extract_array_assignment_list (string, &string_length);
+ temp_var = assign_array_var_from_string (temp_var, temp_string, 0);
+ }
+ FREE (temp_string);
+ if (temp_var)
+ {
+ VSETATTR (temp_var, (att_exported | att_imported));
+ array_needs_making = 1;
+ }
}
else
# endif /* ARRAY_EXPORT */
/* **************************************************************** */
static inline char *
-mk_env_string (name, value, isfunc)
+mk_env_string (name, value, attributes)
const char *name, *value;
- int isfunc;
+ int attributes;
{
size_t name_len, value_len;
char *p, *q, *t;
+ int isfunc, isarray;
name_len = strlen (name);
value_len = STRLEN (value);
+ isfunc = attributes & att_function;
+#if defined (ARRAY_VARS) && defined (ARRAY_EXPORT)
+ isarray = attributes & (att_array|att_assoc);
+#endif
+
/* If we are exporting a shell function, construct the encoded function
name. */
if (isfunc && value)
memcpy (q, BASHFUNC_SUFFIX, BASHFUNC_SUFFLEN);
q += BASHFUNC_SUFFLEN;
}
+#if defined (ARRAY_VARS) && defined (ARRAY_EXPORT)
+ else if (isarray && value)
+ {
+ if (attributes & att_assoc)
+ p = (char *)xmalloc (BASHASSOC_PREFLEN + name_len + BASHASSOC_SUFFLEN + value_len + 2);
+ else
+ p = (char *)xmalloc (BASHARRAY_PREFLEN + name_len + BASHARRAY_SUFFLEN + value_len + 2);
+ q = p;
+ if (attributes & att_assoc)
+ {
+ memcpy (q, BASHASSOC_PREFIX, BASHASSOC_PREFLEN);
+ q += BASHASSOC_PREFLEN;
+ }
+ else
+ {
+ memcpy (q, BASHARRAY_PREFIX, BASHARRAY_PREFLEN);
+ q += BASHARRAY_PREFLEN;
+ }
+ memcpy (q, name, name_len);
+ q += name_len;
+ /* These are actually the same currently */
+ if (attributes & att_assoc)
+ {
+ memcpy (q, BASHASSOC_SUFFIX, BASHASSOC_SUFFLEN);
+ q += BASHARRAY_SUFFLEN;
+ }
+ else
+ {
+ memcpy (q, BASHARRAY_SUFFIX, BASHARRAY_SUFFLEN);
+ q += BASHARRAY_SUFFLEN;
+ }
+ }
+#endif
else
{
p = (char *)xmalloc (2 + name_len + value_len);
}
#endif
+#if defined (ARRAY_VARS)
+# define USE_EXPORTSTR (value == var->exportstr && array_p (var) == 0 && assoc_p (var) == 0)
+#else
+# define USE_EXPORTSTR (value == var->exportstr)
+#endif
+
static char **
make_env_array_from_var_list (vars)
SHELL_VAR **vars;
list = strvec_create ((1 + strvec_len ((char **)vars)));
-#define USE_EXPORTSTR (value == var->exportstr)
-
for (i = 0, list_index = 0; var = vars[i]; i++)
{
#if defined (__CYGWIN__)
continue; /* XXX array vars cannot yet be exported */
# endif /* ARRAY_EXPORT */
else if (assoc_p (var))
-# if 0
+# if ARRAY_EXPORT
value = assoc_to_assign (assoc_cell (var), 0);
# else
continue; /* XXX associative array vars cannot yet be exported */
-# endif
+# endif /* ARRAY_EXPORT */
#endif
else
value = value_cell (var);
/* Gee, I'd like to get away with not using savestring() if we're
using the cached exportstr... */
list[list_index] = USE_EXPORTSTR ? savestring (value)
- : mk_env_string (var->name, value, function_p (var));
+ : mk_env_string (var->name, value, var->attributes);
+
if (USE_EXPORTSTR == 0)
SAVE_EXPORTSTR (var, list[list_index]);
list_index++;
#undef USE_EXPORTSTR
-#if 0 /* not yet */
-#if defined (ARRAY_VARS)
+#if defined (ARRAY_VARS) && defined (ARRAY_EXPORT)
if (array_p (var) || assoc_p (var))
free (value);
-#endif
#endif
}
}