commit bash-20200420 snapshot

This commit is contained in:
Chet Ramey
2020-04-22 16:45:28 -04:00
parent 3235014e5b
commit 87d2ae2ae5
17 changed files with 395 additions and 71 deletions
+65
View 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
+1
View File
@@ -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
View 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);
+8 -21
View 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++;
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
View 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}*@}
+2 -18
View 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.",
"",
+2 -2
View 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);
}
}
+81 -2
View File
@@ -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));
+13 -13
View File
@@ -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
View 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)
{
+36 -6
View 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);
}
+51 -3
View 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;
}
+1 -1
View 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.
+15
View 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));
+49
View 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
+1
View File
@@ -127,3 +127,4 @@ rm -f $TMPDIR/foohist-*
${THIS_SH} ./history2.sub
${THIS_SH} ./history3.sub
${THIS_SH} ./history4.sub
+46
View File
@@ -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