mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-08-06 10:12:38 +02:00
Bash-5.3-alpha release
This commit is contained in:
+114
-63
@@ -1,6 +1,6 @@
|
||||
/* misc.c -- miscellaneous bindable readline functions. */
|
||||
|
||||
/* Copyright (C) 1987-2022 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2024 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.
|
||||
@@ -150,6 +150,7 @@ _rl_arg_dispatch (_rl_arg_cxt cxt, int c)
|
||||
|
||||
if (_rl_digit_p (c))
|
||||
{
|
||||
_rl_add_executing_keyseq (key);
|
||||
r = _rl_digit_value (c);
|
||||
rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + r : r;
|
||||
rl_explicit_arg = 1;
|
||||
@@ -157,6 +158,7 @@ _rl_arg_dispatch (_rl_arg_cxt cxt, int c)
|
||||
}
|
||||
else if (c == '-' && rl_explicit_arg == 0)
|
||||
{
|
||||
_rl_add_executing_keyseq (key);
|
||||
rl_numeric_arg = 1;
|
||||
_rl_argcxt |= NUM_SAWMINUS;
|
||||
rl_arg_sign = -1;
|
||||
@@ -235,6 +237,7 @@ rl_digit_argument (int ignore, int key)
|
||||
else
|
||||
{
|
||||
rl_execute_next (key);
|
||||
_rl_del_executing_keyseq ();
|
||||
return (rl_digit_loop ());
|
||||
}
|
||||
}
|
||||
@@ -306,9 +309,11 @@ void
|
||||
_rl_start_using_history (void)
|
||||
{
|
||||
using_history ();
|
||||
if (_rl_saved_line_for_history)
|
||||
_rl_free_saved_history_line ();
|
||||
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
|
||||
#if 1
|
||||
if (_rl_saved_line_for_history && _rl_saved_line_for_history->data)
|
||||
_rl_free_undo_list ((UNDO_LIST *)_rl_saved_line_for_history->data);
|
||||
#endif
|
||||
_rl_free_saved_history_line ();
|
||||
_rl_history_search_pos = -99; /* some random invalid history position */
|
||||
}
|
||||
|
||||
@@ -339,64 +344,83 @@ rl_maybe_replace_line (void)
|
||||
xfree (temp->line);
|
||||
FREE (temp->timestamp);
|
||||
xfree (temp);
|
||||
/* What about _rl_saved_line_for_history? if the saved undo list is
|
||||
rl_undo_list, and we just put that into a history entry, should
|
||||
we set the saved undo list to NULL? */
|
||||
if (_rl_saved_line_for_history && (UNDO_LIST *)_rl_saved_line_for_history->data == rl_undo_list)
|
||||
_rl_saved_line_for_history->data = 0;
|
||||
/* Do we want to set rl_undo_list = 0 here since we just saved it into
|
||||
a history entry? */
|
||||
rl_undo_list = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
_rl_unsave_line (HIST_ENTRY *entry)
|
||||
{
|
||||
/* Can't call with `1' because rl_undo_list might point to an undo
|
||||
list from a history entry, as in rl_replace_from_history() below. */
|
||||
rl_replace_line (entry->line, 0);
|
||||
rl_undo_list = (UNDO_LIST *)entry->data;
|
||||
|
||||
/* Doesn't free `data'. */
|
||||
_rl_free_history_entry (entry);
|
||||
|
||||
rl_point = rl_end; /* rl_replace_line sets rl_end */
|
||||
}
|
||||
|
||||
/* Restore the _rl_saved_line_for_history if there is one. */
|
||||
int
|
||||
rl_maybe_unsave_line (void)
|
||||
{
|
||||
if (_rl_saved_line_for_history)
|
||||
{
|
||||
/* Can't call with `1' because rl_undo_list might point to an undo
|
||||
list from a history entry, as in rl_replace_from_history() below. */
|
||||
rl_replace_line (_rl_saved_line_for_history->line, 0);
|
||||
rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
|
||||
|
||||
/* Doesn't free `data'. */
|
||||
_rl_free_history_entry (_rl_saved_line_for_history);
|
||||
_rl_unsave_line (_rl_saved_line_for_history);
|
||||
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
|
||||
rl_point = rl_end; /* rl_replace_line sets rl_end */
|
||||
}
|
||||
else
|
||||
rl_ding ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
HIST_ENTRY *
|
||||
_rl_alloc_saved_line (void)
|
||||
{
|
||||
HIST_ENTRY *ret;
|
||||
|
||||
ret = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
|
||||
|
||||
ret->line = savestring (rl_line_buffer);
|
||||
ret->timestamp = (char *)NULL;
|
||||
ret->data = (char *)rl_undo_list;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Save the current line in _rl_saved_line_for_history. */
|
||||
int
|
||||
rl_maybe_save_line (void)
|
||||
{
|
||||
if (_rl_saved_line_for_history == 0)
|
||||
{
|
||||
_rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
|
||||
_rl_saved_line_for_history->line = savestring (rl_line_buffer);
|
||||
_rl_saved_line_for_history->timestamp = (char *)NULL;
|
||||
_rl_saved_line_for_history->data = (char *)rl_undo_list;
|
||||
}
|
||||
_rl_saved_line_for_history = _rl_alloc_saved_line ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Just a wrapper, any self-respecting compiler will inline it. */
|
||||
void
|
||||
_rl_free_saved_line (HIST_ENTRY *entry)
|
||||
{
|
||||
_rl_free_history_entry (entry);
|
||||
}
|
||||
|
||||
int
|
||||
_rl_free_saved_history_line (void)
|
||||
{
|
||||
UNDO_LIST *orig;
|
||||
_rl_free_saved_line (_rl_saved_line_for_history);
|
||||
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
|
||||
|
||||
if (_rl_saved_line_for_history)
|
||||
{
|
||||
if (rl_undo_list && rl_undo_list == (UNDO_LIST *)_rl_saved_line_for_history->data)
|
||||
rl_undo_list = 0;
|
||||
/* Have to free this separately because _rl_free_history entry can't:
|
||||
it doesn't know whether or not this has application data. Only the
|
||||
callers that know this is _rl_saved_line_for_history can know that
|
||||
it's an undo list. */
|
||||
if (_rl_saved_line_for_history->data)
|
||||
_rl_free_undo_list ((UNDO_LIST *)_rl_saved_line_for_history->data);
|
||||
_rl_free_history_entry (_rl_saved_line_for_history);
|
||||
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -554,20 +578,11 @@ rl_end_of_history (int count, int key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Move down to the next history line. */
|
||||
int
|
||||
rl_get_next_history (int count, int key)
|
||||
_rl_next_history_internal (int count)
|
||||
{
|
||||
HIST_ENTRY *temp;
|
||||
|
||||
if (count < 0)
|
||||
return (rl_get_previous_history (-count, key));
|
||||
|
||||
if (count == 0)
|
||||
return 0;
|
||||
|
||||
rl_maybe_replace_line ();
|
||||
|
||||
/* either not saved by rl_newline or at end of line, so set appropriately. */
|
||||
if (_rl_history_saved_point == -1 && (rl_point || rl_end))
|
||||
_rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
|
||||
@@ -582,41 +597,48 @@ rl_get_next_history (int count, int key)
|
||||
}
|
||||
|
||||
if (temp == 0)
|
||||
rl_maybe_unsave_line ();
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
rl_replace_from_history (temp, 0);
|
||||
_rl_history_set_point ();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move down to the next history line. */
|
||||
int
|
||||
rl_get_next_history (int count, int key)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (count < 0)
|
||||
return (rl_get_previous_history (-count, key));
|
||||
|
||||
if (count == 0)
|
||||
return 0;
|
||||
|
||||
rl_maybe_replace_line ();
|
||||
|
||||
r = _rl_next_history_internal (count);
|
||||
|
||||
if (r == 0)
|
||||
rl_maybe_unsave_line ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the previous item out of our interactive history, making it the current
|
||||
line. If there is no previous history, just ding. */
|
||||
int
|
||||
rl_get_previous_history (int count, int key)
|
||||
_rl_previous_history_internal (int count)
|
||||
{
|
||||
HIST_ENTRY *old_temp, *temp;
|
||||
int had_saved_line;
|
||||
|
||||
if (count < 0)
|
||||
return (rl_get_next_history (-count, key));
|
||||
|
||||
if (count == 0 || history_list () == 0)
|
||||
return 0;
|
||||
temp = old_temp = (HIST_ENTRY *)NULL;
|
||||
|
||||
/* either not saved by rl_newline or at end of line, so set appropriately. */
|
||||
if (_rl_history_saved_point == -1 && (rl_point || rl_end))
|
||||
_rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
|
||||
|
||||
/* If we don't have a line saved, then save this one. */
|
||||
had_saved_line = _rl_saved_line_for_history != 0;
|
||||
rl_maybe_save_line ();
|
||||
|
||||
/* If the current line has changed, save the changes. */
|
||||
rl_maybe_replace_line ();
|
||||
|
||||
temp = old_temp = (HIST_ENTRY *)NULL;
|
||||
while (count)
|
||||
{
|
||||
temp = previous_history ();
|
||||
@@ -634,15 +656,41 @@ rl_get_previous_history (int count, int key)
|
||||
|
||||
if (temp == 0)
|
||||
{
|
||||
if (had_saved_line == 0)
|
||||
_rl_free_saved_history_line ();
|
||||
rl_ding ();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rl_replace_from_history (temp, 0);
|
||||
_rl_history_set_point ();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the previous item out of our interactive history, making it the current
|
||||
line. If there is no previous history, just ding. */
|
||||
int
|
||||
rl_get_previous_history (int count, int key)
|
||||
{
|
||||
int had_saved_line, r;
|
||||
|
||||
if (count < 0)
|
||||
return (rl_get_next_history (-count, key));
|
||||
|
||||
if (count == 0 || history_list () == 0)
|
||||
return 0;
|
||||
|
||||
/* If we don't have a line saved, then save this one. */
|
||||
had_saved_line = _rl_saved_line_for_history != 0;
|
||||
rl_maybe_save_line ();
|
||||
|
||||
/* If the current line has changed, save the changes. */
|
||||
rl_maybe_replace_line ();
|
||||
|
||||
r = _rl_previous_history_internal (count);
|
||||
|
||||
if (r == 0 && had_saved_line == 0) /* failed to find previous history */
|
||||
_rl_free_saved_history_line ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -693,7 +741,7 @@ static int saved_history_logical_offset = -1;
|
||||
#define HISTORY_FULL() (history_is_stifled () && history_length >= history_max_entries)
|
||||
|
||||
static int
|
||||
set_saved_history ()
|
||||
set_saved_history (void)
|
||||
{
|
||||
int absolute_offset, count;
|
||||
|
||||
@@ -762,7 +810,10 @@ _rl_set_insert_mode (int im, int force)
|
||||
_rl_set_cursor (im, force);
|
||||
#endif
|
||||
|
||||
RL_UNSETSTATE (RL_STATE_OVERWRITE);
|
||||
rl_insert_mode = im;
|
||||
if (rl_insert_mode == RL_IM_OVERWRITE)
|
||||
RL_SETSTATE (RL_STATE_OVERWRITE);
|
||||
}
|
||||
|
||||
/* Toggle overwrite mode. A positive explicit argument selects overwrite
|
||||
|
||||
Reference in New Issue
Block a user