- 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
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 **));
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 */
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. */
(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)
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)
switch (cs)
{
+ case COMPLETE_DQUOTE2:
+ rtext = sh_mkdoublequoted (mtext, strlen (mtext), 1); /* For now */
+ break;
case COMPLETE_DQUOTE:
rtext = sh_double_quote (mtext);
break;
-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.
/* Cancel alarm before restoring signal handler. */
if (read_timeout)
shtimer_clear (read_timeout);
+#if defined (READLINE)
+ rl_clear_timeout ();
+#endif
read_timeout = 0;
}
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.
.B shopt
below under
.SM
-.BR SHELL BUILTIN COMMANDS .
+.BR "SHELL BUILTIN COMMANDS" .
.SH PARAMETERS
A
.I parameter
/*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);
}
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);
readtok ();
}
else
- evalerror (_("syntax error: operand expected"));
+ evalerror (_("arithmetic syntax error: operand expected"));
return (val);
}
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 */
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
if (do_replace != NO_MATCH && rl_filename_quoting_function)
replacement = (*rl_filename_quoting_function) (match, do_replace, qc);
}
+
return (replacement);
}
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);
_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)
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
/* 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
| 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
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--;
}
;
{
$$ = 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--;
}
;
;
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--;
+ }
;
#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);
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);
{
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");
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_ */
#define VT_STARSUB 128 /* $* or ${array[*]} -- used to split */
+
/* Flags for quoted_strchr */
#define ST_BACKSL 0x01
#define ST_CTLESC 0x02
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))
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;
}
{
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
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))
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);
}
#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
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
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);
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);
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
./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")
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 ")
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 ")
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
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
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
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")
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
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] = <>
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")
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
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
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
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 ...]
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
command return 16 || echo ok 5
command set -o notanoption || echo ok 6
+
+command . /notthere || echo ok 7
+command . -x true || echo ok 8
argv[1] = <$'x\001y\177z'>
argv[1] = <x^Ay^?z>
var=$'x\001y\177z'
-./exp8.sub: line 30: xy\7fz: syntax error: invalid arithmetic operator (error token is "\7fz")
+./exp8.sub: line 30: xy\7fz: arithmetic syntax error: invalid arithmetic operator (error token is "\7fz")
declare -a array=()
declare -a array=([0]=$'x\001y\177z')
argv[1] = <x^Ay^?z>
./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] = <+>
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>
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
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
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
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
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