]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
commit bash-20200420 snapshot
authorChet Ramey <chet.ramey@case.edu>
Wed, 22 Apr 2020 20:45:28 +0000 (16:45 -0400)
committerChet Ramey <chet.ramey@case.edu>
Wed, 22 Apr 2020 20:45:28 +0000 (16:45 -0400)
17 files changed:
CWRU/CWRU.chlog
MANIFEST
arrayfunc.c
bashline.c
doc/bashref.texi
examples/loadables/cut.c
examples/loadables/push.c
hashlib.c
hashlib.h
lib/readline/input.c
lib/readline/isearch.c
lib/readline/readline.c
lib/readline/readline.h
lib/readline/rlprivate.h
tests/history.right
tests/history.tests
tests/history4.sub [new file with mode: 0644]

index 9a51b0656e83efc296ab0ae9d796fe00983927b2..fbd09a271e767f48cc7935ac255173a7c46a9767 100644 (file)
@@ -8076,3 +8076,68 @@ builtins/read.def
          allows a trap action to see the same exit status that the read
          builtin would return when it exits on a signal (e.g., SIGINT == 130).
          From a suggestion by <gentoo_eshoes@tutanota.com>
+
+                                  4/20
+                                  ----
+hashlib.c 
+       - hash_rehash: function to rehash a table, after increasing or decreasing
+         the number of buckets. From patches from Thomas Kremer
+         (https://savannah.gnu.org/patch/?9850) and Koichi Murase
+         <myoga.murase@gmail.com>
+       - hash_grow,hash_shrink: grow or shrink a hash table by a factor of
+         HASH_REHASH_MULTIPLIER (4)
+       - hash_insert,hash_search: call hash_grow if necessary
+
+arrayfunc.c
+       - convert_var_to_{array,assoc}: if the original variable had no value
+         (it was unset), the array variable should be unset as well. Reported
+         by andrej@podzimek.org
+
+                                  4/21
+                                  ----
+bashline.c
+       - set_saved_history: change logic used to decide where in the history
+         operate_and_get_next should start by using a logical offset into the
+         history list that is an offset from history_base. This avoids having
+         to take whether or not the history is stifled and full into account.
+         Report and fix from Greg Price <gnprice@gmail.com>
+       - operate_and_get_next: just calculate the logical offset of where we
+         should be in the history instead of an absolute offset
+
+lib/readline/input.c
+       - _rl_nchars_available: new function, returns the number of characters
+         available to be read if FIONREAD is available
+
+                                  4/22
+                                  ----
+lib/readline/{readline.c,rlprivate.h}
+       - _rl_pending_command: new struct to hold information about a pending
+         command for readline to execute when the current command completes.
+         A command can set this up so that it gets executed like a
+         continuation before redisplay
+
+lib/readline/readline.c
+       - readline_internal_charloop: after _rl_dispatch returns, check
+         _rl_command_to_execute, and, if it's non-zero, redisplay and then
+         execute it as a command
+       - added a small set of library-private functions for managing the
+         executing key sequence (not used yet)
+
+lib/readline/isearch.c
+       - _rl_isearch_dispatch: if we have found an opcode or have added a
+         character to the search string and searched for it, reset the keymap
+         and okeymap members of the search context in preparation for reading
+         another key sequence/opcode
+       - _rl_isearch_dispatch: if we read a key sequence bound to an editing
+         command that is not an `opcode', set up _rl_command_to_execute to
+         execute it after the searching returns and arrange to break out of
+         the search
+       - _rl_isearch_dispatch: if we paste in text from bracketed paste, set
+         the mark as active so we can highlight it when we display the search
+         string
+       - _rl_isearch_dispatch: if we've found the search string, activate the
+         mark and set rl_point and rl_mark so the search string is highlighted
+         when we display the search results
+       - _rl_isearch_dispatch: do translation for keys that map to
+         rl_do_lowercase_version like we do when dispatching while reading a
+         key sequence
index 653c1a1b0c1301f70818af48797d937b8245608f..b31e8595dddbb3a708b0c8d6f9897e6c1c6ce980 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -1141,6 +1141,7 @@ tests/history.list        f       444
 tests/history1.sub     f
 tests/history2.sub     f
 tests/history3.sub     f
+tests/history4.sub     f
 tests/ifs.tests                f
 tests/ifs.right                f
 tests/ifs1.sub         f
index eb1d5fa575a6a5dbae02b2c17d5d3788843cd2d7..6d0aa66330d9978f695dda3dbf1b26e3ace74f39 100644 (file)
@@ -91,7 +91,8 @@ convert_var_to_array (var)
     array_needs_making++;
 
   VSETATTR (var, att_array);
-  VUNSETATTR (var, att_invisible);
+  if (oldval)
+    VUNSETATTR (var, att_invisible);
 
   /* Make sure it's not marked as an associative array any more */
   VUNSETATTR (var, att_assoc);
@@ -128,7 +129,8 @@ convert_var_to_assoc (var)
     array_needs_making++;
 
   VSETATTR (var, att_assoc);
-  VUNSETATTR (var, att_invisible);
+  if (oldval)
+    VUNSETATTR (var, att_invisible);
 
   /* Make sure it's not marked as an indexed array any more */
   VUNSETATTR (var, att_array);
index cd36b0be516396fdfa016540bf3475e22e458be3..8d7c1c1aa8c62da5e0ddc4140d6d715b65b3b566 100644 (file)
@@ -922,27 +922,22 @@ hostnames_matching (text)
 
 /* The equivalent of the Korn shell C-o operate-and-get-next-history-line
    editing command. */
-static int saved_history_line_to_use = -1;
-static int last_saved_history_line = -1;
+static int saved_history_logical_offset = -1;
 
 #define HISTORY_FULL() (history_is_stifled () && history_length >= history_max_entries)
 
 static int
 set_saved_history ()
 {
-  /* XXX - compensate for assumption that history was `shuffled' if it was
-     actually not. */
-  if (HISTORY_FULL () &&
-      hist_last_line_added == 0 &&
-      saved_history_line_to_use < history_length - 1)
-    saved_history_line_to_use++;
-
-  if (saved_history_line_to_use >= 0)
+  int absolute_offset, count;
+
+  if (saved_history_logical_offset >= 0)
     {
-     rl_get_previous_history (history_length - saved_history_line_to_use, 0);
-     last_saved_history_line = saved_history_line_to_use;
+      absolute_offset = saved_history_logical_offset - history_base;
+      count = where_history () - absolute_offset;
+      rl_get_previous_history (count, 0);
     }
-  saved_history_line_to_use = -1;
+  saved_history_logical_offset = -1;
   rl_startup_hook = old_rl_startup_hook;
   return (0);
 }
