]> git.ipfire.org Git - thirdparty/readline.git/commitdiff
asan updates to non-incremental search, redisplay; rework non-incremental search...
authorChet Ramey <chet.ramey@case.edu>
Thu, 27 Apr 2023 19:33:37 +0000 (15:33 -0400)
committerChet Ramey <chet.ramey@case.edu>
Thu, 27 Apr 2023 19:33:37 +0000 (15:33 -0400)
23 files changed:
display.c
doc/rltech.texi
doc/rluser.texi
examples/Makefile.in
examples/excallback.c
examples/fileman.c
examples/hist_erasedups.c
examples/hist_purgecmd.c
examples/manexamp.c
examples/rl-callbacktest.c
examples/rl-timeout.c
examples/rl.c
examples/rlcat.c
examples/rlevent.c
examples/rlptytest.c
examples/rltest.c
histexpand.c
history.h
misc.c
rlprivate.h
search.c
text.c
vi_mode.c

index fb10c60a3fe872faa54a503721ab0653ddac83ae..b390fc9b110688a61faf604442fedc004b0015b3 100644 (file)
--- a/display.c
+++ b/display.c
@@ -1126,19 +1126,6 @@ rl_redisplay (void)
 
              olen = sprintf (obuf, "\\%o", c);
          
-             if (lpos + olen >= _rl_screenwidth)
-               {
-                 temp = _rl_screenwidth - lpos;
-                 CHECK_INV_LBREAKS ();
-                 inv_lbreaks[++newlines] = out + temp;
-#if defined (HANDLE_MULTIBYTE)
-                 line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn;
-#endif
-                 lpos = olen - temp;
-               }
-             else
-               lpos += olen;
-
              for (temp = 0; temp < olen; temp++)
                {
                  invis_addc (&out, obuf[temp], cur_face);
@@ -2043,6 +2030,8 @@ update_line (char *old, char *old_face, char *new, char *new_face, int current_l
 #if defined (HANDLE_MULTIBYTE)
   /* Find the last character that is the same between the two lines.  This
      bounds the region that needs to change. */
+  /* In this case, `last character' means the one farthest from the end of
+     the line. */
   if (mb_cur_max > 1 && rl_byte_oriented == 0)
     {
       ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY);
@@ -2059,7 +2048,7 @@ update_line (char *old, char *old_face, char *new, char *new_face, int current_l
                *olsf != *nlsf)
            break;
 
-         if (*ols == ' ')
+         if (*ols != ' ')
            wsatend = 0;
 
          ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY);
@@ -2128,7 +2117,23 @@ update_line (char *old, char *old_face, char *new, char *new_face, int current_l
       /* We have moved up to a new screen line.  This line may or may not have
          invisible characters on it, but we do our best to recalculate
          visible_wrap_offset based on what we know. */
-      if (current_line == 0)
+       /* This first clause handles the case where the prompt has been
+         recalculated (e.g., by rl_message) but the old prompt is still on
+         the visible line because we haven't overwritten it yet. We want
+         to somehow use the old prompt information, but we only want to do
+         this once. */
+      if (current_line == 0 && saved_local_prompt && old[0] == saved_local_prompt[0] && memcmp (old, saved_local_prompt, saved_local_length) == 0)
+       visible_wrap_offset = saved_invis_chars_first_line;
+      /* This clause handles the opposite: the prompt has been restored (e.g.,
+        by rl_clear_message) but the old saved_local_prompt (now NULL, so we
+        can't directly check it) is still on the visible line because we
+        haven't overwritten it yet. We guess that there aren't any invisible
+        characters in any of the prompts we put in with rl_message */
+      else if (current_line == 0 && local_prompt && new[0] == local_prompt[0] &&
+                (memcmp (new, local_prompt, local_prompt_len) == 0) &&
+                (memcmp (old, local_prompt, local_prompt_len) != 0))
+       visible_wrap_offset = 0;
+      else if (current_line == 0)
        visible_wrap_offset = prompt_invis_chars_first_line;    /* XXX */
 #if 0          /* XXX - not yet */
       else if (current_line == prompt_last_screen_line && wrap_offset > prompt_invis_chars_first_line)
@@ -2826,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
index db38a3110a349a447c567276a91d3b3a9d6d6192..5aa045326c99437dc28e7bf4e85e10e86fdcf954 100644 (file)
@@ -7,7 +7,7 @@ This document describes the GNU Readline Library, a utility for aiding
 in the consistency of user interface across discrete programs that need
 to provide a command line interface.
 
-Copyright (C) 1988--2022 Free Software Foundation, Inc.
+Copyright (C) 1988--2023 Free Software Foundation, Inc.
 
 Permission is granted to make and distribute verbatim copies of
 this manual provided the copyright notice and this permission notice
@@ -2643,7 +2643,7 @@ com_list (char *arg)
   if (!arg)
     arg = "";
 
-  sprintf (syscom, "ls -FClg %s", arg);
+  snprintf (syscom, sizeof (syscom), "ls -FClg %s", arg);
   return (system (syscom));
 @}
 
@@ -2655,9 +2655,9 @@ com_view (char *arg)
 
 #if defined (__MSDOS__)
   /* more.com doesn't grok slashes in pathnames */
-  sprintf (syscom, "less %s", arg);
+  snprintf (syscom, sizeof (syscom), "less %s", arg);
 #else
-  sprintf (syscom, "more %s", arg);
+  snprintf (syscom, sizeof (syscom), "more %s", arg);
 #endif
   return (system (syscom));
 @}
