]> git.ipfire.org Git - thirdparty/readline.git/commitdiff
change history file reading not to skip blank lines in multiline history entries... devel
authorChet Ramey <chet.ramey@case.edu>
Fri, 30 May 2025 14:14:41 +0000 (10:14 -0400)
committerChet Ramey <chet.ramey@case.edu>
Fri, 30 May 2025 14:14:41 +0000 (10:14 -0400)
13 files changed:
CHANGES
NEWS
aclocal.m4
display.c
histexpand.c
histfile.c
history.c
input.c
readline.c
search.c
shell.c
terminal.c
util.c

diff --git a/CHANGES b/CHANGES
index 03ee607bbde6e9a0857cea16c1b06c89baa69d41..8c89f1e36bce609373a9094c1f64ba1b8010ea30 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -108,6 +108,18 @@ jj. Fixes for some use-after-free of the undo list errors when stacking multiple
 kk. Fixes to ensure that completion-prefix-display-length and
     colored-completion-prefix are mutually exclusive.
 
+ll. Fixed a bug that allowed a history search to change the current history
+    list position.
+
+mm. Fixed a bug that allowed ^G to retain a saved command to execute.
+   
+nn. Updates to new export-completions command to allow filename suffixes.
+
+oo. Fixed a redisplay bug with prompts containing multiple sequences of
+    invisible characters that are longer than the screen width.
+
+pp. The history library no longer skips blank lines while it is reading a
+    multiline history entry from a history file.
 
 2. New Features in Readline
 
@@ -153,6 +165,9 @@ l. The default value for `readline-colored-completion-prefix' no longer has a
 m. There is a new bindable command, `export-completions', which writes the
    possible completions for a word to the standard output in a defined format.
 
+n. Readline can reset its idea of the screen dimensions when executing after
+   a SIGCONT.
+
 -------------------------------------------------------------------------------
 This document details the changes between this version, readline-8.2, and
 the previous version, readline-8.1.
diff --git a/NEWS b/NEWS
index 81fa52637442be77bcb368fdf4ff1047056119e9..1fc6989723814f4aed494575e4f7799cdc7dccad 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -45,6 +45,9 @@ l. The default value for `readline-colored-completion-prefix' no longer has a
 m. There is a new bindable command, `export-completions', which writes the
    possible completions for a word to the standard output in a defined format.
 
+n. Readline can reset its idea of the screen dimensions when executing after
+   a SIGCONT.
+
 -------------------------------------------------------------------------------
 This is a terse description of the new features added to readline-8.2 since
 the release of readline-8.1.
index bd598666c88fe465e74b94751f20d0c1acdf4f7a..ae2d8aec96dc31e42fdfc650069e12fda3dd946b 100644 (file)
@@ -2240,3 +2240,68 @@ else
 fi
 AC_DEFINE_UNQUOTED([FNMATCH_EQUIV_FALLBACK], [$bash_cv_fnmatch_equiv_value], [Whether fnmatch can be used for bracket equivalence classes])
 ])