@@ -951,18 +946,10 @@ static int
 operate_and_get_next (count, c)
      int count, c;
 {
-  int where;
-
   /* Accept the current line. */
   rl_newline (1, c);
 
-  /* Find the current line, and find the next line to use. */
-  where = rl_explicit_arg ? count : where_history ();
-
-  if (HISTORY_FULL () || (where >= history_length - 1) || rl_explicit_arg)
-    saved_history_line_to_use = where;
-  else
-    saved_history_line_to_use = where + 1;
+  saved_history_logical_offset = rl_explicit_arg ? count : where_history () + history_base + 1;
 
   old_rl_startup_hook = rl_startup_hook;
   rl_startup_hook = set_saved_history;
index 4c1111a185adcdf01edb15f8a33a087435a458a8..2014440e75e310e3eddb9ecb89b55340f2bbf065 100644 (file)
@@ -2185,7 +2185,7 @@ results.
 
 Substring indexing is zero-based unless the positional parameters
 are used, in which case the indexing starts at 1 by default.
-If @var{offset} is 0, and the positional parameters are used, @code{$@@} is
+If @var{offset} is 0, and the positional parameters are used, @code{$0} is
 prefixed to the list.
 
 @item $@{!@var{prefix}*@}
index 6129b1f971e1285f14528e235b4f3f7d0d7d8d3a..ad9a83357a266d1d4eb27092756b95545b3dc4ef 100644 (file)
@@ -1,5 +1,5 @@
-/* lcut - extract specified fields from a line and assign them to an array or
-         print them to the standard output */
+/* cut,lcut - extract specified fields from a line and assign them to an array
+             or print them to the standard output */
 
 /*
    Copyright (C) 2020 Free Software Foundation, Inc.
@@ -573,22 +573,6 @@ cut_builtin (list)
   return (cut_internal (1, list));
 }
 
-/* Called when builtin is enabled and loaded from the shared object.  If this
-   function returns 0, the load fails. */
-int
-lcut_builtin_load (name)
-     char *name;
-{
-  return (1);
-}
-
-/* Called when builtin is disabled. */
-void
-lcut_builtin_unload (name)
-     char *name;
-{
-}
-
 char *lcut_doc[] = {
        "Extract selected fields from a string.",
        "",
index 194487c0c0207fd14a200eed649e529cdea93a20..b27455b454bbe7a49f44e30ba613ca8aa2c94a2e 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 /*
-   Copyright (C) 1999-2009 Free Software Foundation, Inc.
+   Copyright (C) 1999-2020 Free Software Foundation, Inc.
 
    This file is part of GNU Bash.
    Bash is free software: you can redistribute it and/or modify
@@ -92,7 +92,7 @@ push_builtin (list)
   else
     {
       stop_pipeline (0, (COMMAND *)NULL);
-      xstatus = wait_for (pid);
+      xstatus = wait_for (pid, 0);
       return (xstatus);
     }   
 }
index f8e3b09a240132e09b2e0e987534fd3d45846940..9bb0470707c52cb2f91633cef2df9820008aa831 100644 (file)
--- a/hashlib.c
+++ b/hashlib.c
 #include "shell.h"
 #include "hashlib.h"
 
+/* tunable constants for rehashing */
+#define HASH_REHASH_MULTIPLIER 4
+#define HASH_REHASH_FACTOR     2
+
+#define HASH_SHOULDGROW(table) \
+  ((table)->nentries >= (table)->nbuckets * HASH_REHASH_FACTOR)
+
+/* an initial approximation */
+#define HASH_SHOULDSHRINK(table) \
+  (((table)->nbuckets > DEFAULT_HASH_BUCKETS) && \
+   ((table)->nentries < (table)->nbuckets / HASH_REHASH_MULTIPLIER))
+
 /* Rely on properties of unsigned division (unsigned/int -> unsigned) and
    don't discard the upper 32 bits of the value, if present. */
 #define HASH_BUCKET(s, t, h) (((h) = hash_string (s)) & ((t)->nbuckets - 1))
 
-static BUCKET_CONTENTS *copy_bucket_array __P((BUCKET_CONTENTS *, sh_string_func_t *));
+static BUCKET_CONTENTS *copy_bucket_array PARAMS((BUCKET_CONTENTS *, sh_string_func_t *));
+
+static void hash_rehash PARAMS((HASH_TABLE *, int));
+static void hash_grow PARAMS((HASH_TABLE *));
+static void hash_shrink PARAMS((HASH_TABLE *));
 
 /* Make a new hash table with BUCKETS number of buckets.  Initialize
    each slot in the table to NULL. */
@@ -105,6 +121,60 @@ copy_bucket_array (ba, cpdata)
   return new_bucket;  
 }
 
+static void
+hash_rehash (table, nsize)
+     HASH_TABLE *table;
+     int nsize;
+{
+  int osize, i, j;
+  BUCKET_CONTENTS **old_bucket_array, *item, *next;
+
+  if (table == NULL || nsize == table->nbuckets)
+    return;
+
+  osize = table->nbuckets;
+  old_bucket_array = table->bucket_array;
+
+  table->nbuckets = nsize;
+  table->bucket_array = (BUCKET_CONTENTS **)xmalloc (table->nbuckets * sizeof (BUCKET_CONTENTS *));
+  for (i = 0; i < table->nbuckets; i++)
+    table->bucket_array[i] = (BUCKET_CONTENTS *)NULL;
+
+  for (j = 0; j < osize; j++)
+    {
+      for (item = old_bucket_array[j]; item; item = next)
+       {
+         next = item->next;
+         i = item->khash & (table->nbuckets - 1);
+         item->next = table->bucket_array[i];
+         table->bucket_array[i] = item;
+       }
+    }
+
+  free (old_bucket_array);
+}
+
+static void
+hash_grow (table)
+     HASH_TABLE *table;
+{
+  int nsize;
+
+  nsize = table->nbuckets * HASH_REHASH_MULTIPLIER;
+  if (nsize > 0)               /* overflow */
+    hash_rehash (table, nsize);
+}
+
+static void
+hash_shrink (table)
+     HASH_TABLE *table;
+{
+  int nsize;
+
+  nsize = table->nbuckets / HASH_REHASH_MULTIPLIER;
+  hash_rehash (table, nsize);
+}
+
 HASH_TABLE *
 hash_copy (table, cpdata)
      HASH_TABLE *table;
@@ -136,7 +206,7 @@ hash_copy (table, cpdata)
 
 /* If you want to use 64 bits, use
 FNV_OFFSET     14695981039346656037
-FNV_PRIMT      1099511628211
+FNV_PRIME      1099511628211
 */
 
 /* The `khash' check below requires that strings that compare equally with
@@ -198,6 +268,12 @@ hash_search (string, table, flags)
 
   if (flags & HASH_CREATE)
     {
+      if (HASH_SHOULDGROW (table))
+       {
+         hash_grow (table);
+         bucket = HASH_BUCKET (string, table, hv);
+       }
+
       list = (BUCKET_CONTENTS *)xmalloc (sizeof (BUCKET_CONTENTS));
       list->next = table->bucket_array[bucket];
       table->bucket_array[bucket] = list;
@@ -269,6 +345,9 @@ hash_insert (string, table, flags)
 
   if (item == 0)
     {
+      if (HASH_SHOULDGROW (table))
+       hash_grow (table);
+
       bucket = HASH_BUCKET (string, table, hv);
 
       item = (BUCKET_CONTENTS *)xmalloc (sizeof (BUCKET_CONTENTS));
index 88ea778f032c29d59bde1ad54af9e7bc3de378d1..cf2de9884006aba08e82fb126d18e2e2d47b2f3e 100644 (file)
--- a/hashlib.h
+++ b/hashlib.h
@@ -1,6 +1,6 @@
 /* hashlib.h -- the data structures used in hashing in Bash. */
 
-/* Copyright (C) 1993-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1993-2020 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -45,26 +45,26 @@ typedef struct hash_table {
   int nentries;                        /* How many entries does this table have. */
 } HASH_TABLE;
 
