commit bash-20200825 snapshot

This commit is contained in:
Chet Ramey
2020-09-01 14:43:43 -04:00
parent e4d38c2d74
commit c261f9b80c
13 changed files with 153 additions and 32 deletions
+46
View File
@@ -8931,3 +8931,49 @@ eval.c
- execute_prompt_command: PROMPT_COMMAND can now be an array, subsuming
PROMPT_COMMANDS, which bash no longer looks for. Prompted by a
suggestion from Martijn Dekker <martijn@inlv.org>
8/26
----
builtins/fc.def
- fc_gethnum: now takes a flags word as the third argument, with two
current flag values: HN_LISTING, which means we are listing history
entries, and HN_FIRST, which means we are parsing the first in a
first,last range of history entries
- fc_gethnum: if we have a number >= 0, and it's out of range, return
different values (0 or last history) depending on whether we are
parsing the first or last in a range argument. Based on a report from
Martijn Dekker <martijn@inlv.org>
8/31
----
parse.y
- grammar: call handle_eof_input_unit from the eof-after-error
production only from interactive top-level shells, so a syntax error
in `eval' doesn't exit an interactive shell. Report and fix from
Koichi Murase <myoga.murase@gmail.com>
bashline.c
- bash_execute_unix_command: if we call parse_and_execute with allocated
memory, make sure not to include SEVAL_NOFREE in the flags so it will
free that command string before returning. Report and fix from
Koichi Murase <myoga.murase@gmail.com>
array.[ch]
- array_to_argv: now takes a second argument: COUNTP; returns the number
of elements stored in the strvec
- array_to_argv: don't store array elements with null values; it makes
it hard for callers to walk the whole array reliably
pcomplete.c
- gen_shell_function_matches: change call to array_to_argv
array.h
- execute_array_command: now takes the entire ARRAY * as the first
parameter
eval.c
- execute_array_command: now takes the entire array, puts the elements
into a strvec, and executes each element of the strvevc as a command.
This protects against a command from PROMPT_COMMAND[n] unsetting the
corresponding element of PROMPT_COMMAND.
From a report from Koichi Murase <myoga.murase@gmail.com>
+10 -3
View File
@@ -810,22 +810,29 @@ WORD_LIST *list;
}
char **
array_to_argv (a)
array_to_argv (a, countp)
ARRAY *a;
int *countp;
{
char **ret, *t;
int i;
ARRAY_ELEMENT *ae;
if (a == 0 || array_empty(a))
if (a == 0 || array_empty(a)) {
if (countp)
*countp = 0;
return ((char **)NULL);
}
ret = strvec_create (array_num_elements (a) + 1);
i = 0;
for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) {
t = element_value (ae);
ret[i++] = t ? savestring (t) : (char *)NULL;
if (t)
ret[i++] = savestring (t);
}
ret[i] = (char *)NULL;
if (countp)
*countp = i;
return (ret);
}
+3 -3
View File
@@ -84,7 +84,7 @@ extern WORD_LIST *array_keys_to_word_list PARAMS((ARRAY *));
extern ARRAY *array_assign_list PARAMS((ARRAY *, WORD_LIST *));
extern char **array_to_argv PARAMS((ARRAY *));
extern char **array_to_argv PARAMS((ARRAY *, int *));
extern char *array_to_kvpair PARAMS((ARRAY *, int));
extern char *array_to_assign PARAMS((ARRAY *, int));
@@ -121,7 +121,7 @@ extern ARRAY *array_from_string PARAMS((char *, char *));
#define ALL_ELEMENT_SUB(c) ((c) == '@' || (c) == '*')
/* In eval.c, but uses ARRAY_ELEMENT * */
extern int execute_array_command PARAMS((ARRAY_ELEMENT *, void *));
/* In eval.c, but uses ARRAY * */
extern int execute_array_command PARAMS((ARRAY *, void *));
#endif /* _ARRAY_H_ */
+1 -1
View File
@@ -4340,7 +4340,7 @@ bash_execute_unix_command (count, key)
save_parser_state (&ps);
rl_clear_signals ();
r = parse_and_execute (savestring (cmd), "bash_execute_unix_command", SEVAL_NOHIST|SEVAL_NOFREE);
r = parse_and_execute (savestring (cmd), "bash_execute_unix_command", SEVAL_NOHIST);
rl_set_signals ();
restore_parser_state (&ps);
+27 -6
View File
@@ -90,6 +90,10 @@ extern int errno;
#define HIST_ERANGE INT_MIN+1
#define HIST_NOTFOUND INT_MIN+2
/* Values for the flags argument to fc_gethnum */
#define HN_LISTING 0x01
#define HN_FIRST 0x02
extern int unlink PARAMS((const char *));
extern FILE *sh_mktmpfp PARAMS((char *, int, char **));
@@ -205,7 +209,7 @@ fc_builtin (list)
break;
case 'l':
listing = 1;
listing = HN_LISTING; /* for fc_gethnum */
break;
case 'r':
@@ -329,7 +333,7 @@ fc_builtin (list)
if (list)
{
histbeg = fc_gethnum (list->word->word, hlist, listing);
histbeg = fc_gethnum (list->word->word, hlist, listing|HN_FIRST);
list = list->next;
if (list)
@@ -538,7 +542,9 @@ fc_number (list)
/* Return an absolute index into HLIST which corresponds to COMMAND. If
COMMAND is a number, then it was specified in relative terms. If it
is a string, then it is the start of a command line present in HLIST.
MODE is 1 if we are listing commands, 0 if we are executing them. */
MODE includes HN_LISTING if we are listing commands, and does not if we
are executing them. If MODE includes HN_FIRST we are looking for the
first history number specification. */
static int
fc_gethnum (command, hlist, mode)
char *command;
@@ -546,9 +552,10 @@ fc_gethnum (command, hlist, mode)
int mode;
{
int sign, n, clen, rh;
register int i, j, last_hist, real_last;
register int i, j, last_hist, real_last, listing;
register char *s;
listing = mode & HN_LISTING;
sign = 1;
/* Count history elements. */
for (i = 0; hlist[i]; i++);
@@ -601,19 +608,33 @@ fc_gethnum (command, hlist, mode)
n = atoi (s);
n *= sign;
/* We want to return something that is an offset to HISTORY_BASE. */
/* If the value is negative or zero, then it is an offset from
the current history item. */
/* We don't use HN_FIRST here, so we don't return different values
depending on whether we're looking for the first or last in a
pair of range arguments, but nobody else does, either. */
if (n < 0)
{
n += i + 1;
return (n < 0 ? 0 : n);
}
else if (n == 0)
return ((sign == -1) ? (mode ? real_last : HIST_INVALID) : i);
return ((sign == -1) ? (listing ? real_last : HIST_INVALID) : i);
else
{
/* If we're out of range (greater than I (last history entry) or
less than HISTORY_BASE, we want to return different values
based on whether or not we are looking for the first or last
value in a desired range of history entries. */
n -= history_base;
return (i < n ? i : n);
if (n < 0)
return (mode & HN_FIRST ? 0 : i);
else if (n >= i)
return (mode & HN_FIRST ? 0 : i);
else
return n;
}
}
+16 -8
View File
@@ -263,17 +263,25 @@ send_pwd_to_eterm ()
}
#if defined (ARRAY_VARS)
/* Caller ensures that A has a non-zero number of elements */
int
execute_array_command (ae, v)
ARRAY_ELEMENT *ae;
execute_array_command (a, v)
ARRAY *a;
void *v;
{
char *tag, *command;
char *tag;
char **argv;
int argc, i;
tag = (char *)v;
command = element_value (ae);
if (command && *command)
execute_variable_command (command, tag);
argc = 0;
argv = array_to_argv (a, &argc);
for (i = 0; i < argc; i++)
{
if (argv[i] && argv[i][0])
execute_variable_command (argv[i], tag);
}
strvec_dispose (argv);
return 0;
}
#endif
@@ -294,11 +302,11 @@ execute_prompt_command ()
if (array_p (pcv))
{
if ((pcmds = array_cell (pcv)) && array_num_elements (pcmds) > 0)
array_walk (pcmds, execute_array_command, "PROMPT_COMMAND");
execute_array_command (pcmds, "PROMPT_COMMAND");
return;
}
else if (assoc_p (pcv))
return;
return; /* currently don't allow associative arrays here */
#endif
command_to_execute = value_cell (pcv);
+2 -2
View File
@@ -148,7 +148,7 @@ static int complete_fncmp PARAMS((const char *, int, const char *, int));
static void display_matches PARAMS((char **));
static int compute_lcd_of_matches PARAMS((char **, int, const char *));
static int postprocess_matches PARAMS((char ***, int));
static int compare_match PARAMS((const char *, const char *));
static int compare_match PARAMS((char *, const char *));
static int complete_get_screenwidth PARAMS((void));
static char *make_quoted_replacement PARAMS((char *, int, char *));
@@ -1969,7 +1969,7 @@ _rl_free_match_list (char **matches)
MATCH that is the product of filename completion, which acts on the dequoted
text. */
static int
compare_match (const char *text, const char *match)
compare_match (char *text, const char *match)
{
char *temp;
int r;
+2 -1
View File
@@ -65,7 +65,8 @@
#define SF_FOUND 0x02
#define SF_FAILED 0x04
#define SF_CHGKMAP 0x08
#define SF_PATTERN 0x10 /* unused so far */
#define SF_PATTERN 0x10
#define SF_NOCASE 0x20 /* unused so far */
typedef struct __rl_search_context
{
+1 -1
View File
@@ -420,9 +420,9 @@ inputunit: simple_list simple_list_terminator
global_command = (COMMAND *)NULL;
if (last_command_exit_value == 0)
last_command_exit_value = EX_BADUSAGE; /* force error return */
handle_eof_input_unit ();
if (interactive && parse_and_execute_level == 0)
{
handle_eof_input_unit ();
YYACCEPT;
}
else
+1 -1
View File
@@ -1184,7 +1184,7 @@ gen_shell_function_matches (cs, cmd, text, line, ind, lwords, nw, cw, foundp)
/* XXX - should we filter the list of completions so only those matching
TEXT are returned? Right now, we do not. */
sl = strlist_create (0);
sl->list = array_to_argv (a);
sl->list = array_to_argv (a, 0);
sl->list_len = sl->list_size = array_num_elements (a);
}
+1 -1
View File
@@ -1,4 +1,4 @@
BUILD_DIR=/usr/local/build/chet/bash/bash-current
BUILD_DIR=/usr/local/build/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
+23 -2
View File
@@ -241,5 +241,26 @@ c
d
echo d
d
11 # other out-of-range behavior for future work
12 fc -l 498 502
a
b
c
d
e
f
4 echo d
5 echo e
6 echo f
out of range 1
6 echo f
7 fc -l
8 echo out of range 1
out of range 2
8 echo out of range 1
9 fc -l 502 498
10 echo out of range 2
out of range 3
10 echo out of range 2
11 fc -l 498 502
12 echo out of range 3
out of range 4
13 fc -l 1 99
+20 -3
View File
@@ -14,7 +14,7 @@
trap 'rm -f $HISTFILE' 0 1 2 3 6 15
HISTFILE=$TMPDIR/foohist-$$
HISTFILE=$TMPDIR/fchist-$$
unset HISTIGNORE HISTCONTROL
set -o history
@@ -33,6 +33,23 @@ fc -l -0
echo d
fc -s 0
# other out-of-range behavior for future work
fc -l 498 502
HISTSIZE=4
history -c
echo a
echo b
echo c
echo d
echo e
echo f
fc -l
echo out of range 1
fc -l 502 498
echo out of range 2
fc -l 498 502
echo out of range 3
fc -l 1 99
# other out-of-range behavior for future work
echo out of range 4
fc -l -20 -40