+
+AC_DEFUN([BASH_FUNC_STRCHRNUL],
+[
+  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+  AC_CACHE_CHECK([whether strchrnul works],
+      [bash_cv_func_strchrnul_works],
+      [AC_RUN_IFELSE([AC_LANG_PROGRAM(
+[[
+#include <string.h>
+]],
+[[const char *buf = "abc";
+      return strchrnul (buf, 'd') != buf + 3;
+]]
+)],
+[bash_cv_func_strchrnul_works=yes], [bash_cv_func_strchrnul_works=no],
+[bash_cv_func_strchrnul_works=no]
+)])
+
+if test "$bash_cv_func_strchrnul_works" = "no"; then
+AC_LIBOBJ([strchrnul])
+fi
+])
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor 'install' (even GNU) is that you can't
+# specify the program used to strip binaries.  This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in "make install-strip", and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip".  However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
+#if test "$cross_compiling" != no; then
+  AC_CHECK_TOOL([STRIP], [strip], :)
+#fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
+])
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\    *)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+AC_SUBST([install_sh])])
index 021dc3fc7aa24136ac3a3b879db779ff722fd27a..9aa8c7b50be798be1f327004b5811e95939e2133 100644 (file)
--- a/display.c
+++ b/display.c
@@ -809,7 +809,7 @@ rl_redisplay (void)
 {
   int in, out, c, linenum, cursor_linenum;
   int inv_botlin, lb_botlin, lb_linenum, o_cpos;
-  int newlines, lpos, temp, num, prompt_lines_estimate;
+  int newlines, lpos, temp, num;
   char *prompt_this_line;
   char cur_face;
   int hl_begin, hl_end;
@@ -1014,9 +1014,6 @@ rl_redisplay (void)
      on the first and last prompt lines; change that to use
      local_prompt_invis_chars */
 
-  /* This is zero-based, used to set the newlines */
-  prompt_lines_estimate = lpos / _rl_screenwidth;
-
   /* what if lpos is already >= _rl_screenwidth before we start drawing the
      contents of the command line? */
   if (lpos >= _rl_screenwidth)
@@ -1908,7 +1905,6 @@ update_line (char *old, char *old_face, char *new, char *new_face, int current_l
          if (newwidth > 0)
            {
              int i, j;
-             char *optr;
 
              puts_face (new, new_face, newbytes);
              _rl_last_c_pos = newwidth;
index fc0008e890c85e68a6dba97f067b55f21ab27db7..085b45417c9819b0255bf1bc5eefeba065d906fe 100644 (file)
@@ -679,7 +679,7 @@ history_expand_internal (const char *string, int start, int qc, int *end_index_p
        case 's':
          {
            char *new_event;
-           int delimiter, failed, si, l_temp, ws, we;
+           int delimiter, failed, si, l_temp, we;
 
            if (c == 's')
              {
@@ -778,7 +778,6 @@ history_expand_internal (const char *string, int start, int qc, int *end_index_p
                  {
                    for (; temp[si] && fielddelim (temp[si]); si++)
                      ;
-                   ws = si;
                    we = history_tokenize_word (temp, si);
                  }
 
index 9a259146f002afa871f208366bfef5aeb1d4b305..11bdd84ba90ad30146f3e9dfc4f1069edf3db2f5 100644 (file)
@@ -182,6 +182,7 @@ history_filename (const char *filename)
   return (return_val);
 }
 
+#if defined (DEBUG)
 static char *
 history_backupfile (const char *filename)
 {
@@ -208,6 +209,7 @@ history_backupfile (const char *filename)
   ret[len+1] = '\0';
   return ret;
 }
+#endif
   
 static char *
 history_tempfile (const char *filename)
@@ -267,6 +269,7 @@ read_history_range (const char *filename, int from, int to)
   register char *line_start, *line_end, *p;
   char *input, *buffer, *bufend, *last_ts;
   int file, current_line, chars_read, has_timestamps, reset_comment_char;
+  int skipblanks, default_skipblanks;
   struct stat finfo;
   size_t file_size;
 #if defined (EFBIG)
@@ -380,6 +383,9 @@ read_history_range (const char *filename, int from, int to)
   has_timestamps = HIST_TIMESTAMP_START (buffer);
   history_multiline_entries += has_timestamps && history_write_timestamps;
 
+  /* default is to skip blank lines unless history entries are multiline */
+  default_skipblanks = history_multiline_entries == 0;
+
   /* Skip lines until we are at FROM. */
   if (has_timestamps)
     last_ts = buffer;
@@ -405,6 +411,8 @@ read_history_range (const char *filename, int from, int to)
          }
       }
 
+  skipblanks = default_skipblanks;
+
   /* If there are lines left to gobble, then gobble them now. */
   for (line_end = line_start; line_end < bufend; line_end++)
     if (*line_end == '\n')
@@ -415,10 +423,16 @@ read_history_range (const char *filename, int from, int to)
        else
          *line_end = '\0';
 
-       if (*line_start)
+       if (*line_start || skipblanks == 0)
          {
            if (HIST_TIMESTAMP_START(line_start) == 0)
              {
+               /* If we have multiline entries (default_skipblanks == 0), we
+                  don't want to skip blanks here, since we turned that on at
+                  the last timestamp line. Consider doing this even if
+                  default_skipblanks == 1 in order not to lose blank lines in
+                  commands. */
+               skipblanks = default_skipblanks;
                if (last_ts == NULL && history_length > 0 && history_multiline_entries)
                  _hs_append_history_line (history_length - 1, line_start);
                else
@@ -433,6 +447,9 @@ read_history_range (const char *filename, int from, int to)
              {
                last_ts = line_start;
                current_line--;
+               /* Even if we're not skipping blank lines by default, we want
+                  to skip leading blank lines after a timestamp. */
+               skipblanks = 1;
              }
          }
 
@@ -470,6 +487,7 @@ history_rename (const char *old, const char *new)
 #endif
 }
 
+#if defined (DEBUG)
 /* Save FILENAME to BACK, handling case where FILENAME is a symlink
    (e.g., ~/.bash_history -> .histfiles/.bash_history.$HOSTNAME) */
 static int
@@ -488,6 +506,7 @@ histfile_backup (const char *filename, const char *back)
 #endif
   return (history_rename (filename, back));
 }
+#endif
 
 /* Restore ORIG from BACKUP handling case where ORIG is a symlink
    (e.g., ~/.bash_history -> .histfiles/.bash_history.$HOSTNAME) */
@@ -708,13 +727,13 @@ static int
 history_write_slow (int fd, HIST_ENTRY **the_history, int nelements, int overwrite)
 {
   FILE *fp;
-  int i, j, e;
+  int i, e;
 
   fp = fdopen (fd, overwrite ? "w" : "a");
   if (fp == 0)
     return -1;
 
-  for (j = 0, i = history_length - nelements; i < history_length; i++)
+  for (i = history_length - nelements; i < history_length; i++)
     {
       if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0])
        fprintf (fp, "%s\n", the_history[i]->timestamp);
index aade5e33a3274b7963dbc0cfda7b50ee8a6757fb..2d0400b735b01510e29d0eb56cdaad53669c1af0 100644 (file)
--- a/history.c
+++ b/history.c
@@ -202,7 +202,7 @@ using_history (void)
 int
 history_total_bytes (void)
 {
-  register int i, result;
+  int i, result;
 
   for (i = result = 0; the_history && the_history[i]; i++)
     result += HISTENT_BYTES (the_history[i]);
@@ -545,7 +545,7 @@ void
 _hs_replace_history_data (int which, histdata_t *old, histdata_t *new)
 {
   HIST_ENTRY *entry;
-  register int i, last;
+  int i, last;
 
   if (which < -2 || which >= history_length || history_length == 0 || the_history == 0)
     return;
@@ -581,7 +581,7 @@ _hs_replace_history_data (int which, histdata_t *old, histdata_t *new)
 int
 _hs_search_history_data (histdata_t *needle)
 {
-  register int i;
+  int i;
   HIST_ENTRY *entry;
 
   if (history_length == 0 || the_history == 0)
@@ -605,10 +605,11 @@ HIST_ENTRY *
 remove_history (int which)
 {
   HIST_ENTRY *return_value;
-  register int i;
 #if 1
   int nentries;
   HIST_ENTRY **start, **end;
+#else
+  int i;
 #endif
 
   if (which < 0 || which >= history_length || history_length ==  0 || the_history == 0)
diff --git a/input.c b/input.c
index 4eefb274e6bd0153ddcf9c3881b2bd4cd9614c6e..e6a39e26b64a75aee21138a85d27132e9261502e 100644 (file)
--- a/input.c
+++ b/input.c
@@ -921,7 +921,7 @@ rl_getc (FILE *stream)
 
 /* fprintf(stderr, "rl_getc: result = %d errno = %d\n", result, errno); */
 
-handle_error:
+      /* Handle errors here. */
       osig = _rl_caught_signal;
       ostate = rl_readline_state;
 
index 03ab24ab2a7f66a5a7dc1f369a999d8300d246e6..e77f89d9546da59ffa0b56326c2d82d8da6717a6 100644 (file)
@@ -1366,6 +1366,7 @@ readline_default_bindings (void)
     rl_tty_set_default_bindings (_rl_keymap);
 }
 
+#if defined (DEBUG)
 /* Reset the default bindings for the terminal special characters we're
    interested in back to rl_insert and read the new ones. */
 static void
@@ -1377,6 +1378,7 @@ reset_default_bindings (void)
       rl_tty_set_default_bindings (_rl_keymap);
     }
 }
+#endif
 
 /* Bind some common arrow key sequences in MAP. */
 static void
index 803617570da78d4fda74d94c10ff7bfc3fe3bb89..a7ab9479071dd7b8c5dbd6e75cd79f1eb38b01cb 100644 (file)
--- a/search.c
+++ b/search.c
@@ -590,7 +590,6 @@ rl_history_search_internal (int count, int dir)
 {
   HIST_ENTRY *temp;
   int ret, oldpos, newcol;
-  char *t;
 
   oldpos = where_history ();   /* where are we now? */
   temp = (HIST_ENTRY *)NULL;
@@ -650,6 +649,7 @@ rl_history_search_internal (int count, int dir)
   else
     {
 #if 0
+      char *t;
       t = strstr (rl_line_buffer, history_search_string);      /* XXX */
       rl_point = t ? (int)(t - rl_line_buffer) + _rl_history_search_len : rl_end;
 #else
diff --git a/shell.c b/shell.c
index 7c0f9554fb89255084bddc8e61fc742112f95c63..6f943de7444cb7dea46d5c21d285d2f69a2a338d 100644 (file)
--- a/shell.c
+++ b/shell.c
@@ -118,8 +118,10 @@ sh_single_quote (char *string)
 /* Set the environment variables LINES and COLUMNS to lines and cols,
    respectively. */
 static char setenv_buf[INT_STRLEN_BOUND (int) + 1];
+#if defined (HAVE_PUTENV) && !defined (HAVE_SETENV)
 static char putenv_buf1[INT_STRLEN_BOUND (int) + 6 + 1];       /* sizeof("LINES=") == 6 */
 static char putenv_buf2[INT_STRLEN_BOUND (int) + 8 + 1];       /* sizeof("COLUMNS=") == 8 */
+#endif
 
 void
 sh_set_lines_and_columns (int lines, int cols)
index 2c70553d1c9dcec96f45ec001c5ffa953a652ef5..e644e0966e375ace0abd993d76044c7753b43d1d 100644 (file)
@@ -102,12 +102,20 @@ static char *term_string_buffer = (char *)NULL;
 
 static int tcap_initialized;
 
-#if !defined (__linux__) && !defined (NCURSES_VERSION)
-#  if defined (__EMX__) || defined (NEED_EXTERN_PC)
+/* Systems for which PC/BC/UP are defined in the curses library and need an
+   extern definition here. */
+#if !defined (__linux__) && !defined (__gnu_hurd__) && !defined (NCURSES_VERSION)
+#  define NEED_EXTERN_PC
+#endif /* !__linux__ && !__gnu_hurd__ && !NCURSES_VERSION */
+
+#if defined (__EMX__)
+#  define NEED_EXTERN_PC
+#endif
+
+#if defined (NEED_EXTERN_PC)
 extern 
-#  endif /* __EMX__ || NEED_EXTERN_PC */
+#  endif /* NEED_EXTERN_PC */
 char PC, *BC, *UP;
-#endif /* !__linux__ && !NCURSES_VERSION */
 
 /* Some strings to control terminal actions.  These are output by tputs (). */
 char *_rl_term_clreol;
diff --git a/util.c b/util.c
index 0a5df9b4009e0a6a2832ab8f90767c45f0fc3910..908a05f77b6de1475590c72b18c14bc72329c2aa 100644 (file)
--- a/util.c
+++ b/util.c
@@ -292,7 +292,7 @@ _rl_strpbrk (const char *string1, const char *string2)
   register const char *scan;
 #if defined (HANDLE_MULTIBYTE)
   mbstate_t ps;
-  register int i, v;
+  int v;
 
   memset (&ps, 0, sizeof (mbstate_t));
 #endif