-typedef int hash_wfunc __P((BUCKET_CONTENTS *));
+typedef int hash_wfunc PARAMS((BUCKET_CONTENTS *));
 
 /* Operations on tables as a whole */
-extern HASH_TABLE *hash_create __P((int));
-extern HASH_TABLE *hash_copy __P((HASH_TABLE *, sh_string_func_t *));
-extern void hash_flush __P((HASH_TABLE *, sh_free_func_t *));
-extern void hash_dispose __P((HASH_TABLE *));
-extern void hash_walk __P((HASH_TABLE *, hash_wfunc *));
+extern HASH_TABLE *hash_create PARAMS((int));
+extern HASH_TABLE *hash_copy PARAMS((HASH_TABLE *, sh_string_func_t *));
+extern void hash_flush PARAMS((HASH_TABLE *, sh_free_func_t *));
+extern void hash_dispose PARAMS((HASH_TABLE *));
+extern void hash_walk PARAMS((HASH_TABLE *, hash_wfunc *));
 
 /* Operations to extract information from or pieces of tables */
-extern int hash_bucket __P((const char *, HASH_TABLE *));
-extern int hash_size __P((HASH_TABLE *));
+extern int hash_bucket PARAMS((const char *, HASH_TABLE *));
+extern int hash_size PARAMS((HASH_TABLE *));
 
 /* Operations on hash table entries */
