mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-29 00:19:51 +02:00
commit bash-20111216 snapshot
This commit is contained in:
+120
@@ -12851,3 +12851,123 @@ lib/readline/rlprivate.h
|
||||
lib/readline/doc/rltech.texi
|
||||
- documented new variables: rl_executing_key, rl_executing_keyseq,
|
||||
rl_key_sequence_length
|
||||
|
||||
12/13
|
||||
-----
|
||||
bashline.c
|
||||
- bash_execute_unix_command: replace ad-hoc code that searches
|
||||
cmd_xmap for correct command with call to rl_function_of_keyseq
|
||||
using rl_executing_keyseq; now supports key sequences longer
|
||||
than two characters. Fixes bug reported by Michael Kazior
|
||||
<kazikcz@gmail.com>
|
||||
|
||||
12/15
|
||||
-----
|
||||
make_cmd.c
|
||||
- make_function_def: don't null out source_file before calling
|
||||
make_command so it can be used later on when the function definition
|
||||
is executed
|
||||
|
||||
execute_cmd.c
|
||||
- execute_intern_function: second argument is now FUNCTION_DEF *
|
||||
instead of COMMAND *
|
||||
- execute_command_internal: call execute_intern_function with the
|
||||
new second argument (the entire FUNCTION_DEF instead of just the
|
||||
command member)
|
||||
- execute_intern_function: if DEBUGGER is defined, call
|
||||
bind_function_def before calling bind_function, just like
|
||||
make_function_def does (might be able to take out the call in
|
||||
make_function_def depending on what the debugger does with it).
|
||||
Fixes bug reported by <dethrophes@motd005>
|
||||
|
||||
expr.c
|
||||
- more minor changes to cases of INTMAX_MIN % -1 and INTMAX_MIN / 1;
|
||||
fix typos and logic errors
|
||||
|
||||
12/16
|
||||
-----
|
||||
bashline.c
|
||||
- find_cmd_start: change flags to remove SD_NOSKIPCMD so it skips over
|
||||
command substitutions and doesn't treat them as command separators
|
||||
- attempt_shell_completion: instead of taking first return from
|
||||
find_cmd_name as command name to use for programmable completion,
|
||||
use loop to skip over assignment statements. Fixes problem reported
|
||||
by Raphael Droz <raphael.droz+floss@gmail.com>
|
||||
- attempt_shell_completion: if we don't find a command name but the
|
||||
command line is non-empty, assume the other words are all assignment
|
||||
statements and flag that point is in a command position so we can
|
||||
do command name completion
|
||||
- attempt_shell_completion: if the word being completed is the first
|
||||
word following a series of assignment statements, and the
|
||||
command line is non-empty, flag that point is in a command position
|
||||
so we can do command name completion
|
||||
|
||||
lib/readline/history.c
|
||||
- history_get_time: atol -> strtol
|
||||
|
||||
12/18
|
||||
-----
|
||||
parse.y
|
||||
- parser_in_command_position: external interface to the
|
||||
command_token_position macro for use by other parts of the shell,
|
||||
like the completion mechanism
|
||||
|
||||
externs.h
|
||||
- extern declaration for parser_in_command_position
|
||||
|
||||
12/19
|
||||
-----
|
||||
|
||||
builtins/read.def
|
||||
- read_builtin: make sure all calls to bind_read_variable are passed
|
||||
a non-null string. Fixes bug reported by Dan Douglas
|
||||
<ormaaj@gmail.com>
|
||||
|
||||
bashline.c
|
||||
- attempt_shell_completion: mark that we're in a command position if
|
||||
we're at the start of the line and the parser is ready to accept
|
||||
a reserved word or command name. Feature most recently suggested
|
||||
by Peng Yu <pengyu.ut@gmail.com>
|
||||
|
||||
12/21
|
||||
-----
|
||||
lib/readline/bind.c
|
||||
- _rl_escchar: return the character that would be backslash-escaped
|
||||
to denote the control character passed as an argument ('\n' -> 'n')
|
||||
- _rl_isescape: return 1 if character passed is one that has a
|
||||
backslash escape
|
||||
- _rl_untranslate_macro_value: new second argument: use_escapes, if
|
||||
non-zero translate to backslash escapes where possible instead of
|
||||
using straight \C-x for control character `x'. Change callers
|
||||
- _rl_untranslate_macro_value: now global
|
||||
|
||||
lib/readline/rlprivate.h
|
||||
- _rl_untranslate_macro_value: extern declaration
|
||||
|
||||
lib/readline/{macro.c,readline.h}
|
||||
- rl_print_last_kbd_macro: new bindable function, inspired by patch
|
||||
from Mitchel Humpherys
|
||||
|
||||
lib/readline/funmap.c
|
||||
- print-last-kbd-macro: new bindable command, bound to
|
||||
rl_print_last_kbd_macro
|
||||
|
||||
lib/readline/doc/{rluser.texi,readline.3},doc/bash.1
|
||||
- print-last-kbd-macro: document.
|
||||
|
||||
lib/readline/text.c
|
||||
- _rl_insert_next: if we're defining a macro, make sure the key gets
|
||||
added to the macro text (should really audit calls to rl_read_key()
|
||||
and make sure the right thing is happening for all of them)
|
||||
|
||||
bashline.[ch]
|
||||
- print_unix_command_map: new function, prints all bound commands in
|
||||
cmd_xmap using rl_macro_dumper in a reusable format
|
||||
|
||||
builtins/bind.def
|
||||
- new -X option: print all keysequences bound to Unix commands using
|
||||
print_unix_command_map. Feature suggested by Dennis Williamson
|
||||
(2/2011)
|
||||
|
||||
doc/{bash.1,bashref.texi}
|
||||
- document new `bind -X' option
|
||||
|
||||
@@ -12847,3 +12847,126 @@ lib/readline/readline.h
|
||||
lib/readline/rlprivate.h
|
||||
- new extern declaration for _rl_executing_keyseq_size, buffer size
|
||||
for rl_executing_keyseq
|
||||
|
||||
lib/readline/doc/rltech.texi
|
||||
- documented new variables: rl_executing_key, rl_executing_keyseq,
|
||||
rl_key_sequence_length
|
||||
|
||||
12/13
|
||||
-----
|
||||
bashline.c
|
||||
- bash_execute_unix_command: replace ad-hoc code that searches
|
||||
cmd_xmap for correct command with call to rl_function_of_keyseq
|
||||
using rl_executing_keyseq; now supports key sequences longer
|
||||
than two characters. Fixes bug reported by Michael Kazior
|
||||
<kazikcz@gmail.com>
|
||||
|
||||
12/15
|
||||
-----
|
||||
make_cmd.c
|
||||
- make_function_def: don't null out source_file before calling
|
||||
make_command so it can be used later on when the function definition
|
||||
is executed
|
||||
|
||||
execute_cmd.c
|
||||
- execute_intern_function: second argument is now FUNCTION_DEF *
|
||||
instead of COMMAND *
|
||||
- execute_command_internal: call execute_intern_function with the
|
||||
new second argument (the entire FUNCTION_DEF instead of just the
|
||||
command member)
|
||||
- execute_intern_function: if DEBUGGER is defined, call
|
||||
bind_function_def before calling bind_function, just like
|
||||
make_function_def does (might be able to take out the call in
|
||||
make_function_def depending on what the debugger does with it).
|
||||
Fixes bug reported by <dethrophes@motd005>
|
||||
|
||||
expr.c
|
||||
- more minor changes to cases of INTMAX_MIN % -1 and INTMAX_MIN / 1;
|
||||
fix typos and logic errors
|
||||
|
||||
12/16
|
||||
-----
|
||||
bashline.c
|
||||
- find_cmd_start: change flags to remove SD_NOSKIPCMD so it skips over
|
||||
command substitutions and doesn't treat them as command separators
|
||||
- attempt_shell_completion: instead of taking first return from
|
||||
find_cmd_name as command name to use for programmable completion,
|
||||
use loop to skip over assignment statements. Fixes problem reported
|
||||
by Raphael Droz <raphael.droz+floss@gmail.com>
|
||||
- attempt_shell_completion: if we don't find a command name but the
|
||||
command line is non-empty, assume the other words are all assignment
|
||||
statements and flag that point is in a command position so we can
|
||||
do command name completion
|
||||
- attempt_shell_completion: if the word being completed is the first
|
||||
word following a series of assignment statements, and the
|
||||
command line is non-empty, flag that point is in a command position
|
||||
so we can do command name completion
|
||||
|
||||
lib/readline/history.c
|
||||
- history_get_time: atol -> strtol
|
||||
|
||||
12/18
|
||||
-----
|
||||
parse.y
|
||||
- parser_in_command_position: external interface to the
|
||||
command_token_position macro for use by other parts of the shell,
|
||||
like the completion mechanism
|
||||
|
||||
externs.h
|
||||
- extern declaration for parser_in_command_position
|
||||
|
||||
12/19
|
||||
-----
|
||||
builtins/read.def
|
||||
- read_builtin: make sure all calls to bind_read_variable are passed
|
||||
a non-null string. Fixes bug reported by Dan Douglas
|
||||
<ormaaj@gmail.com>
|
||||
|
||||
bashline.c
|
||||
- attempt_shell_completion: mark that we're in a command position if
|
||||
we're at the start of the line and the parser is ready to accept
|
||||
a reserved word or command name. Feature most recently suggested
|
||||
by Peng Yu <pengyu.ut@gmail.com>
|
||||
|
||||
12/21
|
||||
-----
|
||||
lib/readline/bind.c
|
||||
- _rl_escchar: return the character that would be backslash-escaped
|
||||
to denote the control character passed as an argument ('\n' -> 'n')
|
||||
- _rl_isescape: return 1 if character passed is one that has a
|
||||
backslash escape
|
||||
- _rl_untranslate_macro_value: new second argument: use_escapes, if
|
||||
non-zero translate to backslash escapes where possible instead of
|
||||
using straight \C-x for control character `x'. Change callers
|
||||
- _rl_untranslate_macro_value: now global
|
||||
|
||||
lib/readline/rlprivate.h
|
||||
- _rl_untranslate_macro_value: extern declaration
|
||||
|
||||
lib/readline/{macro.c,readline.h}
|
||||
- rl_print_last_kbd_macro: new bindable function, inspired by patch
|
||||
from Mitchel Humpherys
|
||||
|
||||
lib/readline/funmap.c
|
||||
- print-last-kbd-macro: new bindable command, bound to
|
||||
rl_print_last_kbd_macro
|
||||
|
||||
lib/readline/doc/{rluser.texi,readline.3},doc/bash.1
|
||||
- print-last-kbd-macro: document.
|
||||
|
||||
lib/readline/text.c
|
||||
- _rl_insert_next: if we're defining a macro, make sure the key gets
|
||||
added to the macro text (should really audit calls to rl_read_key()
|
||||
and make sure the right thing is happening for all of them)
|
||||
|
||||
bashline.[ch]
|
||||
- print_unix_command_map: new function, prints all bound commands in
|
||||
cmd_xmap using rl_macro_dumper in a reusable format
|
||||
|
||||
builtins/bind.def
|
||||
- new -X option: print all keysequences bound to Unix commands using
|
||||
print_unix_command_map. Feature suggested by Dennis Williamson
|
||||
(2/2011)
|
||||
|
||||
doc/{bash.1,bashref.texi}
|
||||
- document new `bind -X' option
|
||||
|
||||
+72
-33
@@ -1232,7 +1232,11 @@ bash_backward_kill_shellword (count, key)
|
||||
|
||||
#define COMMAND_SEPARATORS ";|&{(`"
|
||||
/* )} */
|
||||
#define COMMAND_SEPARATORS_PLUS_WS ";|&{(` \t"
|
||||
/* )} */
|
||||
|
||||
/* check for redirections and other character combinations that are not
|
||||
command separators */
|
||||
static int
|
||||
check_redir (ti)
|
||||
int ti;
|
||||
@@ -1247,8 +1251,19 @@ check_redir (ti)
|
||||
if ((this_char == '&' && (prev_char == '<' || prev_char == '>')) ||
|
||||
(this_char == '|' && prev_char == '>'))
|
||||
return (1);
|
||||
else if ((this_char == '{' && prev_char == '$') || /* } */
|
||||
(char_is_quoted (rl_line_buffer, ti)))
|
||||
else if (this_char == '{' && prev_char == '$') /*}*/
|
||||
return (1);
|
||||
#if 0 /* Not yet */
|
||||
else if (this_char == '(' && prev_char == '$') /*)*/
|
||||
return (1);
|
||||
else if (this_char == '(' && prev_char == '<') /*)*/
|
||||
return (1);
|
||||
#if defined (EXTENDED_GLOB)
|
||||
else if (extended_glob && this_char == '(' && prev_char == '!') /*)*/
|
||||
return (1);
|
||||
#endif
|
||||
#endif
|
||||
else if (char_is_quoted (rl_line_buffer, ti))
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
@@ -1266,7 +1281,10 @@ find_cmd_start (start)
|
||||
register int s, os;
|
||||
|
||||
os = 0;
|
||||
while (((s = skip_to_delim (rl_line_buffer, os, COMMAND_SEPARATORS, SD_NOJMP|SD_NOSKIPCMD)) <= start) &&
|
||||
/* Flags == SD_NOJMP only because we want to skip over command substitutions
|
||||
in assignment statements. Have to test whether this affects `standalone'
|
||||
command substitutions as individual words. */
|
||||
while (((s = skip_to_delim (rl_line_buffer, os, COMMAND_SEPARATORS, SD_NOJMP/*|SD_NOSKIPCMD*/)) <= start) &&
|
||||
rl_line_buffer[s])
|
||||
os = s+1;
|
||||
return os;
|
||||
@@ -1370,6 +1388,8 @@ attempt_shell_completion (text, start, end)
|
||||
are prompting at the top level. */
|
||||
if (current_prompt_string == ps1_prompt)
|
||||
in_command_position++;
|
||||
else if (parser_in_command_position ())
|
||||
in_command_position++;
|
||||
}
|
||||
else if (member (rl_line_buffer[ti], command_separator_chars))
|
||||
{
|
||||
@@ -1407,7 +1427,7 @@ attempt_shell_completion (text, start, end)
|
||||
prog_completion_enabled && (progcomp_size () > 0) &&
|
||||
current_prompt_string == ps1_prompt)
|
||||
{
|
||||
int s, e, s1, e1, foundcs;
|
||||
int s, e, s1, e1, os, foundcs;
|
||||
char *n;
|
||||
|
||||
/* XXX - don't free the members */
|
||||
@@ -1415,9 +1435,23 @@ attempt_shell_completion (text, start, end)
|
||||
free (prog_complete_matches);
|
||||
prog_complete_matches = (char **)NULL;
|
||||
|
||||
s = find_cmd_start (start);
|
||||
os = start;
|
||||
n = 0;
|
||||
s = find_cmd_start (os);
|
||||
e = find_cmd_end (end);
|
||||
n = find_cmd_name (s, &s1, &e1);
|
||||
do
|
||||
{
|
||||
/* Skip over assignment statements preceding a command name. If we
|
||||
don't find a command name at all, we can perform command name
|
||||
completion. If we find a partial command name, we should perform
|
||||
command name completion on it. */
|
||||
FREE (n);
|
||||
n = find_cmd_name (s, &s1, &e1);
|
||||
s = e1 + 1;
|
||||
}
|
||||
while (assignment (n, 0));
|
||||
s = s1; /* reset to index where name begins */
|
||||
|
||||
if (start == 0 && end == 0 && e != 0 && text[0] == '\0') /* beginning of non-empty line */
|
||||
foundcs = 0;
|
||||
else if (start == end && start == s1 && e != 0 && e1 > end) /* beginning of command name, leading whitespace */
|
||||
@@ -1428,6 +1462,16 @@ attempt_shell_completion (text, start, end)
|
||||
foundcs = 0; /* whitespace before command name */
|
||||
else if (e > s && assignment (n, 0) == 0)
|
||||
prog_complete_matches = programmable_completions (n, text, s, e, &foundcs);
|
||||
else if (s >= e && n[0] == '\0' && text[0] == '\0' && start > 0)
|
||||
{
|
||||
foundcs = 0; /* empty command name following assignments */
|
||||
in_command_position = 1;
|
||||
}
|
||||
else if (s == start && e == end && STREQ (n, text) && start > 0)
|
||||
{
|
||||
foundcs = 0; /* partial command name following assignments */
|
||||
in_command_position = 1;
|
||||
}
|
||||
else
|
||||
foundcs = 0;
|
||||
FREE (n);
|
||||
@@ -3734,6 +3778,8 @@ bash_execute_unix_command (count, key)
|
||||
{
|
||||
Keymap ckmap; /* current keymap */
|
||||
Keymap xkmap; /* unix command executing keymap */
|
||||
rl_command_func_t *func;
|
||||
int type;
|
||||
register int i, r;
|
||||
intmax_t mi;
|
||||
sh_parser_state_t ps;
|
||||
@@ -3742,34 +3788,15 @@ bash_execute_unix_command (count, key)
|
||||
char ibuf[INT_STRLEN_BOUND(int) + 1];
|
||||
|
||||
/* First, we need to find the right command to execute. This is tricky,
|
||||
because we might have already indirected into another keymap. */
|
||||
ckmap = rl_get_keymap ();
|
||||
if (ckmap != rl_executing_keymap)
|
||||
because we might have already indirected into another keymap, so we
|
||||
have to walk cmd_xmap using the entire key sequence. */
|
||||
cmd = (char *)rl_function_of_keyseq (rl_executing_keyseq, cmd_xmap, &type);
|
||||
|
||||
if (cmd == 0 || type != ISMACR)
|
||||
{
|
||||
/* bogus. we have to search. only handle one level of indirection. */
|
||||
for (i = 0; i < KEYMAP_SIZE; i++)
|
||||
{
|
||||
if (ckmap[i].type == ISKMAP && (Keymap)ckmap[i].function == rl_executing_keymap)
|
||||
break;
|
||||
}
|
||||
if (i < KEYMAP_SIZE)
|
||||
xkmap = (Keymap)cmd_xmap[i].function;
|
||||
else
|
||||
{
|
||||
rl_crlf ();
|
||||
internal_error (_("bash_execute_unix_command: cannot find keymap for command"));
|
||||
rl_forced_update_display ();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
xkmap = cmd_xmap;
|
||||
|
||||
cmd = (char *)xkmap[key].function;
|
||||
|
||||
if (cmd == 0)
|
||||
{
|
||||
rl_ding ();
|
||||
rl_crlf ();
|
||||
internal_error (_("bash_execute_unix_command: cannot find keymap for command"));
|
||||
rl_forced_update_display ();
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -3824,6 +3851,18 @@ bash_execute_unix_command (count, key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
print_unix_command_map ()
|
||||
{
|
||||
Keymap save;
|
||||
|
||||
save = rl_get_keymap ();
|
||||
rl_set_keymap (cmd_xmap);
|
||||
rl_macro_dumper (1);
|
||||
rl_set_keymap (save);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
init_unix_command_map ()
|
||||
{
|
||||
|
||||
+84
-37
@@ -1232,7 +1232,11 @@ bash_backward_kill_shellword (count, key)
|
||||
|
||||
#define COMMAND_SEPARATORS ";|&{(`"
|
||||
/* )} */
|
||||
#define COMMAND_SEPARATORS_PLUS_WS ";|&{(` \t"
|
||||
/* )} */
|
||||
|
||||
/* check for redirections and other character combinations that are not
|
||||
command separators */
|
||||
static int
|
||||
check_redir (ti)
|
||||
int ti;
|
||||
@@ -1247,8 +1251,19 @@ check_redir (ti)
|
||||
if ((this_char == '&' && (prev_char == '<' || prev_char == '>')) ||
|
||||
(this_char == '|' && prev_char == '>'))
|
||||
return (1);
|
||||
else if ((this_char == '{' && prev_char == '$') || /* } */
|
||||
(char_is_quoted (rl_line_buffer, ti)))
|
||||
else if (this_char == '{' && prev_char == '$') /*}*/
|
||||
return (1);
|
||||
#if 0 /* Not yet */
|
||||
else if (this_char == '(' && prev_char == '$') /*)*/
|
||||
return (1);
|
||||
else if (this_char == '(' && prev_char == '<') /*)*/
|
||||
return (1);
|
||||
#if defined (EXTENDED_GLOB)
|
||||
else if (extended_glob && this_char == '(' && prev_char == '!') /*)*/
|
||||
return (1);
|
||||
#endif
|
||||
#endif
|
||||
else if (char_is_quoted (rl_line_buffer, ti))
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
@@ -1266,7 +1281,10 @@ find_cmd_start (start)
|
||||
register int s, os;
|
||||
|
||||
os = 0;
|
||||
while (((s = skip_to_delim (rl_line_buffer, os, COMMAND_SEPARATORS, SD_NOJMP|SD_NOSKIPCMD)) <= start) &&
|
||||
/* Flags == SD_NOJMP only because we want to skip over command substitutions
|
||||
in assignment statements. Have to test whether this affects `standalone'
|
||||
command substitutions as individual words. */
|
||||
while (((s = skip_to_delim (rl_line_buffer, os, COMMAND_SEPARATORS, SD_NOJMP/*|SD_NOSKIPCMD*/)) <= start) &&
|
||||
rl_line_buffer[s])
|
||||
os = s+1;
|
||||
return os;
|
||||
@@ -1370,6 +1388,8 @@ attempt_shell_completion (text, start, end)
|
||||
are prompting at the top level. */
|
||||
if (current_prompt_string == ps1_prompt)
|
||||
in_command_position++;
|
||||
else if (parser_in_command_position ())
|
||||
in_command_position++;
|
||||
}
|
||||
else if (member (rl_line_buffer[ti], command_separator_chars))
|
||||
{
|
||||
@@ -1407,7 +1427,7 @@ attempt_shell_completion (text, start, end)
|
||||
prog_completion_enabled && (progcomp_size () > 0) &&
|
||||
current_prompt_string == ps1_prompt)
|
||||
{
|
||||
int s, e, s1, e1, foundcs;
|
||||
int s, e, s1, e1, os, foundcs;
|
||||
char *n;
|
||||
|
||||
/* XXX - don't free the members */
|
||||
@@ -1415,9 +1435,23 @@ attempt_shell_completion (text, start, end)
|
||||
free (prog_complete_matches);
|
||||
prog_complete_matches = (char **)NULL;
|
||||
|
||||
s = find_cmd_start (start);
|
||||
os = start;
|
||||
n = 0;
|
||||
s = find_cmd_start (os);
|
||||
e = find_cmd_end (end);
|
||||
n = find_cmd_name (s, &s1, &e1);
|
||||
do
|
||||
{
|
||||
/* Skip over assignment statements preceding a command name. If we
|
||||
don't find a command name at all, we can perform command name
|
||||
completion. If we find a partial command name, we should perform
|
||||
command name completion on it. */
|
||||
FREE (n);
|
||||
n = find_cmd_name (s, &s1, &e1);
|
||||
s = e1 + 1;
|
||||
}
|
||||
while (assignment (n, 0));
|
||||
s = s1; /* reset to index where name begins */
|
||||
|
||||
if (start == 0 && end == 0 && e != 0 && text[0] == '\0') /* beginning of non-empty line */
|
||||
foundcs = 0;
|
||||
else if (start == end && start == s1 && e != 0 && e1 > end) /* beginning of command name, leading whitespace */
|
||||
@@ -1428,6 +1462,16 @@ attempt_shell_completion (text, start, end)
|
||||
foundcs = 0; /* whitespace before command name */
|
||||
else if (e > s && assignment (n, 0) == 0)
|
||||
prog_complete_matches = programmable_completions (n, text, s, e, &foundcs);
|
||||
else if (s >= e && n[0] == '\0' && text[0] == '\0' && start > 0)
|
||||
{
|
||||
foundcs = 0; /* empty command name following assignments */
|
||||
in_command_position = 1;
|
||||
}
|
||||
else if (s == start && e == end && STREQ (n, text) && start > 0)
|
||||
{
|
||||
foundcs = 0; /* partial command name following assignments */
|
||||
in_command_position = 1;
|
||||
}
|
||||
else
|
||||
foundcs = 0;
|
||||
FREE (n);
|
||||
@@ -2773,8 +2817,11 @@ bash_directory_expansion (dirname)
|
||||
|
||||
d = savestring (*dirname);
|
||||
|
||||
if (rl_directory_rewrite_hook)
|
||||
(*rl_directory_rewrite_hook) (&d);
|
||||
if ((rl_directory_rewrite_hook) && (*rl_directory_rewrite_hook) (&d))
|
||||
{
|
||||
free (*dirname);
|
||||
*dirname = d;
|
||||
}
|
||||
else if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&d))
|
||||
{
|
||||
free (*dirname);
|
||||
@@ -3731,6 +3778,8 @@ bash_execute_unix_command (count, key)
|
||||
{
|
||||
Keymap ckmap; /* current keymap */
|
||||
Keymap xkmap; /* unix command executing keymap */
|
||||
rl_command_func_t *func;
|
||||
int type;
|
||||
register int i, r;
|
||||
intmax_t mi;
|
||||
sh_parser_state_t ps;
|
||||
@@ -3739,34 +3788,15 @@ bash_execute_unix_command (count, key)
|
||||
char ibuf[INT_STRLEN_BOUND(int) + 1];
|
||||
|
||||
/* First, we need to find the right command to execute. This is tricky,
|
||||
because we might have already indirected into another keymap. */
|
||||
ckmap = rl_get_keymap ();
|
||||
if (ckmap != rl_executing_keymap)
|
||||
because we might have already indirected into another keymap, so we
|
||||
have to walk cmd_xmap using the entire key sequence. */
|
||||
cmd = (char *)rl_function_of_keyseq (rl_executing_keyseq, cmd_xmap, &type);
|
||||
|
||||
if (cmd == 0 || type != ISMACR)
|
||||
{
|
||||
/* bogus. we have to search. only handle one level of indirection. */
|
||||
for (i = 0; i < KEYMAP_SIZE; i++)
|
||||
{
|
||||
if (ckmap[i].type == ISKMAP && (Keymap)ckmap[i].function == rl_executing_keymap)
|
||||
break;
|
||||
}
|
||||
if (i < KEYMAP_SIZE)
|
||||
xkmap = (Keymap)cmd_xmap[i].function;
|
||||
else
|
||||
{
|
||||
rl_crlf ();
|
||||
internal_error (_("bash_execute_unix_command: cannot find keymap for command"));
|
||||
rl_forced_update_display ();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
xkmap = cmd_xmap;
|
||||
|
||||
cmd = (char *)xkmap[key].function;
|
||||
|
||||
if (cmd == 0)
|
||||
{
|
||||
rl_ding ();
|
||||
rl_crlf ();
|
||||
internal_error (_("bash_execute_unix_command: cannot find keymap for command"));
|
||||
rl_forced_update_display ();
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -3821,6 +3851,18 @@ bash_execute_unix_command (count, key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
print_unix_command_map ()
|
||||
{
|
||||
Keymap save;
|
||||
|
||||
save = rl_get_keymap ();
|
||||
rl_set_keymap (unix_cmdmap);
|
||||
rl_macro_dumper (1);
|
||||
rl_set_keymap (save);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
init_unix_command_map ()
|
||||
{
|
||||
@@ -3904,12 +3946,16 @@ bind_keyseq_to_unix_command (line)
|
||||
if (line[i] != ':')
|
||||
{
|
||||
builtin_error (_("%s: missing colon separator"), line);
|
||||
FREE (kseq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
i = isolate_sequence (line, i + 1, 0, &kstart);
|
||||
if (i < 0)
|
||||
return -1;
|
||||
{
|
||||
FREE (kseq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create the value string containing the command to execute. */
|
||||
value = substring (line, kstart, i);
|
||||
@@ -3920,7 +3966,8 @@ bind_keyseq_to_unix_command (line)
|
||||
/* and bind the key sequence in the current keymap to a function that
|
||||
understands how to execute from CMD_XMAP */
|
||||
rl_bind_keyseq_in_map (kseq, bash_execute_unix_command, kmap);
|
||||
|
||||
|
||||
free (kseq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ extern void bashline_set_event_hook __P((void));
|
||||
extern void bashline_reset_event_hook __P((void));
|
||||
|
||||
extern int bind_keyseq_to_unix_command __P((char *));
|
||||
extern int print_unix_command_map __P((void));
|
||||
|
||||
extern char **bash_default_completion __P((const char *, int, int, int, int));
|
||||
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/* bashline.h -- interface to the bash readline functions in bashline.c. */
|
||||
|
||||
/* Copyright (C) 1993-2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash 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 Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (_BASHLINE_H_)
|
||||
#define _BASHLINE_H_
|
||||
|
||||
#include "stdc.h"
|
||||
|
||||
extern int bash_readline_initialized;
|
||||
|
||||
extern void posix_readline_initialize __P((int));
|
||||
extern void reset_completer_word_break_chars __P((void));
|
||||
extern int enable_hostname_completion __P((int));
|
||||
extern void initialize_readline __P((void));
|
||||
extern void bashline_reset __P((void));
|
||||
extern void bashline_reinitialize __P((void));
|
||||
extern int bash_re_edit __P((char *));
|
||||
|
||||
extern void bashline_set_event_hook __P((void));
|
||||
extern void bashline_reset_event_hook __P((void));
|
||||
|
||||
extern int bind_keyseq_to_unix_command __P((char *));
|
||||
|
||||
extern char **bash_default_completion __P((const char *, int, int, int, int));
|
||||
|
||||
void set_directory_hook __P((void));
|
||||
|
||||
/* Used by programmable completion code. */
|
||||
extern char *command_word_completion_function __P((const char *, int));
|
||||
extern char *bash_groupname_completion_function __P((const char *, int));
|
||||
extern char *bash_servicename_completion_function __P((const char *, int));
|
||||
|
||||
extern char **get_hostname_list __P((void));
|
||||
extern void clear_hostname_list __P((void));
|
||||
|
||||
extern char **bash_directory_completion_matches __P((const char *));
|
||||
extern char *bash_dequote_text __P((const char *));
|
||||
|
||||
#endif /* _BASHLINE_H_ */
|
||||
+12
-3
@@ -25,7 +25,7 @@ $PRODUCES bind.c
|
||||
$BUILTIN bind
|
||||
$DEPENDS_ON READLINE
|
||||
$FUNCTION bind_builtin
|
||||
$SHORT_DOC bind [-lpvsPVS] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-x keyseq:shell-command] [keyseq:readline-function or readline-command]
|
||||
$SHORT_DOC bind [-lpsvPSVX] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-x keyseq:shell-command] [keyseq:readline-function or readline-command]
|
||||
Set Readline key bindings and variables.
|
||||
|
||||
Bind a key sequence to a Readline function or a macro, or set a
|
||||
@@ -54,6 +54,8 @@ Options:
|
||||
-f filename Read key bindings from FILENAME.
|
||||
-x keyseq:shell-command Cause SHELL-COMMAND to be executed when
|
||||
KEYSEQ is entered.
|
||||
-X List key sequences bound with -x and associated commands
|
||||
in a form that can be reused as input.
|
||||
|
||||
Exit Status:
|
||||
bind returns 0 unless an unrecognized option is given or an error occurs.
|
||||
@@ -104,6 +106,7 @@ extern int no_line_editing;
|
||||
#define SSFLAG 0x0400
|
||||
#define UFLAG 0x0800
|
||||
#define XFLAG 0x1000
|
||||
#define XXFLAG 0x2000
|
||||
|
||||
int
|
||||
bind_builtin (list)
|
||||
@@ -138,7 +141,7 @@ bind_builtin (list)
|
||||
rl_outstream = stdout;
|
||||
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, "lvpVPsSf:q:u:m:r:x:")) != EOF)
|
||||
while ((opt = internal_getopt (list, "lvpVPsSXf:q:u:m:r:x:")) != EOF)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
@@ -187,6 +190,9 @@ bind_builtin (list)
|
||||
flags |= XFLAG;
|
||||
cmd_seq = list_optarg;
|
||||
break;
|
||||
case 'X':
|
||||
flags |= XXFLAG;
|
||||
break;
|
||||
default:
|
||||
builtin_usage ();
|
||||
BIND_RETURN (EX_USAGE);
|
||||
@@ -201,7 +207,7 @@ bind_builtin (list)
|
||||
if ((flags & MFLAG) && map_name)
|
||||
{
|
||||
kmap = rl_get_keymap_by_name (map_name);
|
||||
if (!kmap)
|
||||
if (kmap == 0)
|
||||
{
|
||||
builtin_error (_("`%s': invalid keymap name"), map_name);
|
||||
BIND_RETURN (EXECUTION_FAILURE);
|
||||
@@ -265,6 +271,9 @@ bind_builtin (list)
|
||||
if (flags & XFLAG)
|
||||
return_code = bind_keyseq_to_unix_command (cmd_seq);
|
||||
|
||||
if (flags & XXFLAG)
|
||||
return_code = print_unix_command_map ();
|
||||
|
||||
/* Process the rest of the arguments as binding specifications. */
|
||||
while (list)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,341 @@
|
||||
This file is bind.def, from which is created bind.c.
|
||||
It implements the builtin "bind" in Bash.
|
||||
|
||||
Copyright (C) 1987-2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash 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 Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$PRODUCES bind.c
|
||||
|
||||
#include <config.h>
|
||||
|
||||
$BUILTIN bind
|
||||
$DEPENDS_ON READLINE
|
||||
$FUNCTION bind_builtin
|
||||
$SHORT_DOC bind [-lpsvPSVX] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-x keyseq:shell-command] [keyseq:readline-function or readline-command]
|
||||
Set Readline key bindings and variables.
|
||||
|
||||
Bind a key sequence to a Readline function or a macro, or set a
|
||||
Readline variable. The non-option argument syntax is equivalent to
|
||||
that found in ~/.inputrc, but must be passed as a single argument:
|
||||
e.g., bind '"\C-x\C-r": re-read-init-file'.
|
||||
|
||||
Options:
|
||||
-m keymap Use KEYMAP as the keymap for the duration of this
|
||||
command. Acceptable keymap names are emacs,
|
||||
emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move,
|
||||
vi-command, and vi-insert.
|
||||
-l List names of functions.
|
||||
-P List function names and bindings.
|
||||
-p List functions and bindings in a form that can be
|
||||
reused as input.
|
||||
-S List key sequences that invoke macros and their values
|
||||
-s List key sequences that invoke macros and their values
|
||||
in a form that can be reused as input.
|
||||
-V List variable names and values
|
||||
-v List variable names and values in a form that can
|
||||
be reused as input.
|
||||
-q function-name Query about which keys invoke the named function.
|
||||
-u function-name Unbind all keys which are bound to the named function.
|
||||
-r keyseq Remove the binding for KEYSEQ.
|
||||
-f filename Read key bindings from FILENAME.
|
||||
-x keyseq:shell-command Cause SHELL-COMMAND to be executed when
|
||||
KEYSEQ is entered.
|
||||
-X List key sequences bound with -x and associated commands
|
||||
in a form that can be reused as input.
|
||||
|
||||
Exit Status:
|
||||
bind returns 0 unless an unrecognized option is given or an error occurs.
|
||||
$END
|
||||
|
||||
#if defined (READLINE)
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# ifdef _MINIX
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "../bashline.h"
|
||||
#include "bashgetopt.h"
|
||||
#include "common.h"
|
||||
|
||||
static int query_bindings __P((char *));
|
||||
static int unbind_command __P((char *));
|
||||
|
||||
extern int no_line_editing;
|
||||
|
||||
#define BIND_RETURN(x) do { return_code = x; goto bind_exit; } while (0)
|
||||
|
||||
#define LFLAG 0x0001
|
||||
#define PFLAG 0x0002
|
||||
#define FFLAG 0x0004
|
||||
#define VFLAG 0x0008
|
||||
#define QFLAG 0x0010
|
||||
#define MFLAG 0x0020
|
||||
#define RFLAG 0x0040
|
||||
#define PPFLAG 0x0080
|
||||
#define VVFLAG 0x0100
|
||||
#define SFLAG 0x0200
|
||||
#define SSFLAG 0x0400
|
||||
#define UFLAG 0x0800
|
||||
#define XFLAG 0x1000
|
||||
#define XXFLAG 0x2000
|
||||
|
||||
int
|
||||
bind_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int return_code;
|
||||
Keymap kmap, saved_keymap;
|
||||
int flags, opt;
|
||||
char *initfile, *map_name, *fun_name, *unbind_name, *remove_seq, *cmd_seq;
|
||||
|
||||
if (no_line_editing)
|
||||
{
|
||||
#if 0
|
||||
builtin_error (_("line editing not enabled"));
|
||||
return (EXECUTION_FAILURE);
|
||||
#else
|
||||
builtin_warning (_("line editing not enabled"));
|
||||
#endif
|
||||
}
|
||||
|
||||
kmap = saved_keymap = (Keymap) NULL;
|
||||
flags = 0;
|
||||
initfile = map_name = fun_name = unbind_name = remove_seq = (char *)NULL;
|
||||
return_code = EXECUTION_SUCCESS;
|
||||
|
||||
if (bash_readline_initialized == 0)
|
||||
initialize_readline ();
|
||||
|
||||
begin_unwind_frame ("bind_builtin");
|
||||
unwind_protect_var (rl_outstream);
|
||||
|
||||
rl_outstream = stdout;
|
||||
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, "lvpVPsSXf:q:u:m:r:x:")) != EOF)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'l':
|
||||
flags |= LFLAG;
|
||||
break;
|
||||
case 'v':
|
||||
flags |= VFLAG;
|
||||
break;
|
||||
case 'p':
|
||||
flags |= PFLAG;
|
||||
break;
|
||||
case 'f':
|
||||
flags |= FFLAG;
|
||||
initfile = list_optarg;
|
||||
break;
|
||||
case 'm':
|
||||
flags |= MFLAG;
|
||||
map_name = list_optarg;
|
||||
break;
|
||||
case 'q':
|
||||
flags |= QFLAG;
|
||||
fun_name = list_optarg;
|
||||
break;
|
||||
case 'u':
|
||||
flags |= UFLAG;
|
||||
unbind_name = list_optarg;
|
||||
break;
|
||||
case 'r':
|
||||
flags |= RFLAG;
|
||||
remove_seq = list_optarg;
|
||||
break;
|
||||
case 'V':
|
||||
flags |= VVFLAG;
|
||||
break;
|
||||
case 'P':
|
||||
flags |= PPFLAG;
|
||||
break;
|
||||
case 's':
|
||||
flags |= SFLAG;
|
||||
break;
|
||||
case 'S':
|
||||
flags |= SSFLAG;
|
||||
break;
|
||||
case 'x':
|
||||
flags |= XFLAG;
|
||||
cmd_seq = list_optarg;
|
||||
break;
|
||||
case 'X':
|
||||
flags |= XXFLAG;
|
||||
break;
|
||||
default:
|
||||
builtin_usage ();
|
||||
BIND_RETURN (EX_USAGE);
|
||||
}
|
||||
}
|
||||
|
||||
list = loptend;
|
||||
|
||||
/* First, see if we need to install a special keymap for this
|
||||
command. Then start on the arguments. */
|
||||
|
||||
if ((flags & MFLAG) && map_name)
|
||||
{
|
||||
kmap = rl_get_keymap_by_name (map_name);
|
||||
if (kmap == 0)
|
||||
{
|
||||
builtin_error (_("`%s': invalid keymap name"), map_name);
|
||||
BIND_RETURN (EXECUTION_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (kmap)
|
||||
{
|
||||
saved_keymap = rl_get_keymap ();
|
||||
rl_set_keymap (kmap);
|
||||
}
|
||||
|
||||
/* XXX - we need to add exclusive use tests here. It doesn't make sense
|
||||
to use some of these options together. */
|
||||
/* Now hack the option arguments */
|
||||
if (flags & LFLAG)
|
||||
rl_list_funmap_names ();
|
||||
|
||||
if (flags & PFLAG)
|
||||
rl_function_dumper (1);
|
||||
|
||||
if (flags & PPFLAG)
|
||||
rl_function_dumper (0);
|
||||
|
||||
if (flags & SFLAG)
|
||||
rl_macro_dumper (1);
|
||||
|
||||
if (flags & SSFLAG)
|
||||
rl_macro_dumper (0);
|
||||
|
||||
if (flags & VFLAG)
|
||||
rl_variable_dumper (1);
|
||||
|
||||
if (flags & VVFLAG)
|
||||
rl_variable_dumper (0);
|
||||
|
||||
if ((flags & FFLAG) && initfile)
|
||||
{
|
||||
if (rl_read_init_file (initfile) != 0)
|
||||
{
|
||||
builtin_error (_("%s: cannot read: %s"), initfile, strerror (errno));
|
||||
BIND_RETURN (EXECUTION_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & QFLAG) && fun_name)
|
||||
return_code = query_bindings (fun_name);
|
||||
|
||||
if ((flags & UFLAG) && unbind_name)
|
||||
return_code = unbind_command (unbind_name);
|
||||
|
||||
if ((flags & RFLAG) && remove_seq)
|
||||
{
|
||||
if (rl_bind_keyseq (remove_seq, (rl_command_func_t *)NULL) != 0)
|
||||
{
|
||||
builtin_error (_("`%s': cannot unbind"), remove_seq);
|
||||
BIND_RETURN (EXECUTION_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & XFLAG)
|
||||
return_code = bind_keyseq_to_unix_command (cmd_seq);
|
||||
|
||||
if (flags & XXFLAG)
|
||||
return_code = print_unix_command_map ();
|
||||
|
||||
/* Process the rest of the arguments as binding specifications. */
|
||||
while (list)
|
||||
{
|
||||
rl_parse_and_bind (list->word->word);
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
bind_exit:
|
||||
if (saved_keymap)
|
||||
rl_set_keymap (saved_keymap);
|
||||
|
||||
run_unwind_frame ("bind_builtin");
|
||||
|
||||
return (sh_chkwrite (return_code));
|
||||
}
|
||||
|
||||
static int
|
||||
query_bindings (name)
|
||||
char *name;
|
||||
{
|
||||
rl_command_func_t *function;
|
||||
char **keyseqs;
|
||||
int j;
|
||||
|
||||
function = rl_named_function (name);
|
||||
if (function == 0)
|
||||
{
|
||||
builtin_error (_("`%s': unknown function name"), name);
|
||||
return EXECUTION_FAILURE;
|
||||
}
|
||||
|
||||
keyseqs = rl_invoking_keyseqs (function);
|
||||
|
||||
if (!keyseqs)
|
||||
{
|
||||
printf (_("%s is not bound to any keys.\n"), name);
|
||||
return EXECUTION_FAILURE;
|
||||
}
|
||||
|
||||
printf (_("%s can be invoked via "), name);
|
||||
for (j = 0; j < 5 && keyseqs[j]; j++)
|
||||
printf ("\"%s\"%s", keyseqs[j], keyseqs[j + 1] ? ", " : ".\n");
|
||||
if (keyseqs[j])
|
||||
printf ("...\n");
|
||||
strvec_dispose (keyseqs);
|
||||
return EXECUTION_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
unbind_command (name)
|
||||
char *name;
|
||||
{
|
||||
rl_command_func_t *function;
|
||||
|
||||
function = rl_named_function (name);
|
||||
if (function == 0)
|
||||
{
|
||||
builtin_error (_("`%s': unknown function name"), name);
|
||||
return EXECUTION_FAILURE;
|
||||
}
|
||||
|
||||
rl_unbind_function_in_map (function, rl_get_keymap ());
|
||||
return EXECUTION_SUCCESS;
|
||||
}
|
||||
#endif /* READLINE */
|
||||
+1
-1
@@ -835,7 +835,7 @@ assign_vars:
|
||||
xfree (t);
|
||||
}
|
||||
else
|
||||
var = bind_read_variable (list->word->word, input_string);
|
||||
var = bind_read_variable (list->word->word, input_string ? input_string : "");
|
||||
|
||||
if (var)
|
||||
{
|
||||
|
||||
+48
-11
@@ -1,7 +1,7 @@
|
||||
This file is read.def, from which is created read.c.
|
||||
It implements the builtin "read" in Bash.
|
||||
|
||||
Copyright (C) 1987-2010 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2011 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -129,14 +129,26 @@ static sighandler sigalrm __P((int));
|
||||
static void reset_alarm __P((void));
|
||||
|
||||
static procenv_t alrmbuf;
|
||||
static int sigalrm_seen, reading;
|
||||
static SigHandler *old_alrm;
|
||||
static unsigned char delim;
|
||||
|
||||
/* In most cases, SIGALRM just sets a flag that we check periodically. This
|
||||
avoids problems with the semi-tricky stuff we do with the xfree of
|
||||
input_string at the top of the unwind-protect list (see below). */
|
||||
#define CHECK_ALRM \
|
||||
do { \
|
||||
if (sigalrm_seen) \
|
||||
longjmp (alrmbuf, 1); \
|
||||
} while (0)
|
||||
|
||||
static sighandler
|
||||
sigalrm (s)
|
||||
int s;
|
||||
{
|
||||
longjmp (alrmbuf, 1);
|
||||
sigalrm_seen = 1;
|
||||
if (reading) /* do the longjmp if we get SIGALRM while in read() */
|
||||
longjmp (alrmbuf, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -201,6 +213,8 @@ read_builtin (list)
|
||||
USE_VAR(list);
|
||||
USE_VAR(ps2);
|
||||
|
||||
sigalrm_seen = reading = 0;
|
||||
|
||||
i = 0; /* Index into the string that we are reading. */
|
||||
raw = edit = 0; /* Not reading raw input by default. */
|
||||
silent = 0;
|
||||
@@ -384,9 +398,12 @@ read_builtin (list)
|
||||
code = setjmp (alrmbuf);
|
||||
if (code)
|
||||
{
|
||||
sigalrm_seen = 0;
|
||||
/* Tricky. The top of the unwind-protect stack is the free of
|
||||
input_string. We want to run all the rest and use input_string,
|
||||
so we have to remove it from the stack. */
|
||||
orig_input_string = 0;
|
||||
|
||||
remove_unwind_protect ();
|
||||
run_unwind_frame ("read_builtin");
|
||||
input_string[i] = '\0'; /* make sure it's terminated */
|
||||
@@ -457,6 +474,7 @@ read_builtin (list)
|
||||
add_unwind_protect (xfree, input_string);
|
||||
interrupt_immediately++;
|
||||
|
||||
CHECK_ALRM;
|
||||
unbuffered_read = (nchars > 0) || (delim != '\n') || input_is_pipe;
|
||||
|
||||
if (prompt && edit == 0)
|
||||
@@ -472,6 +490,8 @@ read_builtin (list)
|
||||
ps2 = 0;
|
||||
for (print_ps2 = eof = retval = 0;;)
|
||||
{
|
||||
CHECK_ALRM;
|
||||
|
||||
#if defined (READLINE)
|
||||
if (edit)
|
||||
{
|
||||
@@ -482,7 +502,9 @@ read_builtin (list)
|
||||
}
|
||||
if (rlbuf == 0)
|
||||
{
|
||||
reading = 1;
|
||||
rlbuf = edit_line (prompt ? prompt : "", itext);
|
||||
reading = 0;
|
||||
rlind = 0;
|
||||
}
|
||||
if (rlbuf == 0)
|
||||
@@ -505,10 +527,12 @@ read_builtin (list)
|
||||
print_ps2 = 0;
|
||||
}
|
||||
|
||||
reading = 1;
|
||||
if (unbuffered_read)
|
||||
retval = zread (fd, &c, 1);
|
||||
else
|
||||
retval = zreadc (fd, &c);
|
||||
reading = 0;
|
||||
|
||||
if (retval <= 0)
|
||||
{
|
||||
@@ -517,15 +541,25 @@ read_builtin (list)
|
||||
break;
|
||||
}
|
||||
|
||||
CHECK_ALRM;
|
||||
|
||||
#if defined (READLINE)
|
||||
}
|
||||
#endif
|
||||
|
||||
CHECK_ALRM;
|
||||
if (i + 4 >= size) /* XXX was i + 2; use i + 4 for multibyte/read_mbchar */
|
||||
{
|
||||
input_string = (char *)xrealloc (input_string, size += 128);
|
||||
remove_unwind_protect ();
|
||||
add_unwind_protect (xfree, input_string);
|
||||
char *t;
|
||||
t = (char *)xrealloc (input_string, size += 128);
|
||||
|
||||
/* Only need to change unwind-protect if input_string changes */
|
||||
if (t != input_string)
|
||||
{
|
||||
input_string = t;
|
||||
remove_unwind_protect ();
|
||||
add_unwind_protect (xfree, input_string);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the next character is to be accepted verbatim, a backslash
|
||||
@@ -559,6 +593,9 @@ read_builtin (list)
|
||||
if ((unsigned char)c == delim)
|
||||
break;
|
||||
|
||||
if (c == '\0' && delim != '\0')
|
||||
continue; /* skip NUL bytes in input */
|
||||
|
||||
if ((skip_ctlesc == 0 && c == CTLESC) || (skip_ctlnul == 0 && c == CTLNUL))
|
||||
{
|
||||
saw_escape++;
|
||||
@@ -567,6 +604,7 @@ read_builtin (list)
|
||||
|
||||
add_char:
|
||||
input_string[i++] = c;
|
||||
CHECK_ALRM;
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (nchars > 0 && MB_CUR_MAX > 1)
|
||||
@@ -582,15 +620,14 @@ add_char:
|
||||
break;
|
||||
}
|
||||
input_string[i] = '\0';
|
||||
CHECK_ALRM;
|
||||
|
||||
#if 1
|
||||
if (retval < 0)
|
||||
{
|
||||
builtin_error (_("read error: %d: %s"), fd, strerror (errno));
|
||||
run_unwind_frame ("read_builtin");
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (tmsec > 0 || tmusec > 0)
|
||||
reset_alarm ();
|
||||
@@ -693,7 +730,7 @@ assign_vars:
|
||||
var = bind_variable ("REPLY", input_string, 0);
|
||||
VUNSETATTR (var, att_invisible);
|
||||
|
||||
free (input_string);
|
||||
xfree (input_string);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
@@ -737,12 +774,12 @@ assign_vars:
|
||||
xfree (t1);
|
||||
}
|
||||
else
|
||||
var = bind_read_variable (varname, t);
|
||||
var = bind_read_variable (varname, t ? t : "");
|
||||
}
|
||||
else
|
||||
{
|
||||
t = (char *)0;
|
||||
var = bind_read_variable (varname, "");
|
||||
var = bind_read_variable< (varname, "");
|
||||
}
|
||||
|
||||
FREE (t);
|
||||
@@ -798,7 +835,7 @@ assign_vars:
|
||||
xfree (t);
|
||||
}
|
||||
else
|
||||
var = bind_read_variable (list->word->word, input_string);
|
||||
var = bind_read_variable (list->word->word, input_string ? input_string : "");
|
||||
|
||||
if (var)
|
||||
{
|
||||
|
||||
+27
-10
@@ -5,12 +5,12 @@
|
||||
.\" Case Western Reserve University
|
||||
.\" chet@po.cwru.edu
|
||||
.\"
|
||||
.\" Last Change: Wed Dec 7 17:34:07 EST 2011
|
||||
.\" Last Change: Wed Dec 21 20:32:29 EST 2011
|
||||
.\"
|
||||
.\" bash_builtins, strip all but Built-Ins section
|
||||
.if \n(zZ=1 .ig zZ
|
||||
.if \n(zY=1 .ig zY
|
||||
.TH BASH 1 "2011 December 7" "GNU Bash 4.2"
|
||||
.TH BASH 1 "2011 December 21" "GNU Bash 4.2"
|
||||
.\"
|
||||
.\" There's some problem with having a `@'
|
||||
.\" in a tagged paragraph with the BSD man macros.
|
||||
@@ -1886,6 +1886,7 @@ upon receipt of a
|
||||
An array variable from which \fBbash\fP reads the possible completions
|
||||
generated by a shell function invoked by the programmable completion
|
||||
facility (see \fBProgrammable Completion\fP below).
|
||||
Each array element contains one possible completion.
|
||||
.TP
|
||||
.B EMACS
|
||||
If \fBbash\fP finds this variable in the environment when the shell starts
|
||||
@@ -5908,6 +5909,9 @@ and store the definition.
|
||||
.B call\-last\-kbd\-macro (C\-x e)
|
||||
Re-execute the last keyboard macro defined, by making the characters
|
||||
in the macro appear as if typed at the keyboard.
|
||||
.B print\-last\-kbd\-macro ()
|
||||
Print the last keyboard macro defined in a format suitable for the
|
||||
\fIinputrc\fP file.
|
||||
.PD
|
||||
.SS Miscellaneous
|
||||
.PP
|
||||
@@ -6117,10 +6121,12 @@ and
|
||||
.SM
|
||||
.B COMP_CWORD
|
||||
variables are also set.
|
||||
When the function or command is invoked, the first argument is the
|
||||
name of the command whose arguments are being completed, the
|
||||
second argument is the word being completed, and the third argument
|
||||
is the word preceding the word being completed on the current command line.
|
||||
When the function or command is invoked,
|
||||
the first argument (\fB$1\fP) is the name of the command whose arguments are
|
||||
being completed,
|
||||
the second argument (\fB$2\fP) is the word being completed,
|
||||
and the third argument (\fB$3\fP) is the word preceding the word being
|
||||
completed on the current command line.
|
||||
No filtering of the generated completions against the word being completed
|
||||
is performed; the function or command has complete freedom in generating
|
||||
the matches.
|
||||
@@ -6131,7 +6137,7 @@ The function may use any of the shell facilities, including the
|
||||
It must put the possible completions in the
|
||||
.SM
|
||||
.B COMPREPLY
|
||||
array variable.
|
||||
array variable, one per array element.
|
||||
.PP
|
||||
Next, any command specified with the \fB\-C\fP option is invoked
|
||||
in an environment equivalent to command substitution.
|
||||
@@ -6703,7 +6709,7 @@ returns 0 unless run when job control is disabled or, when run with
|
||||
job control enabled, any specified \fIjobspec\fP was not found
|
||||
or was started without job control.
|
||||
.TP
|
||||
\fBbind\fP [\fB\-m\fP \fIkeymap\fP] [\fB\-lpsvPSV\fP]
|
||||
\fBbind\fP [\fB\-m\fP \fIkeymap\fP] [\fB\-lpsvPSVX\fP]
|
||||
.PD 0
|
||||
.TP
|
||||
\fBbind\fP [\fB\-m\fP \fIkeymap\fP] [\fB\-q\fP \fIfunction\fP] [\fB\-u\fP \fIfunction\fP] [\fB\-r\fP \fIkeyseq\fP]
|
||||
@@ -6798,6 +6804,10 @@ or
|
||||
.SM
|
||||
.BR READLINE_POINT ,
|
||||
those new values will be reflected in the editing state.
|
||||
.TP
|
||||
.B \-X
|
||||
List all key sequences bound to shell commands and the associated commands
|
||||
in a format that can be reused as input.
|
||||
.PD
|
||||
.PP
|
||||
The return value is 0 unless an unrecognized option is given or an
|
||||
@@ -7124,6 +7134,12 @@ used as the possible completions.
|
||||
\fB\-F\fP \fIfunction\fP
|
||||
The shell function \fIfunction\fP is executed in the current shell
|
||||
environment.
|
||||
When the function is executed,
|
||||
the first argument (\fB$1\fP) is the name of the command whose arguments are
|
||||
being completed,
|
||||
the second argument (\fB$2\fP) is the word being completed,
|
||||
and the third argument (\fB$3\fP) is the word preceding the word being
|
||||
completed on the current command line.
|
||||
When it finishes, the possible completions are retrieved from the value
|
||||
of the
|
||||
.SM
|
||||
@@ -8447,8 +8463,9 @@ are supplied, the line read is assigned to the variable
|
||||
.SM
|
||||
.BR REPLY .
|
||||
The return code is zero, unless end-of-file is encountered, \fBread\fP
|
||||
times out (in which case the return code is greater than 128), or an
|
||||
invalid file descriptor is supplied as the argument to \fB\-u\fP.
|
||||
times out (in which case the return code is greater than 128),
|
||||
a variable assignment error (such as assigning to a readonly variable) occurs,
|
||||
or an invalid file descriptor is supplied as the argument to \fB\-u\fP.
|
||||
.RE
|
||||
.TP
|
||||
\fBreadonly\fP [\fB\-aAf\fP] [\fB\-p\fP] [\fIname\fP[=\fIword\fP] ...]
|
||||
|
||||
+41
-24
@@ -5,12 +5,12 @@
|
||||
.\" Case Western Reserve University
|
||||
.\" chet@po.cwru.edu
|
||||
.\"
|
||||
.\" Last Change: Sat Nov 19 15:15:30 EST 2011
|
||||
.\" Last Change: Wed Dec 21 20:32:29 EST 2011
|
||||
.\"
|
||||
.\" bash_builtins, strip all but Built-Ins section
|
||||
.if \n(zZ=1 .ig zZ
|
||||
.if \n(zY=1 .ig zY
|
||||
.TH BASH 1 "2011 November 19" "GNU Bash 4.2"
|
||||
.TH BASH 1 "2011 December 21" "GNU Bash 4.2"
|
||||
.\"
|
||||
.\" There's some problem with having a `@'
|
||||
.\" in a tagged paragraph with the BSD man macros.
|
||||
@@ -48,7 +48,7 @@ bash \- GNU Bourne-Again SHell
|
||||
.SH SYNOPSIS
|
||||
.B bash
|
||||
[options]
|
||||
[file]
|
||||
[command_string | file]
|
||||
.SH COPYRIGHT
|
||||
.if n Bash is Copyright (C) 1989-2011 by the Free Software Foundation, Inc.
|
||||
.if t Bash is Copyright \(co 1989-2011 by the Free Software Foundation, Inc.
|
||||
@@ -75,13 +75,13 @@ interprets the following options when it is invoked:
|
||||
.PP
|
||||
.PD 0
|
||||
.TP 10
|
||||
.BI \-c "\| string\^"
|
||||
.B \-c
|
||||
If the
|
||||
.B \-c
|
||||
option is present, then commands are read from
|
||||
.IR string .
|
||||
option is present, then commands are read from the first non-option argument
|
||||
.IR command_string .
|
||||
If there are arguments after the
|
||||
.IR string ,
|
||||
.IR command_string ,
|
||||
they are assigned to the positional parameters, starting with
|
||||
.BR $0 .
|
||||
.TP
|
||||
@@ -1981,7 +1981,7 @@ to contain no more than that number of lines by removing the oldest entries.
|
||||
The history file is also truncated to this size after
|
||||
writing it when an interactive shell exits.
|
||||
If the value is 0, the history file is truncated to zero size.
|
||||
Numeric values less than zero are treated as 0.
|
||||
Non-numeric values and numeric values less than zero inhibit truncation.
|
||||
The shell sets the default value to the value of \fBHISTSIZE\fP
|
||||
after reading any startup files.
|
||||
.TP
|
||||
@@ -5908,6 +5908,9 @@ and store the definition.
|
||||
.B call\-last\-kbd\-macro (C\-x e)
|
||||
Re-execute the last keyboard macro defined, by making the characters
|
||||
in the macro appear as if typed at the keyboard.
|
||||
.B print\-last\-kbd\-macro ()
|
||||
Print the last keyboard macro defined in a format suitable for the
|
||||
\fIinputrc\fP file.
|
||||
.PD
|
||||
.SS Miscellaneous
|
||||
.PP
|
||||
@@ -6117,10 +6120,12 @@ and
|
||||
.SM
|
||||
.B COMP_CWORD
|
||||
variables are also set.
|
||||
When the function or command is invoked, the first argument is the
|
||||
name of the command whose arguments are being completed, the
|
||||
second argument is the word being completed, and the third argument
|
||||
is the word preceding the word being completed on the current command line.
|
||||
When the function or command is invoked,
|
||||
the first argument (\fB$1\fP) is the name of the command whose arguments are
|
||||
being completed,
|
||||
the second argument (\fB$2\fP) is the word being completed,
|
||||
and the third argument (\fB$3\fP) is the word preceding the word being
|
||||
completed on the current command line.
|
||||
No filtering of the generated completions against the word being completed
|
||||
is performed; the function or command has complete freedom in generating
|
||||
the matches.
|
||||
@@ -6131,7 +6136,7 @@ The function may use any of the shell facilities, including the
|
||||
It must put the possible completions in the
|
||||
.SM
|
||||
.B COMPREPLY
|
||||
array variable.
|
||||
array variable, one per array element.
|
||||
.PP
|
||||
Next, any command specified with the \fB\-C\fP option is invoked
|
||||
in an environment equivalent to command substitution.
|
||||
@@ -6249,8 +6254,8 @@ is truncated, if necessary, to contain no more than
|
||||
the number of lines specified by the value of
|
||||
.SM
|
||||
.BR HISTFILESIZE .
|
||||
If \fBHISTFILESIZE\fP is unset, or set to a null or non-numeric value,
|
||||
the history file is not truncated.
|
||||
If \fBHISTFILESIZE\fP is unset, or set to null, a non-numeric value,
|
||||
or a numeric value less than zero, the history file is not truncated.
|
||||
When the history file is read,
|
||||
lines beginning with the history comment character followed immediately
|
||||
by a digit are interpreted as timestamps for the preceding history line.
|
||||
@@ -6294,7 +6299,8 @@ to contain no more than
|
||||
lines. If
|
||||
.SM
|
||||
.B HISTFILESIZE
|
||||
is not set, no truncation is performed.
|
||||
is unset, or set to null, a non-numeric value,
|
||||
or a numeric value less than zero, the history file is not truncated.
|
||||
.PP
|
||||
The builtin command
|
||||
.B fc
|
||||
@@ -6457,7 +6463,7 @@ history list starting with
|
||||
.IR string .
|
||||
.TP
|
||||
.B !?\fIstring\fR\fB[?]\fR
|
||||
Refer to the most recent command preceding the current postition in the
|
||||
Refer to the most recent command preceding the current position in the
|
||||
history list containing
|
||||
.IR string .
|
||||
The trailing \fB?\fP may be omitted if
|
||||
@@ -6702,7 +6708,7 @@ returns 0 unless run when job control is disabled or, when run with
|
||||
job control enabled, any specified \fIjobspec\fP was not found
|
||||
or was started without job control.
|
||||
.TP
|
||||
\fBbind\fP [\fB\-m\fP \fIkeymap\fP] [\fB\-lpsvPSV\fP]
|
||||
\fBbind\fP [\fB\-m\fP \fIkeymap\fP] [\fB\-lpsvPSVX\fP]
|
||||
.PD 0
|
||||
.TP
|
||||
\fBbind\fP [\fB\-m\fP \fIkeymap\fP] [\fB\-q\fP \fIfunction\fP] [\fB\-u\fP \fIfunction\fP] [\fB\-r\fP \fIkeyseq\fP]
|
||||
@@ -6797,6 +6803,10 @@ or
|
||||
.SM
|
||||
.BR READLINE_POINT ,
|
||||
those new values will be reflected in the editing state.
|
||||
.TP
|
||||
.B \-X
|
||||
List all key sequences bound to shell commands and the associated commands
|
||||
in a format that can be reused as input.
|
||||
.PD
|
||||
.PP
|
||||
The return value is 0 unless an unrecognized option is given or an
|
||||
@@ -6845,12 +6855,12 @@ call or \fIexpr\fP does not correspond to a valid position in the
|
||||
call stack.
|
||||
.TP
|
||||
\fBcd\fP [\fB\-L\fP|[\fB\-P\fP [\fB\-e\fP]]] [\fIdir\fP]
|
||||
Change the current directory to \fIdir\fP. The variable
|
||||
Change the current directory to \fIdir\fP.
|
||||
if \fIdir\fP is not supplied, the value of the
|
||||
.SM
|
||||
.B HOME
|
||||
is the
|
||||
default
|
||||
.IR dir .
|
||||
shell variable is the default.
|
||||
Any additional arguments following \fIdir\fP are ignored.
|
||||
The variable
|
||||
.SM
|
||||
.B CDPATH
|
||||
@@ -7123,6 +7133,12 @@ used as the possible completions.
|
||||
\fB\-F\fP \fIfunction\fP
|
||||
The shell function \fIfunction\fP is executed in the current shell
|
||||
environment.
|
||||
When the function is executed,
|
||||
the first argument (\fB$1\fP) is the name of the command whose arguments are
|
||||
being completed,
|
||||
the second argument (\fB$2\fP) is the word being completed,
|
||||
and the third argument (\fB$3\fP) is the word preceding the word being
|
||||
completed on the current command line.
|
||||
When it finishes, the possible completions are retrieved from the value
|
||||
of the
|
||||
.SM
|
||||
@@ -8446,8 +8462,9 @@ are supplied, the line read is assigned to the variable
|
||||
.SM
|
||||
.BR REPLY .
|
||||
The return code is zero, unless end-of-file is encountered, \fBread\fP
|
||||
times out (in which case the return code is greater than 128), or an
|
||||
invalid file descriptor is supplied as the argument to \fB\-u\fP.
|
||||
times out (in which case the return code is greater than 128),
|
||||
a variable assignment error (such as assigning to a readonly variable) occurs,
|
||||
or an invalid file descriptor is supplied as the argument to \fB\-u\fP.
|
||||
.RE
|
||||
.TP
|
||||
\fBreadonly\fP [\fB\-aAf\fP] [\fB\-p\fP] [\fIname\fP[=\fIword\fP] ...]
|
||||
|
||||
+9
-3
@@ -3522,7 +3522,7 @@ Aliases are described in @ref{Aliases}.
|
||||
@item bind
|
||||
@btindex bind
|
||||
@example
|
||||
bind [-m @var{keymap}] [-lpsvPSV]
|
||||
bind [-m @var{keymap}] [-lpsvPSVX]
|
||||
bind [-m @var{keymap}] [-q @var{function}] [-u @var{function}] [-r @var{keyseq}]
|
||||
bind [-m @var{keymap}] -f @var{filename}
|
||||
bind [-m @var{keymap}] -x @var{keyseq:shell-command}
|
||||
@@ -3604,6 +3604,10 @@ of the insertion point.
|
||||
If the executed command changes the value of @code{READLINE_LINE} or
|
||||
@code{READLINE_POINT}, those new values will be reflected in the
|
||||
editing state.
|
||||
|
||||
@item -X
|
||||
List all key sequences bound to shell commands and the associated commands
|
||||
in a format that can be reused as input.
|
||||
@end table
|
||||
|
||||
@noindent
|
||||
@@ -4031,8 +4035,9 @@ meaning for the next character read and for line continuation.
|
||||
If no names are supplied, the line read is assigned to the
|
||||
variable @env{REPLY}.
|
||||
The return code is zero, unless end-of-file is encountered, @code{read}
|
||||
times out (in which case the return code is greater than 128), or an
|
||||
invalid file descriptor is supplied as the argument to @option{-u}.
|
||||
times out (in which case the return code is greater than 128),
|
||||
a variable assignment error (such as assigning to a readonly variable) occurs,
|
||||
or an invalid file descriptor is supplied as the argument to @option{-u}.
|
||||
|
||||
Options, if supplied, have the following meanings:
|
||||
|
||||
@@ -5238,6 +5243,7 @@ programmable completion facilities (@pxref{Programmable Completion}).
|
||||
An array variable from which Bash reads the possible completions
|
||||
generated by a shell function invoked by the programmable completion
|
||||
facility (@pxref{Programmable Completion}).
|
||||
Each array element contains one possible completion.
|
||||
|
||||
@item COPROC
|
||||
An array variable created to hold the file descriptors
|
||||
|
||||
+21
-6
@@ -1060,7 +1060,12 @@ will a line containing a @samp{b} anywhere in its value.
|
||||
|
||||
Storing the regular expression in a shell variable is often a useful
|
||||
way to avoid problems with quoting characters that are special to the
|
||||
shell. For example, the following is equivalent to the above:
|
||||
shell.
|
||||
It is sometimes difficult to specify a regular expression literally
|
||||
without using quotes, or to keep track of the quoting used by regular
|
||||
expressions while paying attention to the shell's quote removal.
|
||||
Using a shell variable to store the pattern decreases these problems.
|
||||
For example, the following is equivalent to the above:
|
||||
@example
|
||||
pattern='[[:space:]]*(a)?b'
|
||||
[[ $line =~ $pattern ]]
|
||||
@@ -1069,6 +1074,9 @@ pattern='[[:space:]]*(a)?b'
|
||||
@noindent
|
||||
If you want to match a character that's special to the regular expression
|
||||
grammar, it has to be quoted to remove its special meaning.
|
||||
This means that in the pattern @samp{xxx.txt}, the @samp{.} matches any
|
||||
character in the string (its usual regular expression meaning), but in the
|
||||
pattern @samp{"xxx.txt"} it can only match a literal @samp{.}.
|
||||
Shell programmers should take special care with backslashes, since backslashes
|
||||
are used both by the shell and regular expressions to remove the special
|
||||
meaning from the following character.
|
||||
@@ -3030,8 +3038,9 @@ cd [-L|[-P [-e]]] [@var{directory}]
|
||||
@end example
|
||||
|
||||
Change the current working directory to @var{directory}.
|
||||
If @var{directory} is not given, the value of the @env{HOME} shell
|
||||
variable is used.
|
||||
If @var{directory} is not supplied, the value of the @env{HOME}
|
||||
shell variable is used.
|
||||
Any additional arguments following @var{directory} are ignored.
|
||||
If the shell variable @env{CDPATH} exists, it is used as a search path.
|
||||
If @var{directory} begins with a slash, @env{CDPATH} is not used.
|
||||
|
||||
@@ -3513,7 +3522,7 @@ Aliases are described in @ref{Aliases}.
|
||||
@item bind
|
||||
@btindex bind
|
||||
@example
|
||||
bind [-m @var{keymap}] [-lpsvPSV]
|
||||
bind [-m @var{keymap}] [-lpsvPSVX]
|
||||
bind [-m @var{keymap}] [-q @var{function}] [-u @var{function}] [-r @var{keyseq}]
|
||||
bind [-m @var{keymap}] -f @var{filename}
|
||||
bind [-m @var{keymap}] -x @var{keyseq:shell-command}
|
||||
@@ -3595,6 +3604,10 @@ of the insertion point.
|
||||
If the executed command changes the value of @code{READLINE_LINE} or
|
||||
@code{READLINE_POINT}, those new values will be reflected in the
|
||||
editing state.
|
||||
|
||||
@item -X
|
||||
List all key sequences bound to shell commands and the associated commands
|
||||
in a format that can be reused as input.
|
||||
@end table
|
||||
|
||||
@noindent
|
||||
@@ -4022,8 +4035,9 @@ meaning for the next character read and for line continuation.
|
||||
If no names are supplied, the line read is assigned to the
|
||||
variable @env{REPLY}.
|
||||
The return code is zero, unless end-of-file is encountered, @code{read}
|
||||
times out (in which case the return code is greater than 128), or an
|
||||
invalid file descriptor is supplied as the argument to @option{-u}.
|
||||
times out (in which case the return code is greater than 128),
|
||||
a variable assignment error (such as assigning to a readonly variable) occurs,
|
||||
or an invalid file descriptor is supplied as the argument to @option{-u}.
|
||||
|
||||
Options, if supplied, have the following meanings:
|
||||
|
||||
@@ -5224,6 +5238,7 @@ The line is split into words as Readline would split it, using
|
||||
@code{COMP_WORDBREAKS} as described above.
|
||||
This variable is available only in shell functions invoked by the
|
||||
programmable completion facilities (@pxref{Programmable Completion}).
|
||||
Each array element contains one possible completion.
|
||||
|
||||
@item COMPREPLY
|
||||
An array variable from which Bash reads the possible completions
|
||||
|
||||
+10
-6
@@ -1,6 +1,6 @@
|
||||
/* execute_cmd.c -- Execute a COMMAND structure. */
|
||||
|
||||
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2011 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -195,7 +195,7 @@ static int execute_pipeline __P((COMMAND *, int, int, int, struct fd_bitmap *));
|
||||
|
||||
static int execute_connection __P((COMMAND *, int, int, int, struct fd_bitmap *));
|
||||
|
||||
static int execute_intern_function __P((WORD_DESC *, COMMAND *));
|
||||
static int execute_intern_function __P((WORD_DESC *, FUNCTION_DEF *));
|
||||
|
||||
/* Set to 1 if fd 0 was the subject of redirection to a subshell. Global
|
||||
so that reader_loop can set it to zero before executing a command. */
|
||||
@@ -970,7 +970,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
|
||||
|
||||
case cm_function_def:
|
||||
exec_result = execute_intern_function (command->value.Function_def->name,
|
||||
command->value.Function_def->command);
|
||||
command->value.Function_def);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -5219,9 +5219,9 @@ shell_execve (command, args, env)
|
||||
}
|
||||
|
||||
static int
|
||||
execute_intern_function (name, function)
|
||||
execute_intern_function (name, funcdef)
|
||||
WORD_DESC *name;
|
||||
COMMAND *function;
|
||||
FUNCTION_DEF *funcdef;
|
||||
{
|
||||
SHELL_VAR *var;
|
||||
|
||||
@@ -5251,7 +5251,11 @@ execute_intern_function (name, function)
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
bind_function (name->word, function);
|
||||
#if defined (DEBUGGER)
|
||||
bind_function_def (name->word, funcdef);
|
||||
#endif
|
||||
|
||||
bind_function (name->word, funcdef->command);
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
@@ -499,13 +499,15 @@ expassign ()
|
||||
case DIV:
|
||||
case MOD:
|
||||
if (lvalue == INTMAX_MIN && value == -1)
|
||||
value = (op == DIV) ? 1 : 0;
|
||||
lvalue = (op == DIV) ? INTMAX_MIN : 0;
|
||||
else
|
||||
#if HAVE_IMAXDIV
|
||||
idiv = imaxdiv (lvalue, value);
|
||||
lvalue = (op == DIV) ? idiv.quot : idiv.rem;
|
||||
{
|
||||
idiv = imaxdiv (lvalue, value);
|
||||
lvalue = (op == DIV) ? idiv.quot : idiv.rem;
|
||||
}
|
||||
#else
|
||||
lvalue = (op == DIV) ? lvalue / value : lvalue % value;
|
||||
lvalue = (op == DIV) ? lvalue / value : lvalue % value;
|
||||
#endif
|
||||
break;
|
||||
case PLUS:
|
||||
@@ -843,8 +845,10 @@ exp2 ()
|
||||
val1 *= val2;
|
||||
else if (op == DIV || op == MOD)
|
||||
#if defined (HAVE_IMAXDIV)
|
||||
idiv = imaxdiv (val1, val2);
|
||||
val1 = (op == DIV) ? idiv.quot : idiv.rem;
|
||||
{
|
||||
idiv = imaxdiv (val1, val2);
|
||||
val1 = (op == DIV) ? idiv.quot : idiv.rem;
|
||||
}
|
||||
#else
|
||||
val1 = (op == DIV) ? val1 / val2 : val1 % val2;
|
||||
#endif
|
||||
|
||||
@@ -106,6 +106,8 @@ extern char *xparse_dolparen __P((char *, char *, int *, int));
|
||||
extern void reset_parser __P((void));
|
||||
extern WORD_LIST *parse_string_to_word_list __P((char *, int, const char *));
|
||||
|
||||
extern int parser_in_command_position __P((void));
|
||||
|
||||
extern void free_pushed_string_input __P((void));
|
||||
|
||||
extern char *decode_prompt_string __P((char *));
|
||||
|
||||
+498
@@ -0,0 +1,498 @@
|
||||
/* externs.h -- extern function declarations which do not appear in their
|
||||
own header file. */
|
||||
|
||||
/* Copyright (C) 1993-2010 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash 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 Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Make sure that this is included *after* config.h! */
|
||||
|
||||
#if !defined (_EXTERNS_H_)
|
||||
# define _EXTERNS_H_
|
||||
|
||||
#include "stdc.h"
|
||||
|
||||
/* Functions from expr.c. */
|
||||
extern intmax_t evalexp __P((char *, int *));
|
||||
|
||||
/* Functions from print_cmd.c. */
|
||||
#define FUNC_MULTILINE 0x01
|
||||
#define FUNC_EXTERNAL 0x02
|
||||
|
||||
extern char *make_command_string __P((COMMAND *));
|
||||
extern char *named_function_string __P((char *, COMMAND *, int));
|
||||
|
||||
extern void print_command __P((COMMAND *));
|
||||
extern void print_simple_command __P((SIMPLE_COM *));
|
||||
extern void print_word_list __P((WORD_LIST *, char *));
|
||||
|
||||
/* debugger support */
|
||||
extern void print_for_command_head __P((FOR_COM *));
|
||||
#if defined (SELECT_COMMAND)
|
||||
extern void print_select_command_head __P((SELECT_COM *));
|
||||
#endif
|
||||
extern void print_case_command_head __P((CASE_COM *));
|
||||
#if defined (DPAREN_ARITHMETIC)
|
||||
extern void print_arith_command __P((WORD_LIST *));
|
||||
#endif
|
||||
#if defined (COND_COMMAND)
|
||||
extern void print_cond_command __P((COND_COM *));
|
||||
#endif
|
||||
|
||||
/* set -x support */
|
||||
extern void xtrace_init __P((void));
|
||||
#ifdef NEED_XTRACE_SET_DECL
|
||||
extern void xtrace_set __P((int, FILE *));
|
||||
#endif
|
||||
extern void xtrace_fdchk __P((int));
|
||||
extern void xtrace_reset __P((void));
|
||||
extern char *indirection_level_string __P((void));
|
||||
extern void xtrace_print_assignment __P((char *, char *, int, int));
|
||||
extern void xtrace_print_word_list __P((WORD_LIST *, int));
|
||||
extern void xtrace_print_for_command_head __P((FOR_COM *));
|
||||
#if defined (SELECT_COMMAND)
|
||||
extern void xtrace_print_select_command_head __P((SELECT_COM *));
|
||||
#endif
|
||||
extern void xtrace_print_case_command_head __P((CASE_COM *));
|
||||
#if defined (DPAREN_ARITHMETIC)
|
||||
extern void xtrace_print_arith_cmd __P((WORD_LIST *));
|
||||
#endif
|
||||
#if defined (COND_COMMAND)
|
||||
extern void xtrace_print_cond_term __P((int, int, WORD_DESC *, char *, char *));
|
||||
#endif
|
||||
|
||||
/* Functions from shell.c. */
|
||||
extern void exit_shell __P((int)) __attribute__((__noreturn__));
|
||||
extern void sh_exit __P((int)) __attribute__((__noreturn__));
|
||||
extern void disable_priv_mode __P((void));
|
||||
extern void unbind_args __P((void));
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
extern int shell_is_restricted __P((char *));
|
||||
extern int maybe_make_restricted __P((char *));
|
||||
#endif
|
||||
|
||||
extern void unset_bash_input __P((int));
|
||||
extern void get_current_user_info __P((void));
|
||||
|
||||
/* Functions from eval.c. */
|
||||
extern int reader_loop __P((void));
|
||||
extern int parse_command __P((void));
|
||||
extern int read_command __P((void));
|
||||
|
||||
/* Functions from braces.c. */
|
||||
#if defined (BRACE_EXPANSION)
|
||||
extern char **brace_expand __P((char *));
|
||||
#endif
|
||||
|
||||
/* Miscellaneous functions from parse.y */
|
||||
extern int yyparse __P((void));
|
||||
extern int return_EOF __P((void));
|
||||
extern char *xparse_dolparen __P((char *, char *, int *, int));
|
||||
extern void reset_parser __P((void));
|
||||
extern WORD_LIST *parse_string_to_word_list __P((char *, int, const char *));
|
||||
|
||||
extern void free_pushed_string_input __P((void));
|
||||
|
||||
extern char *decode_prompt_string __P((char *));
|
||||
|
||||
extern int get_current_prompt_level __P((void));
|
||||
extern void set_current_prompt_level __P((int));
|
||||
|
||||
#if defined (HISTORY)
|
||||
extern char *history_delimiting_chars __P((const char *));
|
||||
#endif
|
||||
|
||||
/* Declarations for functions defined in locale.c */
|
||||
extern void set_default_locale __P((void));
|
||||
extern void set_default_locale_vars __P((void));
|
||||
extern int set_locale_var __P((char *, char *));
|
||||
extern int set_lang __P((char *, char *));
|
||||
extern void set_default_lang __P((void));
|
||||
extern char *get_locale_var __P((char *));
|
||||
extern char *localetrans __P((char *, int, int *));
|
||||
extern char *mk_msgstr __P((char *, int *));
|
||||
extern char *localeexpand __P((char *, int, int, int, int *));
|
||||
|
||||
/* Declarations for functions defined in list.c. */
|
||||
extern void list_walk __P((GENERIC_LIST *, sh_glist_func_t *));
|
||||
extern void wlist_walk __P((WORD_LIST *, sh_icpfunc_t *));
|
||||
extern GENERIC_LIST *list_reverse ();
|
||||
extern int list_length ();
|
||||
extern GENERIC_LIST *list_append ();
|
||||
extern GENERIC_LIST *list_remove ();
|
||||
|
||||
/* Declarations for functions defined in stringlib.c */
|
||||
extern int find_string_in_alist __P((char *, STRING_INT_ALIST *, int));
|
||||
extern char *find_token_in_alist __P((int, STRING_INT_ALIST *, int));
|
||||
extern int find_index_in_alist __P((char *, STRING_INT_ALIST *, int));
|
||||
|
||||
extern char *substring __P((const char *, int, int));
|
||||
extern char *strsub __P((char *, char *, char *, int));
|
||||
extern char *strcreplace __P((char *, int, char *, int));
|
||||
extern void strip_leading __P((char *));
|
||||
extern void strip_trailing __P((char *, int, int));
|
||||
extern void xbcopy __P((char *, char *, int));
|
||||
|
||||
/* Functions from version.c. */
|
||||
extern char *shell_version_string __P((void));
|
||||
extern void show_shell_version __P((int));
|
||||
|
||||
/* Functions from the bash library, lib/sh/libsh.a. These should really
|
||||
go into a separate include file. */
|
||||
|
||||
/* declarations for functions defined in lib/sh/casemod.c */
|
||||
extern char *sh_modcase __P((const char *, char *, int));
|
||||
|
||||
/* Defines for flags argument to sh_modcase. These need to agree with what's
|
||||
in lib/sh/casemode.c */
|
||||
#define CASE_LOWER 0x0001
|
||||
#define CASE_UPPER 0x0002
|
||||
#define CASE_CAPITALIZE 0x0004
|
||||
#define CASE_UNCAP 0x0008
|
||||
#define CASE_TOGGLE 0x0010
|
||||
#define CASE_TOGGLEALL 0x0020
|
||||
#define CASE_UPFIRST 0x0040
|
||||
#define CASE_LOWFIRST 0x0080
|
||||
|
||||
#define CASE_USEWORDS 0x1000
|
||||
|
||||
/* declarations for functions defined in lib/sh/clktck.c */
|
||||
extern long get_clk_tck __P((void));
|
||||
|
||||
/* declarations for functions defined in lib/sh/clock.c */
|
||||
extern void clock_t_to_secs ();
|
||||
extern void print_clock_t ();
|
||||
|
||||
/* Declarations for functions defined in lib/sh/dprintf.c */
|
||||
#if !defined (HAVE_DPRINTF)
|
||||
extern void dprintf __P((int, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
|
||||
#endif
|
||||
|
||||
/* Declarations for functions defined in lib/sh/fmtulong.c */
|
||||
#define FL_PREFIX 0x01 /* add 0x, 0X, or 0 prefix as appropriate */
|
||||
#define FL_ADDBASE 0x02 /* add base# prefix to converted value */
|
||||
#define FL_HEXUPPER 0x04 /* use uppercase when converting to hex */
|
||||
#define FL_UNSIGNED 0x08 /* don't add any sign */
|
||||
|
||||
extern char *fmtulong __P((unsigned long int, int, char *, size_t, int));
|
||||
|
||||
/* Declarations for functions defined in lib/sh/fmtulong.c */
|
||||
#if defined (HAVE_LONG_LONG)
|
||||
extern char *fmtullong __P((unsigned long long int, int, char *, size_t, int));
|
||||
#endif
|
||||
|
||||
/* Declarations for functions defined in lib/sh/fmtumax.c */
|
||||
extern char *fmtumax __P((uintmax_t, int, char *, size_t, int));
|
||||
|
||||
/* Declarations for functions defined in lib/sh/fnxform.c */
|
||||
extern char *fnx_fromfs __P((char *, size_t));
|
||||
extern char *fnx_tofs __P((char *, size_t));
|
||||
|
||||
/* Declarations for functions defined in lib/sh/fpurge.c */
|
||||
|
||||
#if defined NEED_FPURGE_DECL
|
||||
#if !HAVE_DECL_FPURGE
|
||||
|
||||
#if HAVE_FPURGE
|
||||
# define fpurge _bash_fpurge
|
||||
#endif
|
||||
extern int fpurge __P((FILE *stream));
|
||||
|
||||
#endif /* HAVE_DECL_FPURGE */
|
||||
#endif /* NEED_FPURGE_DECL */
|
||||
|
||||
/* Declarations for functions defined in lib/sh/getcwd.c */
|
||||
#if !defined (HAVE_GETCWD)
|
||||
extern char *getcwd __P((char *, size_t));
|
||||
#endif
|
||||
|
||||
/* Declarations for functions defined in lib/sh/input_avail.c */
|
||||
extern int input_avail __P((int));
|
||||
|
||||
/* Declarations for functions defined in lib/sh/itos.c */
|
||||
extern char *inttostr __P((intmax_t, char *, size_t));
|
||||
extern char *itos __P((intmax_t));
|
||||
extern char *uinttostr __P((uintmax_t, char *, size_t));
|
||||
extern char *uitos __P((uintmax_t));
|
||||
|
||||
/* declarations for functions defined in lib/sh/makepath.c */
|
||||
#define MP_DOTILDE 0x01
|
||||
#define MP_DOCWD 0x02
|
||||
#define MP_RMDOT 0x04
|
||||
#define MP_IGNDOT 0x08
|
||||
|
||||
extern char *sh_makepath __P((const char *, const char *, int));
|
||||
|
||||
/* declarations for functions defined in lib/sh/mbscasecmp.c */
|
||||
#if !defined (HAVE_MBSCASECMP)
|
||||
extern char *mbscasecmp __P((const char *, const char *));
|
||||
#endif
|
||||
|
||||
/* declarations for functions defined in lib/sh/mbschr.c */
|
||||
#if !defined (HAVE_MBSCHR)
|
||||
extern char *mbschr __P((const char *, int));
|
||||
#endif
|
||||
|
||||
/* declarations for functions defined in lib/sh/mbscmp.c */
|
||||
#if !defined (HAVE_MBSCMP)
|
||||
extern char *mbscmp __P((const char *, const char *));
|
||||
#endif
|
||||
|
||||
/* declarations for functions defined in lib/sh/netconn.c */
|
||||
extern int isnetconn __P((int));
|
||||
|
||||
/* declarations for functions defined in lib/sh/netopen.c */
|
||||
extern int netopen __P((char *));
|
||||
|
||||
/* Declarations for functions defined in lib/sh/oslib.c */
|
||||
|
||||
#if !defined (HAVE_DUP2) || defined (DUP2_BROKEN)
|
||||
extern int dup2 __P((int, int));
|
||||
#endif
|
||||
|
||||
#if !defined (HAVE_GETDTABLESIZE)
|
||||
extern int getdtablesize __P((void));
|
||||
#endif /* !HAVE_GETDTABLESIZE */
|
||||
|
||||
#if !defined (HAVE_GETHOSTNAME)
|
||||
extern int gethostname __P((char *, int));
|
||||
#endif /* !HAVE_GETHOSTNAME */
|
||||
|
||||
extern int getmaxgroups __P((void));
|
||||
extern long getmaxchild __P((void));
|
||||
|
||||
/* declarations for functions defined in lib/sh/pathcanon.c */
|
||||
#define PATH_CHECKDOTDOT 0x0001
|
||||
#define PATH_CHECKEXISTS 0x0002
|
||||
#define PATH_HARDPATH 0x0004
|
||||
#define PATH_NOALLOC 0x0008
|
||||
|
||||
extern char *sh_canonpath __P((char *, int));
|
||||
|
||||
/* declarations for functions defined in lib/sh/pathphys.c */
|
||||
extern char *sh_physpath __P((char *, int));
|
||||
extern char *sh_realpath __P((const char *, char *));
|
||||
|
||||
/* declarations for functions defined in lib/sh/setlinebuf.c */
|
||||
#ifdef NEED_SH_SETLINEBUF_DECL
|
||||
extern int sh_setlinebuf __P((FILE *));
|
||||
#endif
|
||||
|
||||
/* declarations for functions defined in lib/sh/shaccess.c */
|
||||
extern int sh_eaccess __P((char *, int));
|
||||
|
||||
/* declarations for functions defined in lib/sh/shmatch.c */
|
||||
extern int sh_regmatch __P((const char *, const char *, int));
|
||||
|
||||
/* defines for flags argument to sh_regmatch. */
|
||||
#define SHMAT_SUBEXP 0x001 /* save subexpressions in SH_REMATCH */
|
||||
#define SHMAT_PWARN 0x002 /* print a warning message on invalid regexp */
|
||||
|
||||
/* declarations for functions defined in lib/sh/shmbchar.c */
|
||||
extern size_t mbstrlen __P((const char *));
|
||||
extern char *mbsmbchar __P((const char *));
|
||||
|
||||
/* declarations for functions defined in lib/sh/shquote.c */
|
||||
extern char *sh_single_quote __P((const char *));
|
||||
extern char *sh_double_quote __P((const char *));
|
||||
extern char *sh_mkdoublequoted __P((const char *, int, int));
|
||||
extern char *sh_un_double_quote __P((char *));
|
||||
extern char *sh_backslash_quote __P((char *, const char *));
|
||||
extern char *sh_backslash_quote_for_double_quotes __P((char *));
|
||||
extern int sh_contains_shell_metas __P((char *));
|
||||
|
||||
/* declarations for functions defined in lib/sh/spell.c */
|
||||
extern int spname __P((char *, char *));
|
||||
extern char *dirspell __P((char *));
|
||||
|
||||
/* declarations for functions defined in lib/sh/strcasecmp.c */
|
||||
#if !defined (HAVE_STRCASECMP)
|
||||
extern int strncasecmp __P((const char *, const char *, int));
|
||||
extern int strcasecmp __P((const char *, const char *));
|
||||
#endif /* HAVE_STRCASECMP */
|
||||
|
||||
/* declarations for functions defined in lib/sh/strcasestr.c */
|
||||
#if ! HAVE_STRCASESTR
|
||||
extern char *strcasestr __P((const char *, const char *));
|
||||
#endif
|
||||
|
||||
/* declarations for functions defined in lib/sh/strchrnul.c */
|
||||
#if ! HAVE_STRCHRNUL
|
||||
extern char *strchrnul __P((const char *, int));
|
||||
#endif
|
||||
|
||||
/* declarations for functions defined in lib/sh/strerror.c */
|
||||
#if !defined (HAVE_STRERROR) && !defined (strerror)
|
||||
extern char *strerror __P((int));
|
||||
#endif
|
||||
|
||||
/* declarations for functions defined in lib/sh/strftime.c */
|
||||
#if !defined (HAVE_STRFTIME) && defined (NEED_STRFTIME_DECL)
|
||||
extern size_t strftime __P((char *, size_t, const char *, const struct tm *));
|
||||
#endif
|
||||
|
||||
/* declarations for functions and structures defined in lib/sh/stringlist.c */
|
||||
|
||||
/* This is a general-purpose argv-style array struct. */
|
||||
typedef struct _list_of_strings {
|
||||
char **list;
|
||||
int list_size;
|
||||
int list_len;
|
||||
} STRINGLIST;
|
||||
|
||||
typedef int sh_strlist_map_func_t __P((char *));
|
||||
|
||||
extern STRINGLIST *strlist_create __P((int));
|
||||
extern STRINGLIST *strlist_resize __P((STRINGLIST *, int));
|
||||
extern void strlist_flush __P((STRINGLIST *));
|
||||
extern void strlist_dispose __P((STRINGLIST *));
|
||||
extern int strlist_remove __P((STRINGLIST *, char *));
|
||||
extern STRINGLIST *strlist_copy __P((STRINGLIST *));
|
||||
extern STRINGLIST *strlist_merge __P((STRINGLIST *, STRINGLIST *));
|
||||
extern STRINGLIST *strlist_append __P((STRINGLIST *, STRINGLIST *));
|
||||
extern STRINGLIST *strlist_prefix_suffix __P((STRINGLIST *, char *, char *));
|
||||
extern void strlist_print __P((STRINGLIST *, char *));
|
||||
extern void strlist_walk __P((STRINGLIST *, sh_strlist_map_func_t *));
|
||||
extern void strlist_sort __P((STRINGLIST *));
|
||||
|
||||
/* declarations for functions defined in lib/sh/stringvec.c */
|
||||
|
||||
extern char **strvec_create __P((int));
|
||||
extern char **strvec_resize __P((char **, int));
|
||||
extern void strvec_flush __P((char **));
|
||||
extern void strvec_dispose __P((char **));
|
||||
extern int strvec_remove __P((char **, char *));
|
||||
extern int strvec_len __P((char **));
|
||||
extern int strvec_search __P((char **, char *));
|
||||
extern char **strvec_copy __P((char **));
|
||||
extern int strvec_strcmp __P((char **, char **));
|
||||
extern void strvec_sort __P((char **));
|
||||
|
||||
extern char **strvec_from_word_list __P((WORD_LIST *, int, int, int *));
|
||||
extern WORD_LIST *strvec_to_word_list __P((char **, int, int));
|
||||
|
||||
/* declarations for functions defined in lib/sh/strnlen.c */
|
||||
#if !defined (HAVE_STRNLEN)
|
||||
extern size_t strnlen __P((const char *, size_t));
|
||||
#endif
|
||||
|
||||
/* declarations for functions defined in lib/sh/strpbrk.c */
|
||||
#if !defined (HAVE_STRPBRK)
|
||||
extern char *strpbrk __P((const char *, const char *));
|
||||
#endif
|
||||
|
||||
/* declarations for functions defined in lib/sh/strtod.c */
|
||||
#if !defined (HAVE_STRTOD)
|
||||
extern double strtod __P((const char *, char **));
|
||||
#endif
|
||||
|
||||
/* declarations for functions defined in lib/sh/strtol.c */
|
||||
#if !HAVE_DECL_STRTOL
|
||||
extern long strtol __P((const char *, char **, int));
|
||||
#endif
|
||||
|
||||
/* declarations for functions defined in lib/sh/strtoll.c */
|
||||
#if defined (HAVE_LONG_LONG) && !HAVE_DECL_STRTOLL
|
||||
extern long long strtoll __P((const char *, char **, int));
|
||||
#endif
|
||||
|
||||
/* declarations for functions defined in lib/sh/strtoul.c */
|
||||
#if !HAVE_DECL_STRTOUL
|
||||
extern unsigned long strtoul __P((const char *, char **, int));
|
||||
#endif
|
||||
|
||||
/* declarations for functions defined in lib/sh/strtoull.c */
|
||||
#if defined (HAVE_LONG_LONG) && !HAVE_DECL_STRTOULL
|
||||
extern unsigned long long strtoull __P((const char *, char **, int));
|
||||
#endif
|
||||
|
||||
/* declarations for functions defined in lib/sh/strimax.c */
|
||||
#if !HAVE_DECL_STRTOIMAX
|
||||
extern intmax_t strtoimax __P((const char *, char **, int));
|
||||
#endif
|
||||
|
||||
/* declarations for functions defined in lib/sh/strumax.c */
|
||||
#if !HAVE_DECL_STRTOUMAX
|
||||
extern uintmax_t strtoumax __P((const char *, char **, int));
|
||||
#endif
|
||||
|
||||
/* declarations for functions defined in lib/sh/strtrans.c */
|
||||
extern char *ansicstr __P((char *, int, int, int *, int *));
|
||||
extern char *ansic_quote __P((char *, int, int *));
|
||||
extern int ansic_shouldquote __P((const char *));
|
||||
extern char *ansiexpand __P((char *, int, int, int *));
|
||||
|
||||
/* declarations for functions defined in lib/sh/timeval.c. No prototypes
|
||||
so we don't have to count on having a definition of struct timeval in
|
||||
scope when this file is included. */
|
||||
extern void timeval_to_secs ();
|
||||
extern void print_timeval ();
|
||||
|
||||
/* declarations for functions defined in lib/sh/tmpfile.c */
|
||||
#define MT_USETMPDIR 0x0001
|
||||
#define MT_READWRITE 0x0002
|
||||
#define MT_USERANDOM 0x0004
|
||||
|
||||
extern char *sh_mktmpname __P((char *, int));
|
||||
extern int sh_mktmpfd __P((char *, int, char **));
|
||||
/* extern FILE *sh_mktmpfp __P((char *, int, char **)); */
|
||||
|
||||
/* declarations for functions defined in lib/sh/uconvert.c */
|
||||
extern int uconvert __P((char *, long *, long *));
|
||||
|
||||
/* declarations for functions defined in lib/sh/ufuncs.c */
|
||||
extern unsigned int falarm __P((unsigned int, unsigned int));
|
||||
extern unsigned int fsleep __P((unsigned int, unsigned int));
|
||||
|
||||
/* declarations for functions defined in lib/sh/unicode.c */
|
||||
extern int u32cconv __P((unsigned long, char *));
|
||||
|
||||
/* declarations for functions defined in lib/sh/winsize.c */
|
||||
extern void get_new_window_size __P((int, int *, int *));
|
||||
|
||||
/* declarations for functions defined in lib/sh/zcatfd.c */
|
||||
extern int zcatfd __P((int, int, char *));
|
||||
|
||||
/* declarations for functions defined in lib/sh/zgetline.c */
|
||||
extern ssize_t zgetline __P((int, char **, size_t *, int));
|
||||
|
||||
/* declarations for functions defined in lib/sh/zmapfd.c */
|
||||
extern int zmapfd __P((int, char **, char *));
|
||||
|
||||
/* declarations for functions defined in lib/sh/zread.c */
|
||||
extern ssize_t zread __P((int, char *, size_t));
|
||||
extern ssize_t zreadretry __P((int, char *, size_t));
|
||||
extern ssize_t zreadintr __P((int, char *, size_t));
|
||||
extern ssize_t zreadc __P((int, char *));
|
||||
extern ssize_t zreadcintr __P((int, char *));
|
||||
extern void zreset __P((void));
|
||||
extern void zsyncfd __P((int));
|
||||
|
||||
/* declarations for functions defined in lib/sh/zwrite.c */
|
||||
extern int zwrite __P((int, char *, size_t));
|
||||
|
||||
/* declarations for functions defined in lib/glob/gmisc.c */
|
||||
extern int match_pattern_char __P((char *, char *));
|
||||
extern int umatchlen __P((char *, size_t));
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
extern int match_pattern_wchar __P((wchar_t *, wchar_t *));
|
||||
extern int wmatchlen __P((wchar_t *, size_t));
|
||||
#endif
|
||||
|
||||
#endif /* _EXTERNS_H_ */
|
||||
+47
-7
@@ -571,6 +571,40 @@ rl_translate_keyseq (seq, array, len)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
_rl_isescape (c)
|
||||
int c;
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\007':
|
||||
case '\b':
|
||||
case '\f':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case TAB:
|
||||
case 0x0b: return (1);
|
||||
default: return (0);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_rl_escchar (c)
|
||||
int c;
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\007': return ('a');
|
||||
case '\b': return ('b');
|
||||
case '\f': return ('f');
|
||||
case '\n': return ('n');
|
||||
case '\r': return ('r');
|
||||
case TAB: return ('t');
|
||||
case 0x0b: return ('v');
|
||||
default: return (c);
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
rl_untranslate_keyseq (seq)
|
||||
int seq;
|
||||
@@ -622,9 +656,10 @@ rl_untranslate_keyseq (seq)
|
||||
return kseq;
|
||||
}
|
||||
|
||||
static char *
|
||||
_rl_untranslate_macro_value (seq)
|
||||
char *
|
||||
_rl_untranslate_macro_value (seq, use_escapes)
|
||||
char *seq;
|
||||
int use_escapes;
|
||||
{
|
||||
char *ret, *r, *s;
|
||||
int c;
|
||||
@@ -648,9 +683,14 @@ _rl_untranslate_macro_value (seq)
|
||||
else if (CTRL_CHAR (c))
|
||||
{
|
||||
*r++ = '\\';
|
||||
*r++ = 'C';
|
||||
*r++ = '-';
|
||||
c = _rl_to_lower (UNCTRL (c));
|
||||
if (use_escapes && _rl_isescape (c))
|
||||
c = _rl_escchar (c);
|
||||
else
|
||||
{
|
||||
*r++ = 'C';
|
||||
*r++ = '-';
|
||||
c = _rl_to_lower (UNCTRL (c));
|
||||
}
|
||||
}
|
||||
else if (c == RUBOUT)
|
||||
{
|
||||
@@ -2215,7 +2255,7 @@ _rl_macro_dumper_internal (print_readably, map, prefix)
|
||||
{
|
||||
case ISMACR:
|
||||
keyname = _rl_get_keyname (key);
|
||||
out = _rl_untranslate_macro_value ((char *)map[key].function);
|
||||
out = _rl_untranslate_macro_value ((char *)map[key].function, 0);
|
||||
|
||||
if (print_readably)
|
||||
fprintf (rl_outstream, "\"%s%s\": \"%s\"\n", prefix ? prefix : "",
|
||||
@@ -2327,7 +2367,7 @@ _rl_get_string_variable_value (name)
|
||||
{
|
||||
if (_rl_isearch_terminators == 0)
|
||||
return 0;
|
||||
ret = _rl_untranslate_macro_value (_rl_isearch_terminators);
|
||||
ret = _rl_untranslate_macro_value (_rl_isearch_terminators, 0);
|
||||
if (ret)
|
||||
{
|
||||
strncpy (numbuf, ret, sizeof (numbuf) - 1);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1011,6 +1011,9 @@ and store the definition.
|
||||
.B call\-last\-kbd\-macro (C\-x e)
|
||||
Re-execute the last keyboard macro defined, by making the characters
|
||||
in the macro appear as if typed at the keyboard.
|
||||
.B print\-last\-kbd\-macro ()
|
||||
Print the last keyboard macro defined in a format suitable for the
|
||||
\fIinputrc\fP file.
|
||||
.PD
|
||||
.SS Miscellaneous
|
||||
.PP
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1452,6 +1452,10 @@ and save the definition.
|
||||
Re-execute the last keyboard macro defined, by making the characters
|
||||
in the macro appear as if typed at the keyboard.
|
||||
|
||||
@item print-last-kbd-macro ()
|
||||
Print the last keboard macro defined in a format suitable for the
|
||||
@var{inputrc} file.
|
||||
|
||||
@end ftable
|
||||
|
||||
@node Miscellaneous Commands
|
||||
@@ -1800,8 +1804,9 @@ complete -D -F _completion_loader
|
||||
@section Programmable Completion Builtins
|
||||
@cindex completion builtins
|
||||
|
||||
Two builtin commands are available to manipulate the programmable completion
|
||||
facilities.
|
||||
Three builtin commands are available to manipulate the programmable completion
|
||||
facilities: one to specify how the arguments to a particular command are to
|
||||
be completed, and two to modify the completion as it is happening.
|
||||
|
||||
@table @code
|
||||
@item compgen
|
||||
|
||||
@@ -1800,8 +1800,9 @@ complete -D -F _completion_loader
|
||||
@section Programmable Completion Builtins
|
||||
@cindex completion builtins
|
||||
|
||||
Two builtin commands are available to manipulate the programmable completion
|
||||
facilities.
|
||||
Three builtin commands are available to manipulate the programmable completion
|
||||
facilities: one to specify how the arguments to a particular command are to
|
||||
be completed, and two to modify the completion as it is happening.
|
||||
|
||||
@table @code
|
||||
@item compgen
|
||||
@@ -1888,6 +1889,10 @@ quoting special characters, or suppressing trailing spaces).
|
||||
This option is intended to be used with shell functions specified
|
||||
with @option{-F}.
|
||||
|
||||
@item noquote
|
||||
Tell Readline not to quote the completed words if they are filenames
|
||||
(quoting filenames is the default).
|
||||
|
||||
@item nospace
|
||||
Tell Readline not to append a space (the default) to words completed at
|
||||
the end of the line.
|
||||
|
||||
@@ -4,7 +4,7 @@ Copyright (C) 1988-2011 Free Software Foundation, Inc.
|
||||
|
||||
@set EDITION 6.2
|
||||
@set VERSION 6.2
|
||||
@set UPDATED December 10 2011
|
||||
@set UPDATED December 21 2011
|
||||
@set UPDATED-MONTH December 2011
|
||||
|
||||
@set LASTCHANGE Sat Dec 10 21:53:20 EST 2011
|
||||
@set LASTCHANGE Wed Dec 21 21:04:12 EST 2011
|
||||
|
||||
@@ -4,7 +4,7 @@ Copyright (C) 1988-2011 Free Software Foundation, Inc.
|
||||
|
||||
@set EDITION 6.2
|
||||
@set VERSION 6.2
|
||||
@set UPDATED October 2 2011
|
||||
@set UPDATED-MONTH October 2011
|
||||
@set UPDATED December 10 2011
|
||||
@set UPDATED-MONTH December 2011
|
||||
|
||||
@set LASTCHANGE Sun Oct 2 15:54:47 EDT 2011
|
||||
@set LASTCHANGE Sat Dec 10 21:53:20 EST 2011
|
||||
|
||||
@@ -120,6 +120,7 @@ static const FUNMAP default_funmap[] = {
|
||||
#endif
|
||||
{ "possible-completions", rl_possible_completions },
|
||||
{ "previous-history", rl_get_previous_history },
|
||||
{ "print-last-kbd-macro", rl_print_last_kbd_macro },
|
||||
{ "quoted-insert", rl_quoted_insert },
|
||||
{ "re-read-init-file", rl_re_read_init_file },
|
||||
{ "redraw-current-line", rl_refresh_line},
|
||||
|
||||
@@ -238,7 +238,7 @@ rl_initialize_funmap ()
|
||||
|
||||
/* Produce a NULL terminated array of known function names. The array
|
||||
is sorted. The array itself is allocated, but not the strings inside.
|
||||
You should free () the array when you done, but not the pointrs. */
|
||||
You should free () the array when you done, but not the pointers. */
|
||||
const char **
|
||||
rl_funmap_names ()
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* history.c -- standalone history library */
|
||||
|
||||
/* Copyright (C) 1989-2009 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1989-2011 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the GNU History Library (History), a set of
|
||||
routines for managing the text of previously typed lines.
|
||||
@@ -236,7 +236,7 @@ history_get_time (hist)
|
||||
ts = hist->timestamp;
|
||||
if (ts[0] != history_comment_char)
|
||||
return 0;
|
||||
t = (time_t) atol (ts + 1); /* XXX - should use strtol() here */
|
||||
t = (time_t) strtol (ts + 1, (char **)NULL, 10); /* XXX - should use strtol() here */
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,519 @@
|
||||
/* history.c -- standalone history library */
|
||||
|
||||
/* Copyright (C) 1989-2009 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the GNU History Library (History), a set of
|
||||
routines for managing the text of previously typed lines.
|
||||
|
||||
History 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
History 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 History. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* The goal is to make the implementation transparent, so that you
|
||||
don't have to know what data types are used, just what functions
|
||||
you can call. I think I have done that. */
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined (HAVE_STDLIB_H)
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
# include "ansi_stdlib.h"
|
||||
#endif /* HAVE_STDLIB_H */
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# ifdef _MINIX
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "history.h"
|
||||
#include "histlib.h"
|
||||
|
||||
#include "xmalloc.h"
|
||||
|
||||
/* The number of slots to increase the_history by. */
|
||||
#define DEFAULT_HISTORY_GROW_SIZE 50
|
||||
|
||||
static char *hist_inittime PARAMS((void));
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* History Functions */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* An array of HIST_ENTRY. This is where we store the history. */
|
||||
static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL;
|
||||
|
||||
/* Non-zero means that we have enforced a limit on the amount of
|
||||
history that we save. */
|
||||
static int history_stifled;
|
||||
|
||||
/* The current number of slots allocated to the input_history. */
|
||||
static int history_size;
|
||||
|
||||
/* If HISTORY_STIFLED is non-zero, then this is the maximum number of
|
||||
entries to remember. */
|
||||
int history_max_entries;
|
||||
int max_input_history; /* backwards compatibility */
|
||||
|
||||
/* The current location of the interactive history pointer. Just makes
|
||||
life easier for outside callers. */
|
||||
int history_offset;
|
||||
|
||||
/* The number of strings currently stored in the history list. */
|
||||
int history_length;
|
||||
|
||||
/* The logical `base' of the history array. It defaults to 1. */
|
||||
int history_base = 1;
|
||||
|
||||
/* Return the current HISTORY_STATE of the history. */
|
||||
HISTORY_STATE *
|
||||
history_get_history_state ()
|
||||
{
|
||||
HISTORY_STATE *state;
|
||||
|
||||
state = (HISTORY_STATE *)xmalloc (sizeof (HISTORY_STATE));
|
||||
state->entries = the_history;
|
||||
state->offset = history_offset;
|
||||
state->length = history_length;
|
||||
state->size = history_size;
|
||||
state->flags = 0;
|
||||
if (history_stifled)
|
||||
state->flags |= HS_STIFLED;
|
||||
|
||||
return (state);
|
||||
}
|
||||
|
||||
/* Set the state of the current history array to STATE. */
|
||||
void
|
||||
history_set_history_state (state)
|
||||
HISTORY_STATE *state;
|
||||
{
|
||||
the_history = state->entries;
|
||||
history_offset = state->offset;
|
||||
history_length = state->length;
|
||||
history_size = state->size;
|
||||
if (state->flags & HS_STIFLED)
|
||||
history_stifled = 1;
|
||||
}
|
||||
|
||||
/* Begin a session in which the history functions might be used. This
|
||||
initializes interactive variables. */
|
||||
void
|
||||
using_history ()
|
||||
{
|
||||
history_offset = history_length;
|
||||
}
|
||||
|
||||
/* Return the number of bytes that the primary history entries are using.
|
||||
This just adds up the lengths of the_history->lines and the associated
|
||||
timestamps. */
|
||||
int
|
||||
history_total_bytes ()
|
||||
{
|
||||
register int i, result;
|
||||
|
||||
for (i = result = 0; the_history && the_history[i]; i++)
|
||||
result += HISTENT_BYTES (the_history[i]);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* Returns the magic number which says what history element we are
|
||||
looking at now. In this implementation, it returns history_offset. */
|
||||
int
|
||||
where_history ()
|
||||
{
|
||||
return (history_offset);
|
||||
}
|
||||
|
||||
/* Make the current history item be the one at POS, an absolute index.
|
||||
Returns zero if POS is out of range, else non-zero. */
|
||||
int
|
||||
history_set_pos (pos)
|
||||
int pos;
|
||||
{
|
||||
if (pos > history_length || pos < 0 || !the_history)
|
||||
return (0);
|
||||
history_offset = pos;
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Return the current history array. The caller has to be careful, since this
|
||||
is the actual array of data, and could be bashed or made corrupt easily.
|
||||
The array is terminated with a NULL pointer. */
|
||||
HIST_ENTRY **
|
||||
history_list ()
|
||||
{
|
||||
return (the_history);
|
||||
}
|
||||
|
||||
/* Return the history entry at the current position, as determined by
|
||||
history_offset. If there is no entry there, return a NULL pointer. */
|
||||
HIST_ENTRY *
|
||||
current_history ()
|
||||
{
|
||||
return ((history_offset == history_length) || the_history == 0)
|
||||
? (HIST_ENTRY *)NULL
|
||||
: the_history[history_offset];
|
||||
}
|
||||
|
||||
/* Back up history_offset to the previous history entry, and return
|
||||
a pointer to that entry. If there is no previous entry then return
|
||||
a NULL pointer. */
|
||||
HIST_ENTRY *
|
||||
previous_history ()
|
||||
{
|
||||
return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL;
|
||||
}
|
||||
|
||||
/* Move history_offset forward to the next history entry, and return
|
||||
a pointer to that entry. If there is no next entry then return a
|
||||
NULL pointer. */
|
||||
HIST_ENTRY *
|
||||
next_history ()
|
||||
{
|
||||
return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset];
|
||||
}
|
||||
|
||||
/* Return the history entry which is logically at OFFSET in the history array.
|
||||
OFFSET is relative to history_base. */
|
||||
HIST_ENTRY *
|
||||
history_get (offset)
|
||||
int offset;
|
||||
{
|
||||
int local_index;
|
||||
|
||||
local_index = offset - history_base;
|
||||
return (local_index >= history_length || local_index < 0 || the_history == 0)
|
||||
? (HIST_ENTRY *)NULL
|
||||
: the_history[local_index];
|
||||
}
|
||||
|
||||
HIST_ENTRY *
|
||||
alloc_history_entry (string, ts)
|
||||
char *string;
|
||||
char *ts;
|
||||
{
|
||||
HIST_ENTRY *temp;
|
||||
|
||||
temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
|
||||
|
||||
temp->line = string ? savestring (string) : string;
|
||||
temp->data = (char *)NULL;
|
||||
temp->timestamp = ts;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
time_t
|
||||
history_get_time (hist)
|
||||
HIST_ENTRY *hist;
|
||||
{
|
||||
char *ts;
|
||||
time_t t;
|
||||
|
||||
if (hist == 0 || hist->timestamp == 0)
|
||||
return 0;
|
||||
ts = hist->timestamp;
|
||||
if (ts[0] != history_comment_char)
|
||||
return 0;
|
||||
t = (time_t) atol (ts + 1); /* XXX - should use strtol() here */
|
||||
return t;
|
||||
}
|
||||
|
||||
static char *
|
||||
hist_inittime ()
|
||||
{
|
||||
time_t t;
|
||||
char ts[64], *ret;
|
||||
|
||||
t = (time_t) time ((time_t *)0);
|
||||
#if defined (HAVE_VSNPRINTF) /* assume snprintf if vsnprintf exists */
|
||||
snprintf (ts, sizeof (ts) - 1, "X%lu", (unsigned long) t);
|
||||
#else
|
||||
sprintf (ts, "X%lu", (unsigned long) t);
|
||||
#endif
|
||||
ret = savestring (ts);
|
||||
ret[0] = history_comment_char;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Place STRING at the end of the history list. The data field
|
||||
is set to NULL. */
|
||||
void
|
||||
add_history (string)
|
||||
const char *string;
|
||||
{
|
||||
HIST_ENTRY *temp;
|
||||
|
||||
if (history_stifled && (history_length == history_max_entries))
|
||||
{
|
||||
register int i;
|
||||
|
||||
/* If the history is stifled, and history_length is zero,
|
||||
and it equals history_max_entries, we don't save items. */
|
||||
if (history_length == 0)
|
||||
return;
|
||||
|
||||
/* If there is something in the slot, then remove it. */
|
||||
if (the_history[0])
|
||||
(void) free_history_entry (the_history[0]);
|
||||
|
||||
/* Copy the rest of the entries, moving down one slot. */
|
||||
for (i = 0; i < history_length; i++)
|
||||
the_history[i] = the_history[i + 1];
|
||||
|
||||
history_base++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (history_size == 0)
|
||||
{
|
||||
history_size = DEFAULT_HISTORY_GROW_SIZE;
|
||||
the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
|
||||
history_length = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (history_length == (history_size - 1))
|
||||
{
|
||||
history_size += DEFAULT_HISTORY_GROW_SIZE;
|
||||
the_history = (HIST_ENTRY **)
|
||||
xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
|
||||
}
|
||||
history_length++;
|
||||
}
|
||||
}
|
||||
|
||||
temp = alloc_history_entry (string, hist_inittime ());
|
||||
|
||||
the_history[history_length] = (HIST_ENTRY *)NULL;
|
||||
the_history[history_length - 1] = temp;
|
||||
}
|
||||
|
||||
/* Change the time stamp of the most recent history entry to STRING. */
|
||||
void
|
||||
add_history_time (string)
|
||||
const char *string;
|
||||
{
|
||||
HIST_ENTRY *hs;
|
||||
|
||||
if (string == 0)
|
||||
return;
|
||||
hs = the_history[history_length - 1];
|
||||
FREE (hs->timestamp);
|
||||
hs->timestamp = savestring (string);
|
||||
}
|
||||
|
||||
/* Free HIST and return the data so the calling application can free it
|
||||
if necessary and desired. */
|
||||
histdata_t
|
||||
free_history_entry (hist)
|
||||
HIST_ENTRY *hist;
|
||||
{
|
||||
histdata_t x;
|
||||
|
||||
if (hist == 0)
|
||||
return ((histdata_t) 0);
|
||||
FREE (hist->line);
|
||||
FREE (hist->timestamp);
|
||||
x = hist->data;
|
||||
xfree (hist);
|
||||
return (x);
|
||||
}
|
||||
|
||||
HIST_ENTRY *
|
||||
copy_history_entry (hist)
|
||||
HIST_ENTRY *hist;
|
||||
{
|
||||
HIST_ENTRY *ret;
|
||||
char *ts;
|
||||
|
||||
if (hist == 0)
|
||||
return hist;
|
||||
|
||||
ret = alloc_history_entry (hist->line, (char *)NULL);
|
||||
|
||||
ts = hist->timestamp ? savestring (hist->timestamp) : hist->timestamp;
|
||||
ret->timestamp = ts;
|
||||
|
||||
ret->data = hist->data;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Make the history entry at WHICH have LINE and DATA. This returns
|
||||
the old entry so you can dispose of the data. In the case of an
|
||||
invalid WHICH, a NULL pointer is returned. */
|
||||
HIST_ENTRY *
|
||||
replace_history_entry (which, line, data)
|
||||
int which;
|
||||
const char *line;
|
||||
histdata_t data;
|
||||
{
|
||||
HIST_ENTRY *temp, *old_value;
|
||||
|
||||
if (which < 0 || which >= history_length)
|
||||
return ((HIST_ENTRY *)NULL);
|
||||
|
||||
temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
|
||||
old_value = the_history[which];
|
||||
|
||||
temp->line = savestring (line);
|
||||
temp->data = data;
|
||||
temp->timestamp = savestring (old_value->timestamp);
|
||||
the_history[which] = temp;
|
||||
|
||||
return (old_value);
|
||||
}
|
||||
|
||||
/* Replace the DATA in the specified history entries, replacing OLD with
|
||||
NEW. WHICH says which one(s) to replace: WHICH == -1 means to replace
|
||||
all of the history entries where entry->data == OLD; WHICH == -2 means
|
||||
to replace the `newest' history entry where entry->data == OLD; and
|
||||
WHICH >= 0 means to replace that particular history entry's data, as
|
||||
long as it matches OLD. */
|
||||
void
|
||||
replace_history_data (which,old, new)
|
||||
int which;
|
||||
histdata_t *old, *new;
|
||||
{
|
||||
HIST_ENTRY *entry;
|
||||
register int i, last;
|
||||
|
||||
if (which < -2 || which >= history_length || history_length == 0 || the_history == 0)
|
||||
return;
|
||||
|
||||
if (which >= 0)
|
||||
{
|
||||
entry = the_history[which];
|
||||
if (entry && entry->data == old)
|
||||
entry->data = new;
|
||||
return;
|
||||
}
|
||||
|
||||
last = -1;
|
||||
for (i = 0; i < history_length; i++)
|
||||
{
|
||||
entry = the_history[i];
|
||||
if (entry == 0)
|
||||
continue;
|
||||
if (entry->data == old)
|
||||
{
|
||||
last = i;
|
||||
if (which == -1)
|
||||
entry->data = new;
|
||||
}
|
||||
}
|
||||
if (which == -2 && last >= 0)
|
||||
{
|
||||
entry = the_history[last];
|
||||
entry->data = new; /* XXX - we don't check entry->old */
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove history element WHICH from the history. The removed
|
||||
element is returned to you so you can free the line, data,
|
||||
and containing structure. */
|
||||
HIST_ENTRY *
|
||||
remove_history (which)
|
||||
int which;
|
||||
{
|
||||
HIST_ENTRY *return_value;
|
||||
register int i;
|
||||
|
||||
if (which < 0 || which >= history_length || history_length == 0 || the_history == 0)
|
||||
return ((HIST_ENTRY *)NULL);
|
||||
|
||||
return_value = the_history[which];
|
||||
|
||||
for (i = which; i < history_length; i++)
|
||||
the_history[i] = the_history[i + 1];
|
||||
|
||||
history_length--;
|
||||
|
||||
return (return_value);
|
||||
}
|
||||
|
||||
/* Stifle the history list, remembering only MAX number of lines. */
|
||||
void
|
||||
stifle_history (max)
|
||||
int max;
|
||||
{
|
||||
register int i, j;
|
||||
|
||||
if (max < 0)
|
||||
max = 0;
|
||||
|
||||
if (history_length > max)
|
||||
{
|
||||
/* This loses because we cannot free the data. */
|
||||
for (i = 0, j = history_length - max; i < j; i++)
|
||||
free_history_entry (the_history[i]);
|
||||
|
||||
history_base = i;
|
||||
for (j = 0, i = history_length - max; j < max; i++, j++)
|
||||
the_history[j] = the_history[i];
|
||||
the_history[j] = (HIST_ENTRY *)NULL;
|
||||
history_length = j;
|
||||
}
|
||||
|
||||
history_stifled = 1;
|
||||
max_input_history = history_max_entries = max;
|
||||
}
|
||||
|
||||
/* Stop stifling the history. This returns the previous maximum
|
||||
number of history entries. The value is positive if the history
|
||||
was stifled, negative if it wasn't. */
|
||||
int
|
||||
unstifle_history ()
|
||||
{
|
||||
if (history_stifled)
|
||||
{
|
||||
history_stifled = 0;
|
||||
return (history_max_entries);
|
||||
}
|
||||
else
|
||||
return (-history_max_entries);
|
||||
}
|
||||
|
||||
int
|
||||
history_is_stifled ()
|
||||
{
|
||||
return (history_stifled);
|
||||
}
|
||||
|
||||
void
|
||||
clear_history ()
|
||||
{
|
||||
register int i;
|
||||
|
||||
/* This loses because we cannot free the data. */
|
||||
for (i = 0; i < history_length; i++)
|
||||
{
|
||||
free_history_entry (the_history[i]);
|
||||
the_history[i] = (HIST_ENTRY *)NULL;
|
||||
}
|
||||
|
||||
history_offset = history_length = 0;
|
||||
}
|
||||
@@ -263,6 +263,29 @@ rl_call_last_kbd_macro (count, ignore)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rl_print_last_kbd_macro (count, ignore)
|
||||
int count, ignore;
|
||||
{
|
||||
char *m;
|
||||
|
||||
if (current_macro == 0)
|
||||
{
|
||||
rl_ding ();
|
||||
return 0;
|
||||
}
|
||||
m = _rl_untranslate_macro_value (current_macro, 1);
|
||||
rl_crlf ();
|
||||
printf ("%s", m);
|
||||
fflush (stdout);
|
||||
rl_crlf ();
|
||||
FREE (m);
|
||||
rl_forced_update_display ();
|
||||
rl_display_fixed = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
rl_push_macro_input (macro)
|
||||
char *macro;
|
||||
|
||||
+23
-1
@@ -234,7 +234,7 @@ rl_end_kbd_macro (count, ignore)
|
||||
return -1;
|
||||
}
|
||||
|
||||
current_macro_index -= rl_key_sequence_length - 1;
|
||||
current_macro_index -= rl_key_sequence_length;
|
||||
current_macro[current_macro_index] = '\0';
|
||||
|
||||
RL_UNSETSTATE(RL_STATE_MACRODEF);
|
||||
@@ -263,6 +263,28 @@ rl_call_last_kbd_macro (count, ignore)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rl_print_last_kbd_macro (count, ignore)
|
||||
int count, ignore;
|
||||
{
|
||||
char *m;
|
||||
|
||||
if (current_macro == 0)
|
||||
{
|
||||
rl_ding ();
|
||||
return 0;
|
||||
}
|
||||
m = _rl_untranslate_macro_value (current_macro, 1);
|
||||
rl_crlf ();
|
||||
printf ("%s", m);
|
||||
rl_crlf ();
|
||||
FREE (m);
|
||||
rl_forced_update_display ();
|
||||
rl_display_fixed = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
rl_push_macro_input (macro)
|
||||
char *macro;
|
||||
|
||||
@@ -185,6 +185,7 @@ extern int rl_forward_search_history PARAMS((int, int));
|
||||
extern int rl_start_kbd_macro PARAMS((int, int));
|
||||
extern int rl_end_kbd_macro PARAMS((int, int));
|
||||
extern int rl_call_last_kbd_macro PARAMS((int, int));
|
||||
extern int rl_print_last_kbd_macro PARAMS((int, int));
|
||||
|
||||
/* Bindable undo commands. */
|
||||
extern int rl_revert_line PARAMS((int, int));
|
||||
|
||||
@@ -577,6 +577,7 @@ extern Keymap rl_binding_keymap;
|
||||
|
||||
extern int rl_executing_key;
|
||||
extern char *rl_executing_keyseq;
|
||||
extern int rl_key_sequence_length;
|
||||
|
||||
/* Display variables. */
|
||||
/* If non-zero, readline will erase the entire line, including any prompt,
|
||||
|
||||
@@ -246,6 +246,7 @@ extern void _rl_callback_data_dispose PARAMS((_rl_callback_generic_arg *));
|
||||
#endif /* READLINE_CALLBACKS */
|
||||
|
||||
/* bind.c */
|
||||
extern char *_rl_untranslate_macro_value PARAMS((char *, int));
|
||||
|
||||
/* complete.c */
|
||||
extern void _rl_reset_completion_state PARAMS((void));
|
||||
|
||||
@@ -185,7 +185,6 @@ extern int rl_visible_stats;
|
||||
extern int rl_line_buffer_len;
|
||||
extern int rl_arg_sign;
|
||||
extern int rl_visible_prompt_length;
|
||||
extern int rl_key_sequence_length;
|
||||
extern int rl_byte_oriented;
|
||||
|
||||
/* display.c */
|
||||
@@ -247,6 +246,7 @@ extern void _rl_callback_data_dispose PARAMS((_rl_callback_generic_arg *));
|
||||
#endif /* READLINE_CALLBACKS */
|
||||
|
||||
/* bind.c */
|
||||
extern char *_rl_untranslate_macro_value PARAMS ((char *, int));
|
||||
|
||||
/* complete.c */
|
||||
extern void _rl_reset_completion_state PARAMS((void));
|
||||
|
||||
@@ -908,6 +908,9 @@ _rl_insert_next (count)
|
||||
if (c < 0)
|
||||
return -1;
|
||||
|
||||
if (RL_ISSTATE (RL_STATE_MACRODEF))
|
||||
_rl_add_macro_char (c);
|
||||
|
||||
#if defined (HANDLE_SIGNALS)
|
||||
if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
|
||||
_rl_restore_tty_signals ();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -316,7 +316,7 @@ ansic_wshouldquote (string)
|
||||
}
|
||||
|
||||
free (wcstr);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+1
-1
@@ -793,7 +793,7 @@ make_function_def (name, command, lineno, lstart)
|
||||
bind_function_def (name->word, temp);
|
||||
#endif
|
||||
|
||||
temp->source_file = 0;
|
||||
temp->source_file = temp->source_file ? savestring (temp->source_file) : 0;
|
||||
return (make_command (cm_function_def, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
|
||||
@@ -4833,6 +4833,14 @@ find_reserved_word (tokstr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* An interface to let the rest of the shell (primarily the completion
|
||||
system) know what the parser is expecting. */
|
||||
int
|
||||
parser_in_command_position ()
|
||||
{
|
||||
return (command_token_position (last_read_token));
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if defined (READLINE)
|
||||
/* Called after each time readline is called. This insures that whatever
|
||||
|
||||
Reference in New Issue
Block a user