index bb1a24f5da60b350c323382d4f85e252b5fc9713..36e8a38750ba2498cc8f977d27ffd96ad546e004 100644 (file)
@@ -2106,14 +2106,25 @@ be completed, and two to modify the completion as it is happening.
 @item compgen
 @btindex compgen
 @example
-@code{compgen [@var{option}] [@var{word}]}
+@code{compgen [-V @var{varname}] [@var{option}] [@var{word}]}
 @end example
 
 Generate possible completion matches for @var{word} according to
 the @var{option}s, which may be any option accepted by the
 @code{complete}
-builtin with the exception of @option{-p} and @option{-r}, and write
-the matches to the standard output.
+builtin with the exceptions of
+@option{-p},
+@option{-r},
+@option{-D},
+@option{-E},
+and
+@option{-I},
+and write the matches to the standard output.
+
+If the @option{-V} option is supplied, @code{compgen} stores the generated
+completions into the indexed array variable @var{varname} instead of writing
+them to the standard output.
+
 When using the @option{-F} or @option{-C} options, the various shell variables
 set by the programmable completion facilities, while available, will not
 have useful values.
@@ -2130,9 +2141,9 @@ matches were generated.
 @item complete
 @btindex complete
 @example
-@code{complete [-abcdefgjksuv] [-o @var{comp-option}] [-DEI] [-A @var{action}] [-G @var{globpat}]
-[-W @var{wordlist}] [-F @var{function}] [-C @var{command}] [-X @var{filterpat}]
-[-P @var{prefix}] [-S @var{suffix}] @var{name} [@var{name} @dots{}]}
+@code{complete [-abcdefgjksuv] [-o @var{comp-option}] [-DEI] [-A @var{action}]
+[-G @var{globpat}] [-W @var{wordlist}] [-F @var{function}] [-C @var{command}]
+[-X @var{filterpat}] [-P @var{prefix}] [-S @var{suffix}] @var{name} [@var{name} @dots{}]}
 @code{complete -pr [-DEI] [@var{name} @dots{}]}
 @end example
 
@@ -2338,7 +2349,14 @@ case, any completion not matching @var{filterpat} is removed.
 @end table
 
 The return value is true unless an invalid option is supplied, an option
-other than @option{-p} or @option{-r} is supplied without a @var{name}
+other than
+@option{-p},
+@option{-r},
+@option{-D},
+@option{-E},
+or
+@option{-I}
+is supplied without a @var{name}
 argument, an attempt is made to remove a completion specification for
 a @var{name} for which no specification exists, or
 an error occurs adding a completion specification.
index 291c6b7adf8256de95e0ab47a806c199bd284cc3..dc1aba31b035d0a8989e19eb095b4393075e5dc7 100644 (file)
@@ -164,6 +164,7 @@ distclean maintainer-clean: clean
        $(RM) Makefile
 
 fileman.o: fileman.c
+manexamp.o: manexamp.c
 rltest.o: rltest.c
 rltest2.o: rltest2.c
 rl.o: rl.c
@@ -179,6 +180,7 @@ rl-callbacktest.o: rl-callbacktest.c
 rl-timeout.o: rl-timeout.c
 
 fileman.o: $(top_srcdir)/readline.h
+manexamp.o: $(top_srcdir)/readline.h
 rltest.o: $(top_srcdir)/readline.h
 rltest2.o: $(top_srcdir)/readline.h $(top_srcdir)/history.h
 rl.o: $(top_srcdir)/readline.h