-extern BUCKET_CONTENTS *hash_search __P((const char *, HASH_TABLE *, int));
-extern BUCKET_CONTENTS *hash_insert __P((char *, HASH_TABLE *, int));
-extern BUCKET_CONTENTS *hash_remove __P((const char *, HASH_TABLE *, int));
+extern BUCKET_CONTENTS *hash_search PARAMS((const char *, HASH_TABLE *, int));
+extern BUCKET_CONTENTS *hash_insert PARAMS((char *, HASH_TABLE *, int));
+extern BUCKET_CONTENTS *hash_remove PARAMS((const char *, HASH_TABLE *, int));
 
 /* Miscellaneous */
-extern unsigned int hash_string __P((const char *));
+extern unsigned int hash_string PARAMS((const char *));
 
 /* Redefine the function as a macro for speed. */
 #define hash_items(bucket, table) \
index c34dabf0a567afa20030ca28e50561a19fa59a77..9a69e13cc6d7461c01b2d60e56be5c86eb23349b 100644 (file)
@@ -349,8 +349,7 @@ _rl_input_available (void)
   FD_ZERO (&exceptfds);
   FD_SET (tty, &readfds);
   FD_SET (tty, &exceptfds);
-  timeout.tv_sec = 0;
-  timeout.tv_usec = _keyboard_input_timeout;
+  USEC_TO_TIMEVAL (_keyboard_input_timeout, timeout);
   return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0);
 #else
 
