waited for is suspended. Returns 128 + stop signal. This fixes
the problem with `echo one && sleep 5 && echo two' displaying
`two' after the sleep is suspended
+
+ 1/5
+ ---
+print_cmd.c
+ - change indirection_level_string so the code duplicates the first
+ character of $PS4 to indicate the indirection level, rather than
+ the first byte
+
+ 1/8
+ ---
+variables.c
+ - new special variable hook function for COMP_WORDBREAKS; sets
+ rl_completer_word_break_characters back to NULL when the variable
+ is unset
+ - change bind_variable_value to understand dynamic variables with
+ assign_function set, and handle them correctly. If the variable is
+ being appended to, use make_variable_value to create the new
+ value
+ - change bind_variable_internal to understand dynamic variables with
+ assign_function set, and handle them the same way
+ - RANDOM and LINENO now get the integer attribute, so appending works
+ as expected
+ - ditto for HISTCMD, MAILCHECK, OPTIND
+
+lib/readline/display.c
+ - change _rl_make_prompt_for_search to set prompt_physical_chars
+ appropriately
+ - rl_save_prompt and rl_restore_prompt save and restore
+ prompt_prefix_length
+ - change redraw_prompt to use rl_save_prompt and rl_restore_prompt
+ - change rl_restore_prompt to set the `save' variables back to
+ NULL/0 so code can check whether or not the prompt has been saved
+ - change rl_message and rl_clear_message to save and restore the
+ prompt if the caller has not already done it (using a simple
+ semaphore-like variable)
+ - change rl_message to call expand_prompt, so that local_prompt and
+ local_prompt prefix are set before calling the redisplay functions,
+ in case the prompt is longer than a screenwidth (fixes bug
+ reported to debian by epl@unimelb.edu.au)
+
+lib/readline/doc/rltech.texi
+ - make sure to note that rl_save_prompt should be called before
+ rl_message, and rl_restore_prompt before rl_clear_message
+
+pcomplete.c
+ - make sure to save and restore the parser state around the call to
+ execute_shell_function in gen_shell_function_matches. Fixes bug
+ reported by a050106.1.keeLae3x@captaincrumb.com (cute)
+
+lib/readline/readline.c
+ - fix _rl_dispatch_subseq in the case where we're recursing back up
+ the chain (r == -2) and we encounter a key shadowed by a keymap,
+ but originally bound to self-insert. Calling rl_dispatch with
+ ANYOTHERKEY as the first argument will call rl_insert, but with
+ ANYOTHERKEY (256) as the char to insert. Use the shadow keymap
+ and set things up to dispatch to rl_insert with the shadowed key
+ as the argument. Fixes the bug reported by Thomas Glanzmann
+ (sithglan@stud.uni-erlangen.de)
doc/bashref.texi
- documented new `single-help-strings' configure option
+
+ 1/3/2005
+ --------
+jobs.c
+ - make wait_for return a non-zero status if the job or processed
+ waited for is suspended. Returns 128 + stop signal. This fixes
+ the problem with `echo one && sleep 5 && echo two' displaying
+ `two' after the sleep is suspended
+
+ 1/5
+ ---
+print_cmd.c
+ - change indirection_level_string so the code duplicates the first
+ character of $PS4 to indicate the indirection level, rather than
+ the first byte
+
+ 1/8
+ ---
+variables.c
+ - new special variable hook function for COMP_WORDBREAKS; sets
+ rl_completer_word_break_characters back to NULL when the variable
+ is unset
+ - change bind_variable_value to understand dynamic variables with
+ assign_function set, and handle them correctly. If the variable is
+ being appended to, use make_variable_value to create the new
+ value
+ - change bind_variable_internal to understand dynamic variables with
+ assign_function set, and handle them the same way
+ - RANDOM and LINENO now get the integer attribute, so appending works
+ as expected
+ - ditto for HISTCMD, MAILCHECK, OPTIND
+
+lib/readline/display.c
+ - change _rl_make_prompt_for_search to set prompt_physical_chars
+ appropriately
+ - rl_save_prompt and rl_restore_prompt save and restore
+ prompt_prefix_length
+ - change redraw_prompt to use rl_save_prompt and rl_restore_prompt
+ - change rl_restore_prompt to set the `save' variables back to
+ NULL/0 so code can check whether or not the prompt has been saved
+ - change rl_message and rl_clear_message to save and restore the
+ prompt if the caller has not already done it (using a simple
+ semaphore-like variable)
+ - change rl_message to call expand_prompt, so that local_prompt and
+ local_prompt prefix are set before calling the redisplay functions,
+ in case the prompt is longer than a screenwidth (fixes bug
+ reported to debian by epl@unimelb.edu.au)
+
+lib/readline/doc/rltech.texi
+ - make sure to note that rl_save_prompt should be called before
+ rl_message, and rl_restore_prompt before rl_clear_message
+
+pcomplete.c
+ - make sure to save and restore the parser state around the call to
+ execute_shell_function in gen_shell_function_matches. Fixes bug
+ reported by a050106.1.keeLae3x@captaincrumb.com (cute)
+
+
-.\"
+\"
.\" MAN PAGE COMMENTS to
.\"
.\" Chet Ramey
.\" Case Western Reserve University
.\" chet@po.CWRU.Edu
.\"
-.\" Last Change: Wed Dec 22 15:43:06 EST 2004
+.\" Last Change: Tue Jan 4 17:23:59 EST 2005
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
-.TH BASH 1 "2004 Dec 22" "GNU Bash-3.1-devel"
+.TH BASH 1 "2005 Jan 4" "GNU Bash-3.1-devel"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
[options]
[file]
.SH COPYRIGHT
-.if n Bash is Copyright (C) 1989-2004 by the Free Software Foundation, Inc.
-.if t Bash is Copyright \(co 1989-2004 by the Free Software Foundation, Inc.
+.if n Bash is Copyright (C) 1989-2005 by the Free Software Foundation, Inc.
+.if t Bash is Copyright \(co 1989-2005 by the Free Software Foundation, Inc.
.SH DESCRIPTION
.B Bash
is an \fBsh\fR-compatible command language interpreter that
Shell quoting is honored.
Each word is then expanded using
brace expansion, tilde expansion, parameter and variable expansion,
-command substitution, arithmetic expansion, and pathname expansion,
+command substitution, and arithmetic expansion,
as described above under
.SM
.BR EXPANSION .
of @cite{The GNU Bash Reference Manual},
for @code{Bash}, Version @value{VERSION}.
-Copyright @copyright{} 1988-2004 Free Software Foundation, Inc.
+Copyright @copyright{} 1988-2005 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@ignore
-Copyright (C) 1988-2004 Free Software Foundation, Inc.
+Copyright (C) 1988-2005 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Thu Dec 30 17:00:22 EST 2004
/* This file works with both POSIX and BSD systems. It implements job
control. */
-/* Copyright (C) 1989-2003 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2005 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
static int prompt_physical_chars;
+/* Variables to save and restore prompt and display information. */
+
+/* These are getting numerous enough that it's time to create a struct. */
+
+static char *saved_local_prompt;
+static char *saved_local_prefix;
+static int saved_last_invisible;
+static int saved_visible_length;
+static int saved_prefix_length;
+static int saved_invis_chars_first_line;
+static int saved_physical_chars;
+
/* Expand the prompt string S and return the number of visible
characters in *LP, if LP is not null. This is currently more-or-less
a placeholder for expansion. LIP, if non-null is a place to store the
return ((ISPRINT (uc)) ? 1 : 2);
}
-
/* How to print things in the "echo-area". The prompt is treated as a
mini-modeline. */
+static int msg_saved_prompt = 0;
#if defined (USE_VARARGS)
int
#endif
va_end (args);
+ if (saved_local_prompt == 0)
+ {
+ rl_save_prompt ();
+ msg_saved_prompt = 1;
+ }
rl_display_prompt = msg_buf;
+ local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
+ &prompt_last_invisible,
+ &prompt_invis_chars_first_line,
+ &prompt_physical_chars);
+ local_prompt_prefix = (char *)NULL;
(*rl_redisplay_function) ();
+
return 0;
}
#else /* !USE_VARARGS */
{
sprintf (msg_buf, format, arg1, arg2);
msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */
+
rl_display_prompt = msg_buf;
+ if (saved_local_prompt == 0)
+ {
+ rl_save_prompt ();
+ msg_saved_prompt = 1;
+ }
+ local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
+ &prompt_last_invisible,
+ &prompt_invis_chars_first_line,
+ &prompt_physical_chars);
+ local_prompt_prefix = (char *)NULL;
(*rl_redisplay_function) ();
+
return 0;
}
#endif /* !USE_VARARGS */
rl_clear_message ()
{
rl_display_prompt = rl_prompt;
+ if (msg_saved_prompt)
+ {
+ rl_restore_prompt ();
+ msg_saved_prompt = 0;
+ }
(*rl_redisplay_function) ();
return 0;
}
return 0;
}
-/* These are getting numerous enough that it's time to create a struct. */
-
-static char *saved_local_prompt;
-static char *saved_local_prefix;
-static int saved_last_invisible;
-static int saved_visible_length;
-static int saved_invis_chars_first_line;
-static int saved_physical_chars;
-
void
rl_save_prompt ()
{
saved_local_prompt = local_prompt;
saved_local_prefix = local_prompt_prefix;
+ saved_prefix_length = prompt_prefix_length;
saved_last_invisible = prompt_last_invisible;
saved_visible_length = prompt_visible_length;
saved_invis_chars_first_line = prompt_invis_chars_first_line;
saved_physical_chars = prompt_physical_chars;
local_prompt = local_prompt_prefix = (char *)0;
- prompt_last_invisible = prompt_visible_length = 0;
+ prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0;
prompt_invis_chars_first_line = prompt_physical_chars = 0;
}
local_prompt = saved_local_prompt;
local_prompt_prefix = saved_local_prefix;
+ prompt_prefix_length = saved_prefix_length;
prompt_last_invisible = saved_last_invisible;
prompt_visible_length = saved_visible_length;
prompt_invis_chars_first_line = saved_invis_chars_first_line;
prompt_physical_chars = saved_physical_chars;
+
+ /* can test saved_local_prompt to see if prompt info has been saved. */
+ saved_local_prompt = saved_local_prefix = (char *)0;
+ saved_last_invisible = saved_visible_length = saved_prefix_length = 0;
+ saved_invis_chars_first_line = saved_physical_chars = 0;
}
char *
prompt_visible_length = saved_visible_length + 1;
}
+ prompt_physical_chars = saved_physical_chars + 1;
+
return pmt;
}
redraw_prompt (t)
char *t;
{
- char *oldp, *oldl, *oldlprefix;
- int oldlen, oldlast, oldplen, oldninvis, oldphyschars;
+ char *oldp;
- /* Geez, I should make this a struct. */
oldp = rl_display_prompt;
- oldl = local_prompt;
- oldlprefix = local_prompt_prefix;
- oldlen = prompt_visible_length;
- oldplen = prompt_prefix_length;
- oldlast = prompt_last_invisible;
- oldninvis = prompt_invis_chars_first_line;
- oldphyschars = prompt_physical_chars;
+ rl_save_prompt ();
rl_display_prompt = t;
local_prompt = expand_prompt (t, &prompt_visible_length,
&prompt_invis_chars_first_line,
&prompt_physical_chars);
local_prompt_prefix = (char *)NULL;
+
rl_forced_update_display ();
rl_display_prompt = oldp;
- local_prompt = oldl;
- local_prompt_prefix = oldlprefix;
- prompt_visible_length = oldlen;
- prompt_prefix_length = oldplen;
- prompt_last_invisible = oldlast;
- prompt_invis_chars_first_line = oldninvis;
- prompt_physical_chars = oldphyschars;
+ rl_restore_prompt();
}
/* Redisplay the current line after a SIGWINCH is received. */
FREE (local_prompt_prefix);
local_prompt = local_prompt_prefix = (char *)0;
- prompt_last_invisible = prompt_visible_length = 0;
+ prompt_last_invisible = prompt_invis_chars_first_line = 0;
+ prompt_visible_length = prompt_physical_chars = 0;
if (prompt == 0 || *prompt == 0)
return (0);
(wrap_offset > visible_wrap_offset) &&
(_rl_last_c_pos < visible_first_line_len))
{
-#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
nleft = _rl_screenwidth - _rl_last_c_pos;
else
-#endif
- nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos;
+ nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos;
if (nleft)
_rl_clear_to_eol (nleft);
}
the physical cursor position on the screen stays the same,
but the buffer position needs to be adjusted to account
for invisible characters. */
-#if defined (HANDLE_MULTIBYTE)
if ((MB_CUR_MAX == 1 || rl_byte_oriented) && cursor_linenum == 0 && wrap_offset)
-#else
- if (cursor_linenum == 0 && wrap_offset)
-#endif
_rl_last_c_pos += wrap_offset;
}
tx = _rl_col_width (&visible_line[pos], 0, nleft);
else
tx = nleft;
- _rl_backspace (_rl_last_c_pos - tx); /* XXX */
- _rl_last_c_pos = tx;
+ if (_rl_last_c_pos != tx)
+ {
+ _rl_backspace (_rl_last_c_pos - tx); /* XXX */
+ _rl_last_c_pos = tx;
+ }
}
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
the exact cursor position and cut-and-paste with certain terminal
emulators. In this calculation, TEMP is the physical screen
position of the cursor. */
-#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
temp = _rl_last_c_pos;
else
-#endif
- temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
+ temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
&& _rl_last_v_pos == current_line - 1)
{
if (_rl_last_v_pos != current_line)
{
_rl_move_vert (current_line);
-#if defined (HANDLE_MULTIBYTE)
if ((MB_CUR_MAX == 1 || rl_byte_oriented) && current_line == 0 && visible_wrap_offset)
-#else
- if (current_line == 0 && visible_wrap_offset)
-#endif
_rl_last_c_pos += visible_wrap_offset;
}
static int prompt_physical_chars;
+/* Variables to save and restore prompt and display information. */
+
+/* These are getting numerous enough that it's time to create a struct. */
+
+static char *saved_local_prompt;
+static char *saved_local_prefix;
+static int saved_last_invisible;
+static int saved_visible_length;
+static int saved_prefix_length;
+static int saved_invis_chars_first_line;
+static int saved_physical_chars;
+
/* Expand the prompt string S and return the number of visible
characters in *LP, if LP is not null. This is currently more-or-less
a placeholder for expansion. LIP, if non-null is a place to store the
FREE (local_prompt_prefix);
local_prompt = local_prompt_prefix = (char *)0;
- prompt_last_invisible = prompt_visible_length = 0;
+ prompt_last_invisible = prompt_invis_chars_first_line = 0;
+ prompt_visible_length = prompt_physical_chars = 0;
if (prompt == 0 || *prompt == 0)
return (0);
return ((ISPRINT (uc)) ? 1 : 2);
}
-
/* How to print things in the "echo-area". The prompt is treated as a
mini-modeline. */
+static int msg_saved_prompt = 0;
#if defined (USE_VARARGS)
int
va_end (args);
rl_display_prompt = msg_buf;
+ if (saved_local_prompt == 0)
+ {
+ rl_save_prompt ();
+ msg_saved_prompt = 1;
+ }
(*rl_redisplay_function) ();
+
return 0;
}
#else /* !USE_VARARGS */
{
sprintf (msg_buf, format, arg1, arg2);
msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */
+
rl_display_prompt = msg_buf;
+ if (saved_local_prompt == 0)
+ {
+ rl_save_prompt ();
+ msg_saved_prompt = 1;
+ }
(*rl_redisplay_function) ();
+
return 0;
}
#endif /* !USE_VARARGS */
rl_clear_message ()
{
rl_display_prompt = rl_prompt;
+ if (msg_saved_prompt)
+ {
+ rl_restore_prompt ();
+ msg_saved_prompt = 0;
+ }
(*rl_redisplay_function) ();
return 0;
}
return 0;
}
-/* These are getting numerous enough that it's time to create a struct. */
-
-static char *saved_local_prompt;
-static char *saved_local_prefix;
-static int saved_last_invisible;
-static int saved_visible_length;
-static int saved_invis_chars_first_line;
-static int saved_physical_chars;
-
void
rl_save_prompt ()
{
saved_local_prompt = local_prompt;
saved_local_prefix = local_prompt_prefix;
+ saved_prefix_length = prompt_prefix_length;
saved_last_invisible = prompt_last_invisible;
saved_visible_length = prompt_visible_length;
saved_invis_chars_first_line = prompt_invis_chars_first_line;
saved_physical_chars = prompt_physical_chars;
local_prompt = local_prompt_prefix = (char *)0;
- prompt_last_invisible = prompt_visible_length = 0;
+ prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0;
prompt_invis_chars_first_line = prompt_physical_chars = 0;
}
local_prompt = saved_local_prompt;
local_prompt_prefix = saved_local_prefix;
+ prompt_prefix_length = saved_prefix_length;
prompt_last_invisible = saved_last_invisible;
prompt_visible_length = saved_visible_length;
prompt_invis_chars_first_line = saved_invis_chars_first_line;
prompt_physical_chars = saved_physical_chars;
+
+ /* can test saved_local_prompt to see if prompt info has been saved. */
+ saved_local_prompt = saved_local_prefix = (char *)0;
+ saved_last_invisible = saved_visible_length = saved_prefix_length = 0;
+ saved_invis_chars_first_line = saved_physical_chars = 0;
}
char *
prompt_visible_length = saved_visible_length + 1;
}
+ prompt_physical_chars = saved_physical_chars + 1;
+
return pmt;
}
redraw_prompt (t)
char *t;
{
- char *oldp, *oldl, *oldlprefix;
- int oldlen, oldlast, oldplen, oldninvis, oldphyschars;
+ char *oldp;
- /* Geez, I should make this a struct. */
oldp = rl_display_prompt;
- oldl = local_prompt;
- oldlprefix = local_prompt_prefix;
- oldlen = prompt_visible_length;
- oldplen = prompt_prefix_length;
- oldlast = prompt_last_invisible;
- oldninvis = prompt_invis_chars_first_line;
- oldphyschars = prompt_physical_chars;
+ rl_save_prompt ();
rl_display_prompt = t;
local_prompt = expand_prompt (t, &prompt_visible_length,
&prompt_invis_chars_first_line,
&prompt_physical_chars);
local_prompt_prefix = (char *)NULL;
+
rl_forced_update_display ();
rl_display_prompt = oldp;
- local_prompt = oldl;
- local_prompt_prefix = oldlprefix;
- prompt_visible_length = oldlen;
- prompt_prefix_length = oldplen;
- prompt_last_invisible = oldlast;
- prompt_invis_chars_first_line = oldninvis;
- prompt_physical_chars = oldphyschars;
+ rl_restore_prompt();
}
/* Redisplay the current line after a SIGWINCH is received. */
any additional arguments necessary to satisfy the conversion specifications.
The resulting string is displayed in the @dfn{echo area}. The echo area
is also used to display numeric arguments and search strings.
+You should call @code{rl_save_prompt} to save the prompt information
+before calling this function.
@end deftypefun
@deftypefun int rl_clear_message (void)
-Clear the message in the echo area.
+Clear the message in the echo area. If the prompt was saved with a call to
+@code{rl_save_prompt} before the last call to @code{rl_message},
+call @code{rl_restore_prompt} before calling this function.
@end deftypefun
@deftypefun void rl_save_prompt (void)
@deftypefun void rl_restore_prompt (void)
Restore the local Readline prompt display state saved by the most
recent call to @code{rl_save_prompt}.
+if @code{rl_save_prompt} was called to save the prompt before a call
+to @code{rl_message}, this function should be called before the
+corresponding call to @coode{rl_clear_message}.
@end deftypefun
@deftypefun int rl_expand_prompt (char *prompt)
A command function should return 0 if its action completes successfully,
and a non-zero value if some error occurs.
+This is the convention obeyed by all of the builtin Readline bindable
+command functions.
@node Readline Variables
@section Readline Variables
Shell quoting is honored.
Each word is then expanded using
brace expansion, tilde expansion, parameter and variable expansion,
-command substitution, arithmetic expansion, and pathname expansion,
+command substitution, and arithmetic expansion,
as described above (@pxref{Shell Expansions}).
The results are split using the rules described above
(@pxref{Word Splitting}).
@ignore
-Copyright (C) 1988-2004 Free Software Foundation, Inc.
+Copyright (C) 1988-2005 Free Software Foundation, Inc.
@end ignore
@set EDITION 5.1-devel
@set VERSION 5.1-devel
-@set UPDATED 22 November 2004
-@set UPDATED-MONTH November 2004
+@set UPDATED 4 January 2005
+@set UPDATED-MONTH January 2005
-@set LASTCHANGE Mon Nov 22 12:01:42 EST 2004
+@set LASTCHANGE Tue Jan 4 17:26:58 EST 2005
already taken care of pushing any necessary input back onto
the input queue with _rl_unget_char. */
{
-#if 0
- r = _rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key));
-#else
- /* XXX - experimental code -- might never be executed. Save
- for later. */
Keymap m = FUNCTION_TO_KEYMAP (map, key);
int type = m[ANYOTHERKEY].type;
func = m[ANYOTHERKEY].function;
if (type == ISFUNC && func == rl_do_lowercase_version)
r = _rl_dispatch (_rl_to_lower (key), map);
+ else if (type == ISFUNC && func == rl_insert)
+ {
+ /* If the function that was shadowed was self-insert, we
+ somehow need a keymap with map[key].func == self-insert.
+ Let's use this one. */
+ int nt = m[key].type;
+ rl_command_func_t *nf = m[key].function;
+
+ m[key].type = type;
+ m[key].function = func;
+ r = _rl_dispatch (key, m);
+ m[key].type = nt;
+ m[key].function = nf;
+ }
else
r = _rl_dispatch (ANYOTHERKEY, m);
-#endif
}
else if (r && map[ANYOTHERKEY].function)
{
func = m[ANYOTHERKEY].function;
if (type == ISFUNC && func == rl_do_lowercase_version)
r = _rl_dispatch (_rl_to_lower (key), map);
+ else if (type == ISFUNC && func == rl_insert)
+ {
+ /* If the function that was shadowed was self-insert, we
+ somehow need a keymap with map[key].func == self-insert.
+ Let's use this one. */
+ int nt = m[key].type;
+ rl_command_func_t *nf = m[key].function;
+
+ m[key].type = type;
+ m[key].function = func;
+ r = _rl_dispatch (key, m);
+ m[key].type = nt;
+ m[key].function = nf;
+ }
else
r = _rl_dispatch (ANYOTHERKEY, m);
#endif
static void
reset_default_bindings ()
{
- if (rl_bind_stty_chars)
+ if (_rl_bind_stty_chars)
{
rl_tty_unset_default_bindings (_rl_keymap);
rl_tty_set_default_bindings (_rl_keymap);
SHELL_VAR *f, *v;
WORD_LIST *cmdlist;
int fval;
+ sh_parser_state_t ps;
#if defined (ARRAY_VARS)
ARRAY *a;
#endif
bind_compfunc_variables (line, ind, lwords, cw - 1, 0);
cmdlist = build_arg_list (funcname, text, lwords, cw);
-
+
+ save_parser_state (&ps);
fval = execute_shell_function (f, cmdlist);
+ restore_parser_state (&ps);
/* Now clean up and destroy everything. */
dispose_words (cmdlist);
/* Set the variables that the function expects while it executes. Maybe
these should be in the function environment (temporary_env). */
- v = bind_variable ("COMP_LINE", line);
+ v = bind_variable ("COMP_LINE", line, 0);
if (v && exported)
VSETATTR(v, att_exported);
#include "shell.h"
#include "flags.h"
#include <y.tab.h> /* use <...> so we pick it up from the build directory */
+
+#include "shmbutil.h"
+
#include "builtins/common.h"
#if !HAVE_DECL_PRINTF
{
register int i, j;
char *ps4;
+ char ps4_firstc[MB_LEN_MAX+1];
+ int ps4_firstc_len, ps4_len;
indirection_string[0] = '\0';
ps4 = get_string_value ("PS4");
if (ps4 == 0 || *ps4 == '\0')
return (indirection_string);
- for (i = 0; *ps4 && i < indirection_level && i < 99; i++)
- indirection_string[i] = *ps4;
+#if defined (HANDLE_MULTIBYTE)
+ ps4_len = strnlen (ps4, MB_CUR_MAX);
+ ps4_firstc_len = MBLEN (ps4, ps4_len);
+ if (ps4_firstc_len == 1 || ps4_firstc_len == 0 || MB_INVALIDCH (ps4_firstc_len))
+ {
+ ps4_firstc[0] = ps4[0];
+ ps4_firstc[ps4_firstc_len = 1] = '\0';
+ }
+ else
+ memcpy (ps4_firstc, ps4, ps4_firstc_len);
+#else
+ ps4_firstc[0] = ps4[0];
+ ps4_firstc[ps4_firstc_len = 1] = '\0';
+#endif
+
+ for (i = j = 0; ps4_firstc[0] && j < indirection_level && i < 99; i += ps4_firstc_len, j++)
+ {
+ if (ps4_firstc_len == 1)
+ indirection_string[i] = ps4_firstc[0];
+ else
+ memcpy (indirection_string+i, ps4_firstc, ps4_firstc_len);
+ }
- for (j = 1; *ps4 && ps4[j] && i < 99; i++, j++)
+ for (j = ps4_firstc_len; *ps4 && ps4[j] && i < 99; i++, j++)
indirection_string[i] = ps4[j];
indirection_string[i] = '\0';
-BUILD_DIR=/usr/local/build/bash/bash-current
+BUILD_DIR=/usr/local/build/chet/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
names a mail file if MAILPATH is not set, and we should provide a
default only if neither is set. */
if (interactive_shell)
- set_if_not ("MAILCHECK", posixly_correct ? "600" : "60");
+ {
+ temp_var = set_if_not ("MAILCHECK", posixly_correct ? "600" : "60");
+ VSETATTR (temp_var, att_integer);
+ }
/* Do some things with shell level. */
initialize_shell_level ();
set_ppid ();
/* Initialize the `getopts' stuff. */
- bind_variable ("OPTIND", "1", 0);
+ temp_var = bind_variable ("OPTIND", "1", 0);
+ VSETATTR (temp_var, att_integer);
getopts_reset (0);
bind_variable ("OPTERR", "1", 0);
sh_opterr = 1;
INIT_DYNAMIC_VAR ("BASH_SUBSHELL", (char *)NULL, get_subshell, assign_subshell);
INIT_DYNAMIC_VAR ("RANDOM", (char *)NULL, get_random, assign_random);
+ VSETATTR (v, att_integer);
INIT_DYNAMIC_VAR ("LINENO", (char *)NULL, get_lineno, assign_lineno);
+ VSETATTR (v, att_integer);
#if defined (HISTORY)
INIT_DYNAMIC_VAR ("HISTCMD", (char *)NULL, get_histcmd, (sh_var_assign_func_t *)NULL);
+ VSETATTR (v, att_integer);
#endif
#if defined (READLINE)
else if (entry->assign_func) /* array vars have assign functions now */
{
INVALIDATE_EXPORTSTR (entry);
- return ((*(entry->assign_func)) (entry, value, -1));
+ newval = (aflags & ASS_APPEND) ? make_variable_value (entry, value, aflags) : value;
+ entry = (*(entry->assign_func)) (entry, newval, -1);
+ if (newval != value)
+ free (newval);
+ return (entry);
}
else
{
VUNSETATTR (var, att_invisible);
- t = make_variable_value (var, value, aflags);
- FREE (value_cell (var));
- var_setvalue (var, t);
+ if (var->assign_func)
+ {
+ /* If we're appending, we need the old value, so use
+ make_variable_value */
+ t = (aflags & ASS_APPEND) ? make_variable_value (var, value, aflags) : value;
+ (*(var->assign_func)) (var, t, -1);
+ if (t != value && t)
+ free (t);
+ }
+ else
+ {
+ t = make_variable_value (var, value, aflags);
+ FREE (value_cell (var));
+ var_setvalue (var, t);
+ }
INVALIDATE_EXPORTSTR (var);
};
static struct name_and_function special_vars[] = {
+#if defined (READLINE) && defined (PROGRAMMABLE_COMPLETION)
+ { "COMP_WORDBREAKS", sv_comp_wordbreaks },
+#endif
+
{ "GLOBIGNORE", sv_globignore },
#if defined (HISTORY)
}
}
+#if defined (READLINE) && defined (PROGRAMMABLE_COMPLETION)
+void
+sv_comp_wordbreaks (name)
+ char *name;
+{
+ SHELL_VAR *sv;
+
+ sv = find_variable (name);
+ if (sv == 0)
+ rl_completer_word_break_characters = (char *)NULL;
+}
+#endif
+
/* What to do when GLOBIGNORE changes. */
void
sv_globignore (name)
INIT_DYNAMIC_VAR ("BASH_SUBSHELL", (char *)NULL, get_subshell, assign_subshell);
INIT_DYNAMIC_VAR ("RANDOM", (char *)NULL, get_random, assign_random);
+ VSETATTR (v, att_integer);
INIT_DYNAMIC_VAR ("LINENO", (char *)NULL, get_lineno, assign_lineno);
+ VSETATTR (v, att_integer);
#if defined (HISTORY)
INIT_DYNAMIC_VAR ("HISTCMD", (char *)NULL, get_histcmd, (sh_var_assign_func_t *)NULL);
else if (entry->assign_func) /* array vars have assign functions now */
{
INVALIDATE_EXPORTSTR (entry);
- return ((*(entry->assign_func)) (entry, value, -1));
+ newval = (aflags & ASS_APPEND) ? make_variable_value (entry, value, aflags) : value;
+ entry = (*(entry->assign_func)) (entry, newval, -1);
+ if (newval != value)
+ free (newval);
+ return (entry);
}
else
{
VUNSETATTR (var, att_invisible);
- t = make_variable_value (var, value, aflags);
- FREE (value_cell (var));
- var_setvalue (var, t);
+ if (var->assign_func)
+ {
+ /* If we're appending, we need the old value, so use
+ make_variable_value */
+ t = (aflags & ASS_APPEND) ? make_variable_value (var, value, aflags) : value;
+ (*(var->assign_func)) (var, t, -1);
+ if (t != value && t)
+ free (t);
+ }
+ else
+ {
+ t = make_variable_value (var, value, aflags);
+ FREE (value_cell (var));
+ var_setvalue (var, t);
+ }
INVALIDATE_EXPORTSTR (var);
HASH_TABLE (temporary_env). The functions in execute_cmd.c are
responsible for moving the main temporary env to one of the other
temporary environments. The expansion code in subst.c calls this. */
-
- /* XXX - changes needed for `+=' */
int
assign_in_env (word)
WORD_DESC *word;
};
static struct name_and_function special_vars[] = {
+#if defined (READLINE) && defined (PROGRAMMABLE_COMPLETION)
+ { "COMP_WORDBREAKS", sv_comp_wordbreaks },
+#endif
+
{ "GLOBIGNORE", sv_globignore },
#if defined (HISTORY)
}
}
+#if defined (READLINE) && defined (PROGRAMMABLE_COMPLETION)
+void
+sv_comp_wordbreaks (name)
+ char *name;
+{
+ SHELL_VAR *sv;
+
+ sv = find_variable (name);
+ if (sv == 0)
+ rl_completer_word_break_characters = (char *)NULL;
+}
+#endif
+
/* What to do when GLOBIGNORE changes. */
void
sv_globignore (name)
extern void sv_ifs __P((char *));
extern void sv_path __P((char *));
extern void sv_mail __P((char *));
+extern void sv_comp_wordbreaks __P((char *));
extern void sv_globignore __P((char *));
extern void sv_ignoreeof __P((char *));
extern void sv_strict_posix __P((char *));
/* variables.h -- data structures for shell variables. */
-/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
#ifdef USING_BASH_MALLOC
#include <malloc/shmalloc.h>
+extern char *rl_completer_word_break_characters;
PTR_T
sh_xmalloc (bytes, file, line)
size_t bytes;
#endif /* !HAVE_SBRK */
}
+if (temp == rl_completer_word_break_characters)
+ itrace("xmalloc:%s:%d: reallocating rl_completer_word_break_characters");
+
return (temp);
}
--- /dev/null
+/* xmalloc.c -- safe versions of malloc and realloc */
+
+/* Copyright (C) 1991 Free Software Foundation, Inc.
+
+ This file is part of GNU Readline, a library for reading lines
+ of text with interactive input and history editing.
+
+ Readline is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ Readline is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Readline; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#if defined (HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include "bashtypes.h"
+#include <stdio.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include "error.h"
+
+#include "bashintl.h"
+
+#if !defined (PTR_T)
+# if defined (__STDC__)
+# define PTR_T void *
+# else
+# define PTR_T char *
+# endif /* !__STDC__ */
+#endif /* !PTR_T */
+
+#if defined (HAVE_SBRK) && !HAVE_DECL_SBRK
+extern char *sbrk();
+#endif
+
+static PTR_T lbreak;
+static int brkfound;
+static size_t allocated;
+
+/* **************************************************************** */
+/* */
+/* Memory Allocation and Deallocation. */
+/* */
+/* **************************************************************** */
+
+#if defined (HAVE_SBRK)
+static size_t
+findbrk ()
+{
+ if (brkfound == 0)
+ {
+ lbreak = (PTR_T)sbrk (0);
+ brkfound++;
+ }
+ return (char *)sbrk (0) - (char *)lbreak;
+}
+#endif
+
+/* Return a pointer to free()able block of memory large enough
+ to hold BYTES number of bytes. If the memory cannot be allocated,
+ print an error message and abort. */
+PTR_T
+xmalloc (bytes)
+ size_t bytes;
+{
+ PTR_T temp;
+
+ temp = malloc (bytes);
+
+ if (temp == 0)
+ {
+#if defined (HAVE_SBRK)
+ allocated = findbrk ();
+ fatal_error (_("xmalloc: cannot allocate %lu bytes (%lu bytes allocated)"), (unsigned long)bytes, (unsigned long)allocated);
+#else
+ fatal_error (_("xmalloc: cannot allocate %lu bytes"), (unsigned long)bytes);
+#endif /* !HAVE_SBRK */
+ }
+
+ return (temp);
+}
+
+PTR_T
+xrealloc (pointer, bytes)
+ PTR_T pointer;
+ size_t bytes;
+{
+ PTR_T temp;
+
+ temp = pointer ? realloc (pointer, bytes) : malloc (bytes);
+
+ if (temp == 0)
+ {
+#if defined (HAVE_SBRK)
+ allocated = findbrk ();
+ fatal_error (_("xrealloc: cannot reallocate %lu bytes (%lu bytes allocated)"), (unsigned long)bytes, (unsigned long)allocated);
+#else
+ fatal_error (_("xrealloc: cannot allocate %lu bytes"), (unsigned long)bytes);
+#endif /* !HAVE_SBRK */
+ }
+
+ return (temp);
+}
+
+/* Use this as the function to call when adding unwind protects so we
+ don't need to know what free() returns. */
+void
+xfree (string)
+ PTR_T string;
+{
+ if (string)
+ free (string);
+}
+
+#ifdef USING_BASH_MALLOC
+#include <malloc/shmalloc.h>
+
+PTR_T
+sh_xmalloc (bytes, file, line)
+ size_t bytes;
+ char *file;
+ int line;
+{
+ PTR_T temp;
+
+ temp = sh_malloc (bytes, file, line);
+
+ if (temp == 0)
+ {
+#if defined (HAVE_SBRK)
+ allocated = findbrk ();
+ fatal_error (_("xmalloc: %s:%d: cannot allocate %lu bytes (%lu bytes allocated)"), file, line, (unsigned long)bytes, (unsigned long)allocated);
+#else
+ fatal_error (_("xmalloc: %s:%d: cannot allocate %lu bytes"), file, line, (unsigned long)bytes);
+#endif /* !HAVE_SBRK */
+ }
+
+ return (temp);
+}
+
+PTR_T
+sh_xrealloc (pointer, bytes, file, line)
+ PTR_T pointer;
+ size_t bytes;
+ char *file;
+ int line;
+{
+ PTR_T temp;
+
+ temp = pointer ? sh_realloc (pointer, bytes, file, line) : sh_malloc (bytes, file, line);
+
+ if (temp == 0)
+ {
+#if defined (HAVE_SBRK)
+ allocated = findbrk ();
+ fatal_error (_("xrealloc: %s:%d: cannot reallocate %lu bytes (%lu bytes allocated)"), file, line, (unsigned long)bytes, (unsigned long)allocated);
+#else
+ fatal_error (_("xrealloc: %s:%d: cannot allocate %lu bytes"), file, line, (unsigned long)bytes);
+#endif /* !HAVE_SBRK */
+ }
+
+ return (temp);
+}
+
+void
+sh_xfree (string, file, line)
+ PTR_T string;
+ char *file;
+ int line;
+{
+ if (string)
+ sh_free (string, file, line);
+}
+#endif