Import readline 7.0 (patch 5)

This imports readline 7.0 (up to patch 5) while preserving all
gdb-local changes.

This was done by checking out the readline git repository, making a
branch based on the gdb baseline revision, applying the gdb changes to
that branch, and then merging from readline 7.

readline/ChangeLog.gdb
2019-08-12  Tom Tromey  <tom@tromey.com>

	* Imported readline 7.0 patch 5.
This commit is contained in:
Tom Tromey
2018-10-07 12:52:13 -06:00
parent 08132bdd87
commit 775e241e9c
96 changed files with 9082 additions and 1805 deletions

View File

@@ -1,6 +1,6 @@
/* bind.c -- key binding and startup file support for the readline library. */
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
/* Copyright (C) 1987-2016 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.
@@ -72,11 +72,20 @@ extern char *strchr (), *strrchr ();
/* Variables exported by this file. */
Keymap rl_binding_keymap;
static int _rl_skip_to_delim PARAMS((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 char *_rl_read_file PARAMS((char *, size_t *));
static void _rl_init_file_error PARAMS((const char *));
static int _rl_read_init_file PARAMS((const char *, int));
static int glean_key_from_name PARAMS((char *));
static int find_boolean_var PARAMS((const char *));
static int find_string_var PARAMS((const char *));
static char *_rl_get_string_variable_value PARAMS((const char *));
static int substring_member_of_array PARAMS((const char *, const char * const *));
@@ -113,6 +122,9 @@ rl_bind_key (key, function)
int key;
rl_command_func_t *function;
{
char keyseq[3];
int l;
if (key < 0)
return (key);
@@ -131,8 +143,24 @@ rl_bind_key (key, function)
return (key);
}
_rl_keymap[key].type = ISFUNC;
_rl_keymap[key].function = function;
/* If it's bound to a function or macro, just overwrite. Otherwise we have
to treat it as a key sequence so rl_generic_bind handles shadow keymaps
for us. If we are binding '\' make sure to escape it so it makes it
through the call to rl_translate_keyseq. */
if (_rl_keymap[key].type != ISKMAP)
{
_rl_keymap[key].type = ISFUNC;
_rl_keymap[key].function = function;
}
else
{
l = 0;
if (key == '\\')
keyseq[l++] = '\\';
keyseq[l++] = key;
keyseq[l] = '\0';
rl_bind_keyseq (keyseq, function);
}
rl_binding_keymap = _rl_keymap;
return (0);
}
@@ -538,7 +566,7 @@ rl_translate_keyseq (seq, array, len)
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
i++;
for (temp = 2, c -= '0'; ISOCTAL (seq[i]) && temp--; i++)
for (temp = 2, c -= '0'; ISOCTAL ((unsigned char)seq[i]) && temp--; i++)
c = (c * 8) + OCTVALUE (seq[i]);
i--; /* auto-increment in for loop */
array[l++] = c & largest_char;
@@ -567,6 +595,40 @@ rl_translate_keyseq (seq, array, len)
return (0);
}
static int
_rl_isescape (c)
int c;
{
switch (c)
{
case '\007':
case '\b':
case '\f':
case '\n':
case '\r':
case TAB:
case 0x0b: return (1);
default: return (0);
}
}
static int
_rl_escchar (c)
int c;
{
switch (c)
{
case '\007': return ('a');
case '\b': return ('b');
case '\f': return ('f');
case '\n': return ('n');
case '\r': return ('r');
case TAB: return ('t');
case 0x0b: return ('v');
default: return (c);
}
}
char *
rl_untranslate_keyseq (seq)
int seq;
@@ -618,9 +680,10 @@ rl_untranslate_keyseq (seq)
return kseq;
}
static char *
_rl_untranslate_macro_value (seq)
char *
_rl_untranslate_macro_value (seq, use_escapes)
char *seq;
int use_escapes;
{
char *ret, *r, *s;
int c;
@@ -644,9 +707,14 @@ _rl_untranslate_macro_value (seq)
else if (CTRL_CHAR (c))
{
*r++ = '\\';
*r++ = 'C';
*r++ = '-';
c = _rl_to_lower (UNCTRL (c));
if (use_escapes && _rl_isescape (c))
c = _rl_escchar (c);
else
{
*r++ = 'C';
*r++ = '-';
c = _rl_to_lower (UNCTRL (c));
}
}
else if (c == RUBOUT)
{
@@ -926,14 +994,35 @@ _rl_read_init_file (filename, include_level)
}
static void
_rl_init_file_error (msg)
const char *msg;
#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)
_rl_errmsg ("%s: line %d: %s\n", current_readline_init_file,
current_readline_init_lineno, msg);
else
_rl_errmsg ("%s", msg);
fprintf (stderr, "%s: line %d: ", current_readline_init_file,
current_readline_init_lineno);
vfprintf (stderr, format, args);
fprintf (stderr, "\n");
fflush (stderr);
va_end (args);
}
/* **************************************************************** */
@@ -1153,10 +1242,42 @@ handle_parser_directive (statement)
}
/* display an error message about the unknown parser directive */
_rl_init_file_error ("unknown parser directive");
_rl_init_file_error ("%s: unknown parser directive", directive);
return (1);
}
/* Start at STRING[START] and look for DELIM. Return I where STRING[I] ==
DELIM or STRING[I] == 0. DELIM is usually a double quote. */
static int
_rl_skip_to_delim (string, start, delim)
char *string;
int start, delim;
{
int i, c, passc;
for (i = start,passc = 0; c = string[i]; i++)
{
if (passc)
{
passc = 0;
if (c == 0)
break;
continue;
}
if (c == '\\')
{
passc = 1;
continue;
}
if (c == delim)
break;
}
return i;
}
/* Read the binding command from STRING and perform it.
A key binding command looks like: Keyname: function-name\0,
a variable binding command looks like: set variable value.
@@ -1167,12 +1288,12 @@ rl_parse_and_bind (string)
{
char *funname, *kname;
register int c, i;
int key, equivalency;
int key, equivalency, foundmod, foundsep;
while (string && whitespace (*string))
string++;
if (!string || !*string || *string == '#')
if (string == 0 || *string == 0 || *string == '#')
return 0;
/* If this is a parser directive, act on it. */
@@ -1192,31 +1313,16 @@ rl_parse_and_bind (string)
backslash to quote characters in the key expression. */
if (*string == '"')
{
int passc = 0;
i = _rl_skip_to_delim (string, 1, '"');
for (i = 1; c = string[i]; i++)
{
if (passc)
{
passc = 0;
continue;
}
if (c == '\\')
{
passc++;
continue;
}
if (c == '"')
break;
}
/* If we didn't find a closing quote, abort the line. */
if (string[i] == '\0')
{
_rl_init_file_error ("no closing `\"' in key binding");
_rl_init_file_error ("%s: no closing `\"' in key binding", string);
return 1;
}
else
i++; /* skip past closing double quote */
}
/* Advance to the colon (:) or whitespace which separates the two objects. */
@@ -1224,6 +1330,8 @@ rl_parse_and_bind (string)
equivalency = (c == ':' && string[i + 1] == '=');
foundsep = c != 0;
/* Mark the end of the command (or keyname). */
if (string[i])
string[i++] = '\0';
@@ -1236,6 +1344,7 @@ rl_parse_and_bind (string)
if (_rl_stricmp (string, "set") == 0)
{
char *var, *value, *e;
int s;
var = string + i;
/* Make VAR point to start of variable name. */
@@ -1243,25 +1352,37 @@ rl_parse_and_bind (string)
/* Make VALUE point to start of value string. */
value = var;
while (*value && !whitespace (*value)) value++;
while (*value && whitespace (*value) == 0) value++;
if (*value)
*value++ = '\0';
while (*value && whitespace (*value)) value++;
/* Strip trailing whitespace from values to boolean variables. Temp
fix until I get a real quoted-string parser here. */
i = find_boolean_var (var);
if (i >= 0)
/* Strip trailing whitespace from values of boolean variables. */
if (find_boolean_var (var) >= 0)
{
/* remove trailing whitespace */
remove_trailing:
e = value + strlen (value) - 1;
while (e >= value && whitespace (*e))
e--;
e++; /* skip back to whitespace or EOS */
if (*e && e >= value)
*e = '\0';
}
else if ((i = find_string_var (var)) >= 0)
{
/* Allow quoted strings in variable values */
if (*value == '"')
{
i = _rl_skip_to_delim (value, 1, *value);
value[i] = '\0';
value++; /* skip past the quote */
}
else
goto remove_trailing;
}
rl_variable_bind (var, value);
return 0;
}
@@ -1282,32 +1403,13 @@ rl_parse_and_bind (string)
the quoted string delimiter, like the shell. */
if (*funname == '\'' || *funname == '"')
{
int delimiter, passc;
delimiter = string[i++];
for (passc = 0; c = string[i]; i++)
{
if (passc)
{
passc = 0;
continue;
}
if (c == '\\')
{
passc = 1;
continue;
}
if (c == delimiter)
break;
}
if (c)
i = _rl_skip_to_delim (string, i+1, *funname);
if (string[i])
i++;
}
/* Advance to the end of the string. */
for (; string[i] && !whitespace (string[i]); i++);
for (; string[i] && whitespace (string[i]) == 0; i++);
/* No extra whitespace at the end of the string. */
string[i] = '\0';
@@ -1319,6 +1421,12 @@ rl_parse_and_bind (string)
return 0;
}
if (foundsep == 0)
{
_rl_init_file_error ("%s: no key sequence terminator", string);
return 1;
}
/* If this is a new-style key-binding, then do the binding with
rl_bind_keyseq (). Otherwise, let the older code deal with it. */
if (*string == '"')
@@ -1367,7 +1475,7 @@ rl_parse_and_bind (string)
/* Get the actual character we want to deal with. */
kname = strrchr (string, '-');
if (!kname)
if (kname == 0)
kname = string;
else
kname++;
@@ -1375,11 +1483,24 @@ rl_parse_and_bind (string)
key = glean_key_from_name (kname);
/* Add in control and meta bits. */
foundmod = 0;
if (substring_member_of_array (string, _rl_possible_control_prefixes))
key = CTRL (_rl_to_upper (key));
{
key = CTRL (_rl_to_upper (key));
foundmod = 1;
}
if (substring_member_of_array (string, _rl_possible_meta_prefixes))
key = META (key);
{
key = META (key);
foundmod = 1;
}
if (foundmod == 0 && kname != string)
{
_rl_init_file_error ("%s: unknown key modifier", string);
return 1;
}
/* Temporary. Handle old-style keyname with macro-binding. */
if (*funname == '\'' || *funname == '"')
@@ -1406,6 +1527,7 @@ rl_parse_and_bind (string)
#endif /* PREFIX_META_HACK */
else
rl_bind_key (key, rl_named_function (funname));
return 0;
}
@@ -1423,11 +1545,16 @@ static const struct {
{ "bind-tty-special-chars", &_rl_bind_stty_chars, 0 },
{ "blink-matching-paren", &rl_blink_matching_paren, V_SPECIAL },
{ "byte-oriented", &rl_byte_oriented, 0 },
#if defined (COLOR_SUPPORT)
{ "colored-completion-prefix",&_rl_colored_completion_prefix, 0 },
{ "colored-stats", &_rl_colored_stats, 0 },
#endif
{ "completion-ignore-case", &_rl_completion_case_fold, 0 },
{ "completion-map-case", &_rl_completion_case_map, 0 },
{ "convert-meta", &_rl_convert_meta_chars_to_ascii, 0 },
{ "disable-completion", &rl_inhibit_completion, 0 },
{ "echo-control-characters", &_rl_echo_control_chars, 0 },
{ "enable-bracketed-paste", &_rl_enable_bracketed_paste, 0 },
{ "enable-keypad", &_rl_enable_keypad, 0 },
{ "enable-meta-key", &_rl_enable_meta, 0 },
{ "expand-tilde", &rl_complete_with_tilde_expansion, 0 },
@@ -1447,6 +1574,7 @@ static const struct {
{ "revert-all-at-newline", &_rl_revert_all_at_newline, 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 },
{ "skip-completed-text", &_rl_skip_completed_text, 0 },
#if defined (VISIBLE_STATS)
{ "visible-stats", &rl_visible_stats, 0 },
@@ -1486,6 +1614,8 @@ hack_special_boolean_var (i)
else
_rl_bell_preference = AUDIBLE_BELL;
}
else if (_rl_stricmp (name, "show-mode-in-prompt") == 0)
_rl_reset_prompt ();
}
typedef int _rl_sv_func_t PARAMS((const char *));
@@ -1508,9 +1638,13 @@ static int sv_dispprefix PARAMS((const char *));
static int sv_compquery PARAMS((const char *));
static int sv_compwidth PARAMS((const char *));
static int sv_editmode PARAMS((const char *));
static int sv_emacs_modestr PARAMS((const char *));
static int sv_histsize PARAMS((const char *));
static int sv_isrchterm PARAMS((const char *));
static int sv_keymap PARAMS((const char *));
static int sv_seqtimeout PARAMS((const char *));
static int sv_viins_modestr PARAMS((const char *));
static int sv_vicmd_modestr PARAMS((const char *));
static const struct {
const char * const name;
@@ -1523,9 +1657,13 @@ static const struct {
{ "completion-prefix-display-length", V_INT, sv_dispprefix },
{ "completion-query-items", V_INT, sv_compquery },
{ "editing-mode", V_STRING, sv_editmode },
{ "emacs-mode-string", V_STRING, sv_emacs_modestr },
{ "history-size", V_INT, sv_histsize },
{ "isearch-terminators", V_STRING, sv_isrchterm },
{ "keymap", V_STRING, sv_keymap },
{ "keyseq-timeout", V_INT, sv_seqtimeout },
{ "vi-cmd-mode-string", V_STRING, sv_vicmd_modestr },
{ "vi-ins-mode-string", V_STRING, sv_viins_modestr },
{ (char *)NULL, 0, (_rl_sv_func_t *)0 }
};
@@ -1542,7 +1680,7 @@ find_string_var (name)
}
/* A boolean value that can appear in a `set variable' command is true if
the value is null or empty, `on' (case-insenstive), or "1". Any other
the value is null or empty, `on' (case-insensitive), or "1". Any other
values result in 0 (false). */
static int
bool_to_int (value)
@@ -1591,10 +1729,14 @@ rl_variable_bind (name, value)
i = find_string_var (name);
/* For the time being, unknown variable names or string names without a
handler function are simply ignored. */
/* For the time being, string names without a handler function are simply
ignored. */
if (i < 0 || string_varlist[i].set_func == 0)
return 0;
{
if (i < 0)
_rl_init_file_error ("%s: unknown variable name", name);
return 0;
}
v = (*string_varlist[i].set_func) (value);
return v;
@@ -1683,13 +1825,17 @@ static int
sv_histsize (value)
const char *value;
{
int nval = 500;
int nval;
nval = 500;
if (value && *value)
{
nval = atoi (value);
if (nval < 0)
return 1;
{
unstifle_history ();
return 0;
}
}
stifle_history (nval);
return 0;
@@ -1710,6 +1856,23 @@ sv_keymap (value)
return 1;
}
static int
sv_seqtimeout (value)
const char *value;
{
int nval;
nval = 0;
if (value && *value)
{
nval = atoi (value);
if (nval < 0)
nval = 0;
}
_rl_keyseq_timeout = nval;
return 0;
}
static int
sv_bell_style (value)
const char *value;
@@ -1748,7 +1911,7 @@ sv_isrchterm (value)
}
else
{
for (beg = end = 0; whitespace (v[end]) == 0; end++)
for (beg = end = 0; v[end] && whitespace (v[end]) == 0; end++)
;
}
@@ -1762,7 +1925,96 @@ sv_isrchterm (value)
xfree (v);
return 0;
}
extern char *_rl_emacs_mode_str;
static int
sv_emacs_modestr (value)
const char *value;
{
if (value && *value)
{
FREE (_rl_emacs_mode_str);
_rl_emacs_mode_str = (char *)xmalloc (2 * strlen (value) + 1);
rl_translate_keyseq (value, _rl_emacs_mode_str, &_rl_emacs_modestr_len);
_rl_emacs_mode_str[_rl_emacs_modestr_len] = '\0';
return 0;
}
else if (value)
{
FREE (_rl_emacs_mode_str);
_rl_emacs_mode_str = (char *)xmalloc (1);
_rl_emacs_mode_str[_rl_emacs_modestr_len = 0] = '\0';
return 0;
}
else if (value == 0)
{
FREE (_rl_emacs_mode_str);
_rl_emacs_mode_str = 0; /* prompt_modestr does the right thing */
_rl_emacs_modestr_len = 0;
return 0;
}
return 1;
}
static int
sv_viins_modestr (value)
const char *value;
{
if (value && *value)
{
FREE (_rl_vi_ins_mode_str);
_rl_vi_ins_mode_str = (char *)xmalloc (2 * strlen (value) + 1);
rl_translate_keyseq (value, _rl_vi_ins_mode_str, &_rl_vi_ins_modestr_len);
_rl_vi_ins_mode_str[_rl_vi_ins_modestr_len] = '\0';
return 0;
}
else if (value)
{
FREE (_rl_vi_ins_mode_str);
_rl_vi_ins_mode_str = (char *)xmalloc (1);
_rl_vi_ins_mode_str[_rl_vi_ins_modestr_len = 0] = '\0';
return 0;
}
else if (value == 0)
{
FREE (_rl_vi_ins_mode_str);
_rl_vi_ins_mode_str = 0; /* prompt_modestr does the right thing */
_rl_vi_ins_modestr_len = 0;
return 0;
}
return 1;
}
static int
sv_vicmd_modestr (value)
const char *value;
{
if (value && *value)
{
FREE (_rl_vi_cmd_mode_str);
_rl_vi_cmd_mode_str = (char *)xmalloc (2 * strlen (value) + 1);
rl_translate_keyseq (value, _rl_vi_cmd_mode_str, &_rl_vi_cmd_modestr_len);
_rl_vi_cmd_mode_str[_rl_vi_cmd_modestr_len] = '\0';
return 0;
}
else if (value)
{
FREE (_rl_vi_cmd_mode_str);
_rl_vi_cmd_mode_str = (char *)xmalloc (1);
_rl_vi_cmd_mode_str[_rl_vi_cmd_modestr_len = 0] = '\0';
return 0;
}
else if (value == 0)
{
FREE (_rl_vi_cmd_mode_str);
_rl_vi_cmd_mode_str = 0; /* prompt_modestr does the right thing */
_rl_vi_cmd_modestr_len = 0;
return 0;
}
return 1;
}
/* Return the character which matches NAME.
For example, `Space' returns ' '. */
@@ -2167,7 +2419,8 @@ rl_function_dumper (print_readably)
}
}
}
free (names);
xfree (names);
}
/* Print all of the current functions and their bindings to
@@ -2200,7 +2453,7 @@ _rl_macro_dumper_internal (print_readably, map, prefix)
{
case ISMACR:
keyname = _rl_get_keyname (key);
out = _rl_untranslate_macro_value ((char *)map[key].function);
out = _rl_untranslate_macro_value ((char *)map[key].function, 0);
if (print_readably)
fprintf (rl_outstream, "\"%s%s\": \"%s\"\n", prefix ? prefix : "",
@@ -2312,7 +2565,7 @@ _rl_get_string_variable_value (name)
{
if (_rl_isearch_terminators == 0)
return 0;
ret = _rl_untranslate_macro_value (_rl_isearch_terminators);
ret = _rl_untranslate_macro_value (_rl_isearch_terminators, 0);
if (ret)
{
strncpy (numbuf, ret, sizeof (numbuf) - 1);
@@ -2330,6 +2583,17 @@ _rl_get_string_variable_value (name)
ret = rl_get_keymap_name_from_edit_mode ();
return (ret ? ret : "none");
}
else if (_rl_stricmp (name, "keyseq-timeout") == 0)
{
sprintf (numbuf, "%d", _rl_keyseq_timeout);
return (numbuf);
}
else if (_rl_stricmp (name, "emacs-mode-string") == 0)
return (_rl_emacs_mode_str ? _rl_emacs_mode_str : RL_EMACS_MODESTR_DEFAULT);
else if (_rl_stricmp (name, "vi-cmd-mode-string") == 0)
return (_rl_vi_cmd_mode_str ? _rl_vi_cmd_mode_str : RL_VI_CMD_MODESTR_DEFAULT);
else if (_rl_stricmp (name, "vi-ins-mode-string") == 0)
return (_rl_vi_ins_mode_str ? _rl_vi_ins_mode_str : RL_VI_INS_MODESTR_DEFAULT);
else
return (0);
}