@@ -369,6 +368,24 @@ _rl_input_available (void)
   return 0;
 }
 
+int
+_rl_nchars_available ()
+{
+  int chars_avail, fd, result;
+  
+  chars_avail = 0;
+     
+#if defined (FIONREAD)
+  fd = fileno (rl_instream);
+  errno = 0;    
+  result = ioctl (fd, FIONREAD, &chars_avail);    
+  if (result == -1 && errno == EIO)    
+    return -1;    
+#endif
+
+  return chars_avail;
+}
+
 int
 _rl_input_queued (int t)
 {
index c8f60a01dcda3622c0e46740e621781029103701..026c2d7c380ff141b0b8543e61b1a39b35f5db9d 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                 */
 /* **************************************************************** */
 
-/* Copyright (C) 1987-2017 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2020 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.      
@@ -257,6 +257,9 @@ _rl_isearch_init (int direction)
 
   _rl_iscxt = cxt;             /* save globally */
 
+  /* experimental right now */
+  _rl_init_executing_keyseq ();
+
   return cxt;
 }
 
@@ -289,12 +292,16 @@ _rl_isearch_fini (_rl_search_cxt *cxt)
       else
        cxt->sline_index = strlen (rl_line_buffer);
       rl_mark = cxt->save_mark;
+      rl_deactivate_mark ();
     }
 
   rl_point = cxt->sline_index;
   /* Don't worry about where to put the mark here; rl_get_previous_history
-     and rl_get_next_history take care of it. */
+     and rl_get_next_history take care of it.
+     If we want to highlight the search string, this is where to set the
+     point and mark to do it. */
   _rl_fix_point (0);
+  rl_deactivate_mark ();
 
 /*  _rl_optimize_redisplay (); */
   rl_clear_message ();
@@ -346,6 +353,8 @@ _rl_isearch_dispatch (_rl_search_cxt *cxt, int c)
       return -1;
     }
 
