mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-24 22:37:59 +02:00
commit bash-20200420 snapshot
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+4
-2
@@ -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);
|
||||
|
||||
+8
-21
@@ -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++;
|
||||
int absolute_offset, count;
|
||||
|
||||
if (saved_history_line_to_use >= 0)
|
||||
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;
|
||||
|
||||
+1
-1
@@ -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}*@}
|
||||
|
||||
@@ -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.",
|
||||
"",
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,11 +34,27 @@
|
||||
#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));
|
||||
|
||||
@@ -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) \
|
||||
|
||||
+19
-2
@@ -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)
|
||||
{
|
||||
|
||||
+36
-6
@@ -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);
|
||||
}
|
||||
|
||||
+51
-3
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -127,3 +127,4 @@ rm -f $TMPDIR/foohist-*
|
||||
|
||||
${THIS_SH} ./history2.sub
|
||||
${THIS_SH} ./history3.sub
|
||||
${THIS_SH} ./history4.sub
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user