]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
changes to make EOF state available to readline applications; fix for command substit...
authorChet Ramey <chet.ramey@case.edu>
Mon, 21 Feb 2022 15:06:44 +0000 (10:06 -0500)
committerChet Ramey <chet.ramey@case.edu>
Mon, 21 Feb 2022 15:06:44 +0000 (10:06 -0500)
14 files changed:
CWRU/CWRU.chlog
lib/readline/callback.c
lib/readline/doc/rltech.texi
lib/readline/doc/version.texi
lib/readline/history.h
lib/readline/misc.c
lib/readline/readline.c
lib/readline/readline.h
lib/readline/rlprivate.h
lib/readline/rltty.c
lib/readline/search.c
parse.y
parser.h
pathexp.c

index f54788ff7435daadb09880b963d148e935335505..ac14de6542045ddf7edb543567c3208ca4bfb180 100644 (file)
@@ -3184,3 +3184,64 @@ builtins/shopt.def
          the range of the compatNN options, just leave it alone when
          unsetting one of the options (which by definition was already
          unset). Fixes issue reported by Mihai Moldovan <ionic@ionic.de>
+
+                                  2/16
+                                  ----
+lib/readline/search.c
+       - rl_history_search_{pos,len,flags}: rename to have a leading `_'
+       - _rl_history_search_pos: no longer static so other parts of readline
+         can see it
+
+lib/readline/rlprivate.h
+       - _rl_history_search_pos: extern declaration
+
+lib/readline/readline.c
+       - readline_internal_teardown: don't run the undo list against the
+         current history entry if the non-incremental search functions have
+         set _rl_history_search_pos to it, since it doesn't reflect the
+         current contents of the line buffer. Fixes issue reported by
+         Andreas Schwab <schwab@linux-m68k.org>
+
+lib/readline/misc.c
+       - _rl_start_using_history: initialize _rl_history_search_pos to
+         something invalid so it doesn't match where_history()
+
+                                  2/17
+                                  ----
+lib/readline/callback.c
+       - rl_callback_read_char: make sure _rl_eof_found is set to the value
+         of eof before calling the deprep terminal function, so it can do
+         different things based on whether the input code read EOF (or the
+         user entered the EOF character). From a gdb discussion started by
+         Andrew Burgess <aburgess@redhat.com> (still more to do, since this
+         is not part of the public API)
+
+                                  2/18
+                                  ----
+lib/readline/readline.h
+       - RL_STATE_EOF: new readline state value; set when readline reads an
+         EOF character on an empty line or a read returns an error
+       - rl_eof_found: new public variable
+
+lib/readline/rprivate.h
+       - _rl_eof_found: renamed to rl_eof_found, so not declared here
+
+lib/readline/{callback,readline}.c
+       - RL_STATE_EOF: set appropriately when readline gets an EOF. Suggested
+         by Andrew Burgess <aburgess@redhat.com>
+       - RL_STATE_EOF: make sure it's not set when readline starts
+       - rl_eof_found: set appropriately when readline gets an EOF
+
+lib/readline/{callback,readline,rltty}.c
+       - rl_eof_found: new name for _rl_eof_found
+
+lib/readline/doc/rltech.texi
+       - RL_STATE_EOF: document
+
+                                  2/19
+                                  ----
+parse.y
+       - parse_comsub: turn off parser state flags we don't want to inherit
+         into this call to the parser (PST_REGEXP, PST_EXTPAT, PST_CONDCMD,
+         PST_CONDEXPR for now). Fixes bug reported by konsolebox
+         <konsolebox@gmail.com>
index cfff6502170fd7f0d90e5375380532feaaa8919b..1a3235f1990eeec168bd82395ce30b31329e7ae5 100644 (file)
@@ -1,6 +1,6 @@
 /* callback.c -- functions to use readline as an X `callback' mechanism. */
 
