Imported from ../bash-3.0.16.tar.gz.

This commit is contained in:
Jari Aalto 2004-11-09 21:37:25 +00:00
commit eb87367179
21 changed files with 181 additions and 67 deletions

View file

@ -451,7 +451,7 @@ char *v;
*/ */
array_dispose_element(new); array_dispose_element(new);
free(element_value(ae)); free(element_value(ae));
ae->value = savestring(v); ae->value = v ? savestring(v) : (char *)NULL;
return(0); return(0);
} else if (element_index(ae) > i) { } else if (element_index(ae) > i) {
ADD_BEFORE(ae, new); ADD_BEFORE(ae, new);

View file

@ -611,7 +611,7 @@ array_variable_part (s, subp, lenp)
var = find_variable (t); var = find_variable (t);
free (t); free (t);
return var; return (var == 0 || invisible_p (var)) ? (SHELL_VAR *)0 : var;
} }
/* Return a string containing the elements in the array and subscript /* Return a string containing the elements in the array and subscript

View file

@ -100,6 +100,7 @@ static int history_and_alias_expand_line __P((int, int));
#endif #endif
/* Helper functions for Readline. */ /* Helper functions for Readline. */
static int bash_directory_expansion __P((char **));
static int bash_directory_completion_hook __P((char **)); static int bash_directory_completion_hook __P((char **));
static int filename_completion_ignore __P((char **)); static int filename_completion_ignore __P((char **));
static int bash_push_line __P((void)); static int bash_push_line __P((void));
@ -292,7 +293,7 @@ enable_hostname_completion (on_or_off)
/* See if we have anything to do. */ /* See if we have anything to do. */
at = strchr (rl_completer_word_break_characters, '@'); at = strchr (rl_completer_word_break_characters, '@');
if ((at == 0 && on_or_off == 0) || (at != 0 && on_or_off != 0)) if ((at == 0 && on_or_off == 0) || (at != 0 && on_or_off != 0))
return; return old_value;
/* We have something to do. Do it. */ /* We have something to do. Do it. */
nval = (char *)xmalloc (strlen (rl_completer_word_break_characters) + 1 + on_or_off); nval = (char *)xmalloc (strlen (rl_completer_word_break_characters) + 1 + on_or_off);
@ -1406,10 +1407,19 @@ command_word_completion_function (hint_text, state)
filename. */ filename. */
if (*hint_text == '~') if (*hint_text == '~')
{ {
int l, tl, vl; int l, tl, vl, dl;
char *rd;
vl = strlen (val); vl = strlen (val);
tl = strlen (hint_text); tl = strlen (hint_text);
#if 0
l = vl - hint_len; /* # of chars added */ l = vl - hint_len; /* # of chars added */
#else
rd = savestring (filename_hint);
bash_directory_expansion (&rd);
dl = strlen (rd);
l = vl - dl; /* # of chars added */
free (rd);
#endif
temp = (char *)xmalloc (l + 2 + tl); temp = (char *)xmalloc (l + 2 + tl);
strcpy (temp, hint_text); strcpy (temp, hint_text);
strcpy (temp + tl, val + vl - l); strcpy (temp + tl, val + vl - l);
@ -2187,6 +2197,27 @@ bash_ignore_everything (names)
return 0; return 0;
} }
/* Simulate the expansions that will be performed by
rl_filename_completion_function. This must be called with the address of
a pointer to malloc'd memory. */
static int
bash_directory_expansion (dirname)
char **dirname;
{
char *d;
d = savestring (*dirname);
if (rl_directory_rewrite_hook)
(*rl_directory_rewrite_hook) (&d);
if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&d))
{
free (*dirname);
*dirname = d;
}
}
/* Handle symbolic link references and other directory name /* Handle symbolic link references and other directory name
expansions while hacking completion. */ expansions while hacking completion. */
static int static int
@ -2513,7 +2544,7 @@ glob_complete_word (text, state)
static char **matches = (char **)NULL; static char **matches = (char **)NULL;
static int ind; static int ind;
int glen; int glen;
char *ret; char *ret, *ttext;
if (state == 0) if (state == 0)
{ {
@ -2523,17 +2554,22 @@ glob_complete_word (text, state)
FREE (globorig); FREE (globorig);
FREE (globtext); FREE (globtext);
ttext = bash_tilde_expand (text, 0);
if (rl_explicit_arg) if (rl_explicit_arg)
{ {
globorig = savestring (text); globorig = savestring (ttext);
glen = strlen (text); glen = strlen (ttext);
globtext = (char *)xmalloc (glen + 2); globtext = (char *)xmalloc (glen + 2);
strcpy (globtext, text); strcpy (globtext, ttext);
globtext[glen] = '*'; globtext[glen] = '*';
globtext[glen+1] = '\0'; globtext[glen+1] = '\0';
} }
else else
globtext = globorig = savestring (text); globtext = globorig = savestring (ttext);
if (ttext != text)
free (ttext);
matches = shell_glob_filename (globtext); matches = shell_glob_filename (globtext);
if (GLOB_FAILED (matches)) if (GLOB_FAILED (matches))

View file

@ -340,8 +340,8 @@ expand_seqterm (text, tlen)
if (lhs_t == ST_CHAR) if (lhs_t == ST_CHAR)
{ {
lhs_v = lhs[0]; lhs_v = (unsigned char)lhs[0];
rhs_v = rhs[0]; rhs_v = (unsigned char)rhs[0];
} }
else else
{ {
@ -402,6 +402,8 @@ brace_gobbler (text, tlen, indx, satisfy)
{ {
pass_next = 1; pass_next = 1;
i++; i++;
if (quoted == 0)
level++;
continue; continue;
} }
#endif #endif

View file

@ -23,7 +23,7 @@ $PRODUCES trap.c
$BUILTIN trap $BUILTIN trap
$FUNCTION trap_builtin $FUNCTION trap_builtin
$SHORT_DOC trap [-lp] [[arg] signal_spec ...] $SHORT_DOC trap [-lp] [arg signal_spec ...]
The command ARG is to be read and executed when the shell receives The command ARG is to be read and executed when the shell receives
signal(s) SIGNAL_SPEC. If ARG is absent (and a single SIGNAL_SPEC signal(s) SIGNAL_SPEC. If ARG is absent (and a single SIGNAL_SPEC
is supplied) or `-', each specified signal is reset to its original is supplied) or `-', each specified signal is reset to its original
@ -87,7 +87,7 @@ int
trap_builtin (list) trap_builtin (list)
WORD_LIST *list; WORD_LIST *list;
{ {
int list_signal_names, display, result, opt; int list_signal_names, display, result, opt, first_signal;
list_signal_names = display = 0; list_signal_names = display = 0;
result = EXECUTION_SUCCESS; result = EXECUTION_SUCCESS;
@ -118,14 +118,19 @@ trap_builtin (list)
else else
{ {
char *first_arg; char *first_arg;
int operation, sig; int operation, sig, first_signal;
operation = SET; operation = SET;
first_arg = list->word->word; first_arg = list->word->word;
first_signal = first_arg && *first_arg && all_digits (first_arg) && signal_object_p (first_arg, opt);
/* Backwards compatibility */
if (first_signal)
operation = REVERT;
/* When in posix mode, the historical behavior of looking for a /* When in posix mode, the historical behavior of looking for a
missing first argument is disabled. To revert to the original missing first argument is disabled. To revert to the original
signal handling disposition, use `-' as the first argument. */ signal handling disposition, use `-' as the first argument. */
if (posixly_correct == 0 && first_arg && *first_arg && else if (posixly_correct == 0 && first_arg && *first_arg &&
(*first_arg != '-' || first_arg[1]) && (*first_arg != '-' || first_arg[1]) &&
signal_object_p (first_arg, opt) && list->next == 0) signal_object_p (first_arg, opt) && list->next == 0)
operation = REVERT; operation = REVERT;

View file

@ -5953,7 +5953,8 @@ The @code{trap} builtin displays signal names without the leading
@item @item
The @code{trap} builtin doesn't check the first argument for a possible The @code{trap} builtin doesn't check the first argument for a possible
signal specification and revert the signal handling to the original signal specification and revert the signal handling to the original
disposition if it is. If users want to reset the handler for a given disposition if it is, unless that argument consists solely of digits and
is a valid signal number. If users want to reset the handler for a given
signal to the original disposition, they should use @samp{-} as the signal to the original disposition, they should use @samp{-} as the
first argument. first argument.

View file

@ -267,7 +267,7 @@ assignment (string, flags)
c = string[indx = 0]; c = string[indx = 0];
#if defined (ARRAY_VARS) #if defined (ARRAY_VARS)
if ((legal_variable_starter (c) == 0) && (flags && c != '[')) /* ] */ if ((legal_variable_starter (c) == 0) && (flags == 0 || c != '[')) /* ] */
#else #else
if (legal_variable_starter (c) == 0) if (legal_variable_starter (c) == 0)
#endif #endif

View file

@ -31,6 +31,8 @@
extern size_t xmbsrtowcs __P((wchar_t *, const char **, size_t, mbstate_t *)); extern size_t xmbsrtowcs __P((wchar_t *, const char **, size_t, mbstate_t *));
extern size_t xdupmbstowcs __P((wchar_t **, char ***, const char *)); extern size_t xdupmbstowcs __P((wchar_t **, char ***, const char *));
extern size_t mbstrlen __P((const char *));
extern char *xstrchr __P((const char *, int)); extern char *xstrchr __P((const char *, int));
#ifndef MB_INVALIDCH #ifndef MB_INVALIDCH
@ -38,6 +40,9 @@ extern char *xstrchr __P((const char *, int));
#define MB_NULLWCH(x) ((x) == 0) #define MB_NULLWCH(x) ((x) == 0)
#endif #endif
#define MBSLEN(s) (((s) && (s)[0]) ? ((s)[1] ? mbstrlen (s) : 1) : 0)
#define MB_STRLEN(s) ((MB_CUR_MAX > 1) ? MBSLEN (s) : STRLEN (s))
#else /* !HANDLE_MULTIBYTE */ #else /* !HANDLE_MULTIBYTE */
#undef MB_LEN_MAX #undef MB_LEN_MAX
@ -54,6 +59,8 @@ extern char *xstrchr __P((const char *, int));
#define MB_NULLWCH(x) (0) #define MB_NULLWCH(x) (0)
#endif #endif
#define MB_STRLEN(s) (STRLEN(s))
#endif /* !HANDLE_MULTIBYTE */ #endif /* !HANDLE_MULTIBYTE */
/* Declare and initialize a multibyte state. Call must be terminated /* Declare and initialize a multibyte state. Call must be terminated

9
jobs.c
View file

@ -1778,8 +1778,13 @@ raw_job_exit_status (job)
if (pipefail_opt) if (pipefail_opt)
{ {
fail = 0; fail = 0;
for (p = jobs[job]->pipe; p->next != jobs[job]->pipe; p = p->next) p = jobs[job]->pipe;
if (p->status != EXECUTION_SUCCESS) fail = p->status; do
{
if (p->status != EXECUTION_SUCCESS) fail = p->status;
p = p->next;
}
while (p != jobs[job]->pipe);
return fail; return fail;
} }

View file

@ -201,7 +201,7 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
int *lp, *lip, *niflp, *vlp; int *lp, *lip, *niflp, *vlp;
{ {
char *r, *ret, *p; char *r, *ret, *p;
int l, rl, last, ignoring, ninvis, invfl, ind, pind, physchars; int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars;
/* Short-circuit if we can. */ /* Short-circuit if we can. */
if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (pmt, RL_PROMPT_START_IGNORE) == 0) if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
@ -222,6 +222,7 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
r = ret = (char *)xmalloc (l + 1); r = ret = (char *)xmalloc (l + 1);
invfl = 0; /* invisible chars in first line of prompt */ invfl = 0; /* invisible chars in first line of prompt */
invflset = 0; /* we only want to set invfl once */
for (rl = ignoring = last = ninvis = physchars = 0, p = pmt; p && *p; p++) for (rl = ignoring = last = ninvis = physchars = 0, p = pmt; p && *p; p++)
{ {
@ -249,7 +250,10 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
while (l--) while (l--)
*r++ = *p++; *r++ = *p++;
if (!ignoring) if (!ignoring)
rl += ind - pind; {
rl += ind - pind;
physchars += _rl_col_width (pmt, pind, ind);
}
else else
ninvis += ind - pind; ninvis += ind - pind;
p--; /* compensate for later increment */ p--; /* compensate for later increment */
@ -259,16 +263,19 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
{ {
*r++ = *p; *r++ = *p;
if (!ignoring) if (!ignoring)
rl++; /* visible length byte counter */ {
rl++; /* visible length byte counter */
physchars++;
}
else else
ninvis++; /* invisible chars byte counter */ ninvis++; /* invisible chars byte counter */
} }
if (rl >= _rl_screenwidth) if (invflset == 0 && rl >= _rl_screenwidth)
invfl = ninvis; {
invfl = ninvis;
if (ignoring == 0) invflset = 1;
physchars++; }
} }
} }
@ -351,14 +358,14 @@ rl_expand_prompt (prompt)
local_prompt = expand_prompt (p, &prompt_visible_length, local_prompt = expand_prompt (p, &prompt_visible_length,
&prompt_last_invisible, &prompt_last_invisible,
(int *)NULL, (int *)NULL,
(int *)NULL); &prompt_physical_chars);
c = *t; *t = '\0'; c = *t; *t = '\0';
/* The portion of the prompt string up to and including the /* The portion of the prompt string up to and including the
final newline is now null-terminated. */ final newline is now null-terminated. */
local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length, local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
(int *)NULL, (int *)NULL,
&prompt_invis_chars_first_line, &prompt_invis_chars_first_line,
&prompt_physical_chars); (int *)NULL);
*t = c; *t = c;
return (prompt_prefix_length); return (prompt_prefix_length);
} }
@ -417,7 +424,7 @@ rl_redisplay ()
register int in, out, c, linenum, cursor_linenum; register int in, out, c, linenum, cursor_linenum;
register char *line; register char *line;
int c_pos, inv_botlin, lb_botlin, lb_linenum; int c_pos, inv_botlin, lb_botlin, lb_linenum;
int newlines, lpos, temp, modmark; int newlines, lpos, temp, modmark, n0, num;
char *prompt_this_line; char *prompt_this_line;
#if defined (HANDLE_MULTIBYTE) #if defined (HANDLE_MULTIBYTE)
wchar_t wc; wchar_t wc;
@ -573,6 +580,7 @@ rl_redisplay ()
#if defined (HANDLE_MULTIBYTE) #if defined (HANDLE_MULTIBYTE)
memset (_rl_wrapped_line, 0, vis_lbsize); memset (_rl_wrapped_line, 0, vis_lbsize);
num = 0;
#endif #endif
/* prompt_invis_chars_first_line is the number of invisible characters in /* prompt_invis_chars_first_line is the number of invisible characters in
@ -591,13 +599,32 @@ rl_redisplay ()
probably too much work for the benefit gained. How many people have probably too much work for the benefit gained. How many people have
prompts that exceed two physical lines? prompts that exceed two physical lines?
Additional logic fix from Edward Catmur <ed@catmur.co.uk> */ Additional logic fix from Edward Catmur <ed@catmur.co.uk> */
#if defined (HANDLE_MULTIBYTE)
n0 = num;
temp = local_prompt ? strlen (local_prompt) : 0;
while (num < temp)
{
if (_rl_col_width (local_prompt, n0, num) > _rl_screenwidth)
{
num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
break;
}
num++;
}
temp = num +
#else
temp = ((newlines + 1) * _rl_screenwidth) + temp = ((newlines + 1) * _rl_screenwidth) +
#endif /* !HANDLE_MULTIBYTE */
((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line ((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line
: ((newlines == 1) ? wrap_offset : 0)) : ((newlines == 1) ? wrap_offset : 0))
: ((newlines == 0) ? wrap_offset :0)); : ((newlines == 0) ? wrap_offset :0));
inv_lbreaks[++newlines] = temp; inv_lbreaks[++newlines] = temp;
#if defined (HANDLE_MULTIBYTE)
lpos -= _rl_col_width (local_prompt, n0, num);
#else
lpos -= _rl_screenwidth; lpos -= _rl_screenwidth;
#endif
} }
prompt_last_screen_line = newlines; prompt_last_screen_line = newlines;

View file

@ -126,11 +126,11 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero)
if (find_non_zero) if (find_non_zero)
{ {
tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps); tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
while (wcwidth (wc) == 0) while (tmp > 0 && wcwidth (wc) == 0)
{ {
point += tmp; point += tmp;
tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps); tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
if (tmp == (size_t)(0) || tmp == (size_t)(-1) || tmp == (size_t)(-2)) if (MB_NULLWCH (tmp) || MB_INVALIDCH (tmp))
break; break;
} }
} }

View file

@ -276,12 +276,6 @@ rl_maybe_save_line ()
_rl_saved_line_for_history->line = savestring (rl_line_buffer); _rl_saved_line_for_history->line = savestring (rl_line_buffer);
_rl_saved_line_for_history->data = (char *)rl_undo_list; _rl_saved_line_for_history->data = (char *)rl_undo_list;
} }
else if (STREQ (rl_line_buffer, _rl_saved_line_for_history->line) == 0)
{
free (_rl_saved_line_for_history->line);
_rl_saved_line_for_history->line = savestring (rl_line_buffer);
_rl_saved_line_for_history->data = (char *)rl_undo_list; /* XXX possible memleak */
}
return 0; return 0;
} }

View file

@ -272,10 +272,12 @@ rl_vi_search (count, key)
switch (key) switch (key)
{ {
case '?': case '?':
_rl_free_saved_history_line ();
rl_noninc_forward_search (count, key); rl_noninc_forward_search (count, key);
break; break;
case '/': case '/':
_rl_free_saved_history_line ();
rl_noninc_reverse_search (count, key); rl_noninc_reverse_search (count, key);
break; break;
@ -690,7 +692,7 @@ _rl_vi_change_mbchar_case (count)
{ {
wchar_t wc; wchar_t wc;
char mb[MB_LEN_MAX+1]; char mb[MB_LEN_MAX+1];
int mblen; int mblen, p;
mbstate_t ps; mbstate_t ps;
memset (&ps, 0, sizeof (mbstate_t)); memset (&ps, 0, sizeof (mbstate_t));
@ -713,11 +715,14 @@ _rl_vi_change_mbchar_case (count)
/* Vi is kind of strange here. */ /* Vi is kind of strange here. */
if (wc) if (wc)
{ {
p = rl_point;
mblen = wcrtomb (mb, wc, &ps); mblen = wcrtomb (mb, wc, &ps);
if (mblen >= 0) if (mblen >= 0)
mb[mblen] = '\0'; mb[mblen] = '\0';
rl_begin_undo_group (); rl_begin_undo_group ();
rl_delete (1, 0); rl_vi_delete (1, 0);
if (rl_point < p) /* Did we retreat at EOL? */
rl_point++; /* XXX - should we advance more than 1 for mbchar? */
rl_insert_text (mb); rl_insert_text (mb);
rl_end_undo_group (); rl_end_undo_group ();
rl_vi_check (); rl_vi_check ();
@ -1310,12 +1315,16 @@ rl_vi_change_char (count, key)
rl_vi_delete (1, c); rl_vi_delete (1, c);
#if defined (HANDLE_MULTIBYTE) #if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
while (_rl_insert_char (1, c)) {
{ if (rl_point < p) /* Did we retreat at EOL? */
RL_SETSTATE (RL_STATE_MOREINPUT); rl_point++;
c = rl_read_key (); while (_rl_insert_char (1, c))
RL_UNSETSTATE (RL_STATE_MOREINPUT); {
} RL_SETSTATE (RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE (RL_STATE_MOREINPUT);
}
}
else else
#endif #endif
{ {

View file

@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */ looks for to find the patch level (for the sccs version string). */
#define PATCHLEVEL 0 #define PATCHLEVEL 16
#endif /* _PATCHLEVEL_H_ */ #endif /* _PATCHLEVEL_H_ */

View file

@ -863,6 +863,8 @@ bind_comp_words (lwords)
if (array_p (v) == 0) if (array_p (v) == 0)
v = convert_var_to_array (v); v = convert_var_to_array (v);
v = assign_array_var_from_word_list (v, lwords); v = assign_array_var_from_word_list (v, lwords);
VUNSETATTR (v, att_invisible);
return v; return v;
} }
#endif /* ARRAY_VARS */ #endif /* ARRAY_VARS */
@ -1022,6 +1024,8 @@ gen_shell_function_matches (cs, text, line, ind, lwords, nw, cw)
if (array_p (v) == 0) if (array_p (v) == 0)
v = convert_var_to_array (v); v = convert_var_to_array (v);
VUNSETATTR (v, att_invisible);
a = array_cell (v); a = array_cell (v);
if (a == 0 || array_empty (a)) if (a == 0 || array_empty (a))
sl = (STRINGLIST *)NULL; sl = (STRINGLIST *)NULL;

39
subst.c
View file

@ -4691,6 +4691,26 @@ valid_length_expression (name)
legal_identifier (name + 1)); /* ${#PS1} */ legal_identifier (name + 1)); /* ${#PS1} */
} }
#if defined (HANDLE_MULTIBYTE)
size_t
mbstrlen (s)
const char *s;
{
size_t clen, nc;
mbstate_t mbs;
nc = 0;
memset (&mbs, 0, sizeof (mbs));
while ((clen = mbrlen(s, MB_CUR_MAX, &mbs)) != 0 && (MB_INVALIDCH(clen) == 0))
{
s += clen;
nc++;
}
return nc;
}
#endif
/* Handle the parameter brace expansion that requires us to return the /* Handle the parameter brace expansion that requires us to return the
length of a parameter. */ length of a parameter. */
static intmax_t static intmax_t
@ -4746,14 +4766,14 @@ parameter_brace_expand_length (name)
if (legal_number (name + 1, &arg_index)) /* ${#1} */ if (legal_number (name + 1, &arg_index)) /* ${#1} */
{ {
t = get_dollar_var_value (arg_index); t = get_dollar_var_value (arg_index);
number = STRLEN (t); number = MB_STRLEN (t);
FREE (t); FREE (t);
} }
#if defined (ARRAY_VARS) #if defined (ARRAY_VARS)
else if ((var = find_variable (name + 1)) && array_p (var)) else if ((var = find_variable (name + 1)) && (invisible_p (var) == 0) && array_p (var))
{ {
t = array_reference (array_cell (var), 0); t = array_reference (array_cell (var), 0);
number = STRLEN (t); number = MB_STRLEN (t);
} }
#endif #endif
else /* ${#PS1} */ else /* ${#PS1} */
@ -4766,7 +4786,7 @@ parameter_brace_expand_length (name)
if (list) if (list)
dispose_words (list); dispose_words (list);
number = STRLEN (t); number = MB_STRLEN (t);
FREE (t); FREE (t);
} }
} }
@ -4871,7 +4891,7 @@ verify_substring_values (value, substr, vtype, e1p, e2p)
{ {
case VT_VARIABLE: case VT_VARIABLE:
case VT_ARRAYMEMBER: case VT_ARRAYMEMBER:
len = strlen (value); len = MB_STRLEN (value);
break; break;
case VT_POSPARMS: case VT_POSPARMS:
len = number_of_args () + 1; len = number_of_args () + 1;
@ -4879,8 +4899,9 @@ verify_substring_values (value, substr, vtype, e1p, e2p)
#if defined (ARRAY_VARS) #if defined (ARRAY_VARS)
case VT_ARRAYVAR: case VT_ARRAYVAR:
a = (ARRAY *)value; a = (ARRAY *)value;
/* For arrays, the first value deals with array indices. */ /* For arrays, the first value deals with array indices. Negative
len = array_max_index (a); /* arrays index from 0 to n - 1 */ offsets count from one past the array's maximum index. */
len = array_max_index (a) + (*e1p < 0); /* arrays index from 0 to n - 1 */
break; break;
#endif #endif
} }
@ -4891,7 +4912,7 @@ verify_substring_values (value, substr, vtype, e1p, e2p)
if (*e1p < 0) /* negative offsets count from end */ if (*e1p < 0) /* negative offsets count from end */
*e1p += len; *e1p += len;
if (*e1p >= len || *e1p < 0) if (*e1p > len || *e1p < 0)
return (-1); return (-1);
#if defined (ARRAY_VARS) #if defined (ARRAY_VARS)
@ -4982,7 +5003,7 @@ get_var_and_type (varname, value, quoted, varp, valp)
else else
return -1; return -1;
} }
else if ((v = find_variable (varname)) && array_p (v)) else if ((v = find_variable (varname)) && (invisible_p (v) == 0) && array_p (v))
{ {
vtype = VT_ARRAYMEMBER; vtype = VT_ARRAYMEMBER;
*varp = v; *varp = v;

View file

@ -170,8 +170,8 @@ too many elements -- expect three five seven
three five seven three five seven
positive offset - expect five seven positive offset - expect five seven
five seven five seven
negative offset - expect five seven negative offset to unset element - expect seven
five seven seven
positive offset 2 - expect seven positive offset 2 - expect seven
seven seven
negative offset 2 - expect seven negative offset 2 - expect seven

View file

@ -322,7 +322,7 @@ echo ${av[@]:3:5} # how about too many elements?
echo positive offset - expect five seven echo positive offset - expect five seven
echo ${av[@]:5:2} echo ${av[@]:5:2}
echo negative offset - expect five seven echo negative offset to unset element - expect seven
echo ${av[@]: -2:2} echo ${av[@]: -2:2}
echo positive offset 2 - expect seven echo positive offset 2 - expect seven

View file

@ -62,8 +62,8 @@ set -o functrace
trap 'print_debug_trap $LINENO' DEBUG trap 'print_debug_trap $LINENO' DEBUG
trap 'print_return_trap $LINENO' RETURN trap 'print_return_trap $LINENO' RETURN
# Funcname is now an array. Vanilla Bash 2.05 doesn't have FUNCNAME array. # Funcname is now an array, but you still can't see it outside a function
echo "FUNCNAME" ${FUNCNAME[0]} echo "FUNCNAME" ${FUNCNAME[0]:-main}
# We should trace into the below. # We should trace into the below.
# Start easy with a simple function. # Start easy with a simple function.

View file

@ -85,7 +85,7 @@ command: usage: command [-pVv] command [arg ...]
./errors.tests: line 213: /bin/sh + 0: syntax error: operand expected (error token is "/bin/sh + 0") ./errors.tests: line 213: /bin/sh + 0: syntax error: operand expected (error token is "/bin/sh + 0")
./errors.tests: line 216: trap: NOSIG: invalid signal specification ./errors.tests: line 216: trap: NOSIG: invalid signal specification
./errors.tests: line 219: trap: -s: invalid option ./errors.tests: line 219: trap: -s: invalid option
trap: usage: trap [-lp] [[arg] signal_spec ...] trap: usage: trap [-lp] [arg signal_spec ...]
./errors.tests: line 225: return: can only `return' from a function or sourced script ./errors.tests: line 225: return: can only `return' from a function or sourced script
./errors.tests: line 229: break: 0: loop count out of range ./errors.tests: line 229: break: 0: loop count out of range
./errors.tests: line 233: continue: 0: loop count out of range ./errors.tests: line 233: continue: 0: loop count out of range

View file

@ -1419,11 +1419,11 @@ initialize_dynamic_variables ()
v = init_dynamic_array_var ("GROUPS", get_groupset, null_array_assign, att_noassign); v = init_dynamic_array_var ("GROUPS", get_groupset, null_array_assign, att_noassign);
# if defined (DEBUGGER) # if defined (DEBUGGER)
v = init_dynamic_array_var ("BASH_ARGC", get_self, null_array_assign, (att_invisible|att_noassign)); v = init_dynamic_array_var ("BASH_ARGC", get_self, null_array_assign, att_noassign);
v = init_dynamic_array_var ("BASH_ARGV", get_self, null_array_assign, (att_invisible|att_noassign)); v = init_dynamic_array_var ("BASH_ARGV", get_self, null_array_assign, att_noassign);
# endif /* DEBUGGER */ # endif /* DEBUGGER */
v = init_dynamic_array_var ("BASH_SOURCE", get_self, null_array_assign, (att_invisible|att_noassign)); v = init_dynamic_array_var ("BASH_SOURCE", get_self, null_array_assign, att_noassign);
v = init_dynamic_array_var ("BASH_LINENO", get_self, null_array_assign, (att_invisible|att_noassign)); v = init_dynamic_array_var ("BASH_LINENO", get_self, null_array_assign, att_noassign);
#endif #endif
v = init_funcname_var (); v = init_funcname_var ();
@ -1599,7 +1599,10 @@ make_local_variable (name)
/* local foo; local foo; is a no-op. */ /* local foo; local foo; is a no-op. */
old_var = find_variable (name); old_var = find_variable (name);
if (old_var && local_p (old_var) && old_var->context == variable_context) if (old_var && local_p (old_var) && old_var->context == variable_context)
return (old_var); {
VUNSETATTR (old_var, att_invisible);
return (old_var);
}
was_tmpvar = old_var && tempvar_p (old_var); was_tmpvar = old_var && tempvar_p (old_var);
if (was_tmpvar) if (was_tmpvar)