add numeric arguments to bind -x commands and READLINE_ARGUMENT; minor fixes

This commit is contained in:
Chet Ramey
2021-05-24 16:09:47 -04:00
parent 7b024db83e
commit 2047e28584
30 changed files with 365 additions and 43 deletions
+93
View File
@@ -10358,3 +10358,96 @@ arrayfunc.c
builtins/printf.def
- printf_builtin: if LIST_OPTFLAGS includes W_ARRAYREF, set VA_NOEXPAND
in VFLAGS
5/17
----
lib/readline/complete.c
- compute_lcd_of_matches: move a couple of strlen calls out of a loop
in calls to mbrtowc; performance improvement only. Report and fix
from sparrowhawk996@gmail.com
lib/readline/bind.c
- rl_trim_arg_from_keyseq: take a key sequence and its length and
return the index into the key sequence following any initial numeric
argument. Return -1 if there is no numeric argument (the caller is
expected to make sure) or if the key sequence consists *only* of
the numeric argument. The caller should use the remainder of the
key sequence to look up the desired key binding.
lib/readline/readline.h
- rl_trim_arg_from_keyseq: extern declaration
bashline.c
- bash_execute_unix_command: if the argument count is > 1 or we have
an explicit argument, call rl_trim_arg_from_keyseq to get past the
numeric argument and deal with the rest of the key sequence. We still
need a way to pass it to the invoked program or function. From
a report from Jesper Nygards <jesper.nygards@gmail.com>
5/18
----
bashline.c
- bash_execute_unix_command: if the user supplied a numeric argument
when invoking bash_execute_unix_command, pass it to the command in
the READLINE_ARGUMENT variable
lib/readline/readline.[ch]
- _rl_del_executing_keyseq: convenience function to `delete' the last
character added to the executing key sequence. Intended to be used
before calling rl_execute_next or similar functions that push input
back to be re-read
doc/{bash.1,bashref.texi}
- READLINE_ARGUMENT: documented new variable available for commands
defined using `bind -x' keybindings
lib/readline/doc/rltech.texi
- rl_trim_arg_from_keyseq: documented new function
5/19
----
builtins/evalstring.c
- should_suppress_fork: suppress the fork if we're in a process
substitution subshell, in addition to being a simple command
without redirections. From a report back in 10/2020 from
Hyunho Cho <mug896@gmail.com>
bashline.c
- command_word_completion_function: if we're trying to complete an
absolute program (one containing a slash), don't run strcmp or
strcasecmp on the return value from rl_filename_completion_function,
since that duplicates work the filename completion function already
does. From a report back in 1/2021 by awa54@cdak.net
5/22
----
parse.y
- CHECK_FOR_RESERVED_WORD: if we are returning an ESAC and unsetting
PST_CASESTMT, decrement esacs_needed_count
parse.y,shell.h
- sh_parser_state_t: save and restore esacs_needed_count and
expecting_in_token in the shell parser state struct and
save_parser_state/restore_parser_state
print_cmd.c
- print_simple_command: don't bother to call command_print_word_list
with an empty list
- print_simple_command: don't print a space before a redirection list
if there weren't any command words to print
5/24
----
lib/sh/input_avail.c
- nchars_avail: make sure SET and OSET are declared on systems with
select(2). Reported by Larkin Nickle <me@larbob.org>
parse.y
- cond_term: if we read a `!' toggle CMD_INVERT_RETURN instead of
setting it unconditionally. Report and patch from
Vincent Menegaux <vincent.menegaux@gmail.com> via
https://savannah.gnu.org/patch/?10070
+32 -1
View File
@@ -2301,10 +2301,16 @@ globword:
if (absolute_program (hint))
{
#if 0
if (igncase == 0)
match = strncmp (val, hint, hint_len) == 0;
else
match = strncasecmp (val, hint, hint_len) == 0;
#else
/* Why duplicate the comparison rl_filename_completion_function
already performs? */
match = 1;
#endif
/* If we performed tilde expansion, restore the original
filename. */
@@ -4371,12 +4377,28 @@ bash_execute_unix_command (count, key)
SHELL_VAR *v;
char ibuf[INT_STRLEN_BOUND(int) + 1];
Keymap cmd_xmap;
const char *kseq;
size_t kslen;
kseq = rl_executing_keyseq;
kslen = rl_key_sequence_length;
/* If we have a numeric argument, chop it off the front of the key sequence */
if (count > 1 || rl_explicit_arg)
{
i = rl_trim_arg_from_keyseq (rl_executing_keyseq, rl_key_sequence_length, rl_get_keymap ());
if (i > 0)
{
kseq = rl_executing_keyseq + i;
kslen = rl_key_sequence_length - i;
}
}
/* First, we need to find the right command to execute. This is tricky,
because we might have already indirected into another keymap, so we
have to walk cmd_xmap using the entire key sequence. */
cmd_xmap = get_cmd_xmap_from_keymap (rl_get_keymap ());
cmd = (char *)rl_function_of_keyseq_len (rl_executing_keyseq, rl_key_sequence_length, cmd_xmap, &type);
cmd = (char *)rl_function_of_keyseq_len (kseq, kslen, cmd_xmap, &type);
if (type == ISKMAP && (type = ((Keymap) cmd)[ANYOTHERKEY].type) == ISMACR)
cmd = (char*)((Keymap) cmd)[ANYOTHERKEY].function;
@@ -4413,6 +4435,14 @@ bash_execute_unix_command (count, key)
v = bind_int_variable ("READLINE_MARK", value, 0);
if (v)
VSETATTR (v, att_exported);
if (count > 1 || rl_explicit_arg)
{
value = inttostr (count, ibuf, sizeof (ibuf));
v = bind_int_variable ("READLINE_ARGUMENT", value, 0);
if (v)
VSETATTR (v, att_exported);
}
array_needs_making = 1;
save_parser_state (&ps);
@@ -4435,6 +4465,7 @@ bash_execute_unix_command (count, key)
check_unbind_variable ("READLINE_LINE");
check_unbind_variable ("READLINE_POINT");
check_unbind_variable ("READLINE_MARK");
check_unbind_variable ("READLINE_ARGUMENT");
array_needs_making = 1;
/* and restore the readline buffer and display after command execution. */
+3 -5
View File
@@ -88,20 +88,18 @@ int
should_suppress_fork (command)
COMMAND *command;
{
#if 0 /* TAG: bash-5.2 */
int subshell;
subshell = subshell_environment & SUBSHELL_PROCSUB; /* salt to taste */
#endif
return (startup_state == 2 && parse_and_execute_level == 1 &&
running_trap == 0 &&
*bash_input.location.string == '\0' &&
parser_expanding_alias () == 0 &&
running_trap == 0 &&
command->type == cm_simple &&
signal_is_trapped (EXIT_TRAP) == 0 &&
signal_is_trapped (ERROR_TRAP) == 0 &&
any_signals_trapped () < 0 &&
#if 0 /* TAG: bash-5.2 */
#if 1 /* TAG: bash-5.2 */
(subshell || (command->redirects == 0 && command->value.Simple->redirects == 0)) &&
#else
command->redirects == 0 && command->value.Simple->redirects == 0 &&
@@ -575,9 +573,9 @@ parse_string (string, from_file, flags, endp)
code = should_jump_to_top_level = 0;
oglobal = global_command;
ostring = string;
with_input_from_string (string, from_file);
ostring = bash_input.location.string;
while (*(bash_input.location.string)) /* XXX - parser_expanding_alias () ? */
{
command = (COMMAND *)NULL;
+1 -1
View File
@@ -152,7 +152,7 @@ wait_builtin (list)
int arrayflags;
#if 0
arrayflags = assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0;
arrayflags = assoc_expand_once ? VA_NOEXPAND : 0;
if (assoc_expand_once && (list_optflags & W_ARRAYREF))
arrayflags |= VA_ONEWORD|VA_NOEXPAND;
#else
+30 -10
View File
@@ -711,11 +711,12 @@ the conditional expression \fIexpression\fP.
Expressions are composed of the primaries described below under
.SM
.BR "CONDITIONAL EXPRESSIONS" .
Word splitting and pathname expansion are not performed on the words
between the \fB[[\fP and \fB]]\fP; tilde expansion,
parameter and variable expansion,
arithmetic expansion, command substitution, process
substitution, and quote removal are performed.
The words between the \fB[[\fP and \fB]]\fP do not undergo word splitting
and filename expansion.
The shell performs tilde expansion, parameter and
variable expansion, arithmetic expansion, command substitution, process
substitution, and quote removal on those words
(as if the words were enclosed in double quotes).
Conditional operators such as \fB\-f\fP must be unquoted to be recognized
as primaries.
.if t .sp 0.5
@@ -1953,6 +1954,16 @@ If
is unset, it loses its special properties, even if it is
subsequently reset.
.TP
.B READLINE_ARGUMENT
Any numeric argument given to a Readline command that was defined using
.if t \f(CWbind -x\fP
.if n "bind -x"
(see
.SM
.B "SHELL BUILTIN COMMANDS"
below)
when it was invoked.
.TP
.B READLINE_LINE
The contents of the
.B readline
@@ -5048,6 +5059,9 @@ while they execute.
All builtins return an exit status of 2 to indicate incorrect usage,
generally invalid options or missing arguments.
.PP
The exit status of the last command is available in the special
parameter $?.
.PP
\fBBash\fP itself returns the exit status of the last command
executed, unless a syntax error occurs, in which case it exits
with a non-zero value. See also the \fBexit\fP builtin
@@ -7478,7 +7492,8 @@ does not contain a slash, filenames in
.SM
.B PATH
are used to find the directory containing
.IR filename .
.IR filename ,
but \fIfilename\fP does not need to be executable.
The file searched for in
.SM
.B PATH
@@ -7498,12 +7513,12 @@ is not searched.
If any \fIarguments\fP are supplied, they become the positional
parameters when \fIfilename\fP is executed. Otherwise the positional
parameters are unchanged.
If the \fB\-T\fP option is enabled, \fBsource\fP inherits any trap on
If the \fB\-T\fP option is enabled, \fB.\fP inherits any trap on
\fBDEBUG\fP; if it is not, any \fBDEBUG\fP trap string is saved and
restored around the call to \fBsource\fP, and \fBsource\fP unsets the
restored around the call to \fB.\fP, and \fB.\fP unsets the
\fBDEBUG\fP trap while it executes.
If \fB\-T\fP is not set, and the sourced file changes
the \fBDEBUG\fP trap, the new value is retained when \fBsource\fP completes.
the \fBDEBUG\fP trap, the new value is retained when \fB.\fP completes.
The return status is the status of the last command exited within
the script (0 if no commands are executed), and false if
.I filename
@@ -7633,6 +7648,11 @@ and
.B READLINE_MARK
variables to the current location of the insertion point and the saved
insertion point (the mark), respectively.
The shell assigns any numeric argument the user supplied to the
.SM
.B READLINE_ARGUMENT
variable.
If there was no argument, that variable is not set.
If the executed command changes the value of any of
.SM
.BR READLINE_LINE ,
@@ -10360,7 +10380,7 @@ number of positional parameters.
.TP 8
.B sourcepath
If set, the
\fBsource\fP (\fB.\fP) builtin uses the value of
\fB.\fP (\fBsource\fP) builtin uses the value of
.SM
.B PATH
to find the directory containing the file supplied as an argument.
+24 -9
View File
@@ -1145,10 +1145,12 @@ Return a status of 0 or 1 depending on the evaluation of
the conditional expression @var{expression}.
Expressions are composed of the primaries described below in
@ref{Bash Conditional Expressions}.
Word splitting and filename expansion are not performed on the words
between the @code{[[} and @code{]]}; tilde expansion, parameter and
The words between the @code{[[} and @code{]]} do not undergo word splitting
and filename expansion.
The shell performs tilde expansion, parameter and
variable expansion, arithmetic expansion, command substitution, process
substitution, and quote removal are performed.
substitution, and quote removal on those words
(as if the words were enclosed in double quotes).
Conditional operators such as @samp{-f} must be unquoted to be recognized
as primaries.
@@ -1813,7 +1815,8 @@ If @var{value}
is not given, the variable is assigned the null string. All
@var{value}s undergo tilde expansion, parameter and variable expansion,
command substitution, arithmetic expansion, and quote
removal (detailed below). If the variable has its @code{integer}
removal (@pxref{Shell Parameter Expansion}).
If the variable has its @code{integer}
attribute set, then @var{value}
is evaluated as an arithmetic expression even if the @code{$((@dots{}))}
expansion is not used (@pxref{Arithmetic Expansion}).
@@ -3491,6 +3494,9 @@ conditional and list constructs.
All builtins return an exit status of 2 to indicate incorrect usage,
generally invalid options or missing arguments.
The exit status of the last command is available in the special
parameter $? (@pxref{Special Parameters}).
@node Signals
@subsection Signals
@cindex signal handling
@@ -3677,18 +3683,19 @@ The return status is zero.
Read and execute commands from the @var{filename} argument in the
current shell context. If @var{filename} does not contain a slash,
the @env{PATH} variable is used to find @var{filename}.
the @env{PATH} variable is used to find @var{filename},
but @var{filename} does not need to be executable.
When Bash is not in @sc{posix} mode, the current directory is searched
if @var{filename} is not found in @env{$PATH}.
If any @var{arguments} are supplied, they become the positional
parameters when @var{filename} is executed. Otherwise the positional
parameters are unchanged.
If the @option{-T} option is enabled, @code{source} inherits any trap on
If the @option{-T} option is enabled, @code{.} inherits any trap on
@code{DEBUG}; if it is not, any @code{DEBUG} trap string is saved and
restored around the call to @code{source}, and @code{source} unsets the
restored around the call to @code{.}, and @code{.} unsets the
@code{DEBUG} trap while it executes.
If @option{-T} is not set, and the sourced file changes
the @code{DEBUG} trap, the new value is retained when @code{source} completes.
the @code{DEBUG} trap, the new value is retained when @code{.} completes.
The return status is the exit status of the last command executed, or
zero if no commands are executed. If @var{filename} is not found, or
cannot be read, the return status is non-zero.
@@ -4325,6 +4332,9 @@ When @var{shell-command} is executed, the shell sets the
buffer and the @code{READLINE_POINT} and @code{READLINE_MARK} variables
to the current location of the insertion point and the saved insertion
point (the @var{mark}), respectively.
The shell assigns any numeric argument the user supplied to the
@code{READLINE_ARGUMENT} variable.
If there was no argument, that variable is not set.
If the executed command changes the value of any of @code{READLINE_LINE},
@code{READLINE_POINT}, or @code{READLINE_MARK}, those new values will be
reflected in the editing state.
@@ -5745,7 +5755,7 @@ builtin prints an error message when the shift count exceeds the
number of positional parameters.
@item sourcepath
If set, the @code{source} builtin uses the value of @env{PATH}
If set, the @code{.} (@code{source}) builtin uses the value of @env{PATH}
to find the directory containing the file supplied as an argument.
This option is enabled by default.
@@ -6547,6 +6557,11 @@ If @env{RANDOM}
is unset, it loses its special properties, even if it is
subsequently reset.
@item READLINE_ARGUMENT
Any numeric argument given to a Readline command that was defined using
@samp{bind -x} (@pxref{Bash Builtins}
when it was invoked.
@item READLINE_LINE
The contents of the Readline line buffer, for use
with @samp{bind -x} (@pxref{Bash Builtins}).
+2 -2
View File
@@ -2,10 +2,10 @@
Copyright (C) 1988-2021 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Mon May 10 10:12:46 EDT 2021
@set LASTCHANGE Tue May 18 11:34:00 EDT 2021
@set EDITION 5.1
@set VERSION 5.1
@set UPDATED 10 May 2021
@set UPDATED 18 May 2021
@set UPDATED-MONTH May 2021
+4 -1
View File
@@ -1477,6 +1477,7 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
/* If a command is asynchronous in a subshell (like ( foo ) & or
the special case of an asynchronous GROUP command where the
the subshell bit is turned on down in case cm_group: below),
turn off `asynchronous', so that two subshells aren't spawned.
XXX - asynchronous used to be set to 0 in this block, but that
@@ -1621,7 +1622,9 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
default_buffered_input = -1;
#endif
#if 0 /* TAG: bash-5.2 */
#if 0
/* We can't optimize if one of the commands executed by the subshell sets
an exit trap. */
if (user_subshell && command->type == cm_subshell)
optimize_subshell_command (command->value.Subshell->command);
#endif
+69
View File
@@ -880,6 +880,75 @@ rl_function_of_keyseq_len (const char *keyseq, size_t len, Keymap map, int *type
return _rl_function_of_keyseq_internal (keyseq, len, map, type);
}
/* Assuming there is a numeric argument at the beginning of KEYSEQ (the
caller is responsible for checking), return the index of the portion of
the key sequence following the numeric argument. If there's no numeric
argument (?), or if KEYSEQ consists solely of a numeric argument (?),
return -1. */
int
rl_trim_arg_from_keyseq (const char *keyseq, size_t len, Keymap map)
{
register int i, parsing_digits;
unsigned char ic;
if (map == 0)
map = _rl_keymap;
/* The digits following the initial one (e.g., the binding to digit-argument)
or the optional `-' in a binding to digit-argument or universal-argument
are not added to rl_executing_keyseq. This is basically everything read by
rl_digit_loop. The parsing_digits logic is here in case they ever are. */
for (i = parsing_digits = 0; keyseq && i < len; i++)
{
ic = keyseq[i];
if (parsing_digits)
{
if (_rl_digit_p (ic) == 0)
return (i);
continue;
}
if (map[ic].type == ISKMAP)
{
if (i + 1 == len)
return -1;
map = FUNCTION_TO_KEYMAP (map, ic);
continue;
}
if (map[ic].type == ISFUNC)
{
if (map[ic].function != rl_digit_argument && map[ic].function != rl_universal_argument)
return -1;
/* We don't bother with a keyseq that is only a numeric argument */
if (i + 1 == len)
return -1;
parsing_digits = 1;
/* This logic should be identical to rl_digit_loop */
/* We accept M-- as equivalent to M--1, C-u- as equivalent to C-u-1
but set parsing_digits to 2 to note that we saw `-' */
if (map[ic].function == rl_universal_argument && (i + 1 == '-'))
{
i++;
parsing_digits = 2;
continue;
}
if (map[ic].function == rl_digit_argument && ic == '-')
{
parsing_digits = 2;
continue;
}
}
}
/* If we're still parsing digits by the time we get here, we don't allow a
key sequence that consists solely of a numeric argument */
return -1;
}
/* The last key bindings file read. */
static char *last_readline_init_file = (char *)NULL;
+9
View File
@@ -885,6 +885,15 @@ It takes a "translated" key sequence and should be used if the key sequence
can include NUL.
@end deftypefun
@deftypefun {int} rl_trim_arg_from_keyseq (const char *keyseq, size_t len, Keymap map)
If there is a numeric argument at the beginning of @var{keyseq}, possibly
including digits, return the index of the first character in @var{keyseq}
following the numeric argument.
This can be used to skip over the numeric argument (which is available as
@code{rl_numeric_arg} while traversing the key sequence that invoked the
current command.
@end deftypefun
@deftypefun {char **} rl_invoking_keyseqs (rl_command_func_t *function)
Return an array of strings representing the key sequences used to
invoke @var{function} in the current keymap.
+3 -3
View File
@@ -4,7 +4,7 @@ Copyright (C) 1988-2021 Free Software Foundation, Inc.
@set EDITION 8.1
@set VERSION 8.1
@set UPDATED 28 April 2021
@set UPDATED-MONTH April 2021
@set UPDATED 18 May 2021
@set UPDATED-MONTH May 2021
@set LASTCHANGE Wed Apr 28 14:30:42 EDT 2021
@set LASTCHANGE Tue May 18 11:44:17 EDT 2021
+9
View File
@@ -1549,3 +1549,12 @@ _rl_add_executing_keyseq (int key)
RESIZE_KEYSEQ_BUFFER ();
rl_executing_keyseq[rl_key_sequence_length++] = key;
}
/* `delete' the last character added to the executing key sequence. Use this
before calling rl_execute_next to avoid keys being added twice. */
void
_rl_del_executing_keyseq (void)
{
if (rl_key_sequence_length > 0)
rl_key_sequence_length--;
}
+1
View File
@@ -336,6 +336,7 @@ extern char *rl_untranslate_keyseq (int);
extern rl_command_func_t *rl_named_function (const char *);
extern rl_command_func_t *rl_function_of_keyseq (const char *, Keymap, int *);
extern rl_command_func_t *rl_function_of_keyseq_len (const char *, size_t, Keymap, int *);
extern int rl_trim_arg_from_keyseq (const char *, size_t, Keymap);
extern void rl_list_funmap_names (void);
extern char **rl_invoking_keyseqs_in_map (rl_command_func_t *, Keymap);
+1
View File
@@ -379,6 +379,7 @@ extern void _rl_init_executing_keyseq (void);
extern void _rl_term_executing_keyseq (void);
extern void _rl_end_executing_keyseq (void);
extern void _rl_add_executing_keyseq (int);
extern void _rl_del_executing_keyseq (void);
/* rltty.c */
extern int _rl_disable_tty_signals (void);
+1 -1
View File
@@ -110,7 +110,7 @@ nchars_avail (fd, nchars)
#if defined(HAVE_SELECT)
fd_set readfds, exceptfds;
#endif
#if defined (HAVE_PSELECT)
#if defined (HAVE_PSELECT) || defined (HAVE_SELECT)
sigset_t set, oset;
#endif
+10 -3
View File
@@ -2910,9 +2910,10 @@ static int open_brace_count;
break; /* Posix grammar rule 4 */ \
if ((parser_state & PST_CASEPAT) && last_read_token == '(' && word_token_alist[i].token == ESAC) /*)*/ \
break; /* phantom Posix grammar rule 4 */ \
if (word_token_alist[i].token == ESAC) \
if (word_token_alist[i].token == ESAC) { \
parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
else if (word_token_alist[i].token == CASE) \
esacs_needed_count--; \
} else if (word_token_alist[i].token == CASE) \
parser_state |= PST_CASESTMT; \
else if (word_token_alist[i].token == COND_END) \
parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \
@@ -4902,7 +4903,7 @@ cond_term ()
dispose_word (yylval.word); /* not needed */
term = cond_term ();
if (term)
term->flags |= CMD_INVERT_RETURN;
term->flags ^= CMD_INVERT_RETURN;
}
else if (tok == WORD && yylval.word->word[0] == '-' && yylval.word->word[1] && yylval.word->word[2] == 0 && test_unop (yylval.word->word))
{
@@ -6795,6 +6796,9 @@ save_parser_state (ps)
ps->need_here_doc = need_here_doc;
ps->here_doc_first_line = here_doc_first_line;
ps->esacs_needed = esacs_needed_count;
ps->expecting_in = expecting_in_token;
if (need_here_doc == 0)
ps->redir_stack[0] = 0;
else
@@ -6857,6 +6861,9 @@ restore_parser_state (ps)
need_here_doc = ps->need_here_doc;
here_doc_first_line = ps->here_doc_first_line;
esacs_needed_count = ps->esacs_needed;
expecting_in_token = ps->expecting_in;
#if 0
for (i = 0; i < HEREDOC_MAX; i++)
redir_stack[i] = ps->redir_stack[i];
+1
View File
@@ -48,6 +48,7 @@
#define PST_REDIRLIST 0x080000 /* parsing a list of redirections preceding a simple command name */
#define PST_COMMENT 0x100000 /* parsing a shell comment; used by aliases */
#define PST_ENDALIAS 0x200000 /* just finished expanding and consuming an alias */
#define PST_NOEXPAND 0x400000 /* don't expand anything in read_token_word; for command substitution */
/* Definition of the delimiter stack. Needed by parse.y and bashhist.c. */
struct dstack {
+4 -2
View File
@@ -956,11 +956,13 @@ void
print_simple_command (simple_command)
SIMPLE_COM *simple_command;
{
command_print_word_list (simple_command->words, " ");
if (simple_command->words)
command_print_word_list (simple_command->words, " ");
if (simple_command->redirects)
{
cprintf (" ");
if (simple_command->words)
cprintf (" ");
print_redirection_list (simple_command->redirects);
}
}
+11 -1
View File
@@ -807,8 +807,18 @@ do_redirection_internal (redirect, flags, fnp)
continue. */
redirectee_word = redirection_expand (redirectee);
#if 0
/* TAG:bash-5.2 */
/* XXX - what to do with [N]<&$w- where w is unset or null? ksh93
closes N. */
turns it into [N]<&- or [N]>&- and closes N. */
if ((ri == r_move_input_word || ri == r_move_output_word) && redirectee_word == 0)
{
sd = redirect->redirector;
rd.dest = 0;
new_redirect = make_redirection (sd, r_close_this, rd, 0);
}
else
#endif
if (redirectee_word == 0)
return (AMBIGUOUS_REDIRECT);
else if (redirectee_word[0] == '-' && redirectee_word[1] == '\0')
+3
View File
@@ -205,6 +205,9 @@ typedef struct _sh_parser_state_t
int need_here_doc;
int here_doc_first_line;
int esacs_needed;
int expecting_in;
/* structures affecting the parser */
void *pushed_strings;
REDIRECT *redir_stack[HEREDOC_MAX];
+4 -2
View File
@@ -1,5 +1,5 @@
./comsub-eof0.sub: line 1: unexpected EOF while looking for matching `)'
./comsub-eof0.sub: line 5: syntax error: unexpected end of file
./comsub-eof0.sub: line 3: unexpected EOF while looking for matching `)'
./comsub-eof0.sub: line 7: syntax error: unexpected end of file
hi
./comsub-eof2.sub: line 2: warning: here-document at line 1 delimited by end-of-file (wanted `EOF')
hi
@@ -11,5 +11,7 @@ contents
hi
./comsub-eof5.sub: line 13: warning: here-document at line 11 delimited by end-of-file (wanted `EOF')
hi
./comsub-eof5.sub: line 19: warning: here-document at line 17 delimited by end-of-file (wanted `)')
./comsub-eof5.sub: line 15: unexpected EOF while looking for matching `)'
./comsub-eof6.sub: line 1: unexpected EOF while looking for matching `)'
+2
View File
@@ -1,3 +1,5 @@
# it's only the space before the paren that makes this an error
# when I fix it, it will show up here
foo=$(cat <<EOF
hi
EOF )
+6
View File
@@ -7,3 +7,9 @@ echo $(
cat <<\EOF
hi
EOF)
# this is currently an error; if I fix it it will show up here
echo "$(
cat <<\)
hi
))"
+3
View File
@@ -5,11 +5,14 @@ ab
abcd
abcd
mnop
qrst
sh_352.26ax
sh_352.26ay
sh_352.25a sh_352.25b
sh_352.27 ) ) )
abc
def
here doc with )
)
bad' syntax
+14
View File
@@ -28,6 +28,11 @@ echo $(
echo $()
echo ab$()cd
echo ab$( )cd
echo mn$(
)op
echo qr$(
)st
echo $(case a in (a) echo sh_352.26ax; esac )
echo $(case a in (a) echo sh_352.26ay; esac)
@@ -42,6 +47,9 @@ echo $(
echo abc # a comment with )
)
echo $(#a comment with )
echo def)
echo $(
cat <<eof
here doc with )
@@ -250,6 +258,12 @@ unset x
: $(case a in a) echo ;; # comment
esac)
: $(case a in
a)
echo
;; # comment
esac)
# fixed after bash-4.3 released
testing=$(
echo test | while read line; do
+5 -1
View File
@@ -2,6 +2,10 @@ returns: 0
returns: 0
returns: 1
returns: 0
1
0
1
0
returns: 0
returns: 0
returns: 0
@@ -23,7 +27,7 @@ returns: 0
returns: 1
returns: 1
returns: 0
./cond.tests: line 114: [[: 4+: syntax error: operand expected (error token is "+")
./cond.tests: line 122: [[: 4+: syntax error: operand expected (error token is "+")
returns: 1
returns: 0
returns: 0
+8
View File
@@ -33,6 +33,14 @@ echo returns: $?
[[ ! x || x ]]
echo returns: $?
# ! toggles on and off rather than just setting an `invert result' flag
# this differs from ksh93
[[ ! 1 -eq 1 ]]; echo $?
[[ ! ! 1 -eq 1 ]]; echo $?
[[ ! ! ! 1 -eq 1 ]]; echo $?
[[ ! ! ! ! 1 -eq 1 ]]; echo $?
# parenthesized terms didn't work right until post-2.04
[[ a ]]
echo returns: $?
+2
View File
@@ -37,6 +37,8 @@ argv[1] = <^I>
argv[1] = <'A^IB'>
argv[1] = <a^Ib^Ic>
argv[1] = <$'a\tb\tc'>
AD
E
hello' world
hello world!
hello' world!
+3
View File
@@ -132,6 +132,9 @@ recho "$( args $'A\tB' )"
recho $'a\tb\tc'
recho "$'a\tb\tc'"
# tests for $'...' being expanded in command substitution, and when
echo "$(echo $'\t\t\101\104\n\105')"
${THIS_SH} ./nquote1.sub
${THIS_SH} ./nquote2.sub
${THIS_SH} ./nquote3.sub
+7 -1
View File
@@ -1,6 +1,12 @@
unset LC_ALL LC_CTYPE
export LANG=en_US.UTF-8
export LANG=C
case $(printf %d\\n \'A) in
65) ;;
*) echo "printf2.sub: character conversion failed" >&2 ;;
esac
export LANG=en_US.UTF-8
case $(printf %d\\n \'À) in
192) exit 0;;
*) echo "printf2.sub: multibyte character conversion failed" >&2 ; exit 2 ;;