-/* Copyright (C) 1987-2017 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2022 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.
@@ -136,6 +136,8 @@ rl_callback_read_char (void)
       abort ();
     }
 
+  eof = 0;
+
   memcpy ((void *)olevel, (void *)_rl_top_level, sizeof (procenv_t));
 #if defined (HAVE_POSIX_SIGSETJMP)
   jcode = sigsetjmp (_rl_top_level, 0);
@@ -276,6 +278,10 @@ rl_callback_read_char (void)
          _rl_want_redisplay = 0;
        }
 
+      /* Make sure application hooks can see whether we saw EOF. */
+      if (rl_eof_found = eof)
+       RL_SETSTATE(RL_STATE_EOF);
+
       if (rl_done)
        {
          line = readline_internal_teardown (eof);
index 01343edc88aaa1491ae40a917e8838bc9032a91e..6f7ffb931a54bc0cd74174b5e844e74d848f1d88 100644 (file)
@@ -323,6 +323,14 @@ and point define a @emph{region}.
 @deftypevar int rl_done
 Setting this to a non-zero value causes Readline to return the current
 line immediately.
+Readline will set this variable when it has read a key sequence bound
+to @code{accept-line} and is about to return the line to the caller.
+@end deftypevar
+
+@deftypevar int rl_eof_found
+Readline will set this variable when it has read an EOF character (e.g., the
+stty @samp{EOF} character) on an empty line or encountered a read error and
+is about to return a NULL line to the caller.
 @end deftypevar
 
 @deftypevar int rl_num_chars_to_read
@@ -597,6 +605,9 @@ and is about to return the line to the caller.
 Readline has timed out (it did not receive a line or specified number of
 characters before the timeout duration specified by @code{rl_set_timeout}
 elapsed) and is returning that status to the caller.
+@item RL_STATE_EOF
+Readline has read an EOF character (e.g., the stty @samp{EOF} character)
+or encountered a read error and is about to return a NULL line to the caller.
 @end table
 
 @end deftypevar
index 46c88bdb0a48e607b6907fbc481bf9182004d6b8..42ead150df73fd185562ec4cdbe9b7e58b5fb5e7 100644 (file)
@@ -5,7 +5,7 @@ Copyright (C) 1988-2022 Free Software Foundation, Inc.
 @set EDITION 8.2
 @set VERSION 8.2
 
-@set UPDATED Thu Feb 10 10:56:04 EST 2022
+@set UPDATED 18 February 2022
 @set UPDATED-MONTH February 2022
 
-@set LASTCHANGE Thu Feb 10 10:56:20 EST 2022
+@set LASTCHANGE Fri Feb 18 11:12:48 EST 2022
index ad2ce70a179e9e16a0e04f94273c871eb0e866c6..5208f9a463b2a18c5a6e9ee32d120980e989eaaf 100644 (file)
@@ -1,6 +1,6 @@
 /* history.h -- the names of functions that you can call in history. */
 
-/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2022 Free Software Foundation, Inc.
 
    This file contains the GNU History Library (History), a set of
    routines for managing the text of previously typed lines.
index 5670cdac1baf369e1d0c2404c2f3a14ff1c923a4..622ebec520aae9462552931c067256b7eae0cf3e 100644 (file)
@@ -1,6 +1,6 @@
 /* misc.c -- miscellaneous bindable readline functions. */
 
-/* Copyright (C) 1987-2021 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2022 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.      
@@ -308,6 +308,7 @@ _rl_start_using_history (void)
   if (_rl_saved_line_for_history)
     _rl_free_saved_history_line ();
   _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
+  _rl_history_search_pos = -99;                /* some random invalid history position */
 }
 
 /* Free the contents (and containing structure) of a HIST_ENTRY. */
index 371e1fbc66caf8b64bc919fc06b0509955827b6f..888612c6bec6b30aa88da2e072f609a8ea4e0111 100644 (file)
@@ -1,7 +1,7 @@
 /* readline.c -- a general facility for reading lines of input
    with emacs style editing and completion. */
 
-/* Copyright (C) 1987-2021 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2022 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.      
@@ -164,6 +164,9 @@ int rl_end;
 /* Make this non-zero to return the current input_line. */
 int rl_done;
 
+/* If non-zero when readline_internal returns, it means we found EOF */
+int rl_eof_found = 0;
+
 /* The last function executed by readline. */
 rl_command_func_t *rl_last_func = (rl_command_func_t *)NULL;
 
@@ -217,9 +220,6 @@ int _rl_eof_char = CTRL ('D');
 /* Non-zero makes this the next keystroke to read. */
 int rl_pending_input = 0;
 
-/* If non-zero when readline_internal returns, it means we found EOF */
-int _rl_eof_found = 0;
-
 /* Pointer to a useful terminal name. */
 const char *rl_terminal_name = (const char *)NULL;
 
@@ -479,11 +479,17 @@ readline_internal_teardown (int eof)
 
   RL_CHECK_SIGNALS ();
 
