clarify some arithmetic error messages; fix for read builtin readline timeouts; initial implementation of preserving double quotes in readline completion; add starting line number to some "EOF reached" parser error messages

This commit is contained in:
Chet Ramey
2022-11-14 12:08:12 -05:00
parent 31f4d468b6
commit 96115811d8
24 changed files with 317 additions and 134 deletions
+70
View File
@@ -4337,3 +4337,73 @@ lib/readline/display.c
- update_line: use local_prompt_invis_chars to set _rl_last_c_pos
correctly when on a non-terminal prompt line that contains
invisible characters
11/7
----
subst.c
- get_var_and_type: allocate new memory for *valp and return it if the
type is VT_ARRAYMEMBER. The callers -- all of which treat this case
the same as VT_VARIABLE -- will free appropriately. Fixes problems
with using parameter operations like ## on dynamic array variables,
reported by Ivan Kapranov <koltiradw@yandex.ru> back on 8/31/2022
expr.c
- change some error messages to make it clearer these are arithmetic
syntax errors. These will require new translations.
test.c
- integer_expected_error: change the message to remove `expression',
since this is only called for the `test' builtin, where TEST_ARITHEXP
is not in FLAGS. This will require a new translation.
Reported by Emanuele Torre <torreemanuele6@gmail.com> back on
6/15/2022
11/10
-----
builtins/read.def
- reset_timeout: when a timer expires, make sure to cancel any
readline timeout as well with rl_clear_timeout().
From https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1023776
11/11
-----
builtins/reserved.def
- !: add short help text
lib/readline/complete.c
- make_quoted_replacement: if readline found quote characters anywhere
in the filename, but is not completing on an unclosed quoted string,
and there is an application filename quoting function, let that
function quote the filename if necessary
bashline.c
- COMPLETE_DQUOTE2: new completion quoting style define
- bash_expand_filename: new function, runs a filename passed to it
through word expansion, suppressing command and process substitution
and returns the result (in new memory if it's different than the
filename argument)
- bash_quote_filename: if the return value from bash_check_expchar is
`$' or ``', expand the filename and if it contains characters that
should be quoted, set the quoting style to COMPLETE_DQUOTE2
- bash_quote_filename: if the completion quoting style is COMPLETE_DQUOTE2,
use sh_mkdoublequoted to put double quotes around the entire
unexpanded filename instead of using sh_double_quote, which will
backslash-quote any `$'. This is a start at preserving user-supplied
quotes if the (expanded) completed filename requires them. From
reports by Peng Yu <pengyu.ut@gmail.com> in 5/2020 and
Pedro Gimeno <pgba-da0a@personal.formauri.es> in 6/2021
11/14
-----
parse.y
- report_syntax_error: if word_top is set and we reach EOF, report the
starting line number in the error message. From a patch from
L A Walsh <bash@tlinx.org> and Manuel Reiter <manuel.reiter@dwd.de>
back in 9/2018
- MAX_CASE_NEST: doubled to 256, renamed to MAX_COMPOUND_NEST
- read_token_word: add `if', `while', and `until' to the set of
compound commands that use WORD_TOP and WORD_LINENO (with
corresponding changes to grammar productions)
- [grammar]: changed check to decrement WORD_TOP to >= 0 since we
start at -1 and we want to decrement back to -1 when all loops are
closed
+56 -1
View File
@@ -151,6 +151,7 @@ static char *maybe_restore_tilde PARAMS((char *, char *));
static char *bash_filename_rewrite_hook PARAMS((char *, int));
static void bash_directory_expansion PARAMS((char **));
static char *bash_expand_filename PARAMS((char *));
static int bash_filename_stat_hook PARAMS((char **));
static int bash_command_name_stat_hook PARAMS((char **));
static int bash_directory_completion_hook PARAMS((char **));
@@ -328,10 +329,13 @@ static int dabbrev_expand_active = 0;
COMPLETE_DQUOTE = double-quoting the filename
COMPLETE_SQUOTE = single_quoting the filename
COMPLETE_BSQUOTE = backslash-quoting special chars in the filename
COMPLETE_DQUOTE2 = double-quote filename, but leave $ and ` unquoted
*/
#define COMPLETE_DQUOTE 1
#define COMPLETE_SQUOTE 2
#define COMPLETE_BSQUOTE 3
#define COMPLETE_DQUOTE2 4
static int completion_quoting_style = COMPLETE_BSQUOTE;
/* Flag values for the final argument to bash_default_completion */
@@ -3368,6 +3372,38 @@ directory_exists (dirname, should_dequote)
free (new_dirname);
return (r);
}
static char *
bash_expand_filename (filename)
char *filename;
{
char *newname;
int global_nounset;
WORD_LIST *wl;
newname = savestring (filename);
/* no error messages, and expand_prompt_string doesn't longjmp so we don't
have to worry about restoring this setting. */
global_nounset = unbound_vars_is_error;
unbound_vars_is_error = 0;
wl = expand_prompt_string (newname, 0, W_NOCOMSUB|W_NOPROCSUB|W_COMPLETE); /* does the right thing */
unbound_vars_is_error = global_nounset;
free (newname);
if (wl == 0)
return filename;
else
{
newname = string_list (wl);
dispose_words (wl);
if (newname && *newname && STREQ (newname, filename))
{
free (newname);
return filename;
}
return newname;
}
}
/* Expand a filename before the readline completion code passes it to stat(2).
The filename will already have had tilde expansion performed. */
@@ -4291,6 +4327,17 @@ bash_quote_filename (s, rtype, qcp)
(expchar = bash_check_expchar (s, 0, &nextch, &closer)) &&
file_exists (s) == 0)
{
/* If it looks like the name is subject to expansion, see if we want to
double-quote it. */
if (expchar == '$' || expchar == '`')
{
char *newname;
newname = bash_expand_filename (s);
if (newname && strpbrk (newname, rl_filename_quote_characters))
cs = COMPLETE_DQUOTE2;
if (newname != s)
free (newname);
}
/* Usually this will have been set by bash_directory_completion_hook,
but there are cases where it will not be. */
if (rl_filename_quote_characters != custom_filename_quote_characters)
@@ -4300,7 +4347,12 @@ bash_quote_filename (s, rtype, qcp)
else if (*qcp == '\0' && cs == COMPLETE_BSQUOTE && mbschr (s, '\n'))
cs = COMPLETE_SQUOTE;
else if (*qcp == '"')
cs = COMPLETE_DQUOTE;
{
if ((expchar = bash_check_expchar (s, 0, &nextch, &closer)) == '$' || expchar == '`')
cs = COMPLETE_DQUOTE2;
else
cs = COMPLETE_DQUOTE;
}
else if (*qcp == '\'')
cs = COMPLETE_SQUOTE;
#if defined (BANG_HISTORY)
@@ -4324,6 +4376,9 @@ bash_quote_filename (s, rtype, qcp)
switch (cs)
{
case COMPLETE_DQUOTE2:
rtext = sh_mkdoublequoted (mtext, strlen (mtext), 1); /* For now */
break;
case COMPLETE_DQUOTE:
rtext = sh_double_quote (mtext);
break;
+2 -1
View File
@@ -49,7 +49,8 @@ Options which set attributes:
-u to convert the value of each NAME to upper case on assignment
-x to make NAMEs export
Using `+' instead of `-' turns off the given attribute.
Using `+' instead of `-' turns off the given attribute, except for a,
A, and r.
Variables with the integer attribute have arithmetic evaluation (see
the `let' command) performed when the variable is assigned a value.
+3
View File
@@ -167,6 +167,9 @@ reset_timeout ()
/* Cancel alarm before restoring signal handler. */
if (read_timeout)
shtimer_clear (read_timeout);
#if defined (READLINE)
rl_clear_timeout ();
#endif
read_timeout = 0;
}
+10
View File
@@ -19,6 +19,16 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
$BUILTIN !
$DOCNAME bang
$SHORT_DOC ! PIPELINE
Execute PIPELINE, which can be a simple command, and negate PIPELINE's
return status.
Exit Status:
The logical negation of PIPELINE's return status.
$END
$BUILTIN for
$SHORT_DOC for NAME [in WORDS ... ] ; do COMMANDS; done
Execute commands for each member in a list.
+1 -1
View File
@@ -1245,7 +1245,7 @@ See the description of
.B shopt
below under
.SM
.BR SHELL BUILTIN COMMANDS .
.BR "SHELL BUILTIN COMMANDS" .
.SH PARAMETERS
A
.I parameter
+5 -5
View File
@@ -476,7 +476,7 @@ subexpr (expr)
/*TAG:bash-5.3 make it clear that these are arithmetic syntax errors */
if (curtok != 0)
evalerror (_("syntax error in expression"));
evalerror (_("arithmetic syntax error in expression"));
FREE (tokstr);
FREE (expression);
@@ -529,7 +529,7 @@ expassign ()
}
if (tokstr == 0)
evalerror (_("syntax error in variable assignment"));
evalerror (_("arithmetic syntax error in variable assignment"));
/* XXX - watch out for pointer aliasing issues here */
lhs = savestring (tokstr);
@@ -1106,7 +1106,7 @@ exp0 ()
readtok ();
}
else
evalerror (_("syntax error: operand expected"));
evalerror (_("arithmetic syntax error: operand expected"));
return (val);
}
@@ -1497,9 +1497,9 @@ readtok ()
cp--;
/* use curtok, since it hasn't been copied to lasttok yet */
if (curtok == 0 || _is_arithop (curtok) || _is_multiop (curtok))
evalerror (_("syntax error: operand expected"));
evalerror (_("arithmetic syntax error: operand expected"));
else
evalerror (_("syntax error: invalid arithmetic operator"));
evalerror (_("arithmetic syntax error: invalid arithmetic operator"));
}
else
cp--; /* `unget' the character */
+6
View File
@@ -1784,6 +1784,11 @@ make_quoted_replacement (char *match, int mtype, char *qc)
should_quote = rl_filename_quote_characters
? (_rl_strpbrk (match, rl_filename_quote_characters) != 0)
: 0;
/* If we saw a quote in the original word, but readline thinks the
match doesn't need to be quoted, and the application has a filename
quoting function, give the application a chance to quote it if
needed so we don't second-guess the user. */
should_quote |= *qc == 0 && rl_completion_found_quote && mtype != NO_MATCH && rl_filename_quoting_function;
do_replace = should_quote ? mtype : NO_MATCH;
/* Quote the replacement, since we found an embedded
@@ -1791,6 +1796,7 @@ make_quoted_replacement (char *match, int mtype, char *qc)
if (do_replace != NO_MATCH && rl_filename_quoting_function)
replacement = (*rl_filename_quoting_function) (match, do_replace, qc);
}
return (replacement);
}
+29 -22
View File
@@ -609,11 +609,18 @@ rl_expand_prompt (char *prompt)
FREE (local_prompt);
FREE (local_prompt_prefix);
/* Set default values for variables expand_prompt sets */
local_prompt = local_prompt_prefix = (char *)0;
local_prompt_len = 0;
prompt_last_invisible = prompt_invis_chars_first_line = 0;
prompt_visible_length = prompt_physical_chars = 0;
if (local_prompt_invis_chars == 0)
{
local_prompt_invis_chars = (int *)xmalloc (sizeof (int));
local_prompt_invis_chars[0] = 0;
}
if (prompt == 0 || *prompt == 0)
return (0);
@@ -776,6 +783,28 @@ _rl_optimize_redisplay (void)
_rl_quick_redisplay = 1;
}
/* Useful shorthand used by rl_redisplay, update_line, rl_move_cursor_relative */
#define INVIS_FIRST() (local_prompt_invis_chars[0])
#define WRAP_OFFSET(line, offset) ((line <= prompt_last_screen_line) ? local_prompt_invis_chars[line] : 0)
#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l])
#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
#define VIS_FACE(line) (vis_face + vis_lbreaks[line])
#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
#define VIS_LINE_FACE(line) ((line) > _rl_vis_botlin) ? "" : VIS_FACE(line)
#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
#define INV_LINE_FACE(line) (inv_face + inv_lbreaks[line])
#define INV_CHARS_CURRENT_PROMPT_LINE(line) \
(local_prompt_invis_chars[line] > 0)
#define OLD_CPOS_IN_PROMPT() (cpos_adjusted == 0 && \
_rl_last_c_pos != o_cpos && \
_rl_last_c_pos > wrap_offset && \
o_cpos < prompt_last_invisible)
/* Basic redisplay algorithm. See comments inline. */
void
rl_redisplay (void)
@@ -1271,28 +1300,6 @@ rl_redisplay (void)
second and subsequent lines start at inv_lbreaks[N], offset by
OFFSET (which has already been calculated above). */
#define INVIS_FIRST() (local_prompt_invis_chars[0])
#define WRAP_OFFSET(line, offset) ((line <= prompt_last_screen_line) ? local_prompt_invis_chars[line] : 0)
#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l])
#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
#define VIS_FACE(line) (vis_face + vis_lbreaks[line])
#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
#define VIS_LINE_FACE(line) ((line) > _rl_vis_botlin) ? "" : VIS_FACE(line)
#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
#define INV_LINE_FACE(line) (inv_face + inv_lbreaks[line])
#define INV_CHARS_CURRENT_PROMPT_LINE(line) \
(local_prompt_invis_chars[line] > 0)
#define OLD_CPOS_IN_PROMPT() (cpos_adjusted == 0 && \
_rl_last_c_pos != o_cpos && \
_rl_last_c_pos > wrap_offset && \
o_cpos < prompt_last_invisible)
/* We don't want to highlight anything that's going to be off the top
of the display; if the current line takes up more than an entire
screen, just mark the lines that won't be displayed as having a
+57 -32
View File
@@ -317,8 +317,8 @@ static int two_tokens_ago;
/* The line number in a script where the word in a `case WORD', `select WORD'
or `for WORD' begins. This is a nested command maximum, since the array
index is decremented after a case, select, or for command is parsed. */
#define MAX_CASE_NEST 128
static int word_lineno[MAX_CASE_NEST+1];
#define MAX_COMPOUND_NEST 256
static int word_lineno[MAX_COMPOUND_NEST+1];
static int word_top = -1;
/* If non-zero, it is the token that we want read_token to return
@@ -800,9 +800,15 @@ shell_command: for_command
| case_command
{ $$ = $1; }
| WHILE compound_list DO compound_list DONE
{ $$ = make_while_command ($2, $4); }
{
$$ = make_while_command ($2, $4);
if (word_top >= 0) word_top--;
}
| UNTIL compound_list DO compound_list DONE
{ $$ = make_until_command ($2, $4); }
{
$$ = make_until_command ($2, $4);
if (word_top >= 0) word_top--;
}
| select_command
{ $$ = $1; }
| if_command
@@ -822,42 +828,42 @@ shell_command: for_command
for_command: FOR WORD newline_list DO compound_list DONE
{
$$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
| FOR WORD newline_list '{' compound_list '}'
{
$$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
| FOR WORD ';' newline_list DO compound_list DONE
{
$$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
| FOR WORD ';' newline_list '{' compound_list '}'
{
$$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
| FOR WORD newline_list IN word_list list_terminator newline_list DO compound_list DONE
{
$$ = make_for_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
| FOR WORD newline_list IN word_list list_terminator newline_list '{' compound_list '}'
{
$$ = make_for_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
| FOR WORD newline_list IN list_terminator newline_list DO compound_list DONE
{
$$ = make_for_command ($2, (WORD_LIST *)NULL, $8, word_lineno[word_top]);
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
| FOR WORD newline_list IN list_terminator newline_list '{' compound_list '}'
{
$$ = make_for_command ($2, (WORD_LIST *)NULL, $8, word_lineno[word_top]);
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
;
@@ -865,84 +871,84 @@ arith_for_command: FOR ARITH_FOR_EXPRS list_terminator newline_list DO compound_
{
$$ = make_arith_for_command ($2, $6, arith_for_lineno);
if ($$ == 0) YYERROR;
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
| FOR ARITH_FOR_EXPRS list_terminator newline_list '{' compound_list '}'
{
$$ = make_arith_for_command ($2, $6, arith_for_lineno);
if ($$ == 0) YYERROR;
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
| FOR ARITH_FOR_EXPRS DO compound_list DONE
{
$$ = make_arith_for_command ($2, $4, arith_for_lineno);
if ($$ == 0) YYERROR;
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
| FOR ARITH_FOR_EXPRS '{' compound_list '}'
{
$$ = make_arith_for_command ($2, $4, arith_for_lineno);
if ($$ == 0) YYERROR;
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
;
select_command: SELECT WORD newline_list DO compound_list DONE
{
$$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
| SELECT WORD newline_list '{' compound_list '}'
{
$$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
| SELECT WORD ';' newline_list DO compound_list DONE
{
$$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
| SELECT WORD ';' newline_list '{' compound_list '}'
{
$$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
| SELECT WORD newline_list IN word_list list_terminator newline_list DO compound_list DONE
{
$$ = make_select_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
| SELECT WORD newline_list IN word_list list_terminator newline_list '{' compound_list '}'
{
$$ = make_select_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
| SELECT WORD newline_list IN list_terminator newline_list DO compound_list DONE
{
$$ = make_select_command ($2, (WORD_LIST *)NULL, $8, word_lineno[word_top]);
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
| SELECT WORD newline_list IN list_terminator newline_list '{' compound_list '}'
{
$$ = make_select_command ($2, (WORD_LIST *)NULL, $8, word_lineno[word_top]);
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
;
case_command: CASE WORD newline_list IN newline_list ESAC
{
$$ = make_case_command ($2, (PATTERN_LIST *)NULL, word_lineno[word_top]);
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
| CASE WORD newline_list IN case_clause_sequence newline_list ESAC
{
$$ = make_case_command ($2, $5, word_lineno[word_top]);
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
| CASE WORD newline_list IN case_clause ESAC
{
$$ = make_case_command ($2, $5, word_lineno[word_top]);
if (word_top > 0) word_top--;
if (word_top >= 0) word_top--;
}
;
@@ -1058,11 +1064,21 @@ coproc: COPROC shell_command
;
if_command: IF compound_list THEN compound_list FI
{ $$ = make_if_command ($2, $4, (COMMAND *)NULL); }
{
$$ = make_if_command ($2, $4, (COMMAND *)NULL);
if (word_top >= 0) word_top--;
}
| IF compound_list THEN compound_list ELSE compound_list FI
{ $$ = make_if_command ($2, $4, $6); }
{
$$ = make_if_command ($2, $4, $6);
if (word_top >= 0) word_top--;
}
| IF compound_list THEN compound_list elif_clause FI
{ $$ = make_if_command ($2, $4, $5); }
{
$$ = make_if_command ($2, $4, $5);
if (word_top >= 0) word_top--;
}
;
@@ -4450,7 +4466,7 @@ parse_dparen (c)
#if defined (ARITH_FOR_COMMAND)
if (last_read_token == FOR)
{
if (word_top < MAX_CASE_NEST)
if (word_top < MAX_COMPOUND_NEST)
word_top++;
arith_for_lineno = word_lineno[word_top] = line_number;
cmdtyp = parse_arith_cmd (&wval, 0);
@@ -5338,11 +5354,18 @@ got_token:
case CASE:
case SELECT:
case FOR:
if (word_top < MAX_CASE_NEST)
if (word_top < MAX_COMPOUND_NEST)
word_top++;
word_lineno[word_top] = line_number;
expecting_in_token++;
break;
case IF:
case WHILE:
case UNTIL:
if (word_top < MAX_COMPOUND_NEST)
word_top++;
word_lineno[word_top] = line_number;
break;
}
return (result);
@@ -6274,6 +6297,8 @@ report_syntax_error (message)
{
if (EOF_Reached && shell_eof_token && current_token != shell_eof_token)
parser_error (line_number, _("unexpected EOF while looking for matching `%c'"), shell_eof_token);
else if (EOF_Reached && word_top >= 0)
parser_error (line_number, _("syntax error: unexpected end of file from command on line %d"), word_lineno[word_top]);
else
{
msg = EOF_Reached ? _("syntax error: unexpected end of file") : _("syntax error");
+1 -1
View File
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
#define PATCHLEVEL 2
#define PATCHLEVEL 9
#endif /* _PATCHLEVEL_H_ */
+13 -15
View File
@@ -85,6 +85,7 @@ extern int errno;
#define VT_STARSUB 128 /* $* or ${array[*]} -- used to split */
/* Flags for quoted_strchr */
#define ST_BACKSL 0x01
#define ST_CTLESC 0x02
@@ -5912,8 +5913,7 @@ parameter_brace_remove_pattern (varname, value, estatep, patstr, rtype, quoted,
case VT_VARIABLE:
case VT_ARRAYMEMBER:
temp1 = remove_pattern (val, pattern, patspec);
if (vtype == VT_VARIABLE)
FREE (val);
FREE (val);
if (temp1)
{
val = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
@@ -8320,7 +8320,8 @@ get_var_and_type (varname, value, estatep, quoted, flags, varp, valp)
else
{
vtype = VT_ARRAYMEMBER;
*valp = array_value (vname, Q_DOUBLE_QUOTES, flags, estatep);
temp = array_value (vname, Q_DOUBLE_QUOTES, flags, estatep);
*valp = temp ? savestring (temp) : temp;
}
*varp = v;
}
@@ -8337,14 +8338,16 @@ get_var_and_type (varname, value, estatep, quoted, flags, varp, valp)
{
vtype = VT_ARRAYMEMBER;
*varp = v;
*valp = array_value (vname, Q_DOUBLE_QUOTES, flags, estatep);
temp = array_value (vname, Q_DOUBLE_QUOTES, flags, estatep);
*valp = temp ? savestring (temp) : temp;
}
}
else if ((v = find_variable (vname)) && (invisible_p (v) == 0) && (assoc_p (v) || array_p (v)))
{
vtype = VT_ARRAYMEMBER;
*varp = v;
*valp = assoc_p (v) ? assoc_reference (assoc_cell (v), "0") : array_reference (array_cell (v), 0);
temp = assoc_p (v) ? assoc_reference (assoc_cell (v), "0") : array_reference (array_cell (v), 0);
*valp = temp ? savestring (temp) : temp;
}
else
#endif
@@ -8708,8 +8711,7 @@ parameter_brace_transform (varname, value, estatep, xform, rtype, quoted, pflags
case VT_VARIABLE:
case VT_ARRAYMEMBER:
temp1 = string_transform (xc, v, val);
if (vtype == VT_VARIABLE)
FREE (val);
FREE (val);
if (temp1)
{
val = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
@@ -8826,7 +8828,7 @@ parameter_brace_substring (varname, value, estatep, substr, quoted, pflags, flag
this_command_name = oname;
if (r <= 0)
{
if (vtype == VT_VARIABLE)
if (vtype == VT_VARIABLE || vtype == VT_ARRAYMEMBER)
FREE (val);
return ((r == 0) ? &expand_param_error : (char *)NULL);
}
@@ -8842,8 +8844,7 @@ parameter_brace_substring (varname, value, estatep, substr, quoted, pflags, flag
#endif
tt = substring (val, e1, e2);
if (vtype == VT_VARIABLE)
FREE (val);
FREE (val);
if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
temp = quote_string (tt);
else
@@ -9202,7 +9203,6 @@ parameter_brace_patsub (varname, value, estatep, patsub, quoted, pflags, flags)
consistently. */
if (patsub_replacement && rep && *rep && shouldexp_replacement (rep))
mflags |= MATCH_EXPREP;
}
/* ksh93 doesn't allow the match specifier to be a part of the expanded
@@ -9241,8 +9241,7 @@ parameter_brace_patsub (varname, value, estatep, patsub, quoted, pflags, flags)
case VT_VARIABLE:
case VT_ARRAYMEMBER:
temp = pat_subst (val, p, rep, mflags);
if (vtype == VT_VARIABLE)
FREE (val);
FREE (val);
if (temp)
{
tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp);
@@ -9429,8 +9428,7 @@ parameter_brace_casemod (varname, value, estatep, modspec, patspec, quoted, pfla
case VT_VARIABLE:
case VT_ARRAYMEMBER:
temp = sh_modcase (val, pat, modop);
if (vtype == VT_VARIABLE)
FREE (val);
FREE (val);
if (temp)
{
tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp);
+1 -1
View File
@@ -153,7 +153,7 @@ static void
integer_expected_error (pch)
char *pch;
{
test_syntax_error (_("%s: integer expression expected"), pch);
test_syntax_error (_("%s: integer expected"), pch);
}
/* Increment our position in the argument list. Check that we're not
+17 -17
View File
@@ -85,8 +85,8 @@
./arith.tests: line 168: 7 = 43 : attempted assignment to non-variable (error token is "= 43 ")
./arith.tests: line 169: 2#44: value too great for base (error token is "2#44")
./arith.tests: line 170: 44 / 0 : division by 0 (error token is "0 ")
./arith.tests: line 171: let: jv += $iv: syntax error: operand expected (error token is "$iv")
./arith.tests: line 172: jv += $iv : syntax error: operand expected (error token is "$iv ")
./arith.tests: line 171: let: jv += $iv: arithmetic syntax error: operand expected (error token is "$iv")
./arith.tests: line 172: jv += $iv : arithmetic syntax error: operand expected (error token is "$iv ")
./arith.tests: line 173: let: rv = 7 + (43 * 6: missing `)' (error token is "6")
./arith.tests: line 177: 0#4: invalid number (error token is "0#4")
./arith.tests: line 178: 2#110#11: invalid number (error token is "2#110#11")
@@ -97,7 +97,7 @@ ok
6
1
0
./arith.tests: line 196: 4 + : syntax error: operand expected (error token is "+ ")
./arith.tests: line 196: 4 + : arithmetic syntax error: operand expected (error token is "+ ")
16
./arith.tests: line 201: 4 ? : 3 + 5 : expression expected (error token is ": 3 + 5 ")
./arith.tests: line 202: 1 ? 20 : `:' expected for conditional expression (error token is "20 ")
@@ -131,7 +131,7 @@ ok
4
4
7
./arith.tests: line 260: 7-- : syntax error: operand expected (error token is "- ")
./arith.tests: line 260: 7-- : arithmetic syntax error: operand expected (error token is "- ")
./arith.tests: line 262: --x=7 : attempted assignment to non-variable (error token is "=7 ")
./arith.tests: line 263: ++x=7 : attempted assignment to non-variable (error token is "=7 ")
./arith.tests: line 265: x++=7 : attempted assignment to non-variable (error token is "=7 ")
@@ -143,10 +143,10 @@ ok
7
2
2
./arith1.sub: line 15: 4-- : syntax error: operand expected (error token is "- ")
./arith1.sub: line 16: 4++ : syntax error: operand expected (error token is "+ ")
./arith1.sub: line 17: 4 -- : syntax error: operand expected (error token is "- ")
./arith1.sub: line 18: 4 ++ : syntax error: operand expected (error token is "+ ")
./arith1.sub: line 15: 4-- : arithmetic syntax error: operand expected (error token is "- ")
./arith1.sub: line 16: 4++ : arithmetic syntax error: operand expected (error token is "+ ")
./arith1.sub: line 17: 4 -- : arithmetic syntax error: operand expected (error token is "- ")
./arith1.sub: line 18: 4 ++ : arithmetic syntax error: operand expected (error token is "+ ")
1
2
1
@@ -161,10 +161,10 @@ ok
2
-2
1
./arith1.sub: line 48: ((: ++ : syntax error: operand expected (error token is "+ ")
./arith1.sub: line 48: ((: ++ : arithmetic syntax error: operand expected (error token is "+ ")
7
7
./arith1.sub: line 51: ((: -- : syntax error: operand expected (error token is "- ")
./arith1.sub: line 51: ((: -- : arithmetic syntax error: operand expected (error token is "- ")
7
7
7
@@ -183,10 +183,10 @@ ok
1
4
0
./arith2.sub: line 46: ((: -- : syntax error: operand expected (error token is "- ")
./arith2.sub: line 46: ((: -- : arithmetic syntax error: operand expected (error token is "- ")
-7
-7
./arith2.sub: line 50: ((: ++ : syntax error: operand expected (error token is "+ ")
./arith2.sub: line 50: ((: ++ : arithmetic syntax error: operand expected (error token is "+ ")
7
7
-7
@@ -250,14 +250,14 @@ efg
0
0
8 12
./arith.tests: line 310: ((: x=9 y=41 : syntax error in expression (error token is "y=41 ")
./arith.tests: line 314: a b: syntax error in expression (error token is "b")
./arith.tests: line 315: ((: a b: syntax error in expression (error token is "b")
./arith.tests: line 310: ((: x=9 y=41 : arithmetic syntax error in expression (error token is "y=41 ")
./arith.tests: line 314: a b: arithmetic syntax error in expression (error token is "b")
./arith.tests: line 315: ((: a b: arithmetic syntax error in expression (error token is "b")
42
42
42
42
42
42
./arith.tests: line 330: 'foo' : syntax error: operand expected (error token is "'foo' ")
./arith.tests: line 333: b[c]d: syntax error in expression (error token is "d")
./arith.tests: line 330: 'foo' : arithmetic syntax error: operand expected (error token is "'foo' ")
./arith.tests: line 333: b[c]d: arithmetic syntax error in expression (error token is "d")
+12 -12
View File
@@ -400,7 +400,7 @@ qux: unset array element 0: ok
0
0
1
./array17.sub: line 43: ~: syntax error: operand expected (error token is "~")
./array17.sub: line 43: ~: arithmetic syntax error: operand expected (error token is "~")
0
0
3
@@ -415,7 +415,7 @@ one
one
two
two
./array17.sub: line 89: ~ : syntax error: operand expected (error token is "~ ")
./array17.sub: line 89: ~ : arithmetic syntax error: operand expected (error token is "~ ")
1
argv[1] = <>
argv[2] = <>
@@ -453,7 +453,7 @@ declare -A a=([1]="b" [0]="a" )
declare -a var=([0]="[\$(echo" [1]="total" [2]="0)]=1" [3]="[2]=2]")
declare -a var=([0]="[\$(echo total 0)]=1 [2]=2]")
declare -a var=([0]="[\$(echo" [1]="total" [2]="0)]=1" [3]="[2]=2]")
./array19.sub: line 89: total 0: syntax error in expression (error token is "0")
./array19.sub: line 89: total 0: arithmetic syntax error in expression (error token is "0")
declare -a var=()
declare -al foo=([0]="abcde" [1]="two" [2]="three")
declare -al foo=([0]="abcde")
@@ -522,14 +522,14 @@ p3
argv[1] = <y>
<X> <X> <X> <X>
<X> <X> <X> <X>
./array23.sub: line 22: $( echo >&2 foo ) : syntax error: operand expected (error token is "$( echo >&2 foo ) ")
./array23.sub: line 23: $( echo >&2 foo ) : syntax error: operand expected (error token is "$( echo >&2 foo ) ")
./array23.sub: line 24: $( echo >&2 foo ) : syntax error: operand expected (error token is "$( echo >&2 foo ) ")
./array23.sub: line 26: $( echo >&2 foo ) : syntax error: operand expected (error token is "$( echo >&2 foo ) ")
./array23.sub: line 30: $( echo >&2 foo ): syntax error: operand expected (error token is "$( echo >&2 foo )")
./array23.sub: line 33: $( echo >&2 foo ): syntax error: operand expected (error token is "$( echo >&2 foo )")
./array23.sub: line 34: $index: syntax error: operand expected (error token is "$index")
./array23.sub: line 35: $( echo >&2 foo ): syntax error: operand expected (error token is "$( echo >&2 foo )")
./array23.sub: line 22: $( echo >&2 foo ) : arithmetic syntax error: operand expected (error token is "$( echo >&2 foo ) ")
./array23.sub: line 23: $( echo >&2 foo ) : arithmetic syntax error: operand expected (error token is "$( echo >&2 foo ) ")
./array23.sub: line 24: $( echo >&2 foo ) : arithmetic syntax error: operand expected (error token is "$( echo >&2 foo ) ")
./array23.sub: line 26: $( echo >&2 foo ) : arithmetic syntax error: operand expected (error token is "$( echo >&2 foo ) ")
./array23.sub: line 30: $( echo >&2 foo ): arithmetic syntax error: operand expected (error token is "$( echo >&2 foo )")
./array23.sub: line 33: $( echo >&2 foo ): arithmetic syntax error: operand expected (error token is "$( echo >&2 foo )")
./array23.sub: line 34: $index: arithmetic syntax error: operand expected (error token is "$index")
./array23.sub: line 35: $( echo >&2 foo ): arithmetic syntax error: operand expected (error token is "$( echo >&2 foo )")
0
0
0
@@ -583,7 +583,7 @@ jkl
1. indexed:
reference:
1. 0
./array25.sub: line 24: ' ': syntax error: operand expected (error token is "' '")
./array25.sub: line 24: ' ': arithmetic syntax error: operand expected (error token is "' '")
3. 0
4. 0
5. 0
+1 -1
View File
@@ -27,7 +27,7 @@ returns: 0
returns: 1
returns: 1
returns: 0
./cond.tests: line 122: [[: 4+: syntax error: operand expected (error token is "+")
./cond.tests: line 122: [[: 4+: arithmetic syntax error: operand expected (error token is "+")
returns: 1
returns: 0
returns: 0
+10 -5
View File
@@ -83,8 +83,8 @@ readonly: usage: readonly [-aAf] [name[=value] ...] or readonly -p
eval: usage: eval [arg ...]
./errors.tests: line 227: command: -i: invalid option
command: usage: command [-pVv] command [arg ...]
./errors.tests: line 230: /bin/sh + 0: syntax error: operand expected (error token is "/bin/sh + 0")
./errors.tests: line 231: /bin/sh + 0: syntax error: operand expected (error token is "/bin/sh + 0")
./errors.tests: line 230: /bin/sh + 0: arithmetic syntax error: operand expected (error token is "/bin/sh + 0")
./errors.tests: line 231: /bin/sh + 0: arithmetic syntax error: operand expected (error token is "/bin/sh + 0")
./errors.tests: line 234: trap: NOSIG: invalid signal specification
./errors.tests: line 237: trap: -s: invalid option
trap: usage: trap [-lp] [[arg] signal_spec ...]
@@ -196,12 +196,17 @@ ok 4
ok 5
./errors8.sub: line 14: set: notanoption: invalid option name
ok 6
./errors8.sub: line 16: /notthere: No such file or directory
ok 7
./errors8.sub: line 17: .: -x: invalid option
.: usage: . filename [arguments]
ok 8
DEBUG
./errors9.sub: line 6: [[: ++: syntax error: operand expected (error token is "+")
./errors9.sub: line 6: [[: ++: arithmetic syntax error: operand expected (error token is "+")
DEBUG
./errors9.sub: line 8: ((: -- : syntax error: operand expected (error token is "- ")
./errors9.sub: line 8: ((: -- : arithmetic syntax error: operand expected (error token is "- ")
DEBUG
./errors9.sub: line 10: ((: -- : syntax error: operand expected (error token is "- ")
./errors9.sub: line 10: ((: -- : arithmetic syntax error: operand expected (error token is "- ")
bash: line 1: return: can only `return' from a function or sourced script
after return
bash: line 1: return: can only `return' from a function or sourced script
+3
View File
@@ -12,3 +12,6 @@ command shift 12 || echo ok 4
command return 16 || echo ok 5
command set -o notanoption || echo ok 6
command . /notthere || echo ok 7
command . -x true || echo ok 8
+1 -1
View File
@@ -236,7 +236,7 @@ declare -- var="x\001y\177z"$
argv[1] = <$'x\001y\177z'>
argv[1] = <x^Ay^?z>
var=$'x\001y\177z'
./exp8.sub: line 30: xyz: syntax error: invalid arithmetic operator (error token is "z")
./exp8.sub: line 30: xyz: arithmetic syntax error: invalid arithmetic operator (error token is "z")
declare -a array=()
declare -a array=([0]=$'x\001y\177z')
argv[1] = <x^Ay^?z>
+1 -1
View File
@@ -190,7 +190,7 @@ argv[1] = <0>
./more-exp.tests: line 442: ${#=}: bad substitution
./more-exp.tests: line 444: ${#+}: bad substitution
./more-exp.tests: line 446: ${#1xyz}: bad substitution
./more-exp.tests: line 449: #: %: syntax error: operand expected (error token is "%")
./more-exp.tests: line 449: #: %: arithmetic syntax error: operand expected (error token is "%")
argv[1] = <0>
argv[1] = <a+b>
argv[1] = <+>
+1 -1
View File
@@ -3,7 +3,7 @@ argv[1] = <foo>
argv[1] = </usr/homes/chet>
argv[1] = </usr/homes/chet>
argv[1] = </usr/homes/chet>
./new-exp.tests: line 41: HOME: }: syntax error: operand expected (error token is "}")
./new-exp.tests: line 41: HOME: }: arithmetic syntax error: operand expected (error token is "}")
unset
argv[1] = </usr/homes/chet>
argv[1] = </usr/homes/chet>
+8 -8
View File
@@ -1,9 +1,9 @@
declare -A assoc=(["x],b[\$(echo uname >&2)"]="1" )
declare -A assoc=(["\$key"]="1" ["x],b[\$(echo uname >&2)"]="1" )
declare -A assoc=(["\$key"]="1" ["x],b[\$(echo uname >&2)"]="2" )
./quotearray.tests: line 31: ((: 'assoc[x\],b\[\$(echo uname >&2)]++' : syntax error: operand expected (error token is "'assoc[x\],b\[\$(echo uname >&2)]++' ")
./quotearray.tests: line 31: ((: 'assoc[x\],b\[\$(echo uname >&2)]++' : arithmetic syntax error: operand expected (error token is "'assoc[x\],b\[\$(echo uname >&2)]++' ")
declare -A assoc=(["\$key"]="1" ["x],b[\$(echo uname >&2)"]="2" )
./quotearray.tests: line 34: ((: 'assoc[x\],b\[\$(echo uname >&2)]'++ : syntax error: operand expected (error token is "'assoc[x\],b\[\$(echo uname >&2)]'++ ")
./quotearray.tests: line 34: ((: 'assoc[x\],b\[\$(echo uname >&2)]'++ : arithmetic syntax error: operand expected (error token is "'assoc[x\],b\[\$(echo uname >&2)]'++ ")
declare -A assoc=(["\$key"]="1" ["x],b[\$(echo uname >&2)"]="2" )
declare -A assoc=(["\$key"]="1" ["x],b[\$(echo uname >&2)"]="3" )
4
@@ -24,14 +24,14 @@ declare -a a=([0]="12" [1]="42")
declare -Ai assoc=(["']"]="3" ["\$var"]="1" )
105
declare -A assoc=(["\` echo >&2 foo\`"]="42" ["\$( echo >&2 bar)"]="63" )
./quotearray.tests: line 140: x],b[$(echo uname >&2): syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
./quotearray.tests: line 144: x],b[$(echo uname >&2): syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
./quotearray.tests: line 140: x],b[$(echo uname >&2): arithmetic syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
./quotearray.tests: line 144: x],b[$(echo uname >&2): arithmetic syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
1
./quotearray.tests: line 147: x],b[$(echo uname >&2): syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
./quotearray.tests: line 147: x],b[$(echo uname >&2): arithmetic syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
1
./quotearray.tests: line 150: x],b[$(echo uname >&2): syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
./quotearray.tests: line 150: x],b[$(echo uname >&2): arithmetic syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
1
./quotearray.tests: line 153: x],b[$(echo uname >&2): syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
./quotearray.tests: line 153: x],b[$(echo uname >&2): arithmetic syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
1
declare -A assoc
0
@@ -44,7 +44,7 @@ declare -A assoc=(["\` echo >&2 foo\`"]="128" [0]="0" ["]"]="12" ["x],b[\$(echo
foo
0
0
./quotearray1.sub: line 68: 0\],b\[1: syntax error: invalid arithmetic operator (error token is "\],b\[1")
./quotearray1.sub: line 68: 0\],b\[1: arithmetic syntax error: invalid arithmetic operator (error token is "\],b\[1")
declare -a array
0
0
+8 -8
View File
@@ -235,28 +235,28 @@ t -G /tmp/test.group
t -h /tmp/test.symlink
0
t 4+3 -eq 7
./test.tests: line 26: test: 4+3: integer expression expected
./test.tests: line 26: test: 4+3: integer expected
2
b 4-5 -eq 7
./test.tests: line 20: [: 4+3: integer expression expected
./test.tests: line 20: [: 4-5: integer expected
2
t 9 -eq 4+5
./test.tests: line 26: test: 4+5: integer expression expected
./test.tests: line 26: test: 4+5: integer expected
2
b 9 -eq 4+5
./test.tests: line 20: [: 4+5: integer expression expected
./test.tests: line 20: [: 4+5: integer expected
2
t A -eq 7
./test.tests: line 26: test: A: integer expression expected
./test.tests: line 26: test: A: integer expected
2
b A -eq 7
./test.tests: line 20: [: A: integer expression expected
./test.tests: line 20: [: A: integer expected
2
t 9 -eq B
./test.tests: line 26: test: B: integer expression expected
./test.tests: line 26: test: B: integer expected
2
b 9 -eq B
./test.tests: line 20: [: B: integer expression expected
./test.tests: line 20: [: B: integer expected
2
t ( 1 = 2
./test.tests: line 26: test: `)' expected
+1 -1
View File
@@ -397,7 +397,7 @@ fi
echo "t 4+3 -eq 7"
t 4+3 -eq 7
echo "b 4-5 -eq 7"
b 4+3 -eq 7
b 4-5 -eq 7
echo "t 9 -eq 4+5"
t 9 -eq 4+5