diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index f051ce31..a306fa15 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -6103,3 +6103,63 @@ bashline.c - name_is_acceptable: allow FIGNORE suffixes to match the entire pathname like tcsh does instead of requiring a non-empty prefix. From Emanuele Torre + + 4/23 + ---- +lib/readline/misc.c + - _rl_unsave_line: new function, takes a HIST_ENTRY * as an argument, + generalized rl_maybe_unsave_line + - _rl_alloc_saved_line: allocate a new HIST_ENTRY *, populate it like + rl_saved_line_for_history + - _rl_free_saved_line: free a saved HIST_ENTRY * + - _rl_free_saved_history_line: call _rl_free_saved_line + - _rl_previous_history_internal: new function, internals of + rl_get_previous_history; change rl_get_previous_history to call it + +lib/readline/history.h + - HIST_ENTRY_DEFINED: define sentinel if HIST_ENTRY struct defined + +lib/readline/rlprivate.h + - _rl_alloc_saved_line,_rl_free_saved_line,_rl_unsave_line: new extern + function definitions + - _rl_free_saved_search_line: new extern definition + +lib/readline/search.c + - _rl_saved_line_for_search: use private storage to save current line, + avoid clashes with rl_saved_line_for_history + - _rl_free_saved_search_line,_rl_unsave_saved_search_line: new functions + to manage _rl_saved_line_for_search + - noninc_dosearch,_rl_nsearch_abort: clean up _rl_saved_line_for_search + instead of rl_saved_line_for_history + - rl_history_search_internal: allocate private _rl_saved_line_for_search; + unsave or free it as appropriate + - _rl_history_search_reinit: free up any _rl_saved_line_for_search just + in case + +lib/readline/vi_mode.c + - rl_vi_search: free _rl_saved_line_for_search, since that's what the + non-incremental search functions use now + - rl_domove_read_callback: if we read a numeric argument, then a motion + character, make sure the motion character is valid before returning + it and going on + From a report by minipython <599192367@qq.com> + + 4/27 + ---- +lib/readline/display.c + - _rl_move_cursor_relative: when checking to see whether data is within + the invisible line, make sure to stay within the invisible line + line break boundaries + +lib/readline/search.c + - dispose_saved_search_line: new function, either unsave the saved + search line (if we're not at the end of the history) or free it + (if we are). Needs to be immediately followed by call to + make_history_line_current, which resets rl_undo_list + - make_history_line_current: change strategy: rely on callers to + manage _rl_saved_line_for_search and rl_undo_list; just copy the + data from the passed history entry into the line buffer and reset + rl_undo_list + - noninc_dosearch,rl_history_search_internal: call dispose_saved_search_line + before calling make_history_line_current + diff --git a/lib/readline/display.c b/lib/readline/display.c index bed86490..b390fc9b 100644 --- a/lib/readline/display.c +++ b/lib/readline/display.c @@ -2831,7 +2831,7 @@ _rl_move_cursor_relative (int new, const char *data, const char *dataf) (prompt_last_invisible) in the last line. IN_INVISLINE is the offset of DATA in invisible_line */ in_invisline = 0; - if (data > invisible_line && data < invisible_line+inv_lbreaks[_rl_inv_botlin+1]) + if (data > invisible_line && _rl_inv_botlin < inv_lbsize && data < invisible_line+inv_lbreaks[_rl_inv_botlin+1]) in_invisline = data - invisible_line; /* Use NEW when comparing against the last invisible character in the diff --git a/lib/readline/history.h b/lib/readline/history.h index 49e1bf29..0f275a8d 100644 --- a/lib/readline/history.h +++ b/lib/readline/history.h @@ -1,6 +1,6 @@ /* history.h -- the names of functions that you can call in history. */ -/* Copyright (C) 1989-2022 Free Software Foundation, Inc. +/* Copyright (C) 1989-2023 Free Software Foundation, Inc. This file contains the GNU History Library (History), a set of routines for managing the text of previously typed lines. @@ -50,6 +50,10 @@ typedef struct _hist_entry { histdata_t data; } HIST_ENTRY; +#ifndef HIST_ENTRY_DEFINED +# define HIST_ENTRY_DEFINED +#endif + /* Size of the history-library-managed space in history entry HS. */ #define HISTENT_BYTES(hs) (strlen ((hs)->line) + strlen ((hs)->timestamp)) diff --git a/lib/readline/misc.c b/lib/readline/misc.c index e1ccecae..6e9e0305 100644 --- a/lib/readline/misc.c +++ b/lib/readline/misc.c @@ -1,6 +1,6 @@ /* misc.c -- miscellaneous bindable readline functions. */ -/* 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. @@ -307,9 +307,7 @@ 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; + _rl_free_saved_history_line (); _rl_history_search_pos = -99; /* some random invalid history position */ } @@ -352,60 +350,71 @@ rl_maybe_replace_line (void) 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) { - if (_rl_saved_line_for_history) - { - UNDO_LIST *sentinel; + _rl_free_saved_line (_rl_saved_line_for_history); + _rl_saved_line_for_history = (HIST_ENTRY *)NULL; - sentinel = (UNDO_LIST *)_rl_saved_line_for_history->data; - - /* We should only free `data' if it's not the current rl_undo_list and - it's not the `data' member in a history entry somewhere. We have to - free it separately because only the callers know it's an undo list. */ - if (sentinel && sentinel != rl_undo_list && _hs_search_history_data ((histdata_t *)sentinel) < 0) - _rl_free_undo_list (sentinel); - - _rl_free_history_entry (_rl_saved_line_for_history); - _rl_saved_line_for_history = (HIST_ENTRY *)NULL; - } return 0; } @@ -563,20 +572,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; @@ -591,41 +591,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 (); @@ -643,15 +650,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; } diff --git a/lib/readline/rlprivate.h b/lib/readline/rlprivate.h index 573724df..c3e43e39 100644 --- a/lib/readline/rlprivate.h +++ b/lib/readline/rlprivate.h @@ -369,7 +369,13 @@ extern int _rl_arg_callback (_rl_arg_cxt); extern void _rl_reset_argument (void); extern void _rl_start_using_history (void); +#if defined (HIST_ENTRY_DEFINED) +extern HIST_ENTRY *_rl_alloc_saved_line (void); +extern void _rl_free_saved_line (HIST_ENTRY *); +extern void _rl_unsave_line (HIST_ENTRY *); +#endif extern int _rl_free_saved_history_line (void); + extern void _rl_set_insert_mode (int, int); extern void _rl_revert_previous_lines (void); @@ -406,6 +412,8 @@ extern int _rl_restore_tty_signals (void); extern int _rl_nsearch_callback (_rl_search_cxt *); extern int _rl_nsearch_cleanup (_rl_search_cxt *, int); +extern void _rl_free_saved_search_line (void); + /* signals.c */ extern void _rl_signal_handler (int); diff --git a/lib/readline/search.c b/lib/readline/search.c index 965722ba..810ab419 100644 --- a/lib/readline/search.c +++ b/lib/readline/search.c @@ -1,6 +1,6 @@ /* search.c - code for non-incremental searching in emacs and vi modes. */ -/* Copyright (C) 1992-2022 Free Software Foundation, Inc. +/* Copyright (C) 1992-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. @@ -55,6 +55,8 @@ _rl_search_cxt *_rl_nscxt = 0; +static HIST_ENTRY *_rl_saved_line_for_search; + static char *noninc_search_string = (char *) NULL; static int noninc_history_pos; @@ -78,23 +80,57 @@ static _rl_search_cxt *_rl_nsearch_init (int, int); static void _rl_nsearch_abort (_rl_search_cxt *); static int _rl_nsearch_dispatch (_rl_search_cxt *, int); +void +_rl_free_saved_search_line (void) +{ + if (_rl_saved_line_for_search) + _rl_free_saved_line (_rl_saved_line_for_search); + _rl_saved_line_for_search = (HIST_ENTRY *)NULL; +} + +static inline void +_rl_unsave_saved_search_line (void) +{ + if (_rl_saved_line_for_search) + _rl_unsave_line (_rl_saved_line_for_search); + _rl_saved_line_for_search = (HIST_ENTRY *)NULL; +} + +/* We're going to replace the undo list with the one created by inserting + the matching line we found, so we want to free rl_undo_list if it's not + from a history entry. We assume the undo list does not come from a + history entry if we are at the end of the history, entering a new line. + + The call to rl_maybe_replace_line() has already ensured that any undo + list pointing to a history entry has already been saved back to the + history and set rl_undo_list to NULL. */ + +static void +dispose_saved_search_line (void) +{ + UNDO_LIST *xlist; + + if (_hs_at_end_of_history () == 0) + _rl_unsave_saved_search_line (); + else if (_rl_saved_line_for_search) + { + xlist = _rl_saved_line_for_search ? (UNDO_LIST *)_rl_saved_line_for_search->data : 0; + if (xlist) + _rl_free_undo_list (xlist); + _rl_saved_line_for_search->data = 0; + _rl_free_saved_search_line (); + } +} + /* Make the data from the history entry ENTRY be the contents of the current line. This doesn't do anything with rl_point; the caller must set it. */ static void make_history_line_current (HIST_ENTRY *entry) { - UNDO_LIST *xlist; - - xlist = _rl_saved_line_for_history ? (UNDO_LIST *)_rl_saved_line_for_history->data : 0; - /* At this point, rl_undo_list points to a private search string list. */ - if (rl_undo_list && rl_undo_list != (UNDO_LIST *)entry->data && rl_undo_list != xlist && - _hs_search_history_data ((histdata_t *)rl_undo_list) < 0) - rl_free_undo_list (); - rl_undo_list = 0; /* XXX */ - /* Now we create a new undo list with a single insert for this text. WE DON'T CHANGE THE ORIGINAL HISTORY ENTRY UNDO LIST */ + rl_undo_list = 0; /* XXX */ _rl_replace_text (entry->line, 0, rl_end); _rl_fix_point (1); #if defined (VI_MODE) @@ -105,15 +141,6 @@ make_history_line_current (HIST_ENTRY *entry) current editing buffer. */ rl_free_undo_list (); #endif - - /* This will need to free the saved undo list associated with the original - (pre-search) line buffer. - XXX - look at _rl_free_saved_history_line and consider calling it if - rl_undo_list != xlist (or calling rl_free_undo list directly on - _rl_saved_line_for_history->data) */ - if (_rl_saved_line_for_history) - _rl_free_history_entry (_rl_saved_line_for_history); - _rl_saved_line_for_history = (HIST_ENTRY *)NULL; } /* Search the history list for STRING starting at absolute history position @@ -185,7 +212,7 @@ noninc_dosearch (char *string, int dir, int flags) if (pos == -1) { /* Search failed, current history position unchanged. */ - rl_maybe_unsave_line (); + _rl_unsave_saved_search_line (); rl_clear_message (); rl_point = 0; rl_ding (); @@ -194,6 +221,10 @@ noninc_dosearch (char *string, int dir, int flags) noninc_history_pos = pos; + /* We're committed to making the line we found the current contents of + rl_line_buffer. We can dispose of _rl_saved_line_for_search. */ + dispose_saved_search_line (); + oldpos = where_history (); history_set_pos (noninc_history_pos); entry = current_history (); /* will never be NULL after successful search */ @@ -240,7 +271,10 @@ _rl_nsearch_init (int dir, int pchar) cxt->direction = dir; cxt->history_pos = cxt->save_line; - rl_maybe_save_line (); + /* If the current line has changed, put it back into the history if necessary. */ + rl_maybe_replace_line (); + + _rl_saved_line_for_search = _rl_alloc_saved_line (); /* Clear the undo list, since reading the search string should create its own undo list, and the whole list will end up being freed when we @@ -276,7 +310,7 @@ _rl_nsearch_cleanup (_rl_search_cxt *cxt, int r) static void _rl_nsearch_abort (_rl_search_cxt *cxt) { - rl_maybe_unsave_line (); + _rl_unsave_saved_search_line (); rl_point = cxt->save_point; rl_mark = cxt->save_mark; rl_restore_prompt (); @@ -380,6 +414,7 @@ _rl_nsearch_dosearch (_rl_search_cxt *cxt) { if (noninc_search_string == 0) { + _rl_free_saved_search_line (); rl_ding (); rl_restore_prompt (); RL_UNSETSTATE (RL_STATE_NSEARCH); @@ -393,12 +428,17 @@ _rl_nsearch_dosearch (_rl_search_cxt *cxt) FREE (noninc_search_string); noninc_search_string = savestring (rl_line_buffer); - /* If we don't want the subsequent undo list generated by the search + /* We don't want the subsequent undo list generated by the search matching a history line to include the contents of the search string, - we need to clear rl_line_buffer here. For now, we just clear the - undo list generated by reading the search string. (If the search - fails, the old undo list will be restored by rl_maybe_unsave_line.) */ + so we need to clear rl_line_buffer here. If we don't want that, + change the #if 1 to an #if 0 below. We clear the undo list + generated by reading the search string. (If the search fails, the + old undo list will be restored by _rl_unsave_line.) */ + rl_free_undo_list (); +#if 1 + rl_line_buffer[rl_point = rl_end = 0] = '\0'; +#endif } rl_restore_prompt (); @@ -534,11 +574,12 @@ rl_history_search_internal (int count, int dir) { HIST_ENTRY *temp; int ret, oldpos, newcol; - int had_saved_line; char *t; - had_saved_line = _rl_saved_line_for_history != 0; - rl_maybe_save_line (); + /* If the current line has changed, put it back into the history if necessary. */ + rl_maybe_replace_line (); + + _rl_saved_line_for_search = _rl_alloc_saved_line (); temp = (HIST_ENTRY *)NULL; /* Search COUNT times through the history for a line matching @@ -570,8 +611,7 @@ rl_history_search_internal (int count, int dir) /* If we didn't find anything at all, return. */ if (temp == 0) { - /* XXX - check had_saved_line here? */ - rl_maybe_unsave_line (); + _rl_unsave_saved_search_line (); rl_ding (); /* If you don't want the saved history line (last match) to show up in the line buffer after the search fails, change the #if 0 to @@ -584,12 +624,16 @@ rl_history_search_internal (int count, int dir) rl_mark = 0; } #else - rl_point = _rl_history_search_len; /* rl_maybe_unsave_line changes it */ + rl_point = _rl_history_search_len; /* _rl_unsave_line changes it */ rl_mark = rl_end; #endif return 1; } + /* We're committed to making the line we found the current contents of + rl_line_buffer. We can dispose of _rl_saved_line_for_search. */ + dispose_saved_search_line (); + /* Copy the line we found into the current line buffer. */ make_history_line_current (temp); @@ -634,7 +678,7 @@ rl_history_search_reinit (int flags) strncpy (history_search_string + sind, rl_line_buffer, rl_point); history_search_string[rl_point + sind] = '\0'; } - _rl_free_saved_history_line (); /* XXX rl_undo_list? */ + _rl_free_saved_search_line (); } /* Search forward in the history for the string of characters diff --git a/lib/readline/vi_mode.c b/lib/readline/vi_mode.c index a49edaae..762a214e 100644 --- a/lib/readline/vi_mode.c +++ b/lib/readline/vi_mode.c @@ -367,12 +367,12 @@ rl_vi_search (int count, int key) switch (key) { case '?': - _rl_free_saved_history_line (); + _rl_free_saved_search_line (); /* just in case */ rl_noninc_forward_search (count, key); break; case '/': - _rl_free_saved_history_line (); + _rl_free_saved_search_line (); rl_noninc_reverse_search (count, key); break; @@ -1340,6 +1340,13 @@ rl_domove_read_callback (_rl_vimotion_cxt *m) m->motion = 0; return -1; } + else if (member (c, vi_motion) == 0) + { + m->motion = 0; + RL_UNSETSTATE (RL_STATE_VIMOTION); + RL_UNSETSTATE (RL_STATE_NUMERICARG); + return (1); + } m->motion = c; return (rl_domove_motion_callback (m)); } @@ -1364,6 +1371,7 @@ _rl_vi_domove_callback (_rl_vimotion_cxt *m) int c, r; m->motion = c = rl_vi_domove_getchar (m); + if (c < 0) return 1; /* EOF */ r = rl_domove_read_callback (m);