Bash-5.3-alpha release

This commit is contained in:
Chet Ramey
2024-04-22 10:33:38 -04:00
parent f3b6bd1945
commit 622d318652
700 changed files with 136534 additions and 96420 deletions
+210 -197
View File
@@ -1,6 +1,6 @@
/* bind.c -- key binding and startup file support for the readline library. */
/* Copyright (C) 1987-2022 Free Software Foundation, Inc.
/* Copyright (C) 1987-2023 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -65,20 +65,15 @@ extern int errno;
#include "rlshell.h"
#include "xmalloc.h"
#if !defined (strchr) && !defined (__STDC__)
extern char *strchr (), *strrchr ();
#endif /* !strchr && !__STDC__ */
/* Variables exported by this file. */
Keymap rl_binding_keymap;
/* Functions exported by this file. */
rl_macro_print_func_t *rl_macro_display_hook = (rl_macro_print_func_t *)NULL;
static int _rl_skip_to_delim (char *, int, int);
#if defined (USE_VARARGS) && defined (PREFER_STDARG)
static void _rl_init_file_error (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
#else
static void _rl_init_file_error ();
#endif
static rl_command_func_t *_rl_function_of_keyseq_internal (const char *, size_t, Keymap, int *);
@@ -531,8 +526,7 @@ rl_translate_keyseq (const char *seq, char *array, int *len)
/* When there are incomplete prefixes \C- or \M- (has_control || has_meta)
without base character at the end of SEQ, they are processed as the
prefixes for '\0'.
*/
prefixes for '\0'. */
for (i = l = 0; (c = seq[i]) || has_control || has_meta; i++)
{
/* Only backslashes followed by a non-null character are handled
@@ -629,11 +623,17 @@ rl_translate_keyseq (const char *seq, char *array, int *len)
has_meta = 0;
}
/* If convert-meta is turned on, convert a meta char to a key sequence */
/* If convert-meta is turned on, convert a meta char to a key sequence */
if (META_CHAR (c) && _rl_convert_meta_chars_to_ascii)
{
array[l++] = ESC; /* ESC is meta-prefix */
array[l++] = UNMETA (c);
int x = UNMETA (c);
if (x)
{
array[l++] = ESC; /* ESC is meta-prefix */
array[l++] = x;
}
else
array[l++] = c; /* just do the best we can without sticking a NUL in there. */
}
else
array[l++] = (c);
@@ -685,7 +685,8 @@ char *
rl_untranslate_keyseq (int seq)
{
static char kseq[16];
int i, c;
int i;
unsigned char c;
i = 0;
c = seq;
@@ -696,36 +697,23 @@ rl_untranslate_keyseq (int seq)
kseq[i++] = '-';
c = UNMETA (c);
}
else if (c == ESC)
{
kseq[i++] = '\\';
c = 'e';
}
else if (CTRL_CHAR (c))
{
kseq[i++] = '\\';
kseq[i++] = 'C';
kseq[i++] = '-';
c = _rl_to_lower (UNCTRL (c));
}
else if (c == RUBOUT)
{
kseq[i++] = '\\';
kseq[i++] = 'C';
kseq[i++] = '-';
c = '?';
}
if (c == ESC)
{
kseq[i++] = '\\';
c = 'e';
}
else if (c == '\\' || c == '"')
else if (CTRL_CHAR (c) || c == RUBOUT)
{
kseq[i++] = '\\';
kseq[i++] = 'C';
kseq[i++] = '-';
c = (c == RUBOUT) ? '?' : _rl_to_lower (UNCTRL (c));
}
if (c == '\\' || c == '"')
kseq[i++] = '\\';
kseq[i++] = (unsigned char) c;
kseq[i] = '\0';
return kseq;
@@ -735,9 +723,9 @@ char *
_rl_untranslate_macro_value (char *seq, int use_escapes)
{
char *ret, *r, *s;
int c;
unsigned char c;
r = ret = (char *)xmalloc (7 * strlen (seq) + 1);
r = ret = (char *)xmalloc (8 * strlen (seq) + 1);
for (s = seq; *s; s++)
{
c = *s;
@@ -748,7 +736,9 @@ _rl_untranslate_macro_value (char *seq, int use_escapes)
*r++ = '-';
c = UNMETA (c);
}
else if (c == ESC)
/* We want to keep from printing literal control chars */
if (c == ESC)
{
*r++ = '\\';
c = 'e';
@@ -773,15 +763,10 @@ _rl_untranslate_macro_value (char *seq, int use_escapes)
c = '?';
}
if (c == ESC)
{
*r++ = '\\';
c = 'e';
}
else if (c == '\\' || c == '"')
if (c == '\\' || c == '"')
*r++ = '\\';
*r++ = (unsigned char)c;
*r++ = c;
}
*r = '\0';
return ret;
@@ -889,21 +874,30 @@ int
rl_trim_arg_from_keyseq (const char *keyseq, size_t len, Keymap map)
{
register int i, j, parsing_digits;
unsigned char ic;
unsigned int ic; /* int to handle ANYOTHERKEY */
Keymap map0;
if (map == 0)
map = _rl_keymap;
map0 = map;
/* The digits following the initial one (e.g., the binding to digit-argument)
or the optional `-' in a binding to digit-argument or universal-argument
are not added to rl_executing_keyseq. This is basically everything read by
rl_digit_loop. The parsing_digits logic is here in case they ever are. */
/* Make sure to add the digits following the initial one (e.g., the binding
to digit-argument) and the optional `-' in a binding to digit-argument
or universal-argument to rl_executing_keyseq. This is basically
everything read by rl_digit_loop. */
for (i = j = parsing_digits = 0; keyseq && i < len; i++)
{
ic = keyseq[i];
if (parsing_digits == 2)
{
if (ic == '-') /* skip over runs of minus chars */
{
j = i + 1;
continue;
}
parsing_digits = 1;
}
if (parsing_digits)
{
if (_rl_digit_p (ic))
@@ -916,10 +910,11 @@ rl_trim_arg_from_keyseq (const char *keyseq, size_t len, Keymap map)
if (map[ic].type == ISKMAP)
{
if (i + 1 == len)
return -1;
map = FUNCTION_TO_KEYMAP (map, ic);
continue;
if (i + 1 == len)
ic = ANYOTHERKEY;
else
continue;
}
if (map[ic].type == ISFUNC)
{
@@ -938,16 +933,11 @@ rl_trim_arg_from_keyseq (const char *keyseq, size_t len, Keymap map)
/* This logic should be identical to rl_digit_loop */
/* We accept M-- as equivalent to M--1, C-u- as equivalent to C-u-1
but set parsing_digits to 2 to note that we saw `-' */
if (map[ic].function == rl_universal_argument && (i + 1 == '-'))
{
i++;
parsing_digits = 2;
}
if (map[ic].function == rl_digit_argument && ic == '-')
{
parsing_digits = 2;
}
but set parsing_digits to 2 to note that we saw `-'. See above
for the check that skips over one or more `-' characters. */
if (map[ic].function == rl_universal_argument ||
(map[ic].function == rl_digit_argument && ic == '-'))
parsing_digits = 2;
map = map0;
j = i + 1;
@@ -978,11 +968,20 @@ _rl_read_file (char *filename, size_t *sizep)
char *buffer;
int i, file;
file = -1;
if (((file = open (filename, O_RDONLY, 0666)) < 0) || (fstat (file, &finfo) < 0))
file = open (filename, O_RDONLY, 0666);
/* If the open is interrupted, retry once */
if (file < 0 && errno == EINTR)
{
RL_CHECK_SIGNALS ();
file = open (filename, O_RDONLY, 0666);
}
if ((file < 0) || (fstat (file, &finfo) < 0))
{
i = errno;
if (file >= 0)
close (file);
errno = i;
return ((char *)NULL);
}
@@ -991,10 +990,13 @@ _rl_read_file (char *filename, size_t *sizep)
/* check for overflow on very large files */
if (file_size != finfo.st_size || file_size + 1 < file_size)
{
i = errno;
if (file >= 0)
close (file);
#if defined (EFBIG)
errno = EFBIG;
#else
errno = i;
#endif
return ((char *)NULL);
}
@@ -1129,25 +1131,11 @@ _rl_read_init_file (const char *filename, int include_level)
}
static void
#if defined (PREFER_STDARG)
_rl_init_file_error (const char *format, ...)
#else
_rl_init_file_error (va_alist)
va_dcl
#endif
{
va_list args;
#if defined (PREFER_VARARGS)
char *format;
#endif
#if defined (PREFER_STDARG)
va_start (args, format);
#else
va_start (args);
format = va_arg (args, char *);
#endif
fprintf (stderr, "readline: ");
if (currently_reading_init_file)
fprintf (stderr, "%s: line %d: ", current_readline_init_file,
@@ -1167,9 +1155,7 @@ _rl_init_file_error (va_alist)
/* **************************************************************** */
static int
parse_comparison_op (s, indp)
const char *s;
int *indp;
parse_comparison_op (const char *s, int *indp)
{
int i, peekc, op;
@@ -1247,7 +1233,7 @@ const char *rl_readline_name = "other";
/* Stack of previous values of parsing_conditionalized_out. */
static unsigned char *if_stack = (unsigned char *)NULL;
static int if_stack_depth;
static int if_stack_size;
static size_t if_stack_size;
/* Push _rl_parsing_conditionalized_out, and set parser state based
on ARGS. */
@@ -1672,7 +1658,6 @@ rl_parse_and_bind (char *string)
if (_rl_stricmp (string, "set") == 0)
{
char *var, *value, *e;
int s;
var = string + i;
/* Make VAR point to start of variable name. */
@@ -1850,7 +1835,7 @@ rl_parse_and_bind (char *string)
if (*funname == '\'' || *funname == '"')
{
char useq[2];
int fl = strlen (funname);
size_t fl = strlen (funname);
useq[0] = key; useq[1] = '\0';
if (fl && funname[fl - 1] == *funname)
@@ -1917,6 +1902,7 @@ static const struct {
{ "prefer-visible-bell", &_rl_prefer_visible_bell, V_SPECIAL },
{ "print-completions-horizontally", &_rl_print_completions_horizontally, 0 },
{ "revert-all-at-newline", &_rl_revert_all_at_newline, 0 },
{ "search-ignore-case", &_rl_search_case_fold, 0 },
{ "show-all-if-ambiguous", &_rl_complete_show_all, 0 },
{ "show-all-if-unmodified", &_rl_complete_show_unmodified, 0 },
{ "show-mode-in-prompt", &_rl_show_mode_in_prompt, 0 },
@@ -2595,17 +2581,13 @@ _rl_get_keyname (int key)
char *keyname;
int i, c;
keyname = (char *)xmalloc (8);
keyname = (char *)xmalloc (9);
c = key;
/* Since this is going to be used to write out keysequence-function
pairs for possible inclusion in an inputrc file, we don't want to
do any special meta processing on KEY. */
#if 1
/* XXX - Experimental */
/* We might want to do this, but the old version of the code did not. */
/* If this is an escape character, we don't want to do any more processing.
Just add the special ESC key sequence and return. */
if (c == ESC)
@@ -2615,28 +2597,23 @@ _rl_get_keyname (int key)
keyname[2] = '\0';
return keyname;
}
#endif
/* RUBOUT is translated directly into \C-? */
if (key == RUBOUT)
if (key == ANYOTHERKEY)
{
keyname[0] = '\\';
keyname[1] = 'C';
keyname[2] = '-';
keyname[3] = '?';
keyname[4] = '\0';
keyname[0] = '\0';
return keyname;
}
i = 0;
/* Now add special prefixes needed for control characters. This can
potentially change C. */
if (CTRL_CHAR (c))
if (CTRL_CHAR (c) || c == RUBOUT)
{
keyname[i++] = '\\';
keyname[i++] = 'C';
keyname[i++] = '-';
c = _rl_to_lower (UNCTRL (c));
c = (c == RUBOUT) ? '?' : _rl_to_lower (UNCTRL (c));
}
/* XXX experimental code. Turn the characters that are not ASCII or
@@ -2678,7 +2655,7 @@ rl_invoking_keyseqs_in_map (rl_command_func_t *function, Keymap map)
{
register int key;
char **result;
int result_index, result_size;
size_t result_index, result_size;
result = (char **)NULL;
result_index = result_size = 0;
@@ -2714,53 +2691,24 @@ rl_invoking_keyseqs_in_map (rl_command_func_t *function, Keymap map)
{
char **seqs;
register int i;
char *keyname;
size_t knlen;
/* Find the list of keyseqs in this map which have FUNCTION as
their target. Add the key sequences found to RESULT. */
if (map[key].function)
seqs =
rl_invoking_keyseqs_in_map (function, FUNCTION_TO_KEYMAP (map, key));
else
if (map[key].function == 0)
break;
seqs = rl_invoking_keyseqs_in_map (function, FUNCTION_TO_KEYMAP (map, key));
if (seqs == 0)
break;
keyname = _rl_get_keyname (key);
knlen = RL_STRLEN (keyname);
for (i = 0; seqs[i]; i++)
{
char *keyname = (char *)xmalloc (6 + strlen (seqs[i]));
if (key == ESC)
{
/* If ESC is the meta prefix and we're converting chars
with the eighth bit set to ESC-prefixed sequences, then
we can use \M-. Otherwise we need to use the sequence
for ESC. */
if (_rl_convert_meta_chars_to_ascii && map[ESC].type == ISKMAP)
sprintf (keyname, "\\M-");
else
sprintf (keyname, "\\e");
}
else
{
int c = key, l = 0;
if (CTRL_CHAR (c) || c == RUBOUT)
{
keyname[l++] = '\\';
keyname[l++] = 'C';
keyname[l++] = '-';
c = (c == RUBOUT) ? '?' : _rl_to_lower (UNCTRL (c));
}
if (c == '\\' || c == '"')
keyname[l++] = '\\';
keyname[l++] = (char) c;
keyname[l++] = '\0';
}
strcat (keyname, seqs[i]);
xfree (seqs[i]);
char *x;
if (result_index + 2 > result_size)
{
@@ -2768,10 +2716,16 @@ rl_invoking_keyseqs_in_map (rl_command_func_t *function, Keymap map)
result = (char **)xrealloc (result, result_size * sizeof (char *));
}
result[result_index++] = keyname;
x = xmalloc (knlen + RL_STRLEN (seqs[i]) + 1);
strcpy (x, keyname);
strcpy (x + knlen, seqs[i]);
xfree (seqs[i]);
result[result_index++] = x;
result[result_index] = (char *)NULL;
}
xfree (keyname);
xfree (seqs);
}
break;
@@ -2788,6 +2742,56 @@ rl_invoking_keyseqs (rl_command_func_t *function)
return (rl_invoking_keyseqs_in_map (function, _rl_keymap));
}
void
rl_print_keybinding (const char *name, Keymap kmap, int print_readably)
{
rl_command_func_t *function;
char **invokers;
function = rl_named_function (name);
invokers = rl_invoking_keyseqs_in_map (function, kmap ? kmap : _rl_keymap);
if (print_readably)
{
if (!invokers)
fprintf (rl_outstream, "# %s (not bound)\n", name);
else
{
register int j;
for (j = 0; invokers[j]; j++)
{
fprintf (rl_outstream, "\"%s\": %s\n", invokers[j], name);
xfree (invokers[j]);
}
xfree (invokers);
}
}
else
{
if (!invokers)
fprintf (rl_outstream, "%s is not bound to any keys\n", name);
else
{
register int j;
fprintf (rl_outstream, "%s can be found on ", name);
for (j = 0; invokers[j] && j < 5; j++)
fprintf (rl_outstream, "\"%s\"%s", invokers[j], invokers[j + 1] ? ", " : ".\n");
if (j == 5 && invokers[j])
fprintf (rl_outstream, "...\n");
for (j = 0; invokers[j]; j++)
xfree (invokers[j]);
xfree (invokers);
}
}
}
/* Print all of the functions and their bindings to rl_outstream. If
PRINT_READABLY is non-zero, then print the output in such a way
that it can be read back in. */
@@ -2803,58 +2807,7 @@ rl_function_dumper (int print_readably)
fprintf (rl_outstream, "\n");
for (i = 0; name = names[i]; i++)
{
rl_command_func_t *function;
char **invokers;
function = rl_named_function (name);
invokers = rl_invoking_keyseqs_in_map (function, _rl_keymap);
if (print_readably)
{
if (!invokers)
fprintf (rl_outstream, "# %s (not bound)\n", name);
else
{
register int j;
for (j = 0; invokers[j]; j++)
{
fprintf (rl_outstream, "\"%s\": %s\n",
invokers[j], name);
xfree (invokers[j]);
}
xfree (invokers);
}
}
else
{
if (!invokers)
fprintf (rl_outstream, "%s is not bound to any keys\n",
name);
else
{
register int j;
fprintf (rl_outstream, "%s can be found on ", name);
for (j = 0; invokers[j] && j < 5; j++)
{
fprintf (rl_outstream, "\"%s\"%s", invokers[j],
invokers[j + 1] ? ", " : ".\n");
}
if (j == 5 && invokers[j])
fprintf (rl_outstream, "...\n");
for (j = 0; invokers[j]; j++)
xfree (invokers[j]);
xfree (invokers);
}
}
}
rl_print_keybinding (name, _rl_keymap, print_readably);
xfree (names);
}
@@ -2875,9 +2828,9 @@ rl_dump_functions (int count, int key)
static void
_rl_macro_dumper_internal (int print_readably, Keymap map, char *prefix)
{
register int key;
int key;
char *keyname, *out;
int prefix_len;
size_t prefix_len;
for (key = 0; key < KEYMAP_SIZE; key++)
{
@@ -2887,6 +2840,16 @@ _rl_macro_dumper_internal (int print_readably, Keymap map, char *prefix)
keyname = _rl_get_keyname (key);
out = _rl_untranslate_macro_value ((char *)map[key].function, 0);
/* If the application wants to print macros, let it. Give it the
ascii-fied value with backslash escapes, so it will have to use
rl_macro_bind (with its call to rl_translate_keyseq) to get the
same value back. */
if (rl_macro_display_hook)
{
(*rl_macro_display_hook) (keyname, out, print_readably, prefix);
break;
}
if (print_readably)
fprintf (rl_outstream, "\"%s%s\": \"%s\"\n", prefix ? prefix : "",
keyname,
@@ -2950,10 +2913,40 @@ rl_dump_macros (int count, int key)
static char *
_rl_get_string_variable_value (const char *name)
{
static char numbuf[32];
static char numbuf[64]; /* more than enough for INTMAX_MAX */
char *ret;
if (_rl_stricmp (name, "bell-style") == 0)
if (_rl_stricmp (name, "active-region-start-color") == 0)
{
if (_rl_active_region_start_color == 0)
return 0;
ret = _rl_untranslate_macro_value (_rl_active_region_start_color, 0);
if (ret)
{
strncpy (numbuf, ret, sizeof (numbuf) - 1);
xfree (ret);
numbuf[sizeof(numbuf) - 1] = '\0';
}
else
numbuf[0] = '\0';
return numbuf;
}
else if (_rl_stricmp (name, "active-region-end-color") == 0)
{
if (_rl_active_region_end_color == 0)
return 0;
ret = _rl_untranslate_macro_value (_rl_active_region_end_color, 0);
if (ret)
{
strncpy (numbuf, ret, sizeof (numbuf) - 1);
xfree (ret);
numbuf[sizeof(numbuf) - 1] = '\0';
}
else
numbuf[0] = '\0';
return numbuf;
}
else if (_rl_stricmp (name, "bell-style") == 0)
{
switch (_rl_bell_preference)
{
@@ -2970,24 +2963,40 @@ _rl_get_string_variable_value (const char *name)
return (_rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
else if (_rl_stricmp (name, "completion-display-width") == 0)
{
#if defined (HAVE_VSNPRINTF)
snprintf (numbuf, sizeof (numbuf), "%d", _rl_completion_columns);
#else
sprintf (numbuf, "%d", _rl_completion_columns);
#endif
return (numbuf);
}
else if (_rl_stricmp (name, "completion-prefix-display-length") == 0)
{
#if defined (HAVE_VSNPRINTF)
snprintf (numbuf, sizeof (numbuf), "%d", _rl_completion_prefix_display_length);
#else
sprintf (numbuf, "%d", _rl_completion_prefix_display_length);
#endif
return (numbuf);
}
else if (_rl_stricmp (name, "completion-query-items") == 0)
{
#if defined (HAVE_VSNPRINTF)
snprintf (numbuf, sizeof (numbuf), "%d", rl_completion_query_items);
#else
sprintf (numbuf, "%d", rl_completion_query_items);
#endif
return (numbuf);
}
else if (_rl_stricmp (name, "editing-mode") == 0)
return (rl_get_keymap_name_from_edit_mode ());
else if (_rl_stricmp (name, "history-size") == 0)
{
sprintf (numbuf, "%d", history_is_stifled() ? history_max_entries : 0);
#if defined (HAVE_VSNPRINTF)
snprintf (numbuf, sizeof (numbuf), "%d", history_is_stifled() ? history_max_entries : -1);
#else
sprintf (numbuf, "%d", history_is_stifled() ? history_max_entries : -1);
#endif
return (numbuf);
}
else if (_rl_stricmp (name, "isearch-terminators") == 0)
@@ -3014,7 +3023,11 @@ _rl_get_string_variable_value (const char *name)
}
else if (_rl_stricmp (name, "keyseq-timeout") == 0)
{
sprintf (numbuf, "%d", _rl_keyseq_timeout);
#if defined (HAVE_VSNPRINTF)
snprintf (numbuf, sizeof (numbuf), "%d", _rl_keyseq_timeout);
#else
sprintf (numbuf, "%d", _rl_keyseq_timeout);
#endif
return (numbuf);
}
else if (_rl_stricmp (name, "emacs-mode-string") == 0)