+  if (eof)
+    RL_SETSTATE (RL_STATE_EOF);                /* XXX */
+
   /* Restore the original of this history line, iff the line that we
      are editing was originally in the history, AND the line has changed. */
   entry = current_history ();
 
-  if (entry && rl_undo_list)
+  /* We don't want to do this if we executed functions that call
+     history_set_pos to set the history offset to the line containing the
+     non-incremental search string. */
+  if (entry && rl_undo_list && _rl_history_search_pos != where_history ())
     {
       temp = savestring (the_line);
       rl_revert_line (1, 0);
@@ -615,6 +621,7 @@ readline_internal_charloop (void)
          RL_SETSTATE(RL_STATE_DONE);
          return (rl_done = 1);
 #else
+         RL_SETSTATE(RL_STATE_EOF);
          eof_found = 1;
          break;
 #endif
@@ -655,6 +662,7 @@ readline_internal_charloop (void)
          RL_SETSTATE(RL_STATE_DONE);
          return (rl_done = 1);
 #else
+         RL_SETSTATE(RL_STATE_EOF);
          eof_found = 1;
          break;
 #endif
@@ -717,8 +725,8 @@ static char *
 readline_internal (void)
 {
   readline_internal_setup ();
-  _rl_eof_found = readline_internal_charloop ();
-  return (readline_internal_teardown (_rl_eof_found));
+  rl_eof_found = readline_internal_charloop ();
+  return (readline_internal_teardown (rl_eof_found));
 }
 
 void
@@ -1178,7 +1186,7 @@ rl_initialize (void)
 
   /* We aren't done yet.  We haven't even gotten started yet! */
   rl_done = 0;
-  RL_UNSETSTATE(RL_STATE_DONE);
+  RL_UNSETSTATE(RL_STATE_DONE|RL_STATE_TIMEOUT|RL_STATE_EOF);
 
   /* Tell the history routines what is going on. */
   _rl_start_using_history ();
index 7cf1fcf58a42972f1a9fe42b4fac09c3be05cd2b..cac269f0b433ca795a929e0c4c4ebde42446f7de 100644 (file)
@@ -1,6 +1,6 @@
 /* Readline.h -- the names of functions callable from within readline. */
 
-/* Copyright (C) 1987-2021 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2022 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.      
@@ -562,6 +562,10 @@ extern int rl_mark;
    line and should return it. */
 extern int rl_done;
 
+/* Flag to indicate that readline has read an EOF character or read has
+   returned 0 or error, and is returning a NULL line as a result. */
+extern int rl_eof_found;
+
 /* If set to a character value, that will be the next keystroke read. */
 extern int rl_pending_input;
 
@@ -917,7 +921,8 @@ extern int rl_persistent_signal_handlers;
 #define RL_STATE_REDISPLAYING  0x1000000       /* updating terminal display */
 
 #define RL_STATE_DONE          0x2000000       /* done; accepted line */
-#define RL_STATE_TIMEOUT       0x4000000
+#define RL_STATE_TIMEOUT       0x4000000       /* done; timed out */
+#define RL_STATE_EOF           0x8000000       /* done; got eof on read */
 
 #define RL_SETSTATE(x)         (rl_readline_state |= (x))
 #define RL_UNSETSTATE(x)       (rl_readline_state &= ~(x))
index db20b92c9b6f48f0326839ab37fad195b96e33fe..70ff01c2705ea00fa49bfe00d77c9484207449ec 100644 (file)
@@ -563,7 +563,6 @@ extern FILE *_rl_in_stream;
 extern FILE *_rl_out_stream;
 extern int _rl_last_command_was_kill;
 extern int _rl_eof_char;
-extern int _rl_eof_found;
 extern procenv_t _rl_top_level;
 extern _rl_keyseq_cxt *_rl_kscxt;
 extern int _rl_keyseq_timeout;
@@ -574,6 +573,7 @@ extern rl_hook_func_t *_rl_internal_startup_hook;
 
 /* search.c */
 extern _rl_search_cxt *_rl_nscxt;
+extern int _rl_history_search_pos;
 
 /* signals.c */
 extern int volatile _rl_caught_signal;
index b34de2a49619b8522e9ba34fdc320d6f5323cde4..882a3d46b1347f24471c0ccb5708ff7fb662f776 100644 (file)
@@ -1,7 +1,7 @@
 /* rltty.c -- functions to prepare and restore the terminal for readline's
    use. */
 
-/* Copyright (C) 1992-2021 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2022 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.
@@ -694,7 +694,7 @@ rl_deprep_terminal (void)
       fprintf (rl_outstream, BRACK_PASTE_FINI);
       /* Since the last character in BRACK_PASTE_FINI is \r */
       _rl_last_c_pos = 0;
-      if (_rl_eof_found && (RL_ISSTATE (RL_STATE_TIMEOUT) == 0))
+      if (rl_eof_found && (RL_ISSTATE (RL_STATE_TIMEOUT) == 0))
        fprintf (rl_outstream, "\n");
       else if (_rl_echoing_p == 0)
        fprintf (rl_outstream, "\n");
index 325d51ecf46518c1e47507feec38633659c29549..89f5961aad1e9c748caf9f1e35b8c0b8f005d075 100644 (file)
@@ -1,6 +1,6 @@
 /* search.c - code for non-incremental searching in emacs and vi modes. */
 
-/* Copyright (C) 1992-2021 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2022 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.      
@@ -60,9 +60,9 @@ static int noninc_history_pos;
 
 static char *prev_line_found = (char *) NULL;
 
-static int rl_history_search_len;
-static int rl_history_search_pos;
-static int rl_history_search_flags;
+static int _rl_history_search_len;
+/*static*/ int _rl_history_search_pos;
+static int _rl_history_search_flags;
 
 static char *history_search_string;
 static int history_string_size;
@@ -539,14 +539,14 @@ rl_history_search_internal (int count, int dir)
   while (count)
     {
       RL_CHECK_SIGNALS ();
-      ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir, 0, &newcol);
+      ret = noninc_search_from_pos (history_search_string, _rl_history_search_pos + dir, dir, 0, &newcol);
       if (ret == -1)
        break;
 
       /* Get the history entry we found. */
-      rl_history_search_pos = ret;
+      _rl_history_search_pos = ret;
       oldpos = where_history ();
-      history_set_pos (rl_history_search_pos);
+      history_set_pos (_rl_history_search_pos);
       temp = current_history ();       /* will never be NULL after successful search */
       history_set_pos (oldpos);
 
@@ -566,14 +566,14 @@ rl_history_search_internal (int count, int dir)
          in the line buffer after the search fails, change the #if 0 to
          #if 1 */
 #if 0
-      if (rl_point > rl_history_search_len)
+      if (rl_point > _rl_history_search_len)
         {
-          rl_point = rl_end = rl_history_search_len;
+          rl_point = rl_end = _rl_history_search_len;
           rl_line_buffer[rl_end] = '\0';
           rl_mark = 0;
         }
 #else
-      rl_point = rl_history_search_len;        /* rl_maybe_unsave_line changes it */
+      rl_point = _rl_history_search_len;       /* rl_maybe_unsave_line changes it */
       rl_mark = rl_end;
 #endif
       return 1;
@@ -585,16 +585,16 @@ rl_history_search_internal (int count, int dir)
   /* Make sure we set the current history position to the last line found so
      we can do things like operate-and-get-next from here. This is similar to
      how incremental search behaves. */
-  history_set_pos (rl_history_search_pos);     /* XXX */
+  history_set_pos (_rl_history_search_pos);    /* XXX */
 
   /* decide where to put rl_point -- need to change this for pattern search */
-  if (rl_history_search_flags & ANCHORED_SEARCH)
-    rl_point = rl_history_search_len;  /* easy case */
+  if (_rl_history_search_flags & ANCHORED_SEARCH)
+    rl_point = _rl_history_search_len; /* easy case */
   else
     {
 #if 0
       t = strstr (rl_line_buffer, history_search_string);      /* XXX */
-      rl_point = t ? (int)(t - rl_line_buffer) + rl_history_search_len : rl_end;
+      rl_point = t ? (int)(t - rl_line_buffer) + _rl_history_search_len : rl_end;
 #else
       rl_point = (newcol >= 0) ? newcol : rl_end;
 #endif
@@ -609,17 +609,17 @@ rl_history_search_reinit (int flags)
 {
   int sind;
 
-  rl_history_search_pos = where_history ();
-  rl_history_search_len = rl_point;
-  rl_history_search_flags = flags;
+  _rl_history_search_pos = where_history ();
+  _rl_history_search_len = rl_point;
+  _rl_history_search_flags = flags;
 
   prev_line_found = (char *)NULL;
   if (rl_point)
     {
       /* Allocate enough space for anchored and non-anchored searches */
-      if (rl_history_search_len >= history_string_size - 2)
+      if (_rl_history_search_len >= history_string_size - 2)
        {
-         history_string_size = rl_history_search_len + 2;
+         history_string_size = _rl_history_search_len + 2;
          history_search_string = (char *)xrealloc (history_search_string, history_string_size);
        }
       sind = 0;
@@ -644,7 +644,7 @@ rl_history_search_forward (int count, int ignore)
       rl_last_func != rl_history_search_backward)
     rl_history_search_reinit (ANCHORED_SEARCH);
 
-  if (rl_history_search_len == 0)
+  if (_rl_history_search_len == 0)
     return (rl_get_next_history (count, ignore));
   return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
 }
@@ -662,7 +662,7 @@ rl_history_search_backward (int count, int ignore)
       rl_last_func != rl_history_search_backward)
     rl_history_search_reinit (ANCHORED_SEARCH);
 
-  if (rl_history_search_len == 0)
+  if (_rl_history_search_len == 0)
     return (rl_get_previous_history (count, ignore));
   return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
 }