index 923c9238b6ecaf9d799171ec6aa9002f4089c1a5..04ecb140828fcf8e46a4b4ab27320359c0524e68 100644 (file)
@@ -102,7 +102,7 @@ cc_t     old_vtime;
 struct termios term;
 
 int 
-main()
+main(int c, char **v)
 {
     fd_set fds;
 
index 2a8b097ad146b74abce85369c906a6cf426280ac..df579450deb1423a42e126e37e1c8214b6ec3798 100644 (file)
@@ -1,6 +1,6 @@
 /* fileman.c - file manager example for readline library. */
 
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2009,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.
 #  include <readline/history.h>
 #endif
 
-extern char *xmalloc PARAMS((size_t));
+extern char *xmalloc (size_t);
 
-void initialize_readline PARAMS((void));
-void too_dangerous PARAMS((char *));
+void initialize_readline (void);
+void too_dangerous (char *);
 
-int execute_line PARAMS((char *));
-int valid_argument PARAMS((char *, char *));
+int execute_line (char *);
+int valid_argument (char *, char *);
 
 /* The names of functions that actually do the manipulation. */
-int com_list PARAMS((char *));
-int com_view PARAMS((char *));
-int com_rename PARAMS((char *));
-int com_stat PARAMS((char *));
-int com_pwd PARAMS((char *));
-int com_delete PARAMS((char *));
-int com_help PARAMS((char *));
-int com_cd PARAMS((char *));
-int com_quit PARAMS((char *));
+int com_list (char *);
+int com_view (char *);
+int com_rename (char *);
+int com_stat (char *);
+int com_pwd (char *);
+int com_delete (char *);
+int com_help (char *);
+int com_cd (char *);
+int com_quit (char *);
 
 /* A structure which contains information on the commands this program
    can understand. */
@@ -105,8 +105,11 @@ COMMAND commands[] = {
 };
 
 /* Forward declarations. */
-char *stripwhite ();
-COMMAND *find_command ();
+char *dupstr (char *);
+int execute_line (char *);
+char *stripwhite (char *);
+
+COMMAND *find_command (char *);
 
 /* The name of this program, as taken from argv[0]. */
 char *progname;
@@ -115,8 +118,7 @@ char *progname;
 int done;
 
 char *
-dupstr (s)
-     char *s;
+dupstr (char *s)
 {
   char *r;
 
@@ -125,45 +127,9 @@ dupstr (s)
   return (r);
 }
 
-int
-main (argc, argv)
-     int argc;
-     char **argv;
-{
-  char *line, *s;
-
-  progname = argv[0];
-
-  initialize_readline ();      /* Bind our completer. */
-
-  /* Loop reading and executing lines until the user quits. */
-  for ( ; done == 0; )
-    {
-      line = readline ("FileMan: ");
-
-      if (!line)
-        break;
-
-      /* Remove leading and trailing whitespace from the line.
-         Then, if there is anything left, add it to the history list
-         and execute it. */
-      s = stripwhite (line);
-
-      if (*s)
-        {
-          add_history (s);
-          execute_line (s);
-        }
-
-      free (line);
-    }
-  exit (0);
-}
-
 /* Execute a command line. */
 int
-execute_line (line)
-     char *line;
+execute_line (char *line)
 {
   register int i;
   COMMAND *command;
@@ -202,8 +168,7 @@ execute_line (line)
 /* Look up NAME as the name of a command, and return a pointer to that
    command.  Return a NULL pointer if NAME isn't a command name. */
 COMMAND *
-find_command (name)
-     char *name;
+find_command (char *name)
 {
   register int i;
 
@@ -217,8 +182,7 @@ find_command (name)
 /* Strip whitespace from the start and end of STRING.  Return a pointer
    into STRING. */
 char *
-stripwhite (string)
-     char *string;
+stripwhite (char *string)
 {
   register char *s, *t;
 
@@ -242,14 +206,14 @@ stripwhite (string)
 /*                                                                  */
 /* **************************************************************** */
 
-char *command_generator PARAMS((const char *, int));
-char **fileman_completion PARAMS((const char *, int, int));
+char *command_generator (const char *, int);
+char **fileman_completion (const char *, int, int);
 
 /* Tell the GNU Readline library how to complete.  We want to try to complete
    on command names if this is the first word in the line, or on filenames
    if not. */
 void
-initialize_readline ()
+initialize_readline (void)
 {
   /* Allow conditional parsing of the ~/.inputrc file. */
   rl_readline_name = "FileMan";
@@ -264,9 +228,7 @@ initialize_readline ()
    in case we want to do some simple parsing.  Return the array of matches,
    or NULL if there aren't any. */
 char **
-fileman_completion (text, start, end)
-     const char *text;
-     int start, end;
+fileman_completion (const char *text, int start, int end)
 {
   char **matches;
 
@@ -285,9 +247,7 @@ fileman_completion (text, start, end)
    to start from scratch; without any state (i.e. STATE == 0), then we
    start at the top of the list. */
 char *
-command_generator (text, state)
-     const char *text;
-     int state;
+command_generator (const char *text, int state)
 {
   static int list_index, len;
   char *name;
@@ -332,7 +292,7 @@ com_list (arg)
   if (!arg)
     arg = "";
 
-  sprintf (syscom, "ls -FClg %s", arg);
+  snprintf (syscom, sizeof (syscom), "ls -FClg %s", arg);
   return (system (syscom));
 }
 
@@ -345,9 +305,9 @@ com_view (arg)
 
 #if defined (__MSDOS__)
   /* more.com doesn't grok slashes in pathnames */
-  sprintf (syscom, "less %s", arg);
+  snprintf (syscom, sizeof (syscom), "less %s", arg);
 #else
-  sprintf (syscom, "more %s", arg);
+  snprintf (syscom, sizeof (syscom), "more %s", arg);
 #endif
   return (system (syscom));
 }
@@ -504,3 +464,36 @@ valid_argument (caller, arg)
 
   return (1);
 }
+
+int
+main (int argc, char **argv)
+{
+  char *line, *s;
+
+  progname = argv[0];
+
+  initialize_readline ();      /* Bind our completer. */
+
+  /* Loop reading and executing lines until the user quits. */
+  for ( ; done == 0; )
+    {
+      line = readline ("FileMan: ");
+
+      if (!line)
+        break;
+
+      /* Remove leading and trailing whitespace from the line.
+         Then, if there is anything left, add it to the history list
+         and execute it. */
+      s = stripwhite (line);
+
+      if (*s)
+        {
+          add_history (s);
+          execute_line (s);
+        }
+
+      free (line);
+    }
+  exit (0);
+}
index f820eba6aaab4db0c1835dde183c9f85532e7bd5..717bb7e23bd622e8ddcb39f9455df87a2e179c2c 100644 (file)
@@ -1,6 +1,6 @@
 /* hist_erasedups -- remove all duplicate entries from history file */
 
-/* Copyright (C) 2011 Free Software Foundation, Inc.
+/* Copyright (C) 2011,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.
 int hist_erasedups (void);
 
 static void
-usage()
+usage(void)
 {
   fprintf (stderr, "hist_erasedups: usage: hist_erasedups [-t] [filename]\n");
   exit (2);
 }
 
 int
-main (argc, argv)
-     int argc;
-     char **argv;
+main (int argc, char **argv)
 {
   char *fn;
   int r;
@@ -94,7 +92,7 @@ main (argc, argv)
 }
 
 int
-hist_erasedups ()
+hist_erasedups (void)
 {
   int r, n;
   HIST_ENTRY *h, *temp;
index 7992d810dd00c96fa1c6eecb1a8544b1624dfa56..3adb699b735e2c9a32880a2a5b92ec04cb7b189c 100644 (file)
@@ -1,7 +1,7 @@
 /* hist_purgecmd -- remove all instances of command or pattern from history
    file */
 
-/* Copyright (C) 2011 Free Software Foundation, Inc.
+/* Copyright (C) 2011,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.
 int hist_purgecmd (char *, int);
 
 static void
-usage()
+usage(void)
 {
   fprintf (stderr, "hist_purgecmd: usage: hist_purgecmd [-r] [-t] [-f filename] command-spec\n");
   exit (2);
 }
 
 int
-main (argc, argv)
-     int argc;
-     char **argv;
+main (int argc, char **argv)
 {
   char *fn;
   int r, flags;
@@ -109,9 +107,7 @@ main (argc, argv)
 }
 
 int
-hist_purgecmd (cmd, flags)
-     char *cmd;
-     int flags;
+hist_purgecmd (char *cmd, int flags)
 {
   int r, n, rflags;
   HIST_ENTRY *temp;
index 351c6285ed7ecc8bf65bcd574189da65264452b6..c8e11d5c83a76ea812d052eb91e04517d42d8800 100644 (file)
@@ -1,6 +1,6 @@
 /* manexamp.c -- The examples which appear in the documentation are here. */
 
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2009,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.
    You should have received a copy of the GNU General Public License
    along with Readline.  If not, see <http://www.gnu.org/licenses/>.
 */
+#if defined (HAVE_CONFIG_H)
+#  include <config.h>
+#endif
 
+#ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+#endif
+
+
+#include <stdlib.h>
 #include <stdio.h>
-#include <readline/readline.h>
+
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+   
+#include <locale.h>
+
+#ifndef errno
+extern int errno;
+#endif
+
+#if defined (READLINE_LIBRARY)
+#  include "readline.h"
+#  include "history.h"
+#else
+#  include <readline/readline.h>
+#  include <readline/history.h>
+#endif
 
 /* **************************************************************** */
 /*                                                                  */
@@ -33,7 +59,7 @@ static char *line_read = (char *)NULL;
 
 /* Read a string, and return a pointer to it.  Returns NULL on EOF. */
 char *
-rl_gets ()
+rl_gets (void)
 {
   /* If the buffer has already been allocated, return the memory
      to the free pool. */
@@ -60,10 +86,11 @@ rl_gets ()
 /* **************************************************************** */
 
 /* Invert the case of the COUNT following characters. */
-invert_case_line (count, key)
-     int count, key;
+int
+invert_case_line (int count, int key)
 {
-  register int start, end;
+  int start, end;
+  int direction;
 
   start = rl_point;
 
@@ -92,7 +119,7 @@ invert_case_line (count, key)
     }
 
   if (start == end)
-    return;
+    return 0;
 
   /* Tell readline that we are modifying the line, so save the undo
      information. */
@@ -108,4 +135,5 @@ invert_case_line (count, key)
 
   /* Move point to on top of the last character changed. */
   rl_point = end - direction;
+  return 0;
 }
index 7febacd14c47f69ddc9f71cfbc2d6e9b6791b8b8..269ed2e9d317ab3c4937ba7f50fa9cb0c91a884e 100644 (file)
@@ -1,7 +1,9 @@
 /* Standard include files. stdio.h is required. */
+#include <errno.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <string.h>
+#include <unistd.h>
+#include <locale.h>
 
 /* Used for select(2) */
 #include <sys/types.h>
 
 #include <signal.h>
 
-#include <errno.h>
 #include <stdio.h>
 
-#include <locale.h>
-
 /* Standard readline include files. */
-#if defined (READLINE_LIBRARY)
-#  include "readline.h"
-#  include "history.h"
-#else
-#  include <readline/readline.h>
-#  include <readline/history.h>
-#endif
-
-extern int errno;
+#include "readline.h"
+#include "history.h"
 
 static void cb_linehandler (char *);
-static void signandler (int);
+static void sigwinch_handler (int);
+static void sigint_handler (int);
 
-int running, sigwinch_received;
+int running;
+int sigwinch_received;
+int sigint_received;
 const char *prompt = "rltest$ ";
 
 /* Handle SIGWINCH and window size changes when readline is not active and
    reading a character. */
 static void
-sighandler (int sig)
+sigwinch_handler (int sig)
 {
   sigwinch_received = 1;
 }
 
+/* Handle SIGWINCH and window size changes when readline is not active and
+   reading a character. */
+static void
+sigint_handler (int sig)
+{
+  sigint_received = 1;
+}
+
 /* Callback function called for each line when accept-line executed, EOF
    seen, or EOF character read.  This sets a flag and returns; it could
    also call exit(3). */
@@ -52,8 +55,8 @@ cb_linehandler (char *line)
         printf ("\n");
       printf ("exit\n");
       /* This function needs to be called to reset the terminal settings,
-        and calling it from the line handler keeps one extra prompt from
-        being displayed. */
+         and calling it from the line handler keeps one extra prompt from
+         being displayed. */
       rl_callback_handler_remove ();
 
       running = 0;
@@ -61,23 +64,45 @@ cb_linehandler (char *line)
   else
     {
       if (*line)
-       add_history (line);
+        add_history (line);
       printf ("input line: %s\n", line);
       free (line);
     }
 }
 
+int count = 2;
+
+static int
+my_getc (FILE *stream)
+{
+  if (--count == 0)
+    {
+      kill (getpid (), SIGINT);
+    }
+
+  int ch = rl_getc (stream);
+
+  return ch;
+}
+
+
 int
 main (int c, char **v)
 {
   fd_set fds;
   int r;
 
+  /* Set the default locale values according to environment variables. */
   setlocale (LC_ALL, "");
 
-  /* Handle SIGWINCH */
-  signal (SIGWINCH, sighandler);
-  
+  /* Handle window size changes when readline is not active and reading
+     characters. */
+  signal (SIGWINCH, sigwinch_handler);
+
+  signal (SIGINT, sigint_handler);
+
+  rl_getc_function = my_getc;
+
   /* Install the line handler. */
   rl_callback_handler_install (prompt, cb_linehandler);
 
@@ -89,25 +114,35 @@ main (int c, char **v)
   while (running)
     {
       FD_ZERO (&fds);
-      FD_SET (fileno (rl_instream), &fds);    
+      FD_SET (fileno (rl_instream), &fds);
 
       r = select (FD_SETSIZE, &fds, NULL, NULL, NULL);
       if (r < 0 && errno != EINTR)
-       {
-         perror ("rltest: select");
-         rl_callback_handler_remove ();
-         break;
-       }
+        {
+          perror ("rltest: select");
+          rl_callback_handler_remove ();
+          break;
+        }
       if (sigwinch_received)
-       {
-         rl_resize_terminal ();
-         sigwinch_received = 0;
-       }
+        {
+          rl_resize_terminal ();
+          sigwinch_received = 0;
+        }
+      if (sigint_received)
+        {
+          printf ("Quit\n");
+
+          rl_callback_handler_remove ();
+          rl_callback_handler_install (prompt, cb_linehandler);
+
+          sigint_received = 0;
+          continue;
+        }
       if (r < 0)
-       continue;
+        continue;
 
       if (FD_ISSET (fileno (rl_instream), &fds))
-       rl_callback_read_char ();
+        rl_callback_read_char ();
     }
 
   printf ("rltest: Event loop has exited\n");
index b8a24bafb94fcd8670a73ba977f8ca6eaf6e0907..81f00f5d129bf3b3ee9f343bed46bf29b32b778f 100644 (file)
@@ -56,7 +56,7 @@ const char *prompt = "rl-timeout$ ";
 /* **************************************************************** */
 
 void
-rltest_timeout_readline1 ()
+rltest_timeout_readline1 (void)
 {
   const char *temp;
 
@@ -78,14 +78,14 @@ rltest_timeout_readline1 ()
 /* **************************************************************** */
 
 static int
-timeout_handler ()
+timeout_handler (void)
 {
   printf ("timeout\n");
   return READERR;
 }
 
 void
-rltest_timeout_readline2 ()
+rltest_timeout_readline2 (void)
 {
   const char *temp;
 
@@ -134,7 +134,7 @@ cb_linehandler (char *line)
 }
 
 void
-rltest_timeout_callback1 ()
+rltest_timeout_callback1 (void)
 {
   fd_set fds;
   int r;
@@ -180,7 +180,7 @@ rltest_timeout_callback1 ()
 /* **************************************************************** */
 
 static int
-cb_timeouthandler ()
+cb_timeouthandler (void)
 {
   printf ("timeout\n");
   rl_callback_handler_remove ();
@@ -189,7 +189,7 @@ cb_timeouthandler ()
 }
 
 void
-rltest_timeout_callback2 ()
+rltest_timeout_callback2 (void)
 {
   int r;
 
index e04bbd6a58ad21385d87f7f0078642a709644d11..dd8f88d49c32ba2da5f224bc40d4612d1b6aaa02 100644 (file)
@@ -59,7 +59,7 @@ static char *progname;
 static char *deftext;
 
 static int
-set_deftext ()
+set_deftext (void)
 {
   if (deftext)
     {
@@ -71,16 +71,14 @@ set_deftext ()
 }
 
 static void
-usage()
+usage(void)
 {
   fprintf (stderr, "%s: usage: %s [-p prompt] [-u unit] [-d default] [-n nchars]\n",
                progname, progname);
 }
 
 int
-main (argc, argv)
-     int argc;
-     char **argv;
+main (int argc, char **argv)
 {
   char *temp, *prompt;
   struct stat sb;
index f1b036260cdc28211c4906fd9ec9807b91fb5b1a..419a1973a0fcd7a096fb0b215e70404e1d72e2ad 100644 (file)
@@ -4,7 +4,7 @@
  * usage: rlcat
  */
 
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2009,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.
@@ -64,21 +64,20 @@ extern int errno;
 extern int optind;
 extern char *optarg;
 
-static int stdcat();
+static int fcopy(FILE *);
+static int stdcat(int, char **);
 
 static char *progname;
 static int vflag;
 
 static void
-usage()
+usage(void)
 {
   fprintf (stderr, "%s: usage: %s [-vEVN] [filename]\n", progname, progname);
 }
 
 int
-main (argc, argv)
-     int argc;
-     char **argv;
+main (int argc, char **argv)
 {
   char *temp;
   int opt, Vflag, Nflag;
@@ -134,8 +133,7 @@ main (argc, argv)
 }
 
 static int
-fcopy(fp)
-     FILE *fp;
+fcopy(FILE *fp)
 {
   int c;
   char *x;
@@ -155,9 +153,7 @@ fcopy(fp)
 }
 
 int
-stdcat (argc, argv)
-     int argc;
-     char **argv;
+stdcat (int argc, char **argv)
 {
   int  i, fd, r;
   char *s;
index 1b7f4eb25a433f8bcd4a872313c99129f06d044d..57e4b4bc9195a041a9d9401d96d682cab8379b78 100644 (file)
@@ -69,7 +69,7 @@ static char *progname;
 static char *deftext;
 
 static int
-event_hook ()
+event_hook (void)
 {
   fprintf (stderr, "ding!\n");
   sleep (1);
@@ -77,7 +77,7 @@ event_hook ()
 }
 
 static int
-set_deftext ()
+set_deftext (void)
 {
   if (deftext)
     {
@@ -89,16 +89,14 @@ set_deftext ()
 }
 
 static void
-usage()
+usage(void)
 {
   fprintf (stderr, "%s: usage: %s [-p prompt] [-u unit] [-d default] [-n nchars]\n",
                progname, progname);
 }
 
 int
-main (argc, argv)
-     int argc;
-     char **argv;
+main (int argc, char **argv)
 {
   char *temp, *prompt;
   struct stat sb;
index d170f62ff822cc12d66319e6dec2af2633d37bb4..021a868b042060081318f219d487f53f91f4d292 100644 (file)
@@ -42,8 +42,7 @@ static int masterfd = -1;
 static int slavefd;
 
 void
-sigint (s)
-     int s;
+sigint (int s)
 {
   tty_reset (STDIN_FILENO);
   close (masterfd);
@@ -53,14 +52,13 @@ sigint (s)
 }
 
 void
-sigwinch (s)
-     int s;
+sigwinch (int s)
 {
   rl_resize_terminal ();
 }
 
 static int 
-user_input()
+user_input(void)
 {
   int size;
   const int MAX = 1024;
@@ -78,7 +76,7 @@ user_input()
 }
 
 static int 
-readline_input()
+readline_input(void)
 {
   const int MAX = 1024;
   char *buf = (char *)malloc(MAX+1);
@@ -124,7 +122,7 @@ rlctx_send_user_command(char *line)
 }
 
 static void 
-custom_deprep_term_function ()
+custom_deprep_term_function (void)
 {
 }
 
@@ -226,9 +224,10 @@ static enum { RESET, TCBREAK } ttystate = RESET;
  * 
  * Returns: 0 on success, -1 on error
  */
-int tty_cbreak(int fd){
+int tty_cbreak(int fd)
+{
    struct termios buf;
-    int ttysavefd = -1;
+   int ttysavefd = -1;
    
    if(tcgetattr(fd, &save_termios) < 0)
       return -1;
@@ -316,7 +315,7 @@ int tty_reset(int fd)
 }
 
 int 
-main()
+main(int c, char **v)
 {
   int val;
 
index 8b7c00c8c49a0e7f071c09f1d93d818b597afd23..feab90f22a9369852241e2b893c718a7c27910b4 100644 (file)
@@ -4,7 +4,7 @@
 /*                                                                 */
 /* **************************************************************** */
 
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2009,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.
@@ -48,10 +48,8 @@ extern void exit();
 #  include <readline/history.h>
 #endif
 
-extern HIST_ENTRY **history_list ();
-
 int
-main ()
+main (int c, char **v)
 {
   char *temp, *prompt;
   int done;
index f2eb18f6421cfb6729eb31905d69e584b36dceff..db344b497f010e7130431d10a7e6cbc33e4e489e 100644 (file)
@@ -730,7 +730,7 @@ history_expand_internal (const char *string, int start, int qc, int *end_index_p
 
                /* If `&' appears in the rhs, it's supposed to be replaced
                   with the lhs. */
-               if (member ('&', subst_rhs))
+               if (subst_lhs && member ('&', subst_rhs))
                  postproc_subst_rhs ();
              }
            else
index 49e1bf294b31b39d105b17d4f047d1bbf9ad34db..0f275a8d7bb9b9e767871dead674077b52daa35b 100644 (file)
--- a/history.h
+++ b/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/misc.c b/misc.c
index e1ccecae3d5566a455144829012c928c37d67f28..6e9e03052651e91bc824c4d587167b12f1f41651 100644 (file)
--- a/misc.c
+++ b/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;
-
-      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_saved_line (_rl_saved_line_for_history);
+  _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
 
-      _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;
     }
-  return 0;
 }
 
-/* Get the previous item out of our interactive history, making it the current
-   line.  If there is no previous history, just ding. */
+/* Move down to the next history line. */
 int
-rl_get_previous_history (int count, int key)
+rl_get_next_history (int count, int key)
 {
-  HIST_ENTRY *old_temp, *temp;
-  int had_saved_line;
+  int r;
 
   if (count < 0)
-    return (rl_get_next_history (-count, key));
+    return (rl_get_previous_history (-count, key));
 
-  if (count == 0 || history_list () == 0)
+  if (count == 0)
     return 0;
 
-  /* 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;
+  rl_maybe_replace_line ();
 
-  /* 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 ();
+  r = _rl_next_history_internal (count);
 
-  /* If the current line has changed, save the changes. */
-  rl_maybe_replace_line ();
+  if (r == 0)
+    rl_maybe_unsave_line ();
+
+  return 0;
+}
+
+int
+_rl_previous_history_internal (int count)
+{
+  HIST_ENTRY *old_temp, *temp;
 
   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;
+
   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;
 }
index 5c0592b9cb07865eac0b33d62d8485d7e458d904..c3e43e398ae1eabe5753978b55b9585ecc7ae042 100644 (file)
@@ -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);
 
@@ -526,6 +534,7 @@ extern int _rl_menu_complete_prefix_first;
 /* display.c */
 extern int _rl_vis_botlin;
 extern int _rl_last_c_pos;
+extern int _rl_last_v_pos;
 extern int _rl_suppress_redisplay;
 extern int _rl_want_redisplay;
 
index 965722bac3d43fd558294d2ba2b90b39442c80ed..810ab419a338ff1a82a110ca99ea87749f0f5d4e 100644 (file)
--- a/search.c
+++ b/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/text.c b/text.c
index 62e4da2a7bb54036d377d2efd64749fa8f662246..356cac5f2b15ee1536679357ccf9aebeec2a1157 100644 (file)
--- a/text.c
+++ b/text.c
@@ -1229,11 +1229,12 @@ _rl_rubout_char (int count, int key)
       c = rl_line_buffer[--rl_point];
       rl_delete_text (rl_point, orig_point);
       /* The erase-at-end-of-line hack is of questionable merit now. */
-      if (rl_point == rl_end && ISPRINT ((unsigned char)c) && _rl_last_c_pos)
+      if (rl_point == rl_end && ISPRINT ((unsigned char)c) && _rl_last_c_pos && _rl_last_v_pos == 0)
        {
          int l;
          l = rl_character_len (c, rl_point);
-         _rl_erase_at_end_of_line (l);
+         if (_rl_last_c_pos >= l)
+           _rl_erase_at_end_of_line (l);
        }
     }
   else
index 7396e316aeff3c0f8a059d87c6ddc5a20cee1e8d..762a214e81110653b8f593526d0aa0fadfbe76c6 100644 (file)
--- a/vi_mode.c
+++ b/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;
 
@@ -1090,6 +1090,7 @@ _rl_vi_arg_dispatch (int c)
     }
   else
     {
+      rl_restore_prompt ();
       rl_clear_message ();
       rl_stuff_char (key);
       return 0;                /* done */
@@ -1320,7 +1321,7 @@ rl_domove_read_callback (_rl_vimotion_cxt *m)
   /* Readine vi motion char starting numeric argument */
   else if (_rl_digit_p (c) && RL_ISSTATE (RL_STATE_CALLBACK) && RL_ISSTATE (RL_STATE_VIMOTION) && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
     {
-      RL_SETSTATE (RL_STATE_NUMERICARG);
+      _rl_arg_init ();
       return (_rl_vi_arg_dispatch (c));
     }
 #endif
@@ -1330,7 +1331,7 @@ rl_domove_read_callback (_rl_vimotion_cxt *m)
       save = rl_numeric_arg;
       rl_numeric_arg = _rl_digit_value (c);
       rl_explicit_arg = 1;
-      RL_SETSTATE (RL_STATE_NUMERICARG);
+      _rl_arg_init ();
       rl_digit_loop1 ();
       rl_numeric_arg *= save;
       c = rl_vi_domove_getchar (m);
@@ -1339,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));
     }
@@ -1363,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);