+  _rl_add_executing_keyseq (c);
+
   /* If we are moving into a new keymap, modify cxt->keymap and go on.
      This can be a problem if c == ESC and we want to terminate the
      incremental search, so we check */
@@ -396,7 +405,11 @@ add_character:
       if (cxt->mb[1])
        f = rl_function_of_keyseq (cxt->mb, cxt->keymap, (int *)NULL);
       else
-       f = cxt->keymap[c].function;
+       {
+         f = cxt->keymap[c].function;
+         if (f == rl_do_lowercase_version)
+           f = cxt->keymap[_rl_to_lower (c)].function;
+       }
 
       if (f == rl_reverse_search_history)
        cxt->lastc = (cxt->sflags & SF_REVERSE) ? -1 : -2;
@@ -463,9 +476,14 @@ add_character:
        }
       else if (cxt->lastc > 0 && cxt->prevc > 0 && f && f != rl_insert)
        {
-         rl_stuff_char (cxt->lastc);
-         rl_execute_next (cxt->prevc);
-         /* XXX - do we insert everything in cxt->pmb? */
+         _rl_term_executing_keyseq ();         /* should this go in the caller? */
+
+         _rl_pending_command.map = cxt->keymap;
+         _rl_pending_command.count = 1;        /* XXX */
+         _rl_pending_command.key = cxt->lastc;
+         _rl_pending_command.func = f;
+         _rl_command_to_execute = &_rl_pending_command;
+
          return (0);
        }
     }
@@ -511,6 +529,8 @@ add_character:
        return (0);
       }
 
+  _rl_init_executing_keyseq ();
+
   /* Now dispatch on the character.  `Opcodes' affect the search string or
      state.  Other characters are added to the string.  */
   switch (cxt->lastc)
@@ -528,6 +548,7 @@ add_character:
              rl_display_search (cxt->search_string, cxt->sflags, -1);
              break;
            }
+         /* XXX - restore keymap here? */
          return (1);
        }
       else if ((cxt->sflags & SF_REVERSE) && cxt->sline_index >= 0)
@@ -575,6 +596,7 @@ add_character:
       rl_replace_line (cxt->lines[cxt->save_line], 0);
       rl_point = cxt->save_point;
       rl_mark = cxt->save_mark;
+      rl_deactivate_mark ();
       rl_restore_prompt();
       rl_clear_message ();
 
@@ -641,6 +663,7 @@ add_character:
          free (paste);
          break;
        }
+      rl_activate_mark ();
       if (cxt->search_string_index + pastelen + 1 >= cxt->search_string_size)
        {
          cxt->search_string_size += pastelen + 2;
@@ -745,11 +768,15 @@ add_character:
       cxt->sline_index = (cxt->sflags & SF_REVERSE) ? cxt->sline_len - cxt->search_string_index : 0;
     }
 
