mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-26 15:23:09 +02:00
commit bash-20161223 snapshot
This commit is contained in:
@@ -12819,3 +12819,37 @@ doc/bash.1,lib/readline/doc/hsuser.texi
|
||||
lib/readline/history.c
|
||||
- remove_history: use memmove to move the history list around instead
|
||||
of a loop that copies pointers one at a time, similar to add_history
|
||||
|
||||
12/19
|
||||
-----
|
||||
configure.ac
|
||||
- linux: make sure PGRP_PIPE is defined unconditionally for all kernel
|
||||
versions greater than 2.3.*
|
||||
|
||||
lib/readline/history.c
|
||||
- clear_history: when clearing the history, reset history_base to 1
|
||||
(its default)
|
||||
- remove_history_range: new function, removes a set of history entries
|
||||
and returns them all for deallocation
|
||||
|
||||
lib/readline/history.h
|
||||
- remove_history_range: extern declaration
|
||||
|
||||
12/20
|
||||
-----
|
||||
execute_cmd.c
|
||||
- eval_arith_for_expr: pass EXP_EXPANDED to evalexp, since we run the
|
||||
expression through expand_words_no_vars
|
||||
|
||||
12/21
|
||||
-----
|
||||
input.c
|
||||
- b_fill_buffer: when read returns EOF or error, and we reset the
|
||||
buffer and pointers, reset the input pointer to 0. Fixes issue
|
||||
reported by Stephane Chazelas <stephane.chazelas@gmail.com>
|
||||
|
||||
12/22
|
||||
-----
|
||||
arrayfunc.[ch],subst.c
|
||||
- array_expand_index: added new FLAGS argument, reserved for future use,
|
||||
changed callers
|
||||
|
||||
+10
-6
@@ -47,6 +47,9 @@ extern int array_needs_making;
|
||||
once, when performing variable expansion. */
|
||||
int assoc_expand_once = 0;
|
||||
|
||||
/* Ditto for indexed array subscripts */
|
||||
int array_expand_once = 1;
|
||||
|
||||
static SHELL_VAR *bind_array_var_internal __P((SHELL_VAR *, arrayind_t, char *, char *, int));
|
||||
static SHELL_VAR *assign_array_element_internal __P((SHELL_VAR *, char *, char *, char *, int, char *, int));
|
||||
|
||||
@@ -337,7 +340,7 @@ assign_array_element_internal (entry, name, vname, sub, sublen, value, flags)
|
||||
}
|
||||
else
|
||||
{
|
||||
ind = array_expand_index (entry, sub, sublen);
|
||||
ind = array_expand_index (entry, sub, sublen, 0);
|
||||
/* negative subscripts to indexed arrays count back from end */
|
||||
if (entry && ind < 0)
|
||||
ind = (array_p (entry) ? array_max_index (array_cell (entry)) : 0) + 1 + ind;
|
||||
@@ -591,7 +594,7 @@ assign_compound_array_list (var, nlist, flags)
|
||||
|
||||
if (array_p (var))
|
||||
{
|
||||
ind = array_expand_index (var, w + 1, len);
|
||||
ind = array_expand_index (var, w + 1, len, 0);
|
||||
/* negative subscripts to indexed arrays count back from end */
|
||||
if (ind < 0)
|
||||
ind = array_max_index (array_cell (var)) + 1 + ind;
|
||||
@@ -813,7 +816,7 @@ unbind_array_element (var, sub, flags)
|
||||
}
|
||||
else if (array_p (var))
|
||||
{
|
||||
ind = array_expand_index (var, sub, len+1);
|
||||
ind = array_expand_index (var, sub, len+1, 0);
|
||||
/* negative subscripts to indexed arrays count back from end */
|
||||
if (ind < 0)
|
||||
ind = array_max_index (array_cell (var)) + 1 + ind;
|
||||
@@ -829,7 +832,7 @@ unbind_array_element (var, sub, flags)
|
||||
else /* array_p (var) == 0 && assoc_p (var) == 0 */
|
||||
{
|
||||
akey = this_command_name;
|
||||
ind = array_expand_index (var, sub, len+1);
|
||||
ind = array_expand_index (var, sub, len+1, 0);
|
||||
this_command_name = akey;
|
||||
if (ind == 0)
|
||||
{
|
||||
@@ -922,10 +925,11 @@ valid_array_reference (name, flags)
|
||||
|
||||
/* Expand the array index beginning at S and extending LEN characters. */
|
||||
arrayind_t
|
||||
array_expand_index (var, s, len)
|
||||
array_expand_index (var, s, len, flags)
|
||||
SHELL_VAR *var;
|
||||
char *s;
|
||||
int len;
|
||||
int flags;
|
||||
{
|
||||
char *exp, *t, *savecmd;
|
||||
int expok;
|
||||
@@ -1117,7 +1121,7 @@ array_value_internal (s, quoted, flags, rtype, indp)
|
||||
{
|
||||
if ((flags & AV_USEIND) == 0 || indp == 0)
|
||||
{
|
||||
ind = array_expand_index (var, t, len);
|
||||
ind = array_expand_index (var, t, len, 0);
|
||||
if (ind < 0)
|
||||
{
|
||||
/* negative subscripts to indexed arrays count back from end */
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ extern int skipsubscript __P((const char *, int, int));
|
||||
extern void print_array_assignment __P((SHELL_VAR *, int));
|
||||
extern void print_assoc_assignment __P((SHELL_VAR *, int));
|
||||
|
||||
extern arrayind_t array_expand_index __P((SHELL_VAR *, char *, int));
|
||||
extern arrayind_t array_expand_index __P((SHELL_VAR *, char *, int, int));
|
||||
extern int valid_array_reference __P((const char *, int));
|
||||
extern char *array_value __P((const char *, int, int, int *, arrayind_t *));
|
||||
extern char *get_array_value __P((const char *, int, int *, arrayind_t *));
|
||||
|
||||
+15
@@ -355,6 +355,21 @@ bash_delete_histent (i)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
bash_delete_history_range (first, last)
|
||||
int first, last;
|
||||
{
|
||||
register int i;
|
||||
HIST_ENTRY **discard_list;
|
||||
|
||||
discard_list = remove_history_range (first, last);
|
||||
for (i = 0; discard_list && discard_list[i]; i++)
|
||||
free_history_entry (discard_list[i]);
|
||||
history_lines_this_session -= i;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
bash_delete_last_history ()
|
||||
{
|
||||
|
||||
@@ -59,6 +59,7 @@ extern void bash_history_disable __P((void));
|
||||
extern void bash_history_enable __P((void));
|
||||
extern void bash_clear_history __P((void));
|
||||
extern int bash_delete_histent __P((int));
|
||||
extern int bash_delete_history_range __P((int, int));
|
||||
extern int bash_delete_last_history __P((void));
|
||||
extern void load_history __P((void));
|
||||
extern void save_history __P((void));
|
||||
|
||||
+47
-2
@@ -106,7 +106,7 @@ history_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int flags, opt, result, old_history_lines, obase, ind;
|
||||
char *filename, *delete_arg;
|
||||
char *filename, *delete_arg, *range;
|
||||
intmax_t delete_offset;
|
||||
|
||||
flags = 0;
|
||||
@@ -179,6 +179,46 @@ history_builtin (list)
|
||||
return (sh_chkwrite (EXECUTION_SUCCESS));
|
||||
}
|
||||
#endif
|
||||
#if defined (BASH_50) /* bash 5.0 */
|
||||
else if ((flags & DFLAG) && (range = strchr (delete_arg[0] == '-' ? delete_arg + 1 : delete_arg, '-')))
|
||||
{
|
||||
intmax_t delete_start, delete_end;
|
||||
*range++ = '\0';
|
||||
if (legal_number (delete_arg, &delete_start) == 0 || legal_number (range, &delete_end) == 0)
|
||||
{
|
||||
sh_erange (delete_arg, _("history position"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
if (delete_arg[0] == '-' && delete_start < 0)
|
||||
{
|
||||
/* the_history[history_length == 0x0, so this is correct */
|
||||
delete_start += history_length;
|
||||
if (delete_start < history_base)
|
||||
{
|
||||
sh_erange (delete_arg, _("history position"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
}
|
||||
/* numbers as displayed by display_history are offset by history_base */
|
||||
else if (delete_start > 0)
|
||||
delete_start -= history_base;
|
||||
if (range[0] == '-' && delete_end < 0)
|
||||
{
|
||||
delete_end += history_length;
|
||||
if (delete_end < history_base)
|
||||
{
|
||||
sh_erange (delete_arg, _("history position"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
}
|
||||
else if (delete_end > 0)
|
||||
delete_end -= history_base;
|
||||
result = bash_delete_history_range (delete_start, delete_end);
|
||||
if (where_history () > history_length)
|
||||
history_set_pos (history_length);
|
||||
return (result ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
|
||||
}
|
||||
#endif /* BASH_50 */
|
||||
else if (flags & DFLAG)
|
||||
{
|
||||
if (legal_number (delete_arg, &delete_offset) == 0)
|
||||
@@ -189,13 +229,16 @@ history_builtin (list)
|
||||
/* check for negative offsets, count back from end of list */
|
||||
if (delete_arg[0] == '-' && delete_offset < 0)
|
||||
{
|
||||
/* since the_history[history_length] == 0x0, this calculation means
|
||||
that history -d -1 will delete the last history entry, which at
|
||||
this point is the history -d -1 we just added. */
|
||||
ind = history_length + delete_offset;
|
||||
if (ind < history_base)
|
||||
{
|
||||
sh_erange (delete_arg, _("history position"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
opt = ind + 1; /* so history -d -1 deletes last history entry */
|
||||
opt = ind + history_base; /* compensate for opt - history_base below */
|
||||
}
|
||||
else if ((delete_offset < history_base) || (delete_offset > (history_base + history_length)))
|
||||
{
|
||||
@@ -205,6 +248,8 @@ history_builtin (list)
|
||||
else
|
||||
opt = delete_offset;
|
||||
|
||||
/* Positive arguments from numbers as displayed by display_history need
|
||||
to be offset by history_base */
|
||||
result = bash_delete_histent (opt - history_base);
|
||||
/* Since remove_history changes history_length, this can happen if
|
||||
we delete the last history entry. */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#! /bin/sh
|
||||
# From configure.ac for Bash 4.4, version 4.087.
|
||||
# From configure.ac for Bash 4.4, version 4.088.
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for bash 4.4-maint.
|
||||
#
|
||||
@@ -16170,7 +16170,8 @@ solaris2*) LOCAL_CFLAGS=-DSOLARIS ;;
|
||||
lynxos*) LOCAL_CFLAGS=-DRECYCLES_PIDS ;;
|
||||
linux*) LOCAL_LDFLAGS=-rdynamic # allow dynamic loading
|
||||
case "`uname -r`" in
|
||||
2.[456789]*|[34]*) $as_echo "#define PGRP_PIPE 1" >>confdefs.h
|
||||
1.*|2.[0123]*) : ;;
|
||||
*) $as_echo "#define PGRP_PIPE 1" >>confdefs.h
|
||||
;;
|
||||
esac ;;
|
||||
*qnx6*) LOCAL_CFLAGS="-Dqnx -Dqnx6" LOCAL_LIBS="-lncurses" ;;
|
||||
|
||||
+3
-2
@@ -21,7 +21,7 @@ dnl Process this file with autoconf to produce a configure script.
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
AC_REVISION([for Bash 4.4, version 4.087])dnl
|
||||
AC_REVISION([for Bash 4.4, version 4.088])dnl
|
||||
|
||||
define(bashvers, 4.4)
|
||||
define(relstatus, maint)
|
||||
@@ -1105,7 +1105,8 @@ solaris2*) LOCAL_CFLAGS=-DSOLARIS ;;
|
||||
lynxos*) LOCAL_CFLAGS=-DRECYCLES_PIDS ;;
|
||||
linux*) LOCAL_LDFLAGS=-rdynamic # allow dynamic loading
|
||||
case "`uname -r`" in
|
||||
2.[[456789]]*|[[34]]*) AC_DEFINE(PGRP_PIPE) ;;
|
||||
1.*|2.[[0123]]*) : ;;
|
||||
*) AC_DEFINE(PGRP_PIPE) ;;
|
||||
esac ;;
|
||||
*qnx6*) LOCAL_CFLAGS="-Dqnx -Dqnx6" LOCAL_LIBS="-lncurses" ;;
|
||||
*qnx*) LOCAL_CFLAGS="-Dqnx -F -3s" LOCAL_LDFLAGS="-3s" LOCAL_LIBS="-lunix -lncurses" ;;
|
||||
|
||||
+2
-2
@@ -2911,7 +2911,7 @@ eval_arith_for_expr (l, okp)
|
||||
skip the command. */
|
||||
#if defined (DEBUGGER)
|
||||
if (debugging_mode == 0 || r == EXECUTION_SUCCESS)
|
||||
expresult = evalexp (new->word->word, 0, okp);
|
||||
expresult = evalexp (new->word->word, EXP_EXPANDED, okp);
|
||||
else
|
||||
{
|
||||
expresult = 0;
|
||||
@@ -2919,7 +2919,7 @@ eval_arith_for_expr (l, okp)
|
||||
*okp = 1;
|
||||
}
|
||||
#else
|
||||
expresult = evalexp (new->word->word, 0, okp);
|
||||
expresult = evalexp (new->word->word, EXP_EXPANDED, okp);
|
||||
#endif
|
||||
dispose_words (new);
|
||||
}
|
||||
|
||||
@@ -504,7 +504,7 @@ b_fill_buffer (bp)
|
||||
nr = zread (bp->b_fd, bp->b_buffer, bp->b_size);
|
||||
if (nr <= 0)
|
||||
{
|
||||
bp->b_used = 0;
|
||||
bp->b_used = bp->b_inputp = 0;
|
||||
bp->b_buffer[0] = 0;
|
||||
if (nr == 0)
|
||||
bp->b_flag |= B_EOF;
|
||||
|
||||
@@ -525,6 +525,43 @@ remove_history (which)
|
||||
return (return_value);
|
||||
}
|
||||
|
||||
HIST_ENTRY **
|
||||
remove_history_range (first, last)
|
||||
int first, last;
|
||||
{
|
||||
HIST_ENTRY **return_value;
|
||||
register int i;
|
||||
int nentries;
|
||||
HIST_ENTRY **start, **end;
|
||||
|
||||
if (the_history == 0 || history_length == 0)
|
||||
return ((HIST_ENTRY **)NULL);
|
||||
if (first < 0 || first >= history_length || last < 0 || last >= history_length)
|
||||
return ((HIST_ENTRY **)NULL);
|
||||
if (first > last)
|
||||
return (HIST_ENTRY **)NULL;
|
||||
|
||||
nentries = last - first + 1;
|
||||
return_value = (HIST_ENTRY **)malloc ((nentries + 1) * sizeof (HIST_ENTRY *));
|
||||
if (return_value == 0)
|
||||
return return_value;
|
||||
|
||||
/* Return all the deleted entries in a list */
|
||||
for (i = first ; i <= last; i++)
|
||||
return_value[i - first] = the_history[i];
|
||||
return_value[i - first] = (HIST_ENTRY *)NULL;
|
||||
|
||||
/* Copy the rest of the entries, moving down NENTRIES slots. Copy includes
|
||||
trailing NULL. */
|
||||
start = the_history + first;
|
||||
end = the_history + last + 1;
|
||||
memmove (start, end, (history_length - last) * sizeof (HIST_ENTRY *));
|
||||
|
||||
history_length -= nentries;
|
||||
|
||||
return (return_value);
|
||||
}
|
||||
|
||||
/* Stifle the history list, remembering only MAX number of lines. */
|
||||
void
|
||||
stifle_history (max)
|
||||
@@ -586,4 +623,5 @@ clear_history ()
|
||||
}
|
||||
|
||||
history_offset = history_length = 0;
|
||||
history_base = 1; /* reset history base to default */
|
||||
}
|
||||
|
||||
@@ -86,11 +86,13 @@ extern void add_history PARAMS((const char *));
|
||||
STRING. */
|
||||
extern void add_history_time PARAMS((const char *));
|
||||
|
||||
/* A reasonably useless function, only here for completeness. WHICH
|
||||
is the magic number that tells us which element to delete. The
|
||||
elements are numbered from 0. */
|
||||
/* Remove an entry from the history list. WHICH is the magic number that
|
||||
tells us which element to delete. The elements are numbered from 0. */
|
||||
extern HIST_ENTRY *remove_history PARAMS((int));
|
||||
|
||||
/* Remove a set of entries from the history list: FIRST to LAST, inclusive */
|
||||
extern HIST_ENTRY **remove_history_range PARAMS((int, int));
|
||||
|
||||
/* Allocate a history entry consisting of STRING and TIMESTAMP and return
|
||||
a pointer to it. */
|
||||
extern HIST_ENTRY *alloc_history_entry PARAMS((char *, char *));
|
||||
|
||||
@@ -6464,7 +6464,7 @@ array_length_reference (s)
|
||||
}
|
||||
else
|
||||
{
|
||||
ind = array_expand_index (var, t, len);
|
||||
ind = array_expand_index (var, t, len, 0);
|
||||
/* negative subscripts to indexed arrays count back from end */
|
||||
if (var && array_p (var) && ind < 0)
|
||||
ind = array_max_index (array_cell (var)) + 1 + ind;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
BUILD_DIR=/usr/local/build/bash/bash-current
|
||||
BUILD_DIR=/usr/local/build/chet/bash/bash-current
|
||||
THIS_SH=$BUILD_DIR/bash
|
||||
PATH=$PATH:$BUILD_DIR
|
||||
|
||||
|
||||
+62
@@ -2760,6 +2760,52 @@ make_variable_value (var, value, flags)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* If we can optimize appending to string variables, say so */
|
||||
static int
|
||||
can_optimize_assignment (entry, value, aflags)
|
||||
SHELL_VAR *entry;
|
||||
char *value;
|
||||
int aflags;
|
||||
{
|
||||
if ((aflags & ASS_APPEND) == 0)
|
||||
return 0;
|
||||
#if defined (ARRAY_VARS)
|
||||
if (array_p (entry) || assoc_p (entry))
|
||||
return 0;
|
||||
#endif
|
||||
if (integer_p (entry) || uppercase_p (entry) || lowercase_p (entry) || capcase_p (entry))
|
||||
return 0;
|
||||
if (readonly_p (entry) || noassign_p (entry))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* right now we optimize appends to string variables */
|
||||
static SHELL_VAR *
|
||||
optimized_assignment (entry, value, aflags)
|
||||
SHELL_VAR *entry;
|
||||
char *value;
|
||||
int aflags;
|
||||
{
|
||||
size_t len, vlen;
|
||||
char *v, *new;
|
||||
|
||||
v = value_cell (entry);
|
||||
len = STRLEN (v);
|
||||
vlen = STRLEN (value);
|
||||
|
||||
new = (char *)xrealloc (v, len + vlen + 8); /* for now */
|
||||
if (vlen == 1)
|
||||
{
|
||||
new[len] = *value;
|
||||
new[len+1] = '\0';
|
||||
}
|
||||
else
|
||||
strcpy (new + len, value);
|
||||
var_setvalue (entry, new);
|
||||
return entry;
|
||||
}
|
||||
|
||||
/* Bind a variable NAME to VALUE in the HASH_TABLE TABLE, which may be the
|
||||
temporary environment (but usually is not). */
|
||||
static SHELL_VAR *
|
||||
@@ -2863,6 +2909,22 @@ assign_value:
|
||||
else
|
||||
#endif
|
||||
|
||||
/* If we can optimize the assignment, do so and return. Right now, we
|
||||
optimize appends to string variables. */
|
||||
if (can_optimize_assignment (entry, value, aflags))
|
||||
{
|
||||
INVALIDATE_EXPORTSTR (entry);
|
||||
optimized_assignment (entry, value, aflags);
|
||||
|
||||
if (mark_modified_vars)
|
||||
VSETATTR (entry, att_exported);
|
||||
|
||||
if (exported_p (entry))
|
||||
array_needs_making = 1;
|
||||
|
||||
return (entry);
|
||||
}
|
||||
|
||||
newval = make_variable_value (entry, value, aflags); /* XXX */
|
||||
|
||||
/* Invalidate any cached export string */
|
||||
|
||||
Reference in New Issue
Block a user