@@ -681,7 +681,7 @@ rl_history_substr_search_forward (int count, int ignore)
       rl_last_func != rl_history_substr_search_backward)
     rl_history_search_reinit (NON_ANCHORED_SEARCH);
 
-  if (rl_history_search_len == 0)
+  if (_rl_history_search_len == 0)
     return (rl_get_next_history (count, ignore));
   return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
 }
@@ -699,7 +699,7 @@ rl_history_substr_search_backward (int count, int ignore)
       rl_last_func != rl_history_substr_search_backward)
     rl_history_search_reinit (NON_ANCHORED_SEARCH);
 
-  if (rl_history_search_len == 0)
+  if (_rl_history_search_len == 0)
     return (rl_get_previous_history (count, ignore));
   return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
 }
diff --git a/parse.y b/parse.y
index a47982242bdfb408af5eb7bc7d661ec1aae77c84..c61db45708d6167588e8dc717acc654c7c0912f1 100644 (file)
--- a/parse.y
+++ b/parse.y
@@ -3419,7 +3419,7 @@ read_token (command)
     goto tokword;
 
   /* Shell meta-characters. */
-  if MBTEST(shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
+  if MBTEST(shellmeta (character))
     {
 #if defined (ALIAS)
       /* Turn off alias tokenization iff this character sequence would
@@ -4061,6 +4061,10 @@ parse_comsub (qc, open, close, lenp, flags)
   save_parser_state (&ps);
 
   pushed_string_list = (STRING_SAVER *)NULL;
+
+  /* State flags we don't want to persist into command substitutions. */
+  parser_state &= ~(PST_REGEXP|PST_EXTPAT|PST_CONDCMD|PST_CONDEXPR);
+  /* State flags we want to set for this run through the parser. */
   parser_state |= PST_CMDSUBST|PST_EOFTOKEN|PST_NOEXPAND;
 
   shell_eof_token = close;
index e3621d6c3c0684ad8939b51af09ef12d9823eae5..59bf0fec4c427cdd4d009e8319f84e2d762b4ccc 100644 (file)
--- a/parser.h
+++ b/parser.h
@@ -30,7 +30,7 @@
 #define PST_ALEXPNEXT  0x000002        /* expand next word for aliases */
 #define PST_ALLOWOPNBRC        0x000004        /* allow open brace for function def */
 #define PST_NEEDCLOSBRC        0x000008        /* need close brace */
-#define PST_DBLPAREN   0x000010        /* double-paren parsing */
+#define PST_DBLPAREN   0x000010        /* double-paren parsing - unused */
 #define PST_SUBSHELL   0x000020        /* ( ... ) subshell */
 #define PST_CMDSUBST   0x000040        /* $( ... ) command substitution */
 #define PST_CASESTMT   0x000080        /* parsing a case statement */
index 6e7ef283d8960419c056724e840c87891ea5e41d..cfa87e81ce6737bced16767b2ee9eaf5d4a315a5 100644 (file)
--- a/pathexp.c
+++ b/pathexp.c
@@ -171,6 +171,7 @@ ere_char (c)
   return (0);
 }
 
+/* This is only used to determine whether to backslash-quote a character. */
 int
 glob_char_p (s)
      const char *s;