+  /* reset the keymaps for the next time through the loop */
+  cxt->keymap = cxt->okeymap = _rl_keymap;
+
   if (cxt->sflags & SF_FAILED)
     {
       /* We cannot find the search string.  Ding the bell. */
       rl_ding ();
       cxt->history_pos = cxt->last_found_line;
+      rl_deactivate_mark ();
       rl_display_search (cxt->search_string, cxt->sflags, (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos);
       return 1;
     }
@@ -761,7 +788,10 @@ add_character:
     {
       cxt->prev_line_found = cxt->lines[cxt->history_pos];
       rl_replace_line (cxt->lines[cxt->history_pos], 0);
+      rl_activate_mark ();     
       rl_point = cxt->sline_index;
+      if (rl_mark_active_p () && cxt->search_string_index > 0)
+       rl_mark = rl_point + cxt->search_string_index;
       cxt->last_found_line = cxt->history_pos;
       rl_display_search (cxt->search_string, cxt->sflags, (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos);
     }
index c4675bd7339ded0c8ff72aa5e11a9d53331d88d5..66780e44555d120b4c6a18363bbb71eafb4ec330 100644 (file)
@@ -73,11 +73,11 @@ extern int errno;
 #include "xmalloc.h"
 
 #ifndef RL_LIBRARY_VERSION
-#  define RL_LIBRARY_VERSION "5.1"
+#  define RL_LIBRARY_VERSION "8.0"
 #endif
 
 #ifndef RL_READLINE_VERSION
-#  define RL_READLINE_VERSION  0x0501
+#  define RL_READLINE_VERSION  0x0800
 #endif
 
 extern void _rl_free_history_entry PARAMS((HIST_ENTRY *));
@@ -258,6 +258,9 @@ int rl_executing_key;
 char *rl_executing_keyseq = 0;
 int _rl_executing_keyseq_size = 0;
 
+struct _rl_cmd _rl_pending_command;
+struct _rl_cmd *_rl_command_to_execute = (struct _rl_cmd *)NULL;
+
 /* Timeout (specified in milliseconds) when reading characters making up an
    ambiguous multiple-key sequence */
 int _rl_keyseq_timeout = 500;
@@ -634,6 +637,23 @@ readline_internal_charloop (void)
       r = _rl_dispatch ((unsigned char)c, _rl_keymap);
       RL_CHECK_SIGNALS ();
 
+      if (_rl_command_to_execute)
+       {
+         (*rl_redisplay_function) ();
+
+         rl_executing_keymap = _rl_command_to_execute->map;
+         rl_executing_key = _rl_command_to_execute->key;
+
+         rl_dispatching = 1;
+         RL_SETSTATE(RL_STATE_DISPATCHING);
+         r = (*(_rl_command_to_execute->func)) (_rl_command_to_execute->count, _rl_command_to_execute->key);
+         _rl_command_to_execute = 0;
+         RL_UNSETSTATE(RL_STATE_DISPATCHING);
+         rl_dispatching = 0;
+
+         RL_CHECK_SIGNALS ();
+       }
+
       /* If there was no change in _rl_last_command_was_kill, then no kill
         has taken place.  Note that if input is pending we are reading
         a prefix command, so nothing has changed yet. */
@@ -1260,7 +1280,7 @@ readline_initialize_everything (void)
 
   rl_executing_keyseq = malloc (_rl_executing_keyseq_size = 16);
   if (rl_executing_keyseq)
-    rl_executing_keyseq[0] = '\0';
+    rl_executing_keyseq[rl_key_sequence_length = 0] = '\0';
 }
 
 /* If this system allows us to look at the values of the regular
@@ -1472,3 +1492,31 @@ rl_restore_state (struct readline_state *sp)
 
   return (0);
 }
+
+/* Functions to manage the string that is the current key sequence. */
+
+void
+_rl_init_executing_keyseq (void)
+{
+  rl_executing_keyseq[rl_key_sequence_length = 0] = '\0';
+}
+
+void
+_rl_term_executing_keyseq (void)
+{
+  rl_executing_keyseq[rl_key_sequence_length] = '\0';
+}
+
+void
+_rl_end_executing_keyseq (void)
+{
+  if (rl_key_sequence_length > 0)
+    rl_executing_keyseq[--rl_key_sequence_length] = '\0';
+}
+
+void
+_rl_add_executing_keyseq (int key)
+{
+  RESIZE_KEYSEQ_BUFFER ();
+ rl_executing_keyseq[rl_key_sequence_length++] = key;
+}
index 6d154025dd3772f9b04659a3dc86b12f82fd3a07..71b1b0cf22076a3f46f5bb58fa08efd199e9c766 100644 (file)
@@ -1,6 +1,6 @@
 /* Readline.h -- the names of functions callable from within readline. */
 
-/* Copyright (C) 1987-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2020 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.      
index a9fcfc6374bf38c18b173e5943ab20a86290e5af..4cf25dd75736731aa85d87cc2106217fe7aca924 100644 (file)
@@ -109,6 +109,15 @@ typedef struct  __rl_search_context
   char  *search_terminators;
 } _rl_search_cxt;
 
+struct _rl_cmd {
+  Keymap map;
+  int count;
+  int key;
+  rl_command_func_t *func;
+};
+extern struct _rl_cmd _rl_pending_command;
+extern struct _rl_cmd *_rl_command_to_execute;
+
 /* Callback data for reading numeric arguments */
 #define NUM_SAWMINUS   0x01
 #define NUM_SAWDIGITS  0x02
@@ -285,6 +294,7 @@ extern void _rl_refresh_line PARAMS((void));
 /* input.c */
 extern int _rl_any_typein PARAMS((void));
 extern int _rl_input_available PARAMS((void));
+extern int _rl_nchars_available PARAMS((void));
 extern int _rl_input_queued PARAMS((int));
 extern void _rl_insert_typein PARAMS((int));
 extern int _rl_unget_char PARAMS((int));
@@ -353,6 +363,11 @@ extern int _rl_dispatch PARAMS((int, Keymap));
 extern int _rl_dispatch_subseq PARAMS((int, Keymap, int));
 extern void _rl_internal_char_cleanup PARAMS((void));
 
+extern void _rl_init_executing_keyseq PARAMS((void));
+extern void _rl_term_executing_keyseq PARAMS((void));
+extern void _rl_end_executing_keyseq PARAMS((void));
+extern void _rl_add_executing_keyseq PARAMS((int)); 
+
 /* rltty.c */
 extern int _rl_disable_tty_signals PARAMS((void));
 extern int _rl_restore_tty_signals PARAMS((void));
index bd3be440c2a5b6ec5b5049e2ee50b9cf9951d92f..5b83c466e63e2d1f89ea5966fca67eaf447cb62c 100644 (file)
@@ -178,3 +178,52 @@ i
     4  echo g
     5  echo h
 
+
+0
+1
+2
+(left
+mid
+right)
+A
+B
+
+(left
+mid
+right)
+A
+B
+
+(left
+mid
+right)
+A
+B
+
+0
+1
+2
+(left
+mid
+right)
+A
+B
+(left
+mid
+right)
+A
+B
+
+0
+1
+2
+(left
+mid
+right)
+A
+B
+(left
+mid
+right)
+A
+B
index e7451c7b6856be7a13c1ee78a19874daa7f80b02..8826706e1e634905cbd0517d3b36a9200f991d4c 100644 (file)
@@ -127,3 +127,4 @@ rm -f $TMPDIR/foohist-*
 
 ${THIS_SH} ./history2.sub
 ${THIS_SH} ./history3.sub
+${THIS_SH} ./history4.sub
diff --git a/tests/history4.sub b/tests/history4.sub
new file mode 100644 (file)
index 0000000..a6bfd33
--- /dev/null
@@ -0,0 +1,46 @@
+#   This program is free software: you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+HISTFILE=$TMPDIR/newhistory-$$
+export HISTFILE
+
+HISTSIZE=32
+HISTFILESIZE=32
+echo
+set -o history
+history -c
+echo 0
+echo 1
+echo 2
+echo "(left
+mid
+right)"
+echo A
+echo B
+history -w
+set +o history
+
+echo
+printf $'HISTFILE=\n\cRleft\cO\cO\cO\cO\n' | HISTSIZE= ${THIS_SH} --norc -i 2>/dev/null
+echo
+printf $'HISTFILE=\n\cRleft\cO\cO\cO\cO\n' | HISTSIZE=8 ${THIS_SH} --norc -i 2>/dev/null
+
+input="$(cat $HISTFILE)
+"$'\cP\cP\cP\cO\cO
+'
+
+echo
+printf "$input" | HISTSIZE= HISTFILE= ${THIS_SH} --norc -i 2>/dev/null
+echo
+printf "$input" | HISTSIZE=6 HISTFILE= ${THIS_SH} --norc -i 2>/dev/null
+