commit bash-20100525 snapshot

This commit is contained in:
Chet Ramey
2011-12-12 21:59:37 -05:00
parent eb0b2ad86b
commit 6faad6254a
160 changed files with 12731 additions and 588 deletions
+214
View File
@@ -9831,3 +9831,217 @@ lib/sh/strtrans.c
doc/{bash.1,bashref.texi}
- document new \u and \U escape sequences for $'...' and echo (printf
defers to the system's man page or Posix)
5/24
----
execute_cmd.c
- change execute_disk_command to return a status, instead of just
leaving it in `last_command_exit_value', since the parent's return
value is sometimes uses (e.g., when a restricted shell refuses to
run a command with a `/'). Fixes bug reported by David Pitt
<David.Pitt@anz.com>
5/25
----
bashline.c
- change bash completion functions to save and restore the value of
rl_ignore_some_completions_function, and set it to the bash default
of filename_completion_ignore where appropriate. Fixes bug
reported by Henning Bekel <h.bekel@googlemail.com>
variables.c
- new convenience function: find_global_variable (name). Looks for
NAME in the global variables table, skipping any local and
temporary environment variables
builtins/declare.def
- add new -g option to declare/typeset/local, forces variables to be
created or modified at the global scope when executing inside a
shell function. Requested by many, most recently by
konsolebox@gmail.com
5/27
----
test.c
- added new `-v var' unary test operator; returns TRUE if var is set
(i.e., has been assigned a value). Works in both test builtin and
[[ conditional command
doc/{bash.1,bashref.texi}
- documented new `-v var' unary conditional operator
tests/test.tests
- added tests for new -v var operator
builtins/kill.def
- change kill builtin so -PID (pgrp specification) following a
-s sig or -n sig option is not interpreted as a signal specification.
Fixes bug reported by Roman Rakus <rrakus@redhat.com>
builtins/evalstring.c
- in parse_and_execute, if parse_command() returns non-zero,
indicating a parse error, exit the shell if the conditions require
a posix-mode non-interactive shell to abort (parse error in a `.'
script or eval string). Bash-4.1 only printed a warning. This is
from Austin Group interp 114
doc/bashref.texi
- add note to the posix mode section of the texinfo manual noting
the changed behavior for `.' and `eval'
parse.y
- change time_command_acceptable to allow TIME token to appear after
BANG token (to allow `! time foo', which is supposed to be valid)
- change pipeline_command production to allow multiple instances of
`!' (which toggle inverting the return status) and `time' (which
have no effect)
execute_cmd.c
- In posix mode, `time' without a following pipeline prints the
elapsed user, system, and real time for the shell and its
children since the shell was invoked.
It's like `times' but obeys the setting of TIMEFORMAT. A future
revision of Posix will require this
doc/{bashref.texi,bash.1}
- document new posix mode use of `time'
parse.y
- add production to pipeline_command that permits `!' by itself to
be equivalent to `false' (and, with the changes above, permits
`! !' to be roughly equivalent to `true'). A future revision of
Posix will require this
5/28
----
parse.y
- fix \W prompt expansion to use memmove instead of strcpy, since the
source and target strings overlap (though you think it wouldn't
matter, since the overlapping regions are never touched at the same
time). Fixes bug reported by Stéphane Jourdoi
<sjourdois@gmail.com>
parse.y
- Posix interp 217 states that $(( must be parsed first as an
arithmetic expansion, so avoid attempting to parse it as a nested
command substitution. Fixes bug reported by several, most recently
<jwm@horde.net>
subst.c
- change extract_delimited_string to process nested $( as a possible
command substitution, but only if already parsing an arithmetic
expansion. Rest of fix for Posix interp 217
- change parameter_brace_expand_rhs to make the := expansion operator
perform quote removal and both assign the result to the variable and
return it as the result of the expansion, rather than assign the
value after quote removal but return the value before quote removal.
Posix interp 221
- introduce new internal quoting flag: Q_DOLBRACE. Denotes a double-
quoted ${...} expansion. In this case, Posix interp 221 requires
that a backslash quoting an embedded `}' be removed, even though it's
not one of the characters marked as special inside double quotes.
Set in parameter_brace_expand, used by expand_word_internal.
parse.y
- introduce new parsing state, P_DOLBRACE, set when parsing a ${...}
expansion
- set a "dolbrace operator state" in parse_matched_pair to decide
whether the lexer is reading the param, op, or word in
${paramOPword}. Will be used to decide whether or not to treat
single quotes specially in a double-quoted "${...}
5/29
----
parse.y
- change parse_matched_pair so that a single quote appearing in a
double-quoted ${...} expansion is not special unless the expansion
operator is `#[#]' or `%[%]'. Posix interp 221
subst.c
- change string_extract_double_quoted so that a single quote appearing
in a double-quoted ${...} expansion is not special unless the
expansion operator is `#[#]' or `%[%]'. Posix interp 221
doc/bashref.texi
- document posix-mode effects of Posix interp 221
- add section describing GNU parallel as requested by Stallman
lib/readline/complete.c
- broke code that compares filenames read from the file system (and
possibly converted) to words being completed out into a separate
function: complete_fncmp
- augment complete_fncmp to treat hyphen and underscore as equivalent
when comparing filenames if _rl_completion_case_map is set
lib/readline/rlprivate.h
- new extern declaration for _rl_completion_case_map
lib/readline/util.c
- change _rl_strnicmp to return the difference between the characters,
like strcasecmp, and not modify the pointers it is passed
- change _rl_stricmp to not modify the pointers it is passed
lib/readline/bind.c
- new bindable variable, "completion-case-map", toggles value of
_rl_completion_case_map
lib/readline/doc/{rluser.texi,readline.3}
- document new bindable readline variable "completion-case-map"
execute_cmd.c
- change execute_function to reset funcnest and jump back to top level
if funcnest exceeds funcnest_max
- use funcnest_max as a max function nesting level, if set to numeric
value greater than 0 (defaults to 0, so inactive)
variables.c
- new variable FUNCNEST, controls funcnest_max value if set to numeric
value > 0
sig.c
- reset funcnest to 0 when throw_to_top_level occurs
doc/{bash.1,bashref.texi}
- document FUNCNEST variable and its effect on function execution
lib/readline/funmap.c
- add new bindable command names to avoid case-insensitive matching
problems between, for instance, vi-fword and vi-fWord:
vi-forward-word
vi-forward-bigword
vi-backward-word
vi-backward-bigword
vi-end-word
vi-end-bigword
Suggested in a different form in 2006 (!) by Servatius Brandt
<servatius.brandt@arcor.de>
builtins/mapfile.def
- run_callback now takes a new third argument: curline, the line
currently being read and about to be assigned
- the callback function/command now takes an additional argument:
the line to be assigned to the array index. Feature suggested by
Dennis Williamson <dennistwilliamson@gmail.com>
doc/{bash.1,bashref.texi}
- document new additional `line' argument to mapfile callback
5/30
----
builtins/printf.def
- add new %(fmt)T format specifier, where FMT is a strftime format.
Argument is number of seconds since the epoch, with -1 meaning
current time (roughly date +%s) and -2 meaning shell start time
(roughly $SECONDS, unless it's been assigned a value or unset).
Fieldwidth and precision are preserved, strftime result is printed
as with %[-][[fieldwidth][.[precision]]]s
doc/{bash.1,bashref.texi}
- document new %(datefmt)T printf format specifier and special
arguments
builtins/hash.def
- don't permit programs with slashes to be entered into the hash table
at all, even with the -p option. Inconsistency pointed out by
Jan Schampera <jan.schampera@web.de>
+214
View File
@@ -9827,3 +9827,217 @@ builtins/printf.def
lib/sh/strtrans.c
- add code to handle \u and \U escapes as unicode characters, works for
both `echo -e' and $'...'
doc/{bash.1,bashref.texi}
- document new \u and \U escape sequences for $'...' and echo (printf
defers to the system's man page or Posix)
5/24
----
execute_cmd.c
- change execute_disk_command to return a status, instead of just
leaving it in `last_command_exit_value', since the parent's return
value is sometimes uses (e.g., when a restricted shell refuses to
run a command with a `/'). Fixes bug reported by David Pitt
<David.Pitt@anz.com>
5/25
----
bashline.c
- change bash completion functions to save and restore the value of
rl_ignore_some_completions_function, and set it to the bash default
of filename_completion_ignore where appropriate. Fixes bug
reported by Henning Bekel <h.bekel@googlemail.com>
variables.c
- new convenience function: find_global_variable (name). Looks for
NAME in the global variables table, skipping any local and
temporary environment variables
builtins/declare.def
- add new -g option to declare/typeset/local, forces variables to be
created or modified at the global scope when executing inside a
shell function. Requested by many, most recently by
konsolebox@gmail.com
5/27
----
test.c
- added new `-v var' unary test operator; returns TRUE if var is set
(i.e., has been assigned a value). Works in both test builtin and
[[ conditional command
doc/{bash.1,bashref.texi}
- documented new `-v var' unary conditional operator
tests/test.tests
- added tests for new -v var operator
builtins/kill.def
- change kill builtin so -PID (pgrp specification) following a
-s sig or -n sig option is not interpreted as a signal specification.
Fixes bug reported by Roman Rakus <rrakus@redhat.com>
builtins/evalstring.c
- in parse_and_execute, if parse_command() returns non-zero,
indicating a parse error, exit the shell if the conditions require
a posix-mode non-interactive shell to abort (parse error in a `.'
script or eval string). Bash-4.1 only printed a warning. This is
from Austin Group interp 114
doc/bashref.texi
- add note to the posix mode section of the texinfo manual noting
the changed behavior for `.' and `eval'
parse.y
- change time_command_acceptable to allow TIME token to appear after
BANG token (to allow `! time foo', which is supposed to be valid)
- change pipeline_command production to allow multiple instances of
`!' (which toggle inverting the return status) and `time' (which
have no effect)
execute_cmd.c
- In posix mode, `time' without a following pipeline prints the
elapsed user, system, and real time for the shell and its
children since the shell was invoked.
It's like `times' but obeys the setting of TIMEFORMAT. A future
revision of Posix will require this
doc/{bashref.texi,bash.1}
- document new posix mode use of `time'
parse.y
- add production to pipeline_command that permits `!' by itself to
be equivalent to `false' (and, with the changes above, permits
`! !' to be roughly equivalent to `true'). A future revision of
Posix will require this
5/28
----
parse.y
- fix \W prompt expansion to use memmove instead of strcpy, since the
source and target strings overlap (though you think it wouldn't
matter, since the overlapping regions are never touched at the same
time). Fixes bug reported by Stéphane Jourdoi
<sjourdois@gmail.com>
parse.y
- Posix interp 217 states that $(( must be parsed first as an
arithmetic expansion, so avoid attempting to parse it as a nested
command substitution. Fixes bug reported by several, most recently
<jwm@horde.net>
subst.c
- change extract_delimited_string to process nested $( as a possible
command substitution, but only if already parsing an arithmetic
expansion. Rest of fix for Posix interp 217
- change parameter_brace_expand_rhs to make the := expansion operator
perform quote removal and both assign the result to the variable and
return it as the result of the expansion, rather than assign the
value after quote removal but return the value before quote removal.
Posix interp 221
- introduce new internal quoting flag: Q_DOLBRACE. Denotes a double-
quoted ${...} expansion. In this case, Posix interp 221 requires
that a backslash quoting an embedded `}' be removed, even though it's
not one of the characters marked as special inside double quotes.
Set in parameter_brace_expand, used by expand_word_internal.
parse.y
- introduce new parsing state, P_DOLBRACE, set when parsing a ${...}
expansion
- set a "dolbrace operator state" in parse_matched_pair to decide
whether the lexer is reading the param, op, or word in
${paramOPword}. Will be used to decide whether or not to treat
single quotes specially in a double-quoted "${...}
5/29
----
parse.y
- change parse_matched_pair so that a single quote appearing in a
double-quoted ${...} expansion is not special unless the expansion
operator is `#[#]' or `%[%]'. Posix interp 221
subst.c
- change string_extract_double_quoted so that a single quote appearing
in a double-quoted ${...} expansion is not special unless the
expansion operator is `#[#]' or `%[%]'. Posix interp 221
doc/bashref.texi
- document posix-mode effects of Posix interp 221
- add section describing GNU parallel as requested by Stallman
lib/readline/complete.c
- broke code that compares filenames read from the file system (and
possibly converted) to words being completed out into a separate
function: complete_fncmp
- augment complete_fncmp to treat hyphen and underscore as equivalent
when comparing filenames if _rl_completion_case_map is set
lib/readline/rlprivate.h
- new extern declaration for _rl_completion_case_map
lib/readline/util.c
- change _rl_strnicmp to return the difference between the characters,
like strcasecmp, and not modify the pointers it is passed
- change _rl_stricmp to not modify the pointers it is passed
lib/readline/bind.c
- new bindable variable, "completion-case-map", toggles value of
_rl_completion_case_map
lib/readline/doc/{rluser.texi,readline.3}
- document new bindable readline variable "completion-case-map"
execute_cmd.c
- change execute_function to reset funcnest and jump back to top level
if funcnest exceeds funcnest_max
- use funcnest_max as a max function nesting level, if set to numeric
value greater than 0 (defaults to 0, so inactive)
variables.c
- new variable FUNCNEST, controls funcnest_max value if set to numeric
value > 0
sig.c
- reset funcnest to 0 when throw_to_top_level occurs
doc/{bash.1,bashref.texi}
- document FUNCNEST variable and its effect on function execution
lib/readline/funmap.c
- add new bindable command names to avoid case-insensitive matching
problems between, for instance, vi-fword and vi-fWord:
vi-forward-word
vi-forward-bigword
vi-backward-word
vi-backward-bigword
vi-end-word
vi-end-bigword
Suggested in a different form in 2006 (!) by Servatius Brandt
<servatius.brandt@arcor.de>
builtins/mapfile.def
- run_callback now takes a new third argument: curline, the line
currently being read and about to be assigned
- the callback function/command now takes an additional argument:
the line to be assigned to the array index. Feature suggested by
Dennis Williamson <dennistwilliamson@gmail.com>
doc/{bash.1,bashref.texi}
- document new additional `line' argument to mapfile callback
5/30
----
builtins/printf.def
- add new %(fmt)T format specifier, where FMT is a strftime format.
Argument is number of seconds since the epoch, with -1 meaning
current time (roughly date +%s) and -2 meaning shell start time
(roughly $SECONDS, unless it's been assigned a value or unset).
Fieldwidth and precision are preserved, strftime result is printed
as with %[-][[fieldwidth][.[precision]]]s
doc/{bash.1,bashref.texi}
- document new %(datefmt)T printf format specifier and special
arguments
+1 -1
View File
@@ -1,6 +1,6 @@
/* sigs - print signal dispositions for a process */
/* Copyright (C) 1990-2009 Free Software Foundation, Inc.
/* Copyright (C) 1990-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+1 -1
View File
@@ -21,7 +21,7 @@
#include <signal.h>
#include <stdio.h>
extern char *sys_siglist[];
extern const char * const sys_siglist[];
typedef void sighandler();
+7
View File
@@ -799,6 +799,7 @@ tests/comsub-eof.right f
tests/comsub-posix.tests f
tests/comsub-posix.right f
tests/comsub-posix1.sub f
tests/comsub-posix2.sub f
tests/cond.tests f
tests/cond.right f
tests/cond-regexp.sub f
@@ -855,6 +856,7 @@ tests/func.right f
tests/func1.sub f
tests/func2.sub f
tests/func3.sub f
tests/func4.sub f
tests/getopts.tests f
tests/getopts.right f
tests/getopts1.sub f
@@ -932,13 +934,17 @@ tests/nquote5.tests f
tests/nquote5.right f
tests/posix2.tests f
tests/posix2.right f
tests/posixexp.tests f
tests/posixexp.right f
tests/posixpat.tests f
tests/posixpat.right f
tests/prec.right f
tests/precedence f
tests/printf.tests f
tests/printf.right f
tests/printf1.sub f
tests/printf2.sub f
tests/printf3.sub f
tests/quote.tests f
tests/quote.right f
tests/read.tests f
@@ -1021,6 +1027,7 @@ tests/run-nquote3 f
tests/run-nquote4 f
tests/run-nquote5 f
tests/run-posix2 f
tests/run-posixexp f
tests/run-posixpat f
tests/run-precedence f
tests/run-printf f
+8
View File
@@ -436,6 +436,7 @@ lib/sh/timeval.c f
lib/sh/tmpfile.c f
lib/sh/uconvert.c f
lib/sh/ufuncs.c f
lib/sh/unicode.c f
lib/sh/vprint.c f
lib/sh/wcsdup.c f
lib/sh/winsize.c f
@@ -798,6 +799,7 @@ tests/comsub-eof.right f
tests/comsub-posix.tests f
tests/comsub-posix.right f
tests/comsub-posix1.sub f
tests/comsub-posix2.sub f
tests/cond.tests f
tests/cond.right f
tests/cond-regexp.sub f
@@ -854,6 +856,7 @@ tests/func.right f
tests/func1.sub f
tests/func2.sub f
tests/func3.sub f
tests/func4.sub f
tests/getopts.tests f
tests/getopts.right f
tests/getopts1.sub f
@@ -931,6 +934,8 @@ tests/nquote5.tests f
tests/nquote5.right f
tests/posix2.tests f
tests/posix2.right f
tests/posixexp.tests f
tests/posixexp.right f
tests/posixpat.tests f
tests/posixpat.right f
tests/prec.right f
@@ -938,6 +943,7 @@ tests/precedence f
tests/printf.tests f
tests/printf.right f
tests/printf2.sub f
tests/printf3.sub f
tests/quote.tests f
tests/quote.right f
tests/read.tests f
@@ -1020,6 +1026,7 @@ tests/run-nquote3 f
tests/run-nquote4 f
tests/run-nquote5 f
tests/run-posix2 f
tests/run-posixexp f
tests/run-posixpat f
tests/run-precedence f
tests/run-printf f
@@ -1066,6 +1073,7 @@ tests/type.tests f
tests/type.right f
tests/type1.sub f
tests/type2.sub f
tests/type3.sub f
tests/varenv.right f
tests/varenv.sh f
tests/varenv1.sub f
+1 -1
View File
@@ -1,6 +1,6 @@
/* arrayfunc.c -- High-level array functions used by other parts of the shell. */
/* Copyright (C) 2001-2009 Free Software Foundation, Inc.
/* Copyright (C) 2001-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+2 -2
View File
@@ -883,7 +883,7 @@ array_value_internal (s, quoted, allow_all, rtype, indp)
err_badarraysub (s);
return ((char *)NULL);
}
else if (var == 0 || value_cell (var) == 0)
else if (var == 0 || value_cell (var) == 0) /* XXX - check for invisible_p(var) ? */
return ((char *)NULL);
else if (array_p (var) == 0 && assoc_p (var) == 0)
l = add_string_to_list (value_cell (var), (WORD_LIST *)NULL);
@@ -943,7 +943,7 @@ index_error:
goto index_error;
}
if (var == 0)
if (var == 0 || value_cell (var) == 0) /* XXX - check invisible_p(var) ? */
return ((char *)NULL);
if (array_p (var) == 0 && assoc_p (var) == 0)
return (ind == 0 ? value_cell (var) : (char *)NULL);
+1 -1
View File
@@ -1,6 +1,6 @@
/* arrayfunc.h -- declarations for miscellaneous array functions in arrayfunc.c */
/* Copyright (C) 2001-2009 Free Software Foundation, Inc.
/* Copyright (C) 2001-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+1 -1
View File
@@ -51,7 +51,7 @@ extern void print_assoc_assignment __P((SHELL_VAR *, int));
extern arrayind_t array_expand_index __P((char *, int));
extern int valid_array_reference __P((char *));
extern char *array_value __P((char *, int, int *));
extern char *array_value __P((char *, int, int *, arrayind_t *));
extern char *get_array_value __P((char *, int, int *, arrayind_t *));
extern char *array_keys __P((char *, int));
+1 -1
View File
@@ -1,6 +1,6 @@
/* bashhist.c -- bash interface to the GNU history library. */
/* Copyright (C) 1993-2009 Free Software Foundation, Inc.
/* Copyright (C) 1993-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
-3
View File
@@ -733,7 +733,6 @@ bash_add_history (line)
if (command_oriented_history && current_command_line_count > 1)
{
chars_to_add = literal_history ? "\n" : history_delimiting_chars (line);
itrace("bash_add_history: `%s' PST_HEREDOC = %d chars_to_add = `%s'", line, (parser_state&PST_HEREDOC), chars_to_add);
using_history ();
current = previous_history ();
@@ -753,14 +752,12 @@ itrace("bash_add_history: `%s' PST_HEREDOC = %d chars_to_add = `%s'", line, (par
chars_to_add = "";
}
#if 1 /* XXX - bash-4.2 */
/* If we're not in some kind of quoted construct, the current history
entry ends with a newline, and we're going to add a semicolon,
don't. In some cases, it results in a syntax error (e.g., before
a close brace), and it should not be needed. */
if (dstack.delimiter_depth == 0 && current->line[curlen - 1] == '\n' && *chars_to_add == ';')
chars_to_add++;
#endif
new_line = (char *)xmalloc (1
+ curlen
+18 -1
View File
@@ -1,6 +1,6 @@
/* bashline.c -- Bash's interface to the readline library. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -2876,12 +2876,15 @@ dynamic_complete_history (count, key)
int r;
rl_compentry_func_t *orig_func;
rl_completion_func_t *orig_attempt_func;
rl_compignore_func_t *orig_ignore_func;
orig_func = rl_completion_entry_function;
orig_attempt_func = rl_attempted_completion_function;
orig_ignore_func = rl_ignore_some_completions_function;
rl_completion_entry_function = history_completion_generator;
rl_attempted_completion_function = (rl_completion_func_t *)NULL;
rl_ignore_some_completions_function = filename_completion_ignore;
/* XXX - use rl_completion_mode here? */
if (rl_last_func == dynamic_complete_history)
@@ -2891,6 +2894,8 @@ dynamic_complete_history (count, key)
rl_completion_entry_function = orig_func;
rl_attempted_completion_function = orig_attempt_func;
rl_ignore_some_completions_function = orig_ignore_func;
return r;
}
@@ -2901,14 +2906,17 @@ bash_dabbrev_expand (count, key)
int r, orig_suppress, orig_sort;
rl_compentry_func_t *orig_func;
rl_completion_func_t *orig_attempt_func;
rl_compignore_func_t *orig_ignore_func;
orig_func = rl_menu_completion_entry_function;
orig_attempt_func = rl_attempted_completion_function;
orig_ignore_func = rl_ignore_some_completions_function;
orig_suppress = rl_completion_suppress_append;
orig_sort = rl_sort_completion_matches;
rl_menu_completion_entry_function = history_completion_generator;
rl_attempted_completion_function = (rl_completion_func_t *)NULL;
rl_ignore_some_completions_function = filename_completion_ignore;
rl_filename_completion_desired = 0;
rl_completion_suppress_append = 1;
rl_sort_completion_matches = 0;
@@ -2923,6 +2931,7 @@ bash_dabbrev_expand (count, key)
rl_last_func = bash_dabbrev_expand;
rl_menu_completion_entry_function = orig_func;
rl_attempted_completion_function = orig_attempt_func;
rl_ignore_some_completions_function = orig_ignore_func;
rl_completion_suppress_append = orig_suppress;
rl_sort_completion_matches = orig_sort;
@@ -2972,16 +2981,19 @@ bash_complete_filename_internal (what_to_do)
rl_compentry_func_t *orig_func;
rl_completion_func_t *orig_attempt_func;
rl_icppfunc_t *orig_dir_func;
rl_compignore_func_t *orig_ignore_func;
/*const*/ char *orig_rl_completer_word_break_characters;
int r;
orig_func = rl_completion_entry_function;
orig_attempt_func = rl_attempted_completion_function;
orig_dir_func = rl_directory_completion_hook;
orig_ignore_func = rl_ignore_some_completions_function;
orig_rl_completer_word_break_characters = rl_completer_word_break_characters;
rl_completion_entry_function = rl_filename_completion_function;
rl_attempted_completion_function = (rl_completion_func_t *)NULL;
rl_directory_completion_hook = (rl_icppfunc_t *)NULL;
rl_ignore_some_completions_function = filename_completion_ignore;
rl_completer_word_break_characters = " \t\n\"\'";
r = rl_complete_internal (what_to_do);
@@ -2989,6 +3001,7 @@ bash_complete_filename_internal (what_to_do)
rl_completion_entry_function = orig_func;
rl_attempted_completion_function = orig_attempt_func;
rl_directory_completion_hook = orig_dir_func;
rl_ignore_some_completions_function = orig_ignore_func;
rl_completer_word_break_characters = orig_rl_completer_word_break_characters;
return r;
@@ -3166,17 +3179,21 @@ bash_specific_completion (what_to_do, generator)
{
rl_compentry_func_t *orig_func;
rl_completion_func_t *orig_attempt_func;
rl_compignore_func_t *orig_ignore_func;
int r;
orig_func = rl_completion_entry_function;
orig_attempt_func = rl_attempted_completion_function;
orig_ignore_func = rl_ignore_some_completions_function;
rl_completion_entry_function = generator;
rl_attempted_completion_function = NULL;
rl_ignore_some_completions_function = orig_ignore_func;
r = rl_complete_internal (what_to_do);
rl_completion_entry_function = orig_func;
rl_attempted_completion_function = orig_attempt_func;
rl_ignore_some_completions_function = orig_ignore_func;
return r;
}
+21 -4
View File
@@ -175,7 +175,7 @@ static char **prog_complete_matches;
extern int hist_verify;
#endif
extern int current_command_line_count, fc_command_line_count;
extern int current_command_line_count, saved_command_line_count;
extern int last_command_exit_value;
extern int array_needs_making;
extern int posixly_correct, no_symbolic_links;
@@ -863,11 +863,11 @@ edit_and_execute_command (count, c, editing_mode, edit_command)
char *edit_command;
{
char *command, *metaval;
int r, cclc, rrs, metaflag;
int r, rrs, metaflag;
sh_parser_state_t ps;
rrs = rl_readline_state;
cclc = current_command_line_count;
saved_command_line_count = current_command_line_count;
/* Accept the current line. */
rl_newline (1, c);
@@ -907,7 +907,7 @@ edit_and_execute_command (count, c, editing_mode, edit_command)
if (rl_prep_term_function)
(*rl_prep_term_function) (metaflag);
current_command_line_count = cclc;
current_command_line_count = saved_command_line_count;
/* Now erase the contents of the current line and undo the effects of the
rl_accept_line() above. We don't even want to make the text we just
@@ -2876,12 +2876,15 @@ dynamic_complete_history (count, key)
int r;
rl_compentry_func_t *orig_func;
rl_completion_func_t *orig_attempt_func;
rl_compignore_func_t *orig_ignore_func;
orig_func = rl_completion_entry_function;
orig_attempt_func = rl_attempted_completion_function;
orig_ignore_func = rl_ignore_some_completions_function;
rl_completion_entry_function = history_completion_generator;
rl_attempted_completion_function = (rl_completion_func_t *)NULL;
rl_ignore_some_completions_function = filename_completion_ignore;
/* XXX - use rl_completion_mode here? */
if (rl_last_func == dynamic_complete_history)
@@ -2891,6 +2894,8 @@ dynamic_complete_history (count, key)
rl_completion_entry_function = orig_func;
rl_attempted_completion_function = orig_attempt_func;
rl_ignore_some_completions_function = orig_ignore_func;
return r;
}
@@ -2901,14 +2906,17 @@ bash_dabbrev_expand (count, key)
int r, orig_suppress, orig_sort;
rl_compentry_func_t *orig_func;
rl_completion_func_t *orig_attempt_func;
rl_compignore_func_t *orig_ignore_func;
orig_func = rl_menu_completion_entry_function;
orig_attempt_func = rl_attempted_completion_function;
orig_ignore_func = rl_ignore_some_completions_function;
orig_suppress = rl_completion_suppress_append;
orig_sort = rl_sort_completion_matches;
rl_menu_completion_entry_function = history_completion_generator;
rl_attempted_completion_function = (rl_completion_func_t *)NULL;
rl_ignore_some_completions_function = filename_completion_ignore;
rl_filename_completion_desired = 0;
rl_completion_suppress_append = 1;
rl_sort_completion_matches = 0;
@@ -2923,6 +2931,7 @@ bash_dabbrev_expand (count, key)
rl_last_func = bash_dabbrev_expand;
rl_menu_completion_entry_function = orig_func;
rl_attempted_completion_function = orig_attempt_func;
rl_ignore_some_completions_function = orig_ignore_func;
rl_completion_suppress_append = orig_suppress;
rl_sort_completion_matches = orig_sort;
@@ -2972,16 +2981,19 @@ bash_complete_filename_internal (what_to_do)
rl_compentry_func_t *orig_func;
rl_completion_func_t *orig_attempt_func;
rl_icppfunc_t *orig_dir_func;
rl_compignore_func_t *orig_ignore_func;
/*const*/ char *orig_rl_completer_word_break_characters;
int r;
orig_func = rl_completion_entry_function;
orig_attempt_func = rl_attempted_completion_function;
orig_dir_func = rl_directory_completion_hook;
orig_ignore_func = rl_ignore_some_completions_function;
orig_rl_completer_word_break_characters = rl_completer_word_break_characters;
rl_completion_entry_function = rl_filename_completion_function;
rl_attempted_completion_function = (rl_completion_func_t *)NULL;
rl_directory_completion_hook = (rl_icppfunc_t *)NULL;
rl_ignore_some_completions_function = filename_completion_ignore;
rl_completer_word_break_characters = " \t\n\"\'";
r = rl_complete_internal (what_to_do);
@@ -2989,6 +3001,7 @@ bash_complete_filename_internal (what_to_do)
rl_completion_entry_function = orig_func;
rl_attempted_completion_function = orig_attempt_func;
rl_directory_completion_hook = orig_dir_func;
rl_ignore_some_completions_function = orig_ignore_func;
rl_completer_word_break_characters = orig_rl_completer_word_break_characters;
return r;
@@ -3166,17 +3179,21 @@ bash_specific_completion (what_to_do, generator)
{
rl_compentry_func_t *orig_func;
rl_completion_func_t *orig_attempt_func;
rl_compignore_func_t *orig_ignore_func;
int r;
orig_func = rl_completion_entry_function;
orig_attempt_func = rl_attempted_completion_function;
orig_ignore_func = rl_ignore_some_completions_function;
rl_completion_entry_function = generator;
rl_attempted_completion_function = NULL;
rl_ignore_some_completions_function = orig_ignore_func;
r = rl_complete_internal (what_to_do);
rl_completion_entry_function = orig_func;
rl_attempted_completion_function = orig_attempt_func;
rl_ignore_some_completions_function = orig_ignore_func;
return r;
}
+1 -1
View File
@@ -1,7 +1,7 @@
This file is cd.def, from which is created cd.c. It implements the
builtins "cd" and "pwd" in Bash.
Copyright (C) 1987-2009 Free Software Foundation, Inc.
Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+513
View File
@@ -0,0 +1,513 @@
This file is cd.def, from which is created cd.c. It implements the
builtins "cd" and "pwd" 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 cd.c
#include <config.h>
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include "../bashtypes.h"
#include "posixdir.h"
#include "posixstat.h"
#ifndef _MINIX
#include <sys/param.h>
#endif
#include <stdio.h>
#include "../bashansi.h"
#include "../bashintl.h"
#include <errno.h>
#include <tilde/tilde.h>
#include "../shell.h"
#include "../flags.h"
#include "maxpath.h"
#include "common.h"
#include "bashgetopt.h"
#if !defined (errno)
extern int errno;
#endif /* !errno */
extern int posixly_correct;
extern int array_needs_making;
extern const char * const bash_getcwd_errstr;
static int bindpwd __P((int));
static void setpwd __P((char *));
static char *resetpwd __P((char *));
static int change_to_directory __P((char *, int));
/* Change this to 1 to get cd spelling correction by default. */
int cdspelling = 0;
int cdable_vars;
$BUILTIN cd
$FUNCTION cd_builtin
$SHORT_DOC cd [-L|-P] [dir]
Change the shell working directory.
Change the current directory to DIR. The default DIR is the value of the
HOME shell variable.
The variable CDPATH defines the search path for the directory containing
DIR. Alternative directory names in CDPATH are separated by a colon (:).
A null directory name is the same as the current directory. If DIR begins
with a slash (/), then CDPATH is not used.
If the directory is not found, and the shell option `cdable_vars' is set,
the word is assumed to be a variable name. If that variable has a value,
its value is used for DIR.
Options:
-L force symbolic links to be followed
-P use the physical directory structure without following symbolic
links
The default is to follow symbolic links, as if `-L' were specified.
Exit Status:
Returns 0 if the directory is changed; non-zero otherwise.
$END
/* Just set $PWD, don't change OLDPWD. Used by `pwd -P' in posix mode. */
static void
setpwd (dirname)
char *dirname;
{
int old_anm;
SHELL_VAR *tvar;
old_anm = array_needs_making;
tvar = bind_variable ("PWD", dirname ? dirname : "", 0);
if (old_anm == 0 && array_needs_making && exported_p (tvar))
{
update_export_env_inplace ("PWD=", 4, dirname ? dirname : "");
array_needs_making = 0;
}
}
static int
bindpwd (no_symlinks)
int no_symlinks;
{
char *dirname, *pwdvar;
int old_anm, r;
SHELL_VAR *tvar;
r = sh_chkwrite (EXECUTION_SUCCESS);
#define tcwd the_current_working_directory
dirname = tcwd ? (no_symlinks ? sh_physpath (tcwd, 0) : tcwd)
: get_working_directory ("cd");
#undef tcwd
old_anm = array_needs_making;
pwdvar = get_string_value ("PWD");
tvar = bind_variable ("OLDPWD", pwdvar, 0);
if (old_anm == 0 && array_needs_making && exported_p (tvar))
{
update_export_env_inplace ("OLDPWD=", 7, pwdvar);
array_needs_making = 0;
}
setpwd (dirname);
if (dirname && dirname != the_current_working_directory)
free (dirname);
return (r);
}
/* Call get_working_directory to reset the value of
the_current_working_directory () */
static char *
resetpwd (caller)
char *caller;
{
char *tdir;
FREE (the_current_working_directory);
the_current_working_directory = (char *)NULL;
tdir = get_working_directory (caller);
return (tdir);
}
#define LCD_DOVARS 0x001
#define LCD_DOSPELL 0x002
#define LCD_PRINTPATH 0x004
#define LCD_FREEDIRNAME 0x008
/* This builtin is ultimately the way that all user-visible commands should
change the current working directory. It is called by cd_to_string (),
so the programming interface is simple, and it handles errors and
restrictions properly. */
int
cd_builtin (list)
WORD_LIST *list;
{
char *dirname, *cdpath, *path, *temp;
int path_index, no_symlinks, opt, lflag;
#if defined (RESTRICTED_SHELL)
if (restricted)
{
sh_restricted ((char *)NULL);
return (EXECUTION_FAILURE);
}
#endif /* RESTRICTED_SHELL */
no_symlinks = no_symbolic_links;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "LP")) != -1)
{
switch (opt)
{
case 'P':
no_symlinks = 1;
break;
case 'L':
no_symlinks = 0;
break;
default:
builtin_usage ();
return (EXECUTION_FAILURE);
}
}
list = loptend;
lflag = (cdable_vars ? LCD_DOVARS : 0) |
((interactive && cdspelling) ? LCD_DOSPELL : 0);
if (list == 0)
{
/* `cd' without arguments is equivalent to `cd $HOME' */
dirname = get_string_value ("HOME");
if (dirname == 0)
{
builtin_error (_("HOME not set"));
return (EXECUTION_FAILURE);
}
lflag = 0;
}
else if (list->word->word[0] == '-' && list->word->word[1] == '\0')
{
/* This is `cd -', equivalent to `cd $OLDPWD' */
dirname = get_string_value ("OLDPWD");
if (dirname == 0)
{
builtin_error (_("OLDPWD not set"));
return (EXECUTION_FAILURE);
}
#if 0
lflag = interactive ? LCD_PRINTPATH : 0;
#else
lflag = LCD_PRINTPATH; /* According to SUSv3 */
#endif
}
else if (absolute_pathname (list->word->word))
dirname = list->word->word;
else if (privileged_mode == 0 && (cdpath = get_string_value ("CDPATH")))
{
dirname = list->word->word;
/* Find directory in $CDPATH. */
path_index = 0;
while (path = extract_colon_unit (cdpath, &path_index))
{
/* OPT is 1 if the path element is non-empty */
opt = path[0] != '\0';
temp = sh_makepath (path, dirname, MP_DOTILDE);
free (path);
if (change_to_directory (temp, no_symlinks))
{
/* POSIX.2 says that if a nonempty directory from CDPATH
is used to find the directory to change to, the new
directory name is echoed to stdout, whether or not
the shell is interactive. */
if (opt && (path = no_symlinks ? temp : the_current_working_directory))
printf ("%s\n", path);
free (temp);
#if 0
/* Posix.2 says that after using CDPATH, the resultant
value of $PWD will not contain `.' or `..'. */
return (bindpwd (posixly_correct || no_symlinks));
#else
return (bindpwd (no_symlinks));
#endif
}
else
free (temp);
}
/* POSIX.2 says that if `.' does not appear in $CDPATH, we don't
try the current directory, so we just punt now with an error
message if POSIXLY_CORRECT is non-zero. The check for cdpath[0]
is so we don't mistakenly treat a CDPATH value of "" as not
specifying the current directory. */
if (posixly_correct && cdpath[0])
{
builtin_error ("%s: %s", dirname, strerror (ENOENT));
return (EXECUTION_FAILURE);
}
}
else
dirname = list->word->word;
/* When we get here, DIRNAME is the directory to change to. If we
chdir successfully, just return. */
if (change_to_directory (dirname, no_symlinks))
{
if (lflag & LCD_PRINTPATH)
printf ("%s\n", dirname);
return (bindpwd (no_symlinks));
}
/* If the user requests it, then perhaps this is the name of
a shell variable, whose value contains the directory to
change to. */
if (lflag & LCD_DOVARS)
{
temp = get_string_value (dirname);
if (temp && change_to_directory (temp, no_symlinks))
{
printf ("%s\n", temp);
return (bindpwd (no_symlinks));
}
}
/* If the user requests it, try to find a directory name similar in
spelling to the one requested, in case the user made a simple
typo. This is similar to the UNIX 8th and 9th Edition shells. */
if (lflag & LCD_DOSPELL)
{
temp = dirspell (dirname);
if (temp && change_to_directory (temp, no_symlinks))
{
printf ("%s\n", temp);
return (bindpwd (no_symlinks));
}
else
FREE (temp);
}
builtin_error ("%s: %s", dirname, strerror (errno));
return (EXECUTION_FAILURE);
}
$BUILTIN pwd
$FUNCTION pwd_builtin
$SHORT_DOC pwd [-LP]
Print the name of the current working directory.
Options:
-L print the value of $PWD if it names the current working
directory
-P print the physical directory, without any symbolic links
By default, `pwd' behaves as if `-L' were specified.
Exit Status:
Returns 0 unless an invalid option is given or the current directory
cannot be read.
$END
/* Non-zero means that pwd always prints the physical directory, without
symbolic links. */
static int verbatim_pwd;
/* Print the name of the current working directory. */
int
pwd_builtin (list)
WORD_LIST *list;
{
char *directory;
int opt, pflag;
verbatim_pwd = no_symbolic_links;
pflag = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "LP")) != -1)
{
switch (opt)
{
case 'P':
verbatim_pwd = pflag = 1;
break;
case 'L':
verbatim_pwd = 0;
break;
default:
builtin_usage ();
return (EXECUTION_FAILURE);
}
}
list = loptend;
#define tcwd the_current_working_directory
directory = tcwd ? (verbatim_pwd ? sh_physpath (tcwd, 0) : tcwd)
: get_working_directory ("pwd");
/* Try again using getcwd() if canonicalization fails (for instance, if
the file system has changed state underneath bash). */
if ((tcwd && directory == 0) ||
(posixly_correct && same_file (".", tcwd, (struct stat *)0, (struct stat *)0) == 0))
directory = resetpwd ("pwd");
#undef tcwd
if (directory)
{
printf ("%s\n", directory);
/* This is dumb but posix-mandated. */
if (posixly_correct && pflag)
setpwd (directory);
if (directory != the_current_working_directory)
free (directory);
return (sh_chkwrite (EXECUTION_SUCCESS));
}
else
return (EXECUTION_FAILURE);
}
/* Do the work of changing to the directory NEWDIR. Handle symbolic
link following, etc. This function *must* return with
the_current_working_directory either set to NULL (in which case
getcwd() will eventually be called), or set to a string corresponding
to the working directory. Return 1 on success, 0 on failure. */
static int
change_to_directory (newdir, nolinks)
char *newdir;
int nolinks;
{
char *t, *tdir;
int err, canon_failed, r, ndlen, dlen;
tdir = (char *)NULL;
if (the_current_working_directory == 0)
{
t = get_working_directory ("chdir");
FREE (t);
}
t = make_absolute (newdir, the_current_working_directory);
/* TDIR is either the canonicalized absolute pathname of NEWDIR
(nolinks == 0) or the absolute physical pathname of NEWDIR
(nolinks != 0). */
tdir = nolinks ? sh_physpath (t, 0)
: sh_canonpath (t, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
ndlen = strlen (newdir);
dlen = strlen (t);
/* Use the canonicalized version of NEWDIR, or, if canonicalization
failed, use the non-canonical form. */
canon_failed = 0;
if (tdir && *tdir)
free (t);
else
{
FREE (tdir);
tdir = t;
canon_failed = 1;
}
/* In POSIX mode, if we're resolving symlinks logically and sh_canonpath
returns NULL (because it checks the path, it will return NULL if the
resolved path doesn't exist), fail immediately. */
if (posixly_correct && nolinks == 0 && canon_failed && (errno != ENAMETOOLONG || ndlen > PATH_MAX))
{
#if defined ENAMETOOLONG
if (errno != ENOENT && errno != ENAMETOOLONG)
#else
if (errno != ENOENT)
#endif
errno = ENOTDIR;
free (tdir);
return (0);
}
/* If the chdir succeeds, update the_current_working_directory. */
if (chdir (nolinks ? newdir : tdir) == 0)
{
/* If canonicalization failed, but the chdir succeeded, reset the
shell's idea of the_current_working_directory. */
if (canon_failed)
{
t = resetpwd ("cd");
if (t == 0)
set_working_directory (tdir);
}
else
set_working_directory (tdir);
free (tdir);
return (1);
}
/* We failed to change to the appropriate directory name. If we tried
what the user passed (nolinks != 0), punt now. */
if (nolinks)
{
free (tdir);
return (0);
}
err = errno;
/* We're not in physical mode (nolinks == 0), but we failed to change to
the canonicalized directory name (TDIR). Try what the user passed
verbatim. If we succeed, reinitialize the_current_working_directory. */
if (chdir (newdir) == 0)
{
t = resetpwd ("cd");
if (t == 0)
set_working_directory (tdir);
else
free (t);
r = 1;
}
else
{
errno = err;
r = 0;
}
free (tdir);
return r;
}
+1 -1
View File
@@ -1,6 +1,6 @@
/* common.c - utility functions for all builtins */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+1 -1
View File
@@ -367,7 +367,7 @@ make_builtin_argv (list, ip)
return argv;
}
/* Remember LIST in $0 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is
/* Remember LIST in $1 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is
non-zero, then discard whatever the existing arguments are, else
only discard the ones that are to be replaced. */
void
+1 -1
View File
@@ -1,6 +1,6 @@
/* common.h -- extern declarations for functions defined in common.c. */
/* Copyright (C) 1993-2004 Free Software Foundation, Inc.
/* Copyright (C) 1993-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+174
View File
@@ -0,0 +1,174 @@
/* common.h -- extern declarations for functions defined in common.c. */
/* Copyright (C) 1993-2004 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 (__COMMON_H)
# define __COMMON_H
#include "stdc.h"
#define ISOPTION(s, c) (s[0] == '-' && !s[2] && s[1] == c)
/* Flag values for parse_and_execute () */
#define SEVAL_NONINT 0x001
#define SEVAL_INTERACT 0x002
#define SEVAL_NOHIST 0x004
#define SEVAL_NOFREE 0x008
#define SEVAL_RESETLINE 0x010
#define SEVAL_PARSEONLY 0x020
#define SEVAL_NOLONGJMP 0x040
/* Flags for describe_command, shared between type.def and command.def */
#define CDESC_ALL 0x001 /* type -a */
#define CDESC_SHORTDESC 0x002 /* command -V */
#define CDESC_REUSABLE 0x004 /* command -v */
#define CDESC_TYPE 0x008 /* type -t */
#define CDESC_PATH_ONLY 0x010 /* type -p */
#define CDESC_FORCE_PATH 0x020 /* type -ap or type -P */
#define CDESC_NOFUNCS 0x040 /* type -f */
#define CDESC_ABSPATH 0x080 /* convert to absolute path, no ./ */
/* Flags for get_job_by_name */
#define JM_PREFIX 0x01 /* prefix of job name */
#define JM_SUBSTRING 0x02 /* substring of job name */
#define JM_EXACT 0x04 /* match job name exactly */
#define JM_STOPPED 0x08 /* match stopped jobs only */
#define JM_FIRSTMATCH 0x10 /* return first matching job */
/* Flags for remember_args and value of changed_dollar_vars */
#define ARGS_NONE 0x0
#define ARGS_INVOC 0x01
#define ARGS_FUNC 0x02
#define ARGS_SETBLTIN 0x04
/* Functions from common.c */
extern void builtin_error __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
extern void builtin_warning __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
extern void builtin_usage __P((void));
extern void no_args __P((WORD_LIST *));
extern int no_options __P((WORD_LIST *));
/* common error message functions */
extern void sh_needarg __P((char *));
extern void sh_neednumarg __P((char *));
extern void sh_notfound __P((char *));
extern void sh_invalidopt __P((char *));
extern void sh_invalidoptname __P((char *));
extern void sh_invalidid __P((char *));
extern void sh_invalidnum __P((char *));
extern void sh_invalidsig __P((char *));
extern void sh_erange __P((char *, char *));
extern void sh_badpid __P((char *));
extern void sh_badjob __P((char *));
extern void sh_readonly __P((const char *));
extern void sh_nojobs __P((char *));
extern void sh_restricted __P((char *));
extern void sh_notbuiltin __P((char *));
extern void sh_wrerror __P((void));
extern void sh_ttyerror __P((int));
extern int sh_chkwrite __P((int));
extern char **make_builtin_argv __P((WORD_LIST *, int *));
extern void remember_args __P((WORD_LIST *, int));
extern int dollar_vars_changed __P((void));
extern void set_dollar_vars_unchanged __P((void));
extern void set_dollar_vars_changed __P((void));
extern int get_numeric_arg __P((WORD_LIST *, int, intmax_t *));
extern int get_exitstat __P((WORD_LIST *));
extern int read_octal __P((char *));
/* Keeps track of the current working directory. */
extern char *the_current_working_directory;
extern char *get_working_directory __P((char *));
extern void set_working_directory __P((char *));
#if defined (JOB_CONTROL)
extern int get_job_by_name __P((const char *, int));
extern int get_job_spec __P((WORD_LIST *));
#endif
extern int display_signal_list __P((WORD_LIST *, int));
/* It's OK to declare a function as returning a Function * without
providing a definition of what a `Function' is. */
extern struct builtin *builtin_address_internal __P((char *, int));
extern sh_builtin_func_t *find_shell_builtin __P((char *));
extern sh_builtin_func_t *builtin_address __P((char *));
extern sh_builtin_func_t *find_special_builtin __P((char *));
extern void initialize_shell_builtins __P((void));
/* Functions from exit.def */
extern void bash_logout __P((void));
/* Functions from getopts.def */
extern void getopts_reset __P((int));
/* Functions from set.def */
extern int minus_o_option_value __P((char *));
extern void list_minus_o_opts __P((int, int));
extern char **get_minus_o_opts __P((void));
extern int set_minus_o_option __P((int, char *));
extern void set_shellopts __P((void));
extern void parse_shellopts __P((char *));
extern void initialize_shell_options __P((int));
extern void reset_shell_options __P((void));
/* Functions from shopt.def */
extern void reset_shopt_options __P((void));
extern char **get_shopt_options __P((void));
extern int shopt_setopt __P((char *, int));
extern int shopt_listopt __P((char *, int));
extern int set_login_shell __P((char *, int));
extern void set_bashopts __P((void));
extern void parse_bashopts __P((char *));
extern void initialize_bashopts __P((int));
/* Functions from type.def */
extern int describe_command __P((char *, int));
/* Functions from setattr.def */
extern int set_or_show_attributes __P((WORD_LIST *, int, int));
extern int show_all_var_attributes __P((int, int));
extern int show_var_attributes __P((SHELL_VAR *, int, int));
extern int show_name_attributes __P((char *, int));
extern void set_var_attribute __P((char *, int, int));
/* Functions from pushd.def */
extern char *get_dirstack_from_string __P((char *));
extern char *get_dirstack_element __P((intmax_t, int));
extern void set_dirstack_element __P((intmax_t, int, char *));
extern WORD_LIST *get_directory_stack __P((int));
/* Functions from evalstring.c */
extern int parse_and_execute __P((char *, const char *, int));
extern void parse_and_execute_cleanup __P((void));
extern int parse_string __P((char *, const char *, int, char **));
/* Functions from evalfile.c */
extern int maybe_execute_file __P((const char *, int));
extern int source_file __P((const char *, int));
extern int fc_execute_file __P((const char *));
#endif /* !__COMMON_H */
+1 -1
View File
@@ -1,7 +1,7 @@
This file is complete.def, from which is created complete.c.
It implements the builtins "complete", "compgen", and "compopt" in Bash.
Copyright (C) 1999-2009 Free Software Foundation, Inc.
Copyright (C) 1999-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+1 -1
View File
@@ -753,7 +753,7 @@ $SHORT_DOC compopt [-o|+o option] [-DE] [name ...]
Modify or display completion options.
Modify the completion options for each NAME, or, if no NAMEs are supplied,
the completion currently begin executed. If no OPTIONs are givenm, print
the completion currently being executed. If no OPTIONs are given, print
the completion options for each NAME or the current completion specification.
Options:
+16 -10
View File
@@ -1,7 +1,7 @@
This file is declare.def, from which is created declare.c.
It implements the builtins "declare" and "local" in Bash.
Copyright (C) 1987-2009 Free Software Foundation, Inc.
Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -22,7 +22,7 @@ $PRODUCES declare.c
$BUILTIN declare
$FUNCTION declare_builtin
$SHORT_DOC declare [-aAfFilrtux] [-p] [name[=value] ...]
$SHORT_DOC declare [-aAfFgilrtux] [-p] [name[=value] ...]
Set variable values and attributes.
Declare variables and give them attributes. If no NAMEs are given,
@@ -32,6 +32,8 @@ Options:
-f restrict action or display to function names and definitions
-F restrict display to function names only (plus line number and
source file when debugging)
-g create global variables when used in a shell function; otherwise
ignored
-p display the attributes and value of each NAME
Options which set attributes:
@@ -50,7 +52,7 @@ Variables with the integer attribute have arithmetic evaluation (see
the `let' command) performed when the variable is assigned a value.
When used in a function, `declare' makes NAMEs local, as with the `local'
command.
command. The `-g' option suppresses this behavior.
Exit Status:
Returns success unless an invalid option is supplied or an error occurs.
@@ -58,7 +60,7 @@ $END
$BUILTIN typeset
$FUNCTION declare_builtin
$SHORT_DOC typeset [-aAfFilrtux] [-p] name[=value] ...
$SHORT_DOC typeset [-aAfFgilrtux] [-p] name[=value] ...
Set variable values and attributes.
Obsolete. See `help declare'.
@@ -125,9 +127,9 @@ local_builtin (list)
}
#if defined (ARRAY_VARS)
# define DECLARE_OPTS "+acfilprtuxAF"
# define DECLARE_OPTS "+acfgilprtuxAF"
#else
# define DECLARE_OPTS "+cfilprtuxF"
# define DECLARE_OPTS "+cfgilprtuxF"
#endif
/* The workhorse function. */
@@ -137,12 +139,12 @@ declare_internal (list, local_var)
int local_var;
{
int flags_on, flags_off, *flags;
int any_failed, assign_error, pflag, nodefs, opt;
int any_failed, assign_error, pflag, nodefs, opt, mkglobal;
char *t, *subscript_start;
SHELL_VAR *var;
FUNCTION_DEF *shell_fn;
flags_on = flags_off = any_failed = assign_error = pflag = nodefs = 0;
flags_on = flags_off = any_failed = assign_error = pflag = nodefs = mkglobal = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, DECLARE_OPTS)) != EOF)
{
@@ -177,6 +179,10 @@ declare_internal (list, local_var)
case 'f':
*flags |= att_function;
break;
case 'g':
if (flags == &flags_on)
mkglobal = 1;
break;
case 'i':
*flags |= att_integer;
break;
@@ -328,7 +334,7 @@ declare_internal (list, local_var)
/* XXX - this has consequences when we're making a local copy of a
variable that was in the temporary environment. Watch out
for this. */
if (variable_context && ((flags_on & att_function) == 0))
if (variable_context && mkglobal == 0 && ((flags_on & att_function) == 0))
{
#if defined (ARRAY_VARS)
if (flags_on & att_assoc)
@@ -410,7 +416,7 @@ declare_internal (list, local_var)
{
/* Non-null if we just created or fetched a local variable. */
if (var == 0)
var = find_variable (name);
var = mkglobal ? find_global_variable (name) : find_variable (name);
if (var == 0)
{
+16 -10
View File
@@ -22,7 +22,7 @@ $PRODUCES declare.c
$BUILTIN declare
$FUNCTION declare_builtin
$SHORT_DOC declare [-aAfFilrtux] [-p] [name[=value] ...]
$SHORT_DOC declare [-aAfFgilrtux] [-p] [name[=value] ...]
Set variable values and attributes.
Declare variables and give them attributes. If no NAMEs are given,
@@ -32,6 +32,8 @@ Options:
-f restrict action or display to function names and definitions
-F restrict display to function names only (plus line number and
source file when debugging)
-g create global variables when used in a shell function; otherwise
ignored
-p display the attributes and value of each NAME
Options which set attributes:
@@ -50,7 +52,7 @@ Variables with the integer attribute have arithmetic evaluation (see
the `let' command) performed when the variable is assigned a value.
When used in a function, `declare' makes NAMEs local, as with the `local'
command.
command. The `-g' option suppresses this behavior.
Exit Status:
Returns success unless an invalid option is supplied or an error occurs.
@@ -58,7 +60,7 @@ $END
$BUILTIN typeset
$FUNCTION declare_builtin
$SHORT_DOC typeset [-aAfFilrtux] [-p] name[=value] ...
$SHORT_DOC typeset [-aAfFgilrtux] [-p] name[=value] ...
Set variable values and attributes.
Obsolete. See `help declare'.
@@ -125,9 +127,9 @@ local_builtin (list)
}
#if defined (ARRAY_VARS)
# define DECLARE_OPTS "+acfilprtuxAF"
# define DECLARE_OPTS "+acfgilprtuxAF"
#else
# define DECLARE_OPTS "+cfilprtuxF"
# define DECLARE_OPTS "+cfgilprtuxF"
#endif
/* The workhorse function. */
@@ -137,12 +139,12 @@ declare_internal (list, local_var)
int local_var;
{
int flags_on, flags_off, *flags;
int any_failed, assign_error, pflag, nodefs, opt;
int any_failed, assign_error, pflag, nodefs, opt, mkglobal;
char *t, *subscript_start;
SHELL_VAR *var;
FUNCTION_DEF *shell_fn;
flags_on = flags_off = any_failed = assign_error = pflag = nodefs = 0;
flags_on = flags_off = any_failed = assign_error = pflag = nodefs = mkglobal = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, DECLARE_OPTS)) != EOF)
{
@@ -177,6 +179,10 @@ declare_internal (list, local_var)
case 'f':
*flags |= att_function;
break;
case 'g':
if (flags == &flags_on)
mkglobal = 1;
break;
case 'i':
*flags |= att_integer;
break;
@@ -328,7 +334,7 @@ declare_internal (list, local_var)
/* XXX - this has consequences when we're making a local copy of a
variable that was in the temporary environment. Watch out
for this. */
if (variable_context && ((flags_on & att_function) == 0))
if (variable_context && mkglobal == 0 && ((flags_on & att_function) == 0))
{
#if defined (ARRAY_VARS)
if (flags_on & att_assoc)
@@ -410,7 +416,7 @@ declare_internal (list, local_var)
{
/* Non-null if we just created or fetched a local variable. */
if (var == 0)
var = find_variable (name);
var = mkglobal ? find_global_variable (name) : find_variable (name);
if (var == 0)
{
@@ -512,7 +518,7 @@ declare_internal (list, local_var)
{
/* let bind_{array,assoc}_variable take care of this. */
if (assoc_p (var))
bind_assoc_variable (var, name, "0", value, aflags);
bind_assoc_variable (var, name, savestring ("0"), value, aflags);
else
bind_array_variable (name, 0, value, aflags);
}
+1 -5
View File
@@ -1,6 +1,6 @@
/* evalstring.c - evaluate a string as one or more shell commands.
/* Copyright (C) 1996-2009 Free Software Foundation, Inc.
/* Copyright (C) 1996-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -331,13 +331,9 @@ parse_and_execute (string, from_file, flags)
(this_shell_builtin == source_builtin || this_shell_builtin == eval_builtin) &&
last_command_exit_value == EX_BADSYNTAX && posixly_correct)
{
#if 0 /* XXX - for bash-4.2 */
should_jump_to_top_level = 1;
code = ERREXIT;
last_command_exit_value = EX_BADUSAGE;
#else
internal_warning (_("syntax errors in . or eval will cause future versions of the shell to abort as Posix requires"));
#endif
}
/* Since we are shell compatible, syntax errors in a script
+508
View File
@@ -0,0 +1,508 @@
/* evalstring.c - evaluate a string as one or more shell commands.
/* Copyright (C) 1996-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/>.
*/
#include <config.h>
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include "filecntl.h"
#include "../bashansi.h"
#include "../shell.h"
#include "../jobs.h"
#include "../builtins.h"
#include "../flags.h"
#include "../input.h"
#include "../execute_cmd.h"
#include "../redir.h"
#include "../trap.h"
#include "../bashintl.h"
#include <y.tab.h>
#if defined (HISTORY)
# include "../bashhist.h"
#endif
#include "common.h"
#include "builtext.h"
#if !defined (errno)
extern int errno;
#endif
#define IS_BUILTIN(s) (builtin_address_internal(s, 0) != (struct builtin *)NULL)
extern int indirection_level, subshell_environment;
extern int line_number;
extern int current_token, shell_eof_token;
extern int last_command_exit_value;
extern int running_trap;
extern int loop_level;
extern int executing_list;
extern int comsub_ignore_return;
extern int posixly_correct;
extern sh_builtin_func_t *this_shell_builtin;
int parse_and_execute_level = 0;
static int cat_file __P((REDIRECT *));
#define PE_TAG "parse_and_execute top"
#define PS_TAG "parse_string top"
#if defined (HISTORY)
static void
set_history_remembering ()
{
remember_on_history = enable_history_list;
}
#endif
/* How to force parse_and_execute () to clean up after itself. */
void
parse_and_execute_cleanup ()
{
if (running_trap)
{
run_trap_cleanup (running_trap - 1);
unfreeze_jobs_list ();
}
if (have_unwind_protects ())
run_unwind_frame (PE_TAG);
else
parse_and_execute_level = 0; /* XXX */
}
static void
parse_prologue (string, flags, tag)
char *string;
int flags;
char *tag;
{
char *orig_string;
int x;
orig_string = string;
/* Unwind protect this invocation of parse_and_execute (). */
begin_unwind_frame (tag);
unwind_protect_int (parse_and_execute_level);
unwind_protect_jmp_buf (top_level);
unwind_protect_int (indirection_level);
unwind_protect_int (line_number);
unwind_protect_int (loop_level);
unwind_protect_int (executing_list);
unwind_protect_int (comsub_ignore_return);
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
unwind_protect_int (interactive);
#if defined (HISTORY)
if (parse_and_execute_level == 0)
add_unwind_protect (set_history_remembering, (char *)NULL);
else
unwind_protect_int (remember_on_history); /* can be used in scripts */
# if defined (BANG_HISTORY)
if (interactive_shell)
unwind_protect_int (history_expansion_inhibited);
# endif /* BANG_HISTORY */
#endif /* HISTORY */
if (interactive_shell)
{
x = get_current_prompt_level ();
add_unwind_protect (set_current_prompt_level, x);
}
add_unwind_protect (pop_stream, (char *)NULL);
if (orig_string && ((flags & SEVAL_NOFREE) == 0))
add_unwind_protect (xfree, orig_string);
end_unwind_frame ();
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
interactive = (flags & SEVAL_NONINT) ? 0 : 1;
#if defined (HISTORY)
if (flags & SEVAL_NOHIST)
bash_history_disable ();
#endif /* HISTORY */
}
/* Parse and execute the commands in STRING. Returns whatever
execute_command () returns. This frees STRING. FLAGS is a
flags word; look in common.h for the possible values. Actions
are:
(flags & SEVAL_NONINT) -> interactive = 0;
(flags & SEVAL_INTERACT) -> interactive = 1;
(flags & SEVAL_NOHIST) -> call bash_history_disable ()
(flags & SEVAL_NOFREE) -> don't free STRING when finished
(flags & SEVAL_RESETLINE) -> reset line_number to 1
*/
int
parse_and_execute (string, from_file, flags)
char *string;
const char *from_file;
int flags;
{
int code, lreset;
volatile int should_jump_to_top_level, last_result;
COMMAND *volatile command;
parse_prologue (string, flags, PE_TAG);
parse_and_execute_level++;
lreset = flags & SEVAL_RESETLINE;
/* Reset the line number if the caller wants us to. If we don't reset the
line number, we have to subtract one, because we will add one just
before executing the next command (resetting the line number sets it to
0; the first line number is 1). */
push_stream (lreset);
if (lreset == 0)
line_number--;
indirection_level++;
code = should_jump_to_top_level = 0;
last_result = EXECUTION_SUCCESS;
with_input_from_string (string, from_file);
while (*(bash_input.location.string))
{
command = (COMMAND *)NULL;
if (interrupt_state)
{
last_result = EXECUTION_FAILURE;
break;
}
/* Provide a location for functions which `longjmp (top_level)' to
jump to. This prevents errors in substitution from restarting
the reader loop directly, for example. */
code = setjmp (top_level);
if (code)
{
should_jump_to_top_level = 0;
switch (code)
{
case FORCE_EOF:
case ERREXIT:
case EXITPROG:
if (command)
run_unwind_frame ("pe_dispose");
/* Remember to call longjmp (top_level) after the old
value for it is restored. */
should_jump_to_top_level = 1;
goto out;
case DISCARD:
if (command)
run_unwind_frame ("pe_dispose");
last_result = last_command_exit_value = EXECUTION_FAILURE; /* XXX */
if (subshell_environment)
{
should_jump_to_top_level = 1;
goto out;
}
else
{
#if 0
dispose_command (command); /* pe_dispose does this */
#endif
continue;
}
default:
command_error ("parse_and_execute", CMDERR_BADJUMP, code, 0);
break;
}
}
if (parse_command () == 0)
{
if ((flags & SEVAL_PARSEONLY) || (interactive_shell == 0 && read_but_dont_execute))
{
last_result = EXECUTION_SUCCESS;
dispose_command (global_command);
global_command = (COMMAND *)NULL;
}
else if (command = global_command)
{
struct fd_bitmap *bitmap;
bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
begin_unwind_frame ("pe_dispose");
add_unwind_protect (dispose_fd_bitmap, bitmap);
add_unwind_protect (dispose_command, command); /* XXX */
global_command = (COMMAND *)NULL;
if ((subshell_environment & SUBSHELL_COMSUB) && comsub_ignore_return)
command->flags |= CMD_IGNORE_RETURN;
#if defined (ONESHOT)
/*
* IF
* we were invoked as `bash -c' (startup_state == 2) AND
* parse_and_execute has not been called recursively AND
* we're not running a trap AND
* we have parsed the full command (string == '\0') AND
* we're not going to run the exit trap AND
* we have a simple command without redirections AND
* the command is not being timed AND
* the command's return status is not being inverted
* THEN
* tell the execution code that we don't need to fork
*/
if (startup_state == 2 && parse_and_execute_level == 1 &&
running_trap == 0 &&
*bash_input.location.string == '\0' &&
command->type == cm_simple &&
signal_is_trapped (EXIT_TRAP) == 0 &&
command->redirects == 0 && command->value.Simple->redirects == 0 &&
((command->flags & CMD_TIME_PIPELINE) == 0) &&
((command->flags & CMD_INVERT_RETURN) == 0))
{
command->flags |= CMD_NO_FORK;
command->value.Simple->flags |= CMD_NO_FORK;
}
#endif /* ONESHOT */
/* See if this is a candidate for $( <file ). */
if (startup_state == 2 &&
(subshell_environment & SUBSHELL_COMSUB) &&
*bash_input.location.string == '\0' &&
command->type == cm_simple && !command->redirects &&
(command->flags & CMD_TIME_PIPELINE) == 0 &&
command->value.Simple->words == 0 &&
command->value.Simple->redirects &&
command->value.Simple->redirects->next == 0 &&
command->value.Simple->redirects->instruction == r_input_direction)
{
int r;
r = cat_file (command->value.Simple->redirects);
last_result = (r < 0) ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
}
else
last_result = execute_command_internal
(command, 0, NO_PIPE, NO_PIPE, bitmap);
dispose_command (command);
dispose_fd_bitmap (bitmap);
discard_unwind_frame ("pe_dispose");
}
}
else
{
last_result = EXECUTION_FAILURE;
if (interactive_shell == 0 && this_shell_builtin &&
(this_shell_builtin == source_builtin || this_shell_builtin == eval_builtin) &&
last_command_exit_value == EX_BADSYNTAX && posixly_correct)
{
should_jump_to_top_level = 1;
code = ERREXIT;
last_command_exit_value = EX_BADUSAGE;
}
/* Since we are shell compatible, syntax errors in a script
abort the execution of the script. Right? */
break;
}
}
out:
run_unwind_frame (PE_TAG);
if (interrupt_state && parse_and_execute_level == 0)
{
/* An interrupt during non-interactive execution in an
interactive shell (e.g. via $PROMPT_COMMAND) should
not cause the shell to exit. */
interactive = interactive_shell;
throw_to_top_level ();
}
if (should_jump_to_top_level)
jump_to_top_level (code);
return (last_result);
}
/* Parse a command contained in STRING according to FLAGS and return the
number of characters consumed from the string. If non-NULL, set *ENDP
to the position in the string where the parse ended. Used to validate
command substitutions during parsing to obey Posix rules about finding
the end of the command and balancing parens. */
int
parse_string (string, from_file, flags, endp)
char *string;
const char *from_file;
int flags;
char **endp;
{
int code, nc;
volatile int should_jump_to_top_level;
COMMAND *volatile command, *oglobal;
char *ostring;
parse_prologue (string, flags, PS_TAG);
/* Reset the line number if the caller wants us to. If we don't reset the
line number, we have to subtract one, because we will add one just
before executing the next command (resetting the line number sets it to
0; the first line number is 1). */
push_stream (0);
code = should_jump_to_top_level = 0;
oglobal = global_command;
ostring = string;
with_input_from_string (string, from_file);
while (*(bash_input.location.string))
{
command = (COMMAND *)NULL;
#if 0
if (interrupt_state)
break;
#endif
/* Provide a location for functions which `longjmp (top_level)' to
jump to. */
code = setjmp (top_level);
if (code)
{
#if defined (DEBUG)
itrace("parse_string: longjmp executed: code = %d", code);
#endif
should_jump_to_top_level = 0;
switch (code)
{
case FORCE_EOF:
case ERREXIT:
case EXITPROG:
case DISCARD: /* XXX */
if (command)
dispose_command (command);
/* Remember to call longjmp (top_level) after the old
value for it is restored. */
should_jump_to_top_level = 1;
goto out;
default:
command_error ("parse_string", CMDERR_BADJUMP, code, 0);
break;
}
}
if (parse_command () == 0)
{
dispose_command (global_command);
global_command = (COMMAND *)NULL;
}
else
{
if ((flags & SEVAL_NOLONGJMP) == 0)
{
should_jump_to_top_level = 1;
code = DISCARD;
}
else
reset_parser (); /* XXX - sets token_to_read */
break;
}
if (current_token == yacc_EOF || current_token == shell_eof_token)
break;
}
out:
global_command = oglobal;
nc = bash_input.location.string - ostring;
if (endp)
*endp = bash_input.location.string;
run_unwind_frame (PS_TAG);
if (should_jump_to_top_level)
jump_to_top_level (code);
return (nc);
}
/* Handle a $( < file ) command substitution. This expands the filename,
returning errors as appropriate, then just cats the file to the standard
output. */
static int
cat_file (r)
REDIRECT *r;
{
char *fn;
int fd, rval;
if (r->instruction != r_input_direction)
return -1;
/* Get the filename. */
if (posixly_correct && !interactive_shell)
disallow_filename_globbing++;
fn = redirection_expand (r->redirectee.filename);
if (posixly_correct && !interactive_shell)
disallow_filename_globbing--;
if (fn == 0)
{
redirection_error (r, AMBIGUOUS_REDIRECT);
return -1;
}
fd = open(fn, O_RDONLY);
if (fd < 0)
{
file_error (fn);
free (fn);
return -1;
}
rval = zcatfd (fd, 1, fn);
free (fn);
close (fd);
return (rval);
}
+1 -1
View File
@@ -1,7 +1,7 @@
This file is exec.def, from which is created exec.c.
It implements the builtin "exec" in Bash.
Copyright (C) 1987-2009 Free Software Foundation, Inc.
Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+2 -1
View File
@@ -164,7 +164,8 @@ exec_builtin (list)
if (argv0)
{
free (args[0]);
exec_argv0 = args[0] = login ? mkdashname (argv0) : savestring (argv0);
args[0] = login ? mkdashname (argv0) : savestring (argv0);
exec_argv0 = savestring (args[0]);
}
else if (login)
{
+1 -1
View File
@@ -1,7 +1,7 @@
This file is fc.def, from which is created fc.c.
It implements the builtin "fc" in Bash.
Copyright (C) 1987-2009 Free Software Foundation, Inc.
Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+2 -2
View File
@@ -304,8 +304,8 @@ fc_builtin (list)
last_hist = i - rh - hist_last_line_added;
/* XXX */
if (i == last_hist && hlist[last_hist] == 0)
while (saved_command_line_count > 0 && last_hist >= 0 && hlist[last_hist] == 0)
if (saved_command_line_count > 0 && i == last_hist && hlist[last_hist] == 0)
while (last_hist >= 0 && hlist[last_hist] == 0)
last_hist--;
if (last_hist < 0)
{
+4 -4
View File
@@ -1,7 +1,7 @@
This file is hash.def, from which is created hash.c.
It implements the builtin "hash" in Bash.
Copyright (C) 1987-2009 Free Software Foundation, Inc.
Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -159,7 +159,9 @@ hash_builtin (list)
{
/* Add, remove or rehash the specified commands. */
w = list->word->word;
if (pathname)
if (absolute_program (w))
continue;
else if (pathname)
{
if (is_directory (pathname))
{
@@ -173,8 +175,6 @@ hash_builtin (list)
else
phash_insert (w, pathname, 0, 0);
}
else if (absolute_program (w))
continue;
else if (delete)
{
if (phash_remove (w))
+282
View File
@@ -0,0 +1,282 @@
This file is hash.def, from which is created hash.c.
It implements the builtin "hash" 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 hash.c
$BUILTIN hash
$FUNCTION hash_builtin
$SHORT_DOC hash [-lr] [-p pathname] [-dt] [name ...]
Remember or display program locations.
Determine and remember the full pathname of each command NAME. If
no arguments are given, information about remembered commands is displayed.
Options:
-d forget the remembered location of each NAME
-l display in a format that may be reused as input
-p pathname use PATHNAME is the full pathname of NAME
-r forget all remembered locations
-t print the remembered location of each NAME, preceding
each location with the corresponding NAME if multiple
NAMEs are given
Arguments:
NAME Each NAME is searched for in $PATH and added to the list
of remembered commands.
Exit Status:
Returns success unless NAME is not found or an invalid option is given.
$END
#include <config.h>
#include <stdio.h>
#include "../bashtypes.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <errno.h>
#include "../bashansi.h"
#include "../bashintl.h"
#include "../shell.h"
#include "../builtins.h"
#include "../flags.h"
#include "../findcmd.h"
#include "../hashcmd.h"
#include "common.h"
#include "bashgetopt.h"
extern int posixly_correct;
extern int dot_found_in_search;
extern char *this_command_name;
static int add_hashed_command __P((char *, int));
static int print_hash_info __P((BUCKET_CONTENTS *));
static int print_portable_hash_info __P((BUCKET_CONTENTS *));
static int print_hashed_commands __P((int));
static int list_hashed_filename_targets __P((WORD_LIST *, int));
/* Print statistics on the current state of hashed commands. If LIST is
not empty, then rehash (or hash in the first place) the specified
commands. */
int
hash_builtin (list)
WORD_LIST *list;
{
int expunge_hash_table, list_targets, list_portably, delete, opt;
char *w, *pathname;
if (hashing_enabled == 0)
{
builtin_error (_("hashing disabled"));
return (EXECUTION_FAILURE);
}
expunge_hash_table = list_targets = list_portably = delete = 0;
pathname = (char *)NULL;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "dlp:rt")) != -1)
{
switch (opt)
{
case 'd':
delete = 1;
break;
case 'l':
list_portably = 1;
break;
case 'p':
pathname = list_optarg;
break;
case 'r':
expunge_hash_table = 1;
break;
case 't':
list_targets = 1;
break;
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
/* hash -t requires at least one argument. */
if (list == 0 && list_targets)
{
sh_needarg ("-t");
return (EXECUTION_FAILURE);
}
/* We want hash -r to be silent, but hash -- to print hashing info, so
we test expunge_hash_table. */
if (list == 0 && expunge_hash_table == 0)
{
opt = print_hashed_commands (list_portably);
if (opt == 0 && posixly_correct == 0)
printf (_("%s: hash table empty\n"), this_command_name);
return (EXECUTION_SUCCESS);
}
if (expunge_hash_table)
phash_flush ();
/* If someone runs `hash -r -t xyz' he will be disappointed. */
if (list_targets)
return (list_hashed_filename_targets (list, list_portably));
#if defined (RESTRICTED_SHELL)
if (restricted && pathname && strchr (pathname, '/'))
{
sh_restricted (pathname);
return (EXECUTION_FAILURE);
}
#endif
for (opt = EXECUTION_SUCCESS; list; list = list->next)
{
/* Add, remove or rehash the specified commands. */
w = list->word->word;
if (absolute_program (w))
continue;
else if (pathname)
{
if (is_directory (pathname))
{
#ifdef EISDIR
builtin_error ("%s: %s", pathname, strerror (EISDIR));
#else
builtin_error (_("%s: is a directory"), pathname);
#endif
opt = EXECUTION_FAILURE;
}
else
phash_insert (w, pathname, 0, 0);
}
else if (delete)
{
if (phash_remove (w))
{
sh_notfound (w);
opt = EXECUTION_FAILURE;
}
}
else if (add_hashed_command (w, 0))
opt = EXECUTION_FAILURE;
}
fflush (stdout);
return (opt);
}
static int
add_hashed_command (w, quiet)
char *w;
int quiet;
{
int rv;
char *full_path;
rv = 0;
if (find_function (w) == 0 && find_shell_builtin (w) == 0)
{
phash_remove (w);
full_path = find_user_command (w);
if (full_path && executable_file (full_path))
phash_insert (w, full_path, dot_found_in_search, 0);
else
{
if (quiet == 0)
sh_notfound (w);
rv++;
}
FREE (full_path);
}
return (rv);
}
/* Print information about current hashed info. */
static int
print_hash_info (item)
BUCKET_CONTENTS *item;
{
printf ("%4d\t%s\n", item->times_found, pathdata(item)->path);
return 0;
}
static int
print_portable_hash_info (item)
BUCKET_CONTENTS *item;
{
printf ("builtin hash -p %s %s\n", pathdata(item)->path, item->key);
return 0;
}
static int
print_hashed_commands (fmt)
int fmt;
{
if (hashed_filenames == 0 || HASH_ENTRIES (hashed_filenames) == 0)
return (0);
if (fmt == 0)
printf (_("hits\tcommand\n"));
hash_walk (hashed_filenames, fmt ? print_portable_hash_info : print_hash_info);
return (1);
}
static int
list_hashed_filename_targets (list, fmt)
WORD_LIST *list;
int fmt;
{
int all_found, multiple;
char *target;
WORD_LIST *l;
all_found = 1;
multiple = list->next != 0;
for (l = list; l; l = l->next)
{
target = phash_search (l->word->word);
if (target == 0)
{
all_found = 0;
sh_notfound (l->word->word);
continue;
}
if (fmt)
printf ("builtin hash -p %s %s\n", target, l->word->word);
else
{
if (multiple)
printf ("%s\t", l->word->word);
printf ("%s\n", target);
}
}
return (all_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
+2 -4
View File
@@ -1,7 +1,7 @@
This file is kill.def, from which is created kill.c.
It implements the builtin "kill" in Bash.
Copyright (C) 1987-2009 Free Software Foundation, Inc.
Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -121,9 +121,7 @@ kill_builtin (list)
else
sig = decode_signal (sigspec, dflags);
list = list->next;
#if 0
saw_signal++; /* XXX - for bash-4.2 */
#endif
saw_signal++;
}
else
{
+263
View File
@@ -0,0 +1,263 @@
This file is kill.def, from which is created kill.c.
It implements the builtin "kill" 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 kill.c
$BUILTIN kill
$FUNCTION kill_builtin
$SHORT_DOC kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
Send a signal to a job.
Send the processes identified by PID or JOBSPEC the signal named by
SIGSPEC or SIGNUM. If neither SIGSPEC nor SIGNUM is present, then
SIGTERM is assumed.
Options:
-s sig SIG is a signal name
-n sig SIG is a signal number
-l list the signal names; if arguments follow `-l' they are
assumed to be signal numbers for which names should be listed
Kill is a shell builtin for two reasons: it allows job IDs to be used
instead of process IDs, and allows processes to be killed if the limit
on processes that you can create is reached.
Exit Status:
Returns success unless an invalid option is given or an error occurs.
$END
#include <config.h>
#include <stdio.h>
#include <errno.h>
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include "../bashansi.h"
#include "../bashintl.h"
#include "../shell.h"
#include "../trap.h"
#include "../jobs.h"
#include "common.h"
/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
#if !defined (errno)
extern int errno;
#endif /* !errno */
extern int posixly_correct;
static void kill_error __P((pid_t, int));
#if !defined (CONTINUE_AFTER_KILL_ERROR)
# define CONTINUE_OR_FAIL return (EXECUTION_FAILURE)
#else
# define CONTINUE_OR_FAIL goto continue_killing
#endif /* CONTINUE_AFTER_KILL_ERROR */
/* Here is the kill builtin. We only have it so that people can type
kill -KILL %1? No, if you fill up the process table this way you
can still kill some. */
int
kill_builtin (list)
WORD_LIST *list;
{
int sig, any_succeeded, listing, saw_signal, dflags;
char *sigspec, *word;
pid_t pid;
intmax_t pid_value;
if (list == 0)
{
builtin_usage ();
return (EXECUTION_FAILURE);
}
any_succeeded = listing = saw_signal = 0;
sig = SIGTERM;
sigspec = "TERM";
dflags = DSIG_NOCASE | ((posixly_correct == 0) ? DSIG_SIGPREFIX : 0);
/* Process options. */
while (list)
{
word = list->word->word;
if (ISOPTION (word, 'l'))
{
listing++;
list = list->next;
}
else if (ISOPTION (word, 's') || ISOPTION (word, 'n'))
{
list = list->next;
if (list)
{
sigspec = list->word->word;
if (sigspec[0] == '0' && sigspec[1] == '\0')
sig = 0;
else
sig = decode_signal (sigspec, dflags);
list = list->next;
saw_signal++;
}
else
{
sh_needarg (word);
return (EXECUTION_FAILURE);
}
}
else if (ISOPTION (word, '-'))
{
list = list->next;
break;
}
else if (ISOPTION (word, '?'))
{
builtin_usage ();
return (EXECUTION_SUCCESS);
}
/* If this is a signal specification then process it. We only process
the first one seen; other arguments may signify process groups (e.g,
-num == process group num). */
else if (*word == '-' && saw_signal == 0)
{
sigspec = word + 1;
sig = decode_signal (sigspec, dflags);
saw_signal++;
list = list->next;
}
else
break;
}
if (listing)
return (display_signal_list (list, 0));
/* OK, we are killing processes. */
if (sig == NO_SIG)
{
sh_invalidsig (sigspec);
return (EXECUTION_FAILURE);
}
if (list == 0)
{
builtin_usage ();
return (EXECUTION_FAILURE);
}
while (list)
{
word = list->word->word;
if (*word == '-')
word++;
/* Use the entire argument in case of minus sign presence. */
if (*word && legal_number (list->word->word, &pid_value) && (pid_value == (pid_t)pid_value))
{
pid = (pid_t) pid_value;
if (kill_pid (pid, sig, pid < -1) < 0)
{
if (errno == EINVAL)
sh_invalidsig (sigspec);
else
kill_error (pid, errno);
CONTINUE_OR_FAIL;
}
else
any_succeeded++;
}
#if defined (JOB_CONTROL)
else if (*list->word->word && *list->word->word != '%')
{
builtin_error (_("%s: arguments must be process or job IDs"), list->word->word);
CONTINUE_OR_FAIL;
}
else if (*word)
/* Posix.2 says you can kill without job control active (4.32.4) */
{ /* Must be a job spec. Check it out. */
int job;
sigset_t set, oset;
JOB *j;
BLOCK_CHILD (set, oset);
job = get_job_spec (list);
if (INVALID_JOB (job))
{
if (job != DUP_JOB)
sh_badjob (list->word->word);
UNBLOCK_CHILD (oset);
CONTINUE_OR_FAIL;
}
j = get_job_by_jid (job);
/* Job spec used. Kill the process group. If the job was started
without job control, then its pgrp == shell_pgrp, so we have
to be careful. We take the pid of the first job in the pipeline
in that case. */
pid = IS_JOBCONTROL (job) ? j->pgrp : j->pipe->pid;
UNBLOCK_CHILD (oset);
if (kill_pid (pid, sig, 1) < 0)
{
if (errno == EINVAL)
sh_invalidsig (sigspec);
else
kill_error (pid, errno);
CONTINUE_OR_FAIL;
}
else
any_succeeded++;
}
#endif /* !JOB_CONTROL */
else
{
sh_badpid (list->word->word);
CONTINUE_OR_FAIL;
}
continue_killing:
list = list->next;
}
return (any_succeeded ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
static void
kill_error (pid, e)
pid_t pid;
int e;
{
char *x;
x = strerror (e);
if (x == 0)
x = _("Unknown error");
builtin_error ("(%ld) - %s", (long)pid, x);
}
+18 -11
View File
@@ -2,7 +2,7 @@ This file is mapfile.def, from which is created mapfile.c.
It implements the builtin "mapfile" in Bash.
Copyright (C) 2005-2006 Rocky Bernstein for Free Software Foundation, Inc.
Copyright (C) 2008,2009 Free Software Foundation, Inc.
Copyright (C) 2008-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -44,7 +44,8 @@ Arguments:
If -C is supplied without -c, the default quantum is 5000. When
CALLBACK is evaluated, it is supplied the index of the next array
element to be assigned as an additional argument.
element to be assigned and the line to be assigned to that element
as additional arguments.
If not supplied with an explicit origin, mapfile will clear ARRAY before
assigning to it.
@@ -88,7 +89,10 @@ extern int errno;
#if defined (ARRAY_VARS)
static int run_callback __P((const char *, unsigned int, const char *));
#define DEFAULT_ARRAY_NAME "MAPFILE"
#define DEFAULT_VARIABLE_NAME "MAPLINE" /* not used right now */
/* The value specifying how frequently `mapfile' calls the callback. */
#define DEFAULT_QUANTUM 5000
@@ -98,18 +102,20 @@ extern int errno;
#define MAPF_CHOP 0x02
static int
run_callback(callback, current_index)
run_callback (callback, curindex, curline)
const char *callback;
unsigned int current_index;
unsigned int curindex;
const char *curline;
{
unsigned int execlen;
char *execstr;
char *execstr, *qline;
int flags;
execlen = strlen (callback) + 10;
/* 1 for space between %s and %d,
qline = sh_single_quote (curline);
execlen = strlen (callback) + strlen (qline) + 10;
/* 1 for each space between %s and %d,
another 1 for the last nul char for C string. */
execlen += 2;
execlen += 3;
execstr = xmalloc (execlen);
flags = SEVAL_NOHIST;
@@ -117,8 +123,9 @@ run_callback(callback, current_index)
if (interactive)
flags |= SEVAL_INTERACT;
#endif
snprintf (execstr, execlen, "%s %d", callback, current_index);
return parse_and_execute(execstr, NULL, flags);
snprintf (execstr, execlen, "%s %d %s", callback, curindex, qline);
free (qline);
return parse_and_execute (execstr, NULL, flags);
}
static void
@@ -202,7 +209,7 @@ mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_n
/* Has a callback been registered and if so is it time to call it? */
if (callback && line_count && (line_count % callback_quantum) == 0)
{
run_callback (callback, array_index);
run_callback (callback, array_index, line);
/* Reset the buffer for bash own stream. */
if (unbuffered_read == 0)
+357
View File
@@ -0,0 +1,357 @@
This file is mapfile.def, from which is created mapfile.c.
It implements the builtin "mapfile" in Bash.
Copyright (C) 2005-2006 Rocky Bernstein for Free Software Foundation, Inc.
Copyright (C) 2008-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/>.
$PRODUCES mapfile.c
$BUILTIN mapfile
$FUNCTION mapfile_builtin
$SHORT_DOC mapfile [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]
Read lines from the standard input into an indexed array variable.
Read lines from the standard input into the indexed array variable ARRAY, or
from file descriptor FD if the -u option is supplied. The variable MAPFILE
is the default ARRAY.
Options:
-n count Copy at most COUNT lines. If COUNT is 0, all lines are copied.
-O origin Begin assigning to ARRAY at index ORIGIN. The default index is 0.
-s count Discard the first COUNT lines read.
-t Remove a trailing newline from each line read.
-u fd Read lines from file descriptor FD instead of the standard input.
-C callback Evaluate CALLBACK each time QUANTUM lines are read.
-c quantum Specify the number of lines read between each call to CALLBACK.
Arguments:
ARRAY Array variable name to use for file data.
If -C is supplied without -c, the default quantum is 5000. When
CALLBACK is evaluated, it is supplied the index of the next array
element to be assigned as an additional argument.
If not supplied with an explicit origin, mapfile will clear ARRAY before
assigning to it.
Exit Status:
Returns success unless an invalid option is given or ARRAY is readonly or
not an indexed array.
$END
$BUILTIN readarray
$FUNCTION mapfile_builtin
$SHORT_DOC readarray [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]
Read lines from a file into an array variable.
A synonym for `mapfile'.
$END
#include <config.h>
#include "builtins.h"
#include "posixstat.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "bashansi.h"
#include "bashintl.h"
#include <stdio.h>
#include <errno.h>
#include "../bashintl.h"
#include "../shell.h"
#include "common.h"
#include "bashgetopt.h"
#if !defined (errno)
extern int errno;
#endif
#if defined (ARRAY_VARS)
static int run_callback __P((const char *, unsigned int, const char *));
#define DEFAULT_ARRAY_NAME "MAPFILE"
#define DEFAULT_VARIABLE_NAME "MAPLINE" /* not used right now */
/* The value specifying how frequently `mapfile' calls the callback. */
#define DEFAULT_QUANTUM 5000
/* Values for FLAGS */
#define MAPF_CLEARARRAY 0x01
#define MAPF_CHOP 0x02
static int
run_callback (callback, curindex, curline)
const char *callback;
unsigned int curindex;
const char *curline;
{
unsigned int execlen;
char *execstr, *qline;
int flags;
qline = sh_single_quote (curline);
execlen = strlen (callback) + strlen (qline) + 10;
/* 1 for each space between %s and %d,
another 1 for the last nul char for C string. */
execlen += 3;
execstr = xmalloc (execlen);
flags = SEVAL_NOHIST;
#if 0
if (interactive)
flags |= SEVAL_INTERACT;
#endif
snprintf (execstr, execlen, "%s %d %s", callback, curindex, qline);
free (qline);
return parse_and_execute (execstr, NULL, flags);
}
static void
do_chop(line)
char * line;
{
int length;
length = strlen (line);
if (length && line[length-1] == '\n')
line[length-1] = '\0';
}
static int
mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_name, flags)
int fd;
long line_count_goal, origin, nskip, callback_quantum;
char *callback, *array_name;
int flags;
{
char *line;
size_t line_length;
unsigned int array_index, line_count;
SHELL_VAR *entry;
int unbuffered_read;
line = NULL;
line_length = 0;
unbuffered_read = 0;
/* The following check should be done before reading any lines. Doing it
here allows us to call bind_array_element instead of bind_array_variable
and skip the variable lookup on every call. */
entry = find_or_make_array_variable (array_name, 1);
if (entry == 0 || readonly_p (entry) || noassign_p (entry))
{
if (entry && readonly_p (entry))
err_readonly (array_name);
return (EXECUTION_FAILURE);
}
else if (array_p (entry) == 0)
{
builtin_error (_("%s: not an indexed array"), array_name);
return (EXECUTION_FAILURE);
}
if (flags & MAPF_CLEARARRAY)
array_flush (array_cell (entry));
#ifndef __CYGWIN__
unbuffered_read = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
#else
unbuffered_read = 1;
#endif
zreset ();
/* Skip any lines at beginning of file? */
for (line_count = 0; line_count < nskip; line_count++)
if (zgetline (fd, &line, &line_length, unbuffered_read) < 0)
break;
line = 0;
line_length = 0;
/* Reset the buffer for bash own stream */
interrupt_immediately++;
for (array_index = origin, line_count = 1;
zgetline (fd, &line, &line_length, unbuffered_read) != -1;
array_index++, line_count++)
{
/* Have we exceeded # of lines to store? */
if (line_count_goal != 0 && line_count > line_count_goal)
break;
/* Remove trailing newlines? */
if (flags & MAPF_CHOP)
do_chop (line);
/* Has a callback been registered and if so is it time to call it? */
if (callback && line_count && (line_count % callback_quantum) == 0)
{
run_callback (callback, array_index, line);
/* Reset the buffer for bash own stream. */
if (unbuffered_read == 0)
zsyncfd (fd);
}
bind_array_element (entry, array_index, line, 0);
}
xfree (line);
if (unbuffered_read == 0)
zsyncfd (fd);
interrupt_immediately--;
return EXECUTION_SUCCESS;
}
int
mapfile_builtin (list)
WORD_LIST *list;
{
int opt, code, fd, clear_array, flags;
intmax_t intval;
long lines, origin, nskip, callback_quantum;
char *array_name, *callback;
clear_array = 1;
fd = 0;
lines = origin = nskip = 0;
flags = MAPF_CLEARARRAY;
callback_quantum = DEFAULT_QUANTUM;
callback = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "u:n:O:tC:c:s:")) != -1)
{
switch (opt)
{
case 'u':
code = legal_number (list_optarg, &intval);
if (code == 0 || intval < 0 || intval != (int)intval)
{
builtin_error (_("%s: invalid file descriptor specification"), list_optarg);
return (EXECUTION_FAILURE);
}
else
fd = intval;
if (sh_validfd (fd) == 0)
{
builtin_error (_("%d: invalid file descriptor: %s"), fd, strerror (errno));
return (EXECUTION_FAILURE);
}
break;
case 'n':
code = legal_number (list_optarg, &intval);
if (code == 0 || intval < 0 || intval != (unsigned)intval)
{
builtin_error (_("%s: invalid line count"), list_optarg);
return (EXECUTION_FAILURE);
}
else
lines = intval;
break;
case 'O':
code = legal_number (list_optarg, &intval);
if (code == 0 || intval < 0 || intval != (unsigned)intval)
{
builtin_error (_("%s: invalid array origin"), list_optarg);
return (EXECUTION_FAILURE);
}
else
origin = intval;
flags &= ~MAPF_CLEARARRAY;
break;
case 't':
flags |= MAPF_CHOP;
break;
case 'C':
callback = list_optarg;
break;
case 'c':
code = legal_number (list_optarg, &intval);
if (code == 0 || intval <= 0 || intval != (unsigned)intval)
{
builtin_error (_("%s: invalid callback quantum"), list_optarg);
return (EXECUTION_FAILURE);
}
else
callback_quantum = intval;
break;
case 's':
code = legal_number (list_optarg, &intval);
if (code == 0 || intval < 0 || intval != (unsigned)intval)
{
builtin_error (_("%s: invalid line count"), list_optarg);
return (EXECUTION_FAILURE);
}
else
nskip = intval;
break;
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
if (list == 0)
array_name = DEFAULT_ARRAY_NAME;
else if (list->word == 0 || list->word->word == 0)
{
builtin_error ("internal error: getting variable name");
return (EXECUTION_FAILURE);
}
else if (list->word->word[0] == '\0')
{
builtin_error (_("empty array variable name"));
return (EX_USAGE);
}
else
array_name = list->word->word;
if (legal_identifier (array_name) == 0 && valid_array_reference (array_name) == 0)
{
sh_invalidid (array_name);
return (EXECUTION_FAILURE);
}
return mapfile (fd, lines, origin, nskip, callback_quantum, callback, array_name, flags);
}
#else
int
mapfile_builtin (list)
WORD_LIST *list;
{
builtin_error (_("array variable support required"));
return (EXECUTION_FAILURE);
}
#endif /* ARRAY_VARS */
+1 -1
View File
@@ -1,7 +1,7 @@
/* mkbuiltins.c - Create builtins.c, builtext.h, and builtdoc.c from
a single source file called builtins.def. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+2 -5
View File
@@ -1380,7 +1380,7 @@ write_documentation (stream, documentation, indentation, flags)
{
register int i, j;
register char *line;
int string_array, texinfo, base_indent, last_cpp, filename_p;
int string_array, texinfo, base_indent, filename_p;
if (stream == 0)
return;
@@ -1407,7 +1407,7 @@ write_documentation (stream, documentation, indentation, flags)
base_indent = (string_array && single_longdoc_strings && filename_p == 0) ? BASE_INDENT : 0;
for (i = last_cpp = 0, texinfo = (flags & TEXINFO); line = documentation[i]; i++)
for (i = 0, texinfo = (flags & TEXINFO); line = documentation[i]; i++)
{
/* Allow #ifdef's to be written out verbatim, but don't put them into
separate help files. */
@@ -1415,11 +1415,8 @@ write_documentation (stream, documentation, indentation, flags)
{
if (string_array && filename_p == 0 && single_longdoc_strings == 0)
fprintf (stream, "%s\n", line);
last_cpp = 1;
continue;
}
else
last_cpp = 0;
/* prefix with N_( for gettext */
if (string_array && single_longdoc_strings == 0)
+85 -12
View File
@@ -1,7 +1,7 @@
This file is printf.def, from which is created printf.c.
It implements the builtin "printf" in Bash.
Copyright (C) 1997-2009 Free Software Foundation, Inc.
Copyright (C) 1997-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -72,9 +72,12 @@ $END
# include <inttypes.h>
#endif
#include "posixtime.h"
#include "../bashansi.h"
#include "../bashintl.h"
#define NEED_STRFTIME_DECL
#include "../shell.h"
#include "shmbutil.h"
#include "stdc.h"
@@ -167,6 +170,8 @@ extern int errno;
#define SKIP1 "#'-+ 0"
#define LENMODS "hjlLtz"
extern time_t shell_start_time;
#if !HAVE_ASPRINTF
extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
#endif
@@ -177,7 +182,7 @@ extern int vsnprintf __P((char *, size_t, const char *, va_list)) __attribute__(
static void printf_erange __P((char *));
static int printstr __P((char *, char *, int, int, int));
static int tescape __P((char *, char *, int *));
static int tescape __P((char *, char *, int *, int *));
static char *bexpand __P((char *, int, int *, int *));
static char *vbadd __P((char *, int));
static int vbprintf __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
@@ -226,7 +231,7 @@ printf_builtin (list)
char convch, thisch, nextch, *format, *modstart, *fmt, *start;
#if defined (HANDLE_MULTIBYTE)
char mbch[25]; /* 25 > MB_LEN_MAX, plus can handle 4-byte UTF-8 and large Unicode characters*/
int mbind;
int mbind, mblen;
#endif
conversion_error = 0;
@@ -309,11 +314,11 @@ printf_builtin (list)
/* Accommodate possible use of \u or \U, which can result in
multibyte characters */
memset (mbch, '\0', sizeof (mbch));
fmt += tescape (fmt, mbch, (int *)NULL);
for (mbind = 0; mbch[mbind]; mbind++)
fmt += tescape (fmt, mbch, &mblen, (int *)NULL);
for (mbind = 0; mbind < mblen; mbind++)
PC (mbch[mbind]);
#else
fmt += tescape (fmt, &nextch, (int *)NULL);
fmt += tescape (fmt, &nextch, (int *)NULL, (int *)NULL);
PC (nextch);
#endif
fmt--; /* for loop will increment it for us again */
@@ -414,6 +419,70 @@ printf_builtin (list)
break;
}
case '(':
{
char *timefmt, timebuf[128], *t;
int n;
intmax_t arg;
time_t secs;
struct tm *tm;
modstart[1] = nextch; /* restore char after left paren */
timefmt = xmalloc (strlen (fmt) + 3);
fmt++; /* skip over left paren */
for (t = timefmt, n = 1; *fmt; )
{
if (*fmt == '(')
n++;
else if (*fmt == ')')
n--;
if (n == 0)
break;
*t++ = *fmt++;
}
*t = '\0';
if (*++fmt != 'T')
{
builtin_warning (_("`%c': invalid time format specification"), *fmt);
fmt = start;
free (timefmt);
PC (*fmt);
continue;
}
if (timefmt[0] == '\0')
{
timefmt[0] = '%';
timefmt[1] = 'X'; /* locale-specific current time - should we use `+'? */
timefmt[2] = '\0';
}
/* argument is seconds since the epoch with special -1 and -2 */
arg = getintmax ();
if (arg == -1)
secs = NOW; /* roughly date +%s */
else if (arg == -2)
secs = shell_start_time; /* roughly $SECONDS */
else
secs = arg;
tm = localtime (&secs);
n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
free (timefmt);
if (n == 0)
timebuf[0] = '\0';
else
timebuf[sizeof(timebuf) - 1] = '\0';
/* convert to %s format that preserves fieldwidth and precision */
modstart[0] = 's';
modstart[1] = '\0';
n = printstr (start, timebuf, strlen (timebuf), fieldwidth, precision); /* XXX - %s for now */
if (n < 0)
{
sh_wrerror ();
clearerr (stdout);
PRETURN (EXECUTION_FAILURE);
}
break;
}
case 'n':
{
char *var;
@@ -712,15 +781,17 @@ printstr (fmt, string, len, fieldwidth, precision)
do the \c short-circuiting, and \c is treated as an unrecognized escape
sequence; we also bypass the other processing specific to %b arguments. */
static int
tescape (estart, cp, sawc)
tescape (estart, cp, lenp, sawc)
char *estart;
char *cp;
int *sawc;
int *lenp, *sawc;
{
register char *p;
int temp, c, evalue;
p = estart;
if (lenp)
*lenp = 1;
switch (c = *p++)
{
@@ -788,6 +859,8 @@ tescape (estart, cp, sawc)
{
temp = u32cconv (evalue, cp);
cp[temp] = '\0';
if (lenp)
*lenp = temp;
}
break;
#endif
@@ -832,7 +905,7 @@ bexpand (string, len, sawc, lenp)
char *ret, *r, *s, c;
#if defined (HANDLE_MULTIBYTE)
char mbch[25];
int mbind;
int mbind, mblen;
#endif
if (string == 0 || len == 0)
@@ -856,9 +929,9 @@ bexpand (string, len, sawc, lenp)
temp = 0;
#if defined (HANDLE_MULTIBYTE)
memset (mbch, '\0', sizeof (mbch));
s += tescape (s, mbch, &temp);
s += tescape (s, mbch, &mblen, &temp);
#else
s += tescape (s, &c, &temp);
s += tescape (s, &c, (int *)NULL, &temp);
#endif
if (temp)
{
@@ -868,7 +941,7 @@ bexpand (string, len, sawc, lenp)
}
#if defined (HANDLE_MULTIBYTE)
for (mbind = 0; mbch[mbind]; mbind++)
for (mbind = 0; mbind < mblen; mbind++)
*r++ = mbch[mbind];
#else
*r++ = c;
+91 -13
View File
@@ -72,9 +72,12 @@ $END
# include <inttypes.h>
#endif
#include "posixtime.h"
#include "../bashansi.h"
#include "../bashintl.h"
#define NEED_STRFTIME_DECL
#include "../shell.h"
#include "shmbutil.h"
#include "stdc.h"
@@ -167,6 +170,8 @@ extern int errno;
#define SKIP1 "#'-+ 0"
#define LENMODS "hjlLtz"
extern time_t shell_start_time;
#if !HAVE_ASPRINTF
extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
#endif
@@ -177,7 +182,7 @@ extern int vsnprintf __P((char *, size_t, const char *, va_list)) __attribute__(
static void printf_erange __P((char *));
static int printstr __P((char *, char *, int, int, int));
static int tescape __P((char *, char *, int *));
static int tescape __P((char *, char *, int *, int *));
static char *bexpand __P((char *, int, int *, int *));
static char *vbadd __P((char *, int));
static int vbprintf __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
@@ -226,7 +231,7 @@ printf_builtin (list)
char convch, thisch, nextch, *format, *modstart, *fmt, *start;
#if defined (HANDLE_MULTIBYTE)
char mbch[25]; /* 25 > MB_LEN_MAX, plus can handle 4-byte UTF-8 and large Unicode characters*/
int mbind;
int mbind, mblen;
#endif
conversion_error = 0;
@@ -309,11 +314,11 @@ printf_builtin (list)
/* Accommodate possible use of \u or \U, which can result in
multibyte characters */
memset (mbch, '\0', sizeof (mbch));
fmt += tescape (fmt, mbch, (int *)NULL);
for (mbind = 0; mbch[mbind]; mbind++)
fmt += tescape (fmt, mbch, &mblen, (int *)NULL);
for (mbind = 0; mbind < mblen; mbind++)
PC (mbch[mbind]);
#else
fmt += tescape (fmt, &nextch, (int *)NULL);
fmt += tescape (fmt, &nextch, (int *)NULL, (int *)NULL);
PC (nextch);
#endif
fmt--; /* for loop will increment it for us again */
@@ -414,6 +419,70 @@ printf_builtin (list)
break;
}
case '(':
{
char *timefmt, timebuf[128], *t;
int n;
intmax_t arg;
time_t secs;
struct tm *tm;
modstart[1] = nextch; /* restore char after left paren */
timefmt = xmalloc (strlen (fmt) + 3);
fmt++; /* skip over left paren */
for (t = timefmt, n = 1; *fmt; )
{
if (*fmt == '(')
n++;
else if (*fmt == ')')
n--;
if (n == 0)
break;
*t++ = *fmt++;
}
*t = '\0';
if (*++fmt != 'T')
{
builtin_warning (_("`%c': invalid time format specification"), *fmt);
fmt = start;
free (timefmt);
PC (*fmt);
continue;
}
if (timefmt[0] == '\0')
{
timefmt[0] = '%';
timefmt[1] = 'X'; /* locale-specific current time - should we use `+'? */
timefmt[2] = '\0';
}
/* argument is seconds since the epoch with special -1 and -2 */
arg = getintmax ();
if (arg == -1)
secs = NOW; /* roughly date +%s */
else if (arg == -2)
secs = shell_start_time; /* roughly $SECONDS */
else
secs = arg;
tm = localtime (&secs);
n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
free (timefmt);
if (n == 0)
timebuf[0] = '\0';
else
timebuf[sizeof(timebuf) - 1] = '\0';
/* convert to %s format that preserves fieldwidth and precision */
modstart[0] = 's';
modstart[1] = '\0';
n = printstr (start, timebuf, strlen (timebuf), fieldwidth, precision); /* XXX - %s for now */
if (n < 0)
{
sh_wrerror ();
clearerr (stdout);
PRETURN (EXECUTION_FAILURE);
}
break;
}
case 'n':
{
char *var;
@@ -712,15 +781,17 @@ printstr (fmt, string, len, fieldwidth, precision)
do the \c short-circuiting, and \c is treated as an unrecognized escape
sequence; we also bypass the other processing specific to %b arguments. */
static int
tescape (estart, cp, sawc)
tescape (estart, cp, lenp, sawc)
char *estart;
char *cp;
int *sawc;
int *lenp, *sawc;
{
register char *p;
int temp, c, evalue;
p = estart;
if (lenp)
*lenp = 1;
switch (c = *p++)
{
@@ -782,8 +853,15 @@ tescape (estart, cp, sawc)
*cp = '\\';
return 0;
}
temp = u32cconv (evalue, cp);
cp[temp] = '\0';
if (evalue <= UCHAR_MAX)
*cp = evalue;
else
{
temp = u32cconv (evalue, cp);
cp[temp] = '\0';
if (lenp)
*lenp = temp;
}
break;
#endif
@@ -827,7 +905,7 @@ bexpand (string, len, sawc, lenp)
char *ret, *r, *s, c;
#if defined (HANDLE_MULTIBYTE)
char mbch[25];
int mbind;
int mbind, mblen;
#endif
if (string == 0 || len == 0)
@@ -851,9 +929,9 @@ bexpand (string, len, sawc, lenp)
temp = 0;
#if defined (HANDLE_MULTIBYTE)
memset (mbch, '\0', sizeof (mbch));
s += tescape (s, mbch, &temp);
s += tescape (s, mbch, &mblen, &temp);
#else
s += tescape (s, &c, &temp);
s += tescape (s, &c, (int *)NULL, &temp);
#endif
if (temp)
{
@@ -863,7 +941,7 @@ bexpand (string, len, sawc, lenp)
}
#if defined (HANDLE_MULTIBYTE)
for (mbind = 0; mbch[mbind]; mbind++)
for (mbind = 0; mbind < mblen; mbind++)
*r++ = mbch[mbind];
#else
*r++ = c;
+1 -1
View File
@@ -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-2009 Free Software Foundation, Inc.
Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+2 -2
View File
@@ -390,7 +390,6 @@ read_builtin (list)
run_unwind_frame ("read_builtin");
input_string[i] = '\0'; /* make sure it's terminated */
retval = 128+SIGALRM;
itrace("read_builtin: before goto assign_vars: interrupt_immediately = %d", interrupt_immediately);
goto assign_vars;
}
old_alrm = set_signal_handler (SIGALRM, sigalrm);
@@ -616,13 +615,14 @@ add_char:
if (unbuffered_read == 0)
zsyncfd (fd);
discard_unwind_frame ("read_builtin");
retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
assign_vars:
interrupt_immediately--;
terminate_immediately--;
discard_unwind_frame ("read_builtin");
#if defined (ARRAY_VARS)
/* If -a was given, take the string read, break it into a list of words,
+1 -1
View File
@@ -1,7 +1,7 @@
This file is setattr.def, from which is created setattr.c.
It implements the builtins "export" and "readonly", in Bash.
Copyright (C) 1987-2009 Free Software Foundation, Inc.
Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+1 -1
View File
@@ -433,7 +433,7 @@ show_var_attributes (var, pattr, nodefs)
printf ("%s\n", var->name);
else if (function_p (var))
printf ("%s\n", named_function_string (var->name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL));
else if (invisible_p (var) || var_isnull (var))
else if (invisible_p (var) || var_isset (var) == 0)
printf ("%s\n", var->name);
else
{
+3 -1
View File
@@ -1,7 +1,7 @@
This file is shopt.def, from which is created shopt.c.
It implements the Bash `shopt' builtin.
Copyright (C) 1994-2009 Free Software Foundation, Inc.
Copyright (C) 1994-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -124,6 +124,7 @@ static int shopt_login_shell;
static int shopt_compat31;
static int shopt_compat32;
static int shopt_compat40;
static int shopt_compat41;
typedef int shopt_set_func_t __P((char *, int));
@@ -146,6 +147,7 @@ static struct {
{ "compat31", &shopt_compat31, set_compatibility_level },
{ "compat32", &shopt_compat32, set_compatibility_level },
{ "compat40", &shopt_compat40, set_compatibility_level },
{ "compat41", &shopt_compat41, set_compatibility_level },
#if defined (READLINE)
{ "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL },
#endif
+717
View File
@@ -0,0 +1,717 @@
This file is shopt.def, from which is created shopt.c.
It implements the Bash `shopt' builtin.
Copyright (C) 1994-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 shopt.c
$BUILTIN shopt
$FUNCTION shopt_builtin
$SHORT_DOC shopt [-pqsu] [-o] [optname ...]
Set and unset shell options.
Change the setting of each shell option OPTNAME. Without any option
arguments, list all shell options with an indication of whether or not each
is set.
Options:
-o restrict OPTNAMEs to those defined for use with `set -o'
-p print each shell option with an indication of its status
-q suppress output
-s enable (set) each OPTNAME
-u disable (unset) each OPTNAME
Exit Status:
Returns success if OPTNAME is enabled; fails if an invalid option is
given or OPTNAME is disabled.
$END
#include <config.h>
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include <stdio.h>
#include "version.h"
#include "../bashintl.h"
#include "../shell.h"
#include "../flags.h"
#include "common.h"
#include "bashgetopt.h"
#if defined (HISTORY)
# include "../bashhist.h"
#endif
#define UNSETOPT 0
#define SETOPT 1
#define OPTFMT "%-15s\t%s\n"
extern int allow_null_glob_expansion, fail_glob_expansion, glob_dot_filenames;
extern int cdable_vars, mail_warning, source_uses_path;
extern int no_exit_on_failed_exec, print_shift_error;
extern int check_hashed_filenames, promptvars;
extern int cdspelling, expand_aliases;
extern int extended_quote;
extern int check_window_size;
extern int glob_ignore_case, match_ignore_case;
extern int hup_on_exit;
extern int xpg_echo;
extern int gnu_error_format;
extern int check_jobs_at_exit;
extern int autocd;
extern int glob_star;
#if defined (EXTENDED_GLOB)
extern int extended_glob;
#endif
#if defined (READLINE)
extern int hist_verify, history_reediting, perform_hostname_completion;
extern int no_empty_command_completion;
extern int force_fignore;
extern int dircomplete_spelling;
extern int enable_hostname_completion __P((int));
#endif
#if defined (PROGRAMMABLE_COMPLETION)
extern int prog_completion_enabled;
#endif
#if defined (RESTRICTED_SHELL)
extern char *shell_name;
#endif
#if defined (DEBUGGER)
extern int debugging_mode;
#endif
static void shopt_error __P((char *));
static int set_shellopts_after_change __P((char *, int));
static int shopt_enable_hostname_completion __P((char *, int));
static int set_compatibility_level __P((char *, int));
#if defined (RESTRICTED_SHELL)
static int set_restricted_shell __P((char *, int));
#endif
static int shopt_login_shell;
static int shopt_compat31;
static int shopt_compat32;
static int shopt_compat40;
static int shopt_compat41;
typedef int shopt_set_func_t __P((char *, int));
static struct {
char *name;
int *value;
shopt_set_func_t *set_func;
} shopt_vars[] = {
{ "autocd", &autocd, (shopt_set_func_t *)NULL },
{ "cdable_vars", &cdable_vars, (shopt_set_func_t *)NULL },
{ "cdspell", &cdspelling, (shopt_set_func_t *)NULL },
{ "checkhash", &check_hashed_filenames, (shopt_set_func_t *)NULL },
#if defined (JOB_CONTROL)
{ "checkjobs", &check_jobs_at_exit, (shopt_set_func_t *)NULL },
#endif
{ "checkwinsize", &check_window_size, (shopt_set_func_t *)NULL },
#if defined (HISTORY)
{ "cmdhist", &command_oriented_history, (shopt_set_func_t *)NULL },
#endif
{ "compat31", &shopt_compat31, set_compatibility_level },
{ "compat32", &shopt_compat32, set_compatibility_level },
{ "compat40", &shopt_compat40, set_compatibility_level },
{ "compat41", &shopt_compat41, set_compatibility_level },
#if defined (READLINE)
{ "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL },
#endif
{ "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL },
{ "execfail", &no_exit_on_failed_exec, (shopt_set_func_t *)NULL },
{ "expand_aliases", &expand_aliases, (shopt_set_func_t *)NULL },
#if defined (DEBUGGER)
{ "extdebug", &debugging_mode, (shopt_set_func_t *)NULL },
#endif
#if defined (EXTENDED_GLOB)
{ "extglob", &extended_glob, (shopt_set_func_t *)NULL },
#endif
{ "extquote", &extended_quote, (shopt_set_func_t *)NULL },
{ "failglob", &fail_glob_expansion, (shopt_set_func_t *)NULL },
#if defined (READLINE)
{ "force_fignore", &force_fignore, (shopt_set_func_t *)NULL },
#endif
{ "globstar", &glob_star, (shopt_set_func_t *)NULL },
{ "gnu_errfmt", &gnu_error_format, (shopt_set_func_t *)NULL },
#if defined (HISTORY)
{ "histappend", &force_append_history, (shopt_set_func_t *)NULL },
#endif
#if defined (READLINE)
{ "histreedit", &history_reediting, (shopt_set_func_t *)NULL },
{ "histverify", &hist_verify, (shopt_set_func_t *)NULL },
{ "hostcomplete", &perform_hostname_completion, shopt_enable_hostname_completion },
#endif
{ "huponexit", &hup_on_exit, (shopt_set_func_t *)NULL },
{ "interactive_comments", &interactive_comments, set_shellopts_after_change },
#if defined (HISTORY)
{ "lithist", &literal_history, (shopt_set_func_t *)NULL },
#endif
{ "login_shell", &shopt_login_shell, set_login_shell },
{ "mailwarn", &mail_warning, (shopt_set_func_t *)NULL },
#if defined (READLINE)
{ "no_empty_cmd_completion", &no_empty_command_completion, (shopt_set_func_t *)NULL },
#endif
{ "nocaseglob", &glob_ignore_case, (shopt_set_func_t *)NULL },
{ "nocasematch", &match_ignore_case, (shopt_set_func_t *)NULL },
{ "nullglob", &allow_null_glob_expansion, (shopt_set_func_t *)NULL },
#if defined (PROGRAMMABLE_COMPLETION)
{ "progcomp", &prog_completion_enabled, (shopt_set_func_t *)NULL },
#endif
{ "promptvars", &promptvars, (shopt_set_func_t *)NULL },
#if defined (RESTRICTED_SHELL)
{ "restricted_shell", &restricted_shell, set_restricted_shell },
#endif
{ "shift_verbose", &print_shift_error, (shopt_set_func_t *)NULL },
{ "sourcepath", &source_uses_path, (shopt_set_func_t *)NULL },
{ "xpg_echo", &xpg_echo, (shopt_set_func_t *)NULL },
{ (char *)0, (int *)0, (shopt_set_func_t *)NULL }
};
#define N_SHOPT_OPTIONS (sizeof (shopt_vars) / sizeof (shopt_vars[0]))
#define GET_SHOPT_OPTION_VALUE(i) (*shopt_vars[i].value)
static const char * const on = "on";
static const char * const off = "off";
static int find_shopt __P((char *));
static int toggle_shopts __P((int, WORD_LIST *, int));
static void print_shopt __P((char *, int, int));
static int list_shopts __P((WORD_LIST *, int));
static int list_some_shopts __P((int, int));
static int list_shopt_o_options __P((WORD_LIST *, int));
static int list_some_o_options __P((int, int));
static int set_shopt_o_options __P((int, WORD_LIST *, int));
#define SFLAG 0x01
#define UFLAG 0x02
#define QFLAG 0x04
#define OFLAG 0x08
#define PFLAG 0x10
int
shopt_builtin (list)
WORD_LIST *list;
{
int opt, flags, rval;
flags = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "psuoq")) != -1)
{
switch (opt)
{
case 's':
flags |= SFLAG;
break;
case 'u':
flags |= UFLAG;
break;
case 'q':
flags |= QFLAG;
break;
case 'o':
flags |= OFLAG;
break;
case 'p':
flags |= PFLAG;
break;
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
if ((flags & (SFLAG|UFLAG)) == (SFLAG|UFLAG))
{
builtin_error (_("cannot set and unset shell options simultaneously"));
return (EXECUTION_FAILURE);
}
rval = EXECUTION_SUCCESS;
if ((flags & OFLAG) && ((flags & (SFLAG|UFLAG)) == 0)) /* shopt -o */
rval = list_shopt_o_options (list, flags);
else if (list && (flags & OFLAG)) /* shopt -so args */
rval = set_shopt_o_options ((flags & SFLAG) ? FLAG_ON : FLAG_OFF, list, flags & QFLAG);
else if (flags & OFLAG) /* shopt -so */
rval = list_some_o_options ((flags & SFLAG) ? 1 : 0, flags);
else if (list && (flags & (SFLAG|UFLAG))) /* shopt -su args */
rval = toggle_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, list, flags & QFLAG);
else if ((flags & (SFLAG|UFLAG)) == 0) /* shopt [args] */
rval = list_shopts (list, flags);
else /* shopt -su */
rval = list_some_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, flags);
return (rval);
}
/* Reset the options managed by `shopt' to the values they would have at
shell startup. */
void
reset_shopt_options ()
{
allow_null_glob_expansion = glob_dot_filenames = 0;
cdable_vars = mail_warning = 0;
no_exit_on_failed_exec = print_shift_error = 0;
check_hashed_filenames = cdspelling = expand_aliases = check_window_size = 0;
source_uses_path = promptvars = 1;
#if defined (EXTENDED_GLOB)
extended_glob = 0;
#endif
#if defined (HISTORY)
literal_history = force_append_history = 0;
command_oriented_history = 1;
#endif
#if defined (READLINE)
hist_verify = history_reediting = 0;
perform_hostname_completion = 1;
#endif
shopt_login_shell = login_shell;
}
static int
find_shopt (name)
char *name;
{
int i;
for (i = 0; shopt_vars[i].name; i++)
if (STREQ (name, shopt_vars[i].name))
return i;
return -1;
}
static void
shopt_error (s)
char *s;
{
builtin_error (_("%s: invalid shell option name"), s);
}
static int
toggle_shopts (mode, list, quiet)
int mode;
WORD_LIST *list;
int quiet;
{
WORD_LIST *l;
int ind, rval;
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
{
ind = find_shopt (l->word->word);
if (ind < 0)
{
shopt_error (l->word->word);
rval = EXECUTION_FAILURE;
}
else
{
*shopt_vars[ind].value = mode; /* 1 for set, 0 for unset */
if (shopt_vars[ind].set_func)
(*shopt_vars[ind].set_func) (shopt_vars[ind].name, mode);
}
}
set_bashopts ();
return (rval);
}
static void
print_shopt (name, val, flags)
char *name;
int val, flags;
{
if (flags & PFLAG)
printf ("shopt %s %s\n", val ? "-s" : "-u", name);
else
printf (OPTFMT, name, val ? on : off);
}
/* List the values of all or any of the `shopt' options. Returns 0 if
all were listed or all variables queried were on; 1 otherwise. */
static int
list_shopts (list, flags)
WORD_LIST *list;
int flags;
{
WORD_LIST *l;
int i, val, rval;
if (list == 0)
{
for (i = 0; shopt_vars[i].name; i++)
{
val = *shopt_vars[i].value;
if ((flags & QFLAG) == 0)
print_shopt (shopt_vars[i].name, val, flags);
}
return (sh_chkwrite (EXECUTION_SUCCESS));
}
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
{
i = find_shopt (l->word->word);
if (i < 0)
{
shopt_error (l->word->word);
rval = EXECUTION_FAILURE;
continue;
}
val = *shopt_vars[i].value;
if (val == 0)
rval = EXECUTION_FAILURE;
if ((flags & QFLAG) == 0)
print_shopt (l->word->word, val, flags);
}
return (sh_chkwrite (rval));
}
static int
list_some_shopts (mode, flags)
int mode, flags;
{
int val, i;
for (i = 0; shopt_vars[i].name; i++)
{
val = *shopt_vars[i].value;
if (((flags & QFLAG) == 0) && mode == val)
print_shopt (shopt_vars[i].name, val, flags);
}
return (sh_chkwrite (EXECUTION_SUCCESS));
}
static int
list_shopt_o_options (list, flags)
WORD_LIST *list;
int flags;
{
WORD_LIST *l;
int val, rval;
if (list == 0)
{
if ((flags & QFLAG) == 0)
list_minus_o_opts (-1, (flags & PFLAG));
return (sh_chkwrite (EXECUTION_SUCCESS));
}
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
{
val = minus_o_option_value (l->word->word);
if (val == -1)
{
sh_invalidoptname (l->word->word);
rval = EXECUTION_FAILURE;
continue;
}
if (val == 0)
rval = EXECUTION_FAILURE;
if ((flags & QFLAG) == 0)
{
if (flags & PFLAG)
printf ("set %co %s\n", val ? '-' : '+', l->word->word);
else
printf (OPTFMT, l->word->word, val ? on : off);
}
}
return (sh_chkwrite (rval));
}
static int
list_some_o_options (mode, flags)
int mode, flags;
{
if ((flags & QFLAG) == 0)
list_minus_o_opts (mode, (flags & PFLAG));
return (sh_chkwrite (EXECUTION_SUCCESS));
}
static int
set_shopt_o_options (mode, list, quiet)
int mode;
WORD_LIST *list;
int quiet;
{
WORD_LIST *l;
int rval;
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
{
if (set_minus_o_option (mode, l->word->word) == EXECUTION_FAILURE)
rval = EXECUTION_FAILURE;
}
set_shellopts ();
return rval;
}
/* If we set or unset interactive_comments with shopt, make sure the
change is reflected in $SHELLOPTS. */
static int
set_shellopts_after_change (option_name, mode)
char *option_name;
int mode;
{
set_shellopts ();
return (0);
}
static int
shopt_enable_hostname_completion (option_name, mode)
char *option_name;
int mode;
{
return (enable_hostname_completion (mode));
}
static int
set_compatibility_level (option_name, mode)
char *option_name;
int mode;
{
/* Need to change logic here as we add more compatibility levels */
/* First, check option_name so we can turn off other compat options when
one is set. */
if (mode && option_name[6] == '3' && option_name[7] == '1')
shopt_compat32 = shopt_compat40 = 0;
else if (mode && option_name[6] == '3' && option_name[7] == '2')
shopt_compat31 = shopt_compat40 = 0;
else if (mode && option_name[6] == '4' && option_name[7] == '0')
shopt_compat31 = shopt_compat32 = 0;
/* Then set shell_compatibility_level based on what remains */
if (shopt_compat31)
shell_compatibility_level = 31;
else if (shopt_compat32)
shell_compatibility_level = 32;
else if (shopt_compat40)
shell_compatibility_level = 40;
else
shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
return 0;
}
#if defined (RESTRICTED_SHELL)
/* Don't allow the value of restricted_shell to be modified. */
static int
set_restricted_shell (option_name, mode)
char *option_name;
int mode;
{
static int save_restricted = -1;
if (save_restricted == -1)
save_restricted = shell_is_restricted (shell_name);
restricted_shell = save_restricted;
return (0);
}
#endif /* RESTRICTED_SHELL */
/* Not static so shell.c can call it to initialize shopt_login_shell */
int
set_login_shell (option_name, mode)
char *option_name;
int mode;
{
shopt_login_shell = login_shell != 0;
return (0);
}
char **
get_shopt_options ()
{
char **ret;
int n, i;
n = sizeof (shopt_vars) / sizeof (shopt_vars[0]);
ret = strvec_create (n + 1);
for (i = 0; shopt_vars[i].name; i++)
ret[i] = savestring (shopt_vars[i].name);
ret[i] = (char *)NULL;
return ret;
}
/*
* External interface for other parts of the shell. NAME is a string option;
* MODE is 0 if we want to unset an option; 1 if we want to set an option.
* REUSABLE is 1 if we want to print output in a form that may be reused.
*/
int
shopt_setopt (name, mode)
char *name;
int mode;
{
WORD_LIST *wl;
int r;
wl = add_string_to_list (name, (WORD_LIST *)NULL);
r = toggle_shopts (mode, wl, 0);
dispose_words (wl);
return r;
}
int
shopt_listopt (name, reusable)
char *name;
int reusable;
{
int i;
if (name == 0)
return (list_shopts ((WORD_LIST *)NULL, reusable ? PFLAG : 0));
i = find_shopt (name);
if (i < 0)
{
shopt_error (name);
return (EXECUTION_FAILURE);
}
print_shopt (name, *shopt_vars[i].value, reusable ? PFLAG : 0);
return (sh_chkwrite (EXECUTION_SUCCESS));
}
void
set_bashopts ()
{
char *value;
char tflag[N_SHOPT_OPTIONS];
int vsize, i, vptr, *ip, exported;
SHELL_VAR *v;
for (vsize = i = 0; shopt_vars[i].name; i++)
{
tflag[i] = 0;
if (GET_SHOPT_OPTION_VALUE (i))
{
vsize += strlen (shopt_vars[i].name) + 1;
tflag[i] = 1;
}
}
value = (char *)xmalloc (vsize + 1);
for (i = vptr = 0; shopt_vars[i].name; i++)
{
if (tflag[i])
{
strcpy (value + vptr, shopt_vars[i].name);
vptr += strlen (shopt_vars[i].name);
value[vptr++] = ':';
}
}
if (vptr)
vptr--; /* cut off trailing colon */
value[vptr] = '\0';
v = find_variable ("BASHOPTS");
/* Turn off the read-only attribute so we can bind the new value, and
note whether or not the variable was exported. */
if (v)
{
VUNSETATTR (v, att_readonly);
exported = exported_p (v);
}
else
exported = 0;
v = bind_variable ("BASHOPTS", value, 0);
/* Turn the read-only attribute back on, and turn off the export attribute
if it was set implicitly by mark_modified_vars and SHELLOPTS was not
exported before we bound the new value. */
VSETATTR (v, att_readonly);
if (mark_modified_vars && exported == 0 && exported_p (v))
VUNSETATTR (v, att_exported);
free (value);
}
void
parse_bashopts (value)
char *value;
{
char *vname;
int vptr, ind;
vptr = 0;
while (vname = extract_colon_unit (value, &vptr))
{
ind = find_shopt (vname);
if (ind >= 0)
*shopt_vars[ind].value = 1;
free (vname);
}
}
void
initialize_bashopts (no_bashopts)
int no_bashopts;
{
char *temp;
SHELL_VAR *var;
if (no_bashopts == 0)
{
var = find_variable ("BASHOPTS");
/* set up any shell options we may have inherited. */
if (var && imported_p (var))
{
temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var));
if (temp)
{
parse_bashopts (temp);
free (temp);
}
}
}
/* Set up the $BASHOPTS variable. */
set_bashopts ();
}
+2 -1
View File
@@ -1,7 +1,7 @@
This file is test.def, from which is created test.c.
It implements the builtin "test" in Bash.
Copyright (C) 1987-2009 Free Software Foundation, Inc.
Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -80,6 +80,7 @@ String operators:
Other operators:
-o OPTION True if the shell option OPTION is enabled.
-v VAR True if the shell variable VAR is set
! EXPR True if expr is false.
EXPR1 -a EXPR2 True if both expr1 AND expr2 are true.
EXPR1 -o EXPR2 True if either expr1 OR expr2 is true.
+155
View File
@@ -0,0 +1,155 @@
This file is test.def, from which is created test.c.
It implements the builtin "test" 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 test.c
$BUILTIN test
$FUNCTION test_builtin
$SHORT_DOC test [expr]
Evaluate conditional expression.
Exits with a status of 0 (true) or 1 (false) depending on
the evaluation of EXPR. Expressions may be unary or binary. Unary
expressions are often used to examine the status of a file. There
are string operators as well, and numeric comparison operators.
File operators:
-a FILE True if file exists.
-b FILE True if file is block special.
-c FILE True if file is character special.
-d FILE True if file is a directory.
-e FILE True if file exists.
-f FILE True if file exists and is a regular file.
-g FILE True if file is set-group-id.
-h FILE True if file is a symbolic link.
-L FILE True if file is a symbolic link.
-k FILE True if file has its `sticky' bit set.
-p FILE True if file is a named pipe.
-r FILE True if file is readable by you.
-s FILE True if file exists and is not empty.
-S FILE True if file is a socket.
-t FD True if FD is opened on a terminal.
-u FILE True if the file is set-user-id.
-w FILE True if the file is writable by you.
-x FILE True if the file is executable by you.
-O FILE True if the file is effectively owned by you.
-G FILE True if the file is effectively owned by your group.
-N FILE True if the file has been modified since it was last read.
FILE1 -nt FILE2 True if file1 is newer than file2 (according to
modification date).
FILE1 -ot FILE2 True if file1 is older than file2.
FILE1 -ef FILE2 True if file1 is a hard link to file2.
String operators:
-z STRING True if string is empty.
-n STRING
STRING True if string is not empty.
STRING1 = STRING2
True if the strings are equal.
STRING1 != STRING2
True if the strings are not equal.
STRING1 < STRING2
True if STRING1 sorts before STRING2 lexicographically.
STRING1 > STRING2
True if STRING1 sorts after STRING2 lexicographically.
Other operators:
-o OPTION True if the shell option OPTION is enabled.
-v VAR True if the shell variable VAR is set
! EXPR True if expr is false.
EXPR1 -a EXPR2 True if both expr1 AND expr2 are true.
EXPR1 -o EXPR2 True if either expr1 OR expr2 is true.
arg1 OP arg2 Arithmetic tests. OP is one of -eq, -ne,
-lt, -le, -gt, or -ge.
Arithmetic binary operators return true if ARG1 is equal, not-equal,
less-than, less-than-or-equal, greater-than, or greater-than-or-equal
than ARG2.
Exit Status:
Returns success if EXPR evaluates to true; fails if EXPR evaluates to
false or an invalid argument is given.
$END
$BUILTIN [
$DOCNAME test_bracket
$FUNCTION test_builtin
$SHORT_DOC [ arg... ]
Evaluate conditional expression.
This is a synonym for the "test" builtin, but the last argument must
be a literal `]', to match the opening `['.
$END
#include <config.h>
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include "../bashansi.h"
#include "../bashintl.h"
#include "../shell.h"
#include "../test.h"
#include "common.h"
extern char *this_command_name;
/* TEST/[ builtin. */
int
test_builtin (list)
WORD_LIST *list;
{
char **argv;
int argc, result;
/* We let Matthew Bradburn and Kevin Braunsdorf's code do the
actual test command. So turn the list of args into an array
of strings, since that is what their code wants. */
if (list == 0)
{
if (this_command_name[0] == '[' && !this_command_name[1])
{
builtin_error (_("missing `]'"));
return (EX_BADUSAGE);
}
return (EXECUTION_FAILURE);
}
argv = make_builtin_argv (list, &argc);
result = test_command (argc, argv);
free ((char *)argv);
return (result);
}
+1 -1
View File
@@ -1,7 +1,7 @@
This file is trap.def, from which is created trap.c.
It implements the builtin "trap" in Bash.
Copyright (C) 1987-2009 Free Software Foundation, Inc.
Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+1
View File
@@ -129,6 +129,7 @@ trap_builtin (list)
else if (display || list == 0)
{
initialize_terminating_signals ();
get_all_original_signals ();
return (sh_chkwrite (display_traps (list)));
}
else
+1 -1
View File
@@ -1,7 +1,7 @@
This file is ulimit.def, from which is created ulimit.c.
It implements the builtin "ulimit" in Bash.
Copyright (C) 1987-2009 Free Software Foundation, Inc.
Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+1 -1
View File
@@ -118,7 +118,7 @@ extern int errno;
# undef HAVE_RESOURCE
#endif
#if !HAVE_RESOURCE && HAVE_ULIMIT_H
#if !defined (HAVE_RESOURCE) && defined (HAVE_ULIMIT_H)
# include <ulimit.h>
#endif
+1 -1
View File
@@ -1,7 +1,7 @@
/* command.h -- The structures used internally to represent commands, and
the extern declarations of the functions used to create them. */
/* Copyright (C) 1993-2009 Free Software Foundation, Inc.
/* Copyright (C) 1993-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+1
View File
@@ -105,6 +105,7 @@ enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select,
#define SUBSHELL_PIPE 0x10 /* subshell from a pipeline element */
#define SUBSHELL_PROCSUB 0x20 /* subshell caused by <(command) or >(command) */
#define SUBSHELL_COPROC 0x40 /* subshell from a coproc pipeline */
#define SUBSHELL_RESETTRAP 0x80 /* subshell needs to reset trap strings on first call to trap */
/* A structure which represents a word. */
typedef struct word_desc {
+66 -19
View File
@@ -5,12 +5,12 @@
.\" Case Western Reserve University
.\" chet@po.cwru.edu
.\"
.\" Last Change: Sat Apr 17 23:24:15 EDT 2010
.\" Last Change: Sun May 30 17:03:08 EDT 2010
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
.TH BASH 1 "2010 April 17" "GNU Bash-4.1"
.TH BASH 1 "2010 May 30" "GNU Bash-4.1"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -565,6 +565,15 @@ under
.B "Shell Variables"
below.
.PP
When the shell is in \fIposix mode\fP, \fBtime\fP
may be followed by a newline. In this case, the shell displays the
total user and system time consumed by the shell and its children.
The
.SM
.B TIMEFORMAT
variable may be used to specify the format of
the time information.
.PP
Each command in a pipeline is executed as a separate process (i.e., in a
subshell).
.SS Lists
@@ -1881,6 +1890,11 @@ A sample value is
.if t \f(CW".o:~"\fP.
.if n ".o:~".
.TP
.B FUNCNEST
If set to a numeric value greater than 0, defines a maximum function
nesting level. Function invocations that exceed this nesting level
will cause the current command to abort.
.TP
.B GLOBIGNORE
A colon-separated list of patterns defining the set of filenames to
be ignored by pathname expansion.
@@ -3781,6 +3795,11 @@ Variables local to the function may be declared with the
builtin command. Ordinarily, variables and their values
are shared between the function and its caller.
.PP
The \fBFUNCNEST\fP variable, if set to a numeric value greater
than 0, defines a maximum function nesting level. Function
invocations that exceed the limit cause the entire command to
abort.
.PP
If the builtin command
.B return
is executed in a function, the function completes and
@@ -4021,7 +4040,7 @@ True if \fIfile1\fP is older than \fIfile2\fP, or if \fIfile2\fP exists
and \fIfile1\fP does not.
.TP
.B \-o \fIoptname\fP
True if shell option
True if the shell option
.I optname
is enabled.
See the list of options under the description of the
@@ -4030,6 +4049,11 @@ option to the
.B set
builtin below.
.TP
.B \-v \fIvarname\fP
True if the shell variable
.I varname
is set (has been assigned a value).
.TP
.B \-z \fIstring\fP
True if the length of \fIstring\fP is zero.
.TP
@@ -7058,10 +7082,10 @@ is greater than the number of enclosing loops, the last enclosing loop
(the ``top-level'' loop) is resumed.
The return value is 0 unless \fIn\fP is not greater than or equal to 1.
.TP
\fBdeclare\fP [\fB\-aAfFilrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
\fBdeclare\fP [\fB\-aAfFgilrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
.PD 0
.TP
\fBtypeset\fP [\fB\-aAfFilrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
\fBtypeset\fP [\fB\-aAfFgilrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
.PD
Declare variables and/or give them attributes.
If no \fIname\fPs are given then display the values of variables.
@@ -7090,6 +7114,11 @@ are displayed as well. The
.B \-F
option implies
.BR \-f .
The
.B \-g
option forces variables to be created or modified at the global scope,
even when \fBdeclare\fP is executed in a shell function.
It is ignored in all other cases.
The following options can
be used to restrict output to variables with the specified attribute or
to give variables attributes:
@@ -7144,11 +7173,11 @@ turns off the attribute instead,
with the exceptions that \fB+a\fP
may not be used to destroy an array variable and \fB+r\fP will not
remove the readonly attribute.
When used in a function,
makes each
When used in a function, makes each
\fIname\fP local, as with the
.B local
command.
command,
unless the \fB\-g\P option is supplied,
If a variable name is followed by =\fIvalue\fP, the value of
the variable is set to \fIvalue\fP.
The return value is 0 unless an invalid option is encountered,
@@ -8004,7 +8033,8 @@ is specified without
.BR \-c ,
the default quantum is 5000.
When \fIcallback\fP is evaluated, it is supplied the index of the next
array element to be assigned as an additional argument.
array element to be assigned and the line to be assigned to that element
as additional arguments.
\fIcallback\fP is evaluated after the line is read but before the
array element is assigned.
.PP
@@ -8068,32 +8098,49 @@ directory change fails.
\fBprintf\fP [\fB\-v\fP \fIvar\fP] \fIformat\fP [\fIarguments\fP]
Write the formatted \fIarguments\fP to the standard output under the
control of the \fIformat\fP.
The \fB\-v\fP option causes the output to be assigned to the variable
\fIvar\fP rather than being printed to the standard output.
.sp 1
The \fIformat\fP is a character string which contains three types of objects:
plain characters, which are simply copied to standard output, character
escape sequences, which are converted and copied to the standard output, and
format specifications, each of which causes printing of the next successive
\fIargument\fP.
In addition to the standard \fIprintf\fP(1) formats, \fB%b\fP causes
In addition to the standard \fIprintf\fP(1) format specifications,
\fBprintf\fP interprets the following extensions:
.RS
.PD 0
.TP
.B %b
causes
\fBprintf\fP to expand backslash escape sequences in the corresponding
\fIargument\fP (except that \fB\ec\fP terminates output, backslashes in
\fB\e\(aq\fP, \fB\e"\fP, and \fB\e?\fP are not removed, and octal escapes
beginning with \fB\e0\fP may contain up to four digits),
and \fB%q\fP causes \fBprintf\fP to output the corresponding
beginning with \fB\e0\fP may contain up to four digits).
.TP
.B %q
causes \fBprintf\fP to output the corresponding
\fIargument\fP in a format that can be reused as shell input.
.sp 1
.TP
.B %(\fIdatefmt\fP)T
causes \fBprintf\fP to output the date-time string resulting from using
\fIdatefmt\fP as a format string for \fIstrftime\fP(3). The corresponding
\fIargument\fP is an integer representing the number of seconds since the
epoch. Two special argument values may be used: -1 represents the current
time, and -2 represents the time the shell was invoked.
.PD
.PP
Arguments to non-string format specifiers are treated as C constants,
except that a leading plus or minus sign is allowed, and if the leading
character is a single or double quote, the value is the ASCII value of
the following character.
.sp 1
The \fB\-v\fP option causes the output to be assigned to the variable
\fIvar\fP rather than being printed to the standard output.
.sp 1
.PP
The \fIformat\fP is reused as necessary to consume all of the \fIarguments\fP.
If the \fIformat\fP requires more \fIarguments\fP than are supplied, the
extra format specifications behave as if a zero value or null string, as
appropriate, had been supplied. The return value is zero on success,
non-zero on failure.
appropriate, had been supplied.
The return value is zero on success, non-zero on failure.
.RE
.TP
\fBpushd\fP [\fB\-n\fP] [+\fIn\fP] [\-\fIn\fP]
.PD 0
+82 -19
View File
@@ -5,12 +5,12 @@
.\" Case Western Reserve University
.\" chet@po.cwru.edu
.\"
.\" Last Change: Sat Apr 17 23:24:15 EDT 2010
.\" Last Change: Sat May 29 20:59:17 EDT 2010
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
.TH BASH 1 "2010 April 17" "GNU Bash-4.1"
.TH BASH 1 "2010 May 29" "GNU Bash-4.1"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -565,6 +565,15 @@ under
.B "Shell Variables"
below.
.PP
When the shell is in \fIposix mode\fP, \fBtime\fP
may be followed by a newline. In this case, the shell displays the
total user and system time consumed by the shell and its children.
The
.SM
.B TIMEFORMAT
variable may be used to specify the format of
the time information.
.PP
Each command in a pipeline is executed as a separate process (i.e., in a
subshell).
.SS Lists
@@ -1104,6 +1113,14 @@ the eight-bit character whose value is the octal value \fInnn\fP
the eight-bit character whose value is the hexadecimal value \fIHH\fP
(one or two hex digits)
.TP
.B \eu\fIHHHH\fP
the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value
\fIHHHH\fP (one to four hex digits)
.TP
.B \eU\fIHHHHHHHH\fP
the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value
\fIHHHHHHHH\fP (one to eight hex digits)
.TP
.B \ec\fIx\fP
a control-\fIx\fP character
.PD
@@ -1873,6 +1890,11 @@ A sample value is
.if t \f(CW".o:~"\fP.
.if n ".o:~".
.TP
.B FUNCNEST
If set to a numeric value greater than 0, defines a maximum function
nesting level. Function invocations that exceed this nesting level
will cause the current command to abort.
.TP
.B GLOBIGNORE
A colon-separated list of patterns defining the set of filenames to
be ignored by pathname expansion.
@@ -3773,6 +3795,11 @@ Variables local to the function may be declared with the
builtin command. Ordinarily, variables and their values
are shared between the function and its caller.
.PP
The \fBFUNCNEST\fP variable, if set to a numeric value greater
than 0, defines a maximum function nesting level. Function
invocations that exceed the limit cause the entire command to
abort.
.PP
If the builtin command
.B return
is executed in a function, the function completes and
@@ -4013,7 +4040,7 @@ True if \fIfile1\fP is older than \fIfile2\fP, or if \fIfile2\fP exists
and \fIfile1\fP does not.
.TP
.B \-o \fIoptname\fP
True if shell option
True if the shell option
.I optname
is enabled.
See the list of options under the description of the
@@ -4022,6 +4049,11 @@ option to the
.B set
builtin below.
.TP
.B \-v \fIvarname\fP
True if the shell variable
.I varname
is set (has been assigned a value).
.TP
.B \-z \fIstring\fP
True if the length of \fIstring\fP is zero.
.TP
@@ -7050,10 +7082,10 @@ is greater than the number of enclosing loops, the last enclosing loop
(the ``top-level'' loop) is resumed.
The return value is 0 unless \fIn\fP is not greater than or equal to 1.
.TP
\fBdeclare\fP [\fB\-aAfFilrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
\fBdeclare\fP [\fB\-aAfFgilrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
.PD 0
.TP
\fBtypeset\fP [\fB\-aAfFilrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
\fBtypeset\fP [\fB\-aAfFgilrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
.PD
Declare variables and/or give them attributes.
If no \fIname\fPs are given then display the values of variables.
@@ -7082,6 +7114,11 @@ are displayed as well. The
.B \-F
option implies
.BR \-f .
The
.B \-g
option forces variables to be created or modified at the global scope,
even when \fBdeclare\fP is executed in a shell function.
It is ignored in all other cases.
The following options can
be used to restrict output to variables with the specified attribute or
to give variables attributes:
@@ -7136,11 +7173,11 @@ turns off the attribute instead,
with the exceptions that \fB+a\fP
may not be used to destroy an array variable and \fB+r\fP will not
remove the readonly attribute.
When used in a function,
makes each
When used in a function, makes each
\fIname\fP local, as with the
.B local
command.
command,
unless the \fB\-g\P option is supplied,
If a variable name is followed by =\fIvalue\fP, the value of
the variable is set to \fIvalue\fP.
The return value is 0 unless an invalid option is encountered,
@@ -7293,6 +7330,14 @@ the eight-bit character whose value is the octal value \fInnn\fP
.B \ex\fIHH\fP
the eight-bit character whose value is the hexadecimal value \fIHH\fP
(one or two hex digits)
.TP
.B \eu\fIHHHH\fP
the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value
\fIHHHH\fP (one to four hex digits)
.TP
.B \eU\fIHHHHHHHH\fP
the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value
\fIHHHHHHHH\fP (one to eight hex digits)
.PD
.RE
.TP
@@ -7988,7 +8033,8 @@ is specified without
.BR \-c ,
the default quantum is 5000.
When \fIcallback\fP is evaluated, it is supplied the index of the next
array element to be assigned as an additional argument.
array element to be assigned and the line to be assigned to that element
as additional arguments.
\fIcallback\fP is evaluated after the line is read but before the
array element is assigned.
.PP
@@ -8052,32 +8098,49 @@ directory change fails.
\fBprintf\fP [\fB\-v\fP \fIvar\fP] \fIformat\fP [\fIarguments\fP]
Write the formatted \fIarguments\fP to the standard output under the
control of the \fIformat\fP.
The \fB\-v\fP option causes the output to be assigned to the variable
\fIvar\fP rather than being printed to the standard output.
.sp 1
The \fIformat\fP is a character string which contains three types of objects:
plain characters, which are simply copied to standard output, character
escape sequences, which are converted and copied to the standard output, and
format specifications, each of which causes printing of the next successive
\fIargument\fP.
In addition to the standard \fIprintf\fP(1) formats, \fB%b\fP causes
In addition to the standard \fIprintf\fP(1) format specifications,
\fBprintf\fP interprets the following extensions:
.RS
.PD 0
.TP
.B %b
causes
\fBprintf\fP to expand backslash escape sequences in the corresponding
\fIargument\fP (except that \fB\ec\fP terminates output, backslashes in
\fB\e\(aq\fP, \fB\e"\fP, and \fB\e?\fP are not removed, and octal escapes
beginning with \fB\e0\fP may contain up to four digits),
and \fB%q\fP causes \fBprintf\fP to output the corresponding
beginning with \fB\e0\fP may contain up to four digits).
.TP
.B %q
causes \fBprintf\fP to output the corresponding
\fIargument\fP in a format that can be reused as shell input.
.sp 1
.TP
.B %(\fIdatefmt\fP)T
causes \fBprintf\fP to output the date-time string resulting from using
\fIdatefmt\fP as a format string for \fIstrftime\fP(3). The corresponding
\fIargument\fP is an integer representing the number of seconds since the
epoch. Two special argument values may be used: -1 represents the current
time, and -2 represents the time the shell was invoked.
.PD
.PP
Arguments to non-string format specifiers are treated as C constants,
except that a leading plus or minus sign is allowed, and if the leading
character is a single or double quote, the value is the ASCII value of
the following character.
.sp 1
The \fB\-v\fP option causes the output to be assigned to the variable
\fIvar\fP rather than being printed to the standard output.
.sp 1
.PP
The \fIformat\fP is reused as necessary to consume all of the \fIarguments\fP.
If the \fIformat\fP requires more \fIarguments\fP than are supplied, the
extra format specifications behave as if a zero value or null string, as
appropriate, had been supplied. The return value is zero on success,
non-zero on failure.
appropriate, had been supplied.
The return value is zero on success, non-zero on failure.
.RE
.TP
\fBpushd\fP [\fB\-n\fP] [+\fIn\fP] [\-\fIn\fP]
.PD 0
+143 -12
View File
@@ -596,6 +596,7 @@ some other grouping.
* Lists:: How to execute commands sequentially.
* Compound Commands:: Shell commands for control flow.
* Coprocesses:: Two-way communication between commands.
* GNU Parallel:: Running commands in parallel.
@end menu
@node Simple Commands
@@ -654,6 +655,12 @@ The use of @code{time} as a reserved word permits the timing of
shell builtins, shell functions, and pipelines. An external
@code{time} command cannot time these easily.
When the shell is in @sc{posix} mode (@pxref{Bash POSIX Mode}), @code{time}
may be followed by a newline. In this case, the shell displays the
total user and system time consumed by the shell and its children.
The @env{TIMEFORMAT} variable may be used to specify the format of
the time information.
If the pipeline is not executed asynchronously (@pxref{Lists}), the
shell waits for all commands in the pipeline to complete.
@@ -1132,6 +1139,79 @@ builtin command may be used to wait for the coprocess to terminate.
The return status of a coprocess is the exit status of @var{command}.
@node GNU Parallel
@subsection GNU Parallel
GNU Parallel, as its name suggests, can be used to build and run commands
in parallel. You may run the same command with different arguments, whether
they are filenames, usernames, hostnames, or lines read from files.
For a complete description, refer to the GNU Parallel documentation. A few
examples should provide a brief introduction to its use.
For example, it is easy to prefix each line in a text file with a specified
string:
@example
cat file | parallel -k echo prefix_string
@end example
The @option{-k} option is required to preserve the lines' order.
Similarly, you can append a specified string to each line in a text file:
@example
cat file | parallel -k echo @{@} append_string
@end example
You can use Parallel to move files from the current directory when the
number of files is too large to process with one @code{mv} invocation:
@example
ls | parallel mv @{@} destdir
@end example
As you can see, the @{@} is replaced with each line read from standard input.
This will run as many @code{mv} commands as there are files in the current
directory. You can emulate a parallel @code{xargs} by adding the @option{-X}
option:
@example
ls | parallel -X mv @{@} destdir
@end example
GNU Parallel can replace certain common idioms that operate on lines read
from a file (in this case, filenames):
@example
for x in $(cat list); do
do-something1 $x config-$x
do-something2 < $x
done | process-output
@end example
with a more compact syntax reminiscent of lambdas:
@example
cat list | parallel "do-something1 @{@} config-@{@} ; do-something2 < @{@}" | process-output
@end example
Parallel provides a built-in mechanism to remove filename extensions, which
lends itself to batch file transformations or renaming:
@example
ls *.gz | parallel -j+0 "zcat @{@} | bzip2 >@{.@}.bz2 && rm @{@}"
@end example
This will recompress all files in the current directory with names ending
in .gz using bzip2, running one job per CPU (-j+0) in parallel.
If a command generates output, you may want to preserve the input order in
the output. For instance, the following command
@example
@{ echo foss.org.my ; echo debian.org; echo freenetproject.org; @} | parallel traceroute
@end example
will display as output the traceroute invocation that finishes first. Using
the @option{-k} option, as we saw above
@example
@{ echo foss.org.my ; echo debian.org; echo freenetproject.org; @} | parallel -k traceroute
@end example
will ensure that the output of @code{traceroute foss.org.my} is displayed first.
@node Shell Functions
@section Shell Functions
@cindex shell function
@@ -1204,6 +1284,11 @@ shell option has been enabled.
@xref{Bourne Shell Builtins}, for the description of the
@code{trap} builtin.
The @env{FUNCNEST} variable, if set to a numeric value greater
than 0, defines a maximum function nesting level. Function
invocations that exceed the limit cause the entire command to
abort.
If the builtin command @code{return}
is executed in a function, the function completes and
execution resumes with the next command after the function
@@ -3456,6 +3541,11 @@ If the @code{extdebug} shell option is enabled using @code{shopt}
(@pxref{The Shopt Builtin}), the source file name and line number where
the function is defined are displayed as well.
@option{-F} implies @option{-f}.
The @option{-g} option forces variables to be created or modified at
the global scope, even when \fBdeclare\fP is executed in a shell function.
It is ignored in all other cases.
The following options can be used to restrict output to variables with
the specified attributes or to give variables attributes:
@@ -3504,8 +3594,9 @@ with the exceptions that @samp{+a}
may not be used to destroy an array variable and @samp{+r} will not
remove the readonly attribute.
When used in a function, @code{declare} makes each @var{name} local,
as with the @code{local} command. If a variable name is followed by
=@var{value}, the value of the variable is set to @var{value}.
as with the @code{local} command, unless the @samp{-g} option is used.
If a variable name is followed by =@var{value}, the value of the variable
is set to @var{value}.
The return status is zero unless an invalid option is encountered,
an attempt is made to define a function using @samp{-f foo=bar},
@@ -3693,7 +3784,8 @@ Specify the number of lines read between each call to @var{callback}.
If @option{-C} is specified without @option{-c},
the default quantum is 5000.
When @var{callback} is evaluated, it is supplied the index of the next
array element to be assigned as an additional argument.
array element to be assigned and the line to be assigned to that element
as additional arguments.
@var{callback} is evaluated after the line is read but before the
array element is assigned.
@@ -3711,28 +3803,41 @@ printf [-v @var{var}] @var{format} [@var{arguments}]
@end example
Write the formatted @var{arguments} to the standard output under the
control of the @var{format}.
The @option{-v} option causes the output to be assigned to the variable
@var{var} rather than being printed to the standard output.
The @var{format} is a character string which contains three types of objects:
plain characters, which are simply copied to standard output, character
escape sequences, which are converted and copied to the standard output, and
format specifications, each of which causes printing of the next successive
@var{argument}.
In addition to the standard @code{printf(1)} formats, @samp{%b} causes
@code{printf} to expand backslash escape sequences in the corresponding
@var{argument},
In addition to the standard @code{printf(1)} formats, @code{printf}
interprets the following extensions:
@table @code
@item %b
causes @code{printf} to expand backslash escape sequences in the
corresponding @var{argument},
(except that @samp{\c} terminates output, backslashes in
@samp{\'}, @samp{\"}, and @samp{\?} are not removed, and octal escapes
beginning with @samp{\0} may contain up to four digits),
and @samp{%q} causes @code{printf} to output the
beginning with @samp{\0} may contain up to four digits).
@item %q
causes @code{printf} to output the
corresponding @var{argument} in a format that can be reused as shell input.
@item %(@var{datefmt})T
causes @code{printf} to output the date-time string resulting from using
@var{datefmt} as a format string for @code{strftime}(3). The corresponding
@var{argument} is an integer representing the number of seconds since the
epoch. Two special argument values may be used: -1 represents the current
time, and -2 represents the time the shell was invoked.
@end table
@noindent
Arguments to non-string format specifiers are treated as C language constants,
except that a leading plus or minus sign is allowed, and if the leading
character is a single or double quote, the value is the ASCII value of
the following character.
The @option{-v} option causes the output to be assigned to the variable
@var{var} rather than being printed to the standard output.
The @var{format} is reused as necessary to consume all of the @var{arguments}.
If the @var{format} requires more @var{arguments} than are supplied, the
extra format specifications behave as if a zero value or null string, as
@@ -4954,6 +5059,11 @@ Assignments to @env{FUNCNAME} have no effect and return an error status.
If @env{FUNCNAME} is unset, it loses its special properties, even if
it is subsequently reset.
@item FUNCNEST
If set to a numeric value greater than 0, defines a maximum function
nesting level. Function invocations that exceed this nesting level
will cause the current command to abort.
@item GLOBIGNORE
A colon-separated list of patterns defining the set of filenames to
be ignored by filename expansion.
@@ -5855,10 +5965,13 @@ True if @var{file1} is older than @var{file2},
or if @var{file2} exists and @var{file1} does not.
@item -o @var{optname}
True if shell option @var{optname} is enabled.
True if the shell option @var{optname} is enabled.
The list of options appears in the description of the @option{-o}
option to the @code{set} builtin (@pxref{The Set Builtin}).
@item -v @var{varname}
True if the shell variable @var{varname} is set (has been assigned a value).
@item -z @var{string}
True if the length of @var{string} is zero.
@@ -6489,6 +6602,11 @@ is not found.
Non-interactive shells exit if a syntax error in an arithmetic expansion
results in an invalid expression.
@item
Non-interactive shells exit if there is a syntax error in a script read
with the @code{.} or @code{source} builtins, or in a string processed by
the @code{eval} builtin.
@item
Redirection operators do not perform filename expansion on the word
in the redirection unless the shell is interactive.
@@ -6507,6 +6625,19 @@ causes a fatal syntax error in non-interactive shells.
@sc{posix} special builtins are found before shell functions
during command lookup.
@item
The @code{time} reserved word may be used by itself as a command. When
used in this way, it displays timing statistics for the shell and its
completed children. The @env{TIMEFORMAT} variable controls the format
of the timing information.
@item
When parsing and expanding a $@{@dots{}@} expansion that appears within
double quotes, single quotes are no longer special and cannot be used to
quote a closing brace or other special character, unless the operator is
one of those defined to perform pattern removal. In this case, they do
not have to appear as matched pairs.
@item
If a @sc{posix} special builtin returns an error status, a
non-interactive shell exits. The fatal errors are those listed in
+134 -4
View File
@@ -522,6 +522,12 @@ the eight-bit character whose value is the octal value @var{nnn}
@item \x@var{HH}
the eight-bit character whose value is the hexadecimal value @var{HH}
(one or two hex digits)
@item \u@var{HHHH}
the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value
@var{HHHH} (one to four hex digits)
@item \U@var{HHHHHHHH}
the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value
@var{HHHHHHHH} (one to eight hex digits)
@item \c@var{x}
a control-@var{x} character
@end table
@@ -590,6 +596,7 @@ some other grouping.
* Lists:: How to execute commands sequentially.
* Compound Commands:: Shell commands for control flow.
* Coprocesses:: Two-way communication between commands.
* GNU Parallel:: Running commands in parallel.
@end menu
@node Simple Commands
@@ -648,6 +655,12 @@ The use of @code{time} as a reserved word permits the timing of
shell builtins, shell functions, and pipelines. An external
@code{time} command cannot time these easily.
When the shell is in @sc{posix} mode (@pxref{Bash POSIX Mode}), @code{time}
may be followed by a newline. In this case, the shell displays the
total user and system time consumed by the shell and its children.
The @env{TIMEFORMAT} variable may be used to specify the format of
the time information.
If the pipeline is not executed asynchronously (@pxref{Lists}), the
shell waits for all commands in the pipeline to complete.
@@ -1126,6 +1139,79 @@ builtin command may be used to wait for the coprocess to terminate.
The return status of a coprocess is the exit status of @var{command}.
@node GNU Parallel
@subsection GNU Parallel
GNU Parallel, as its name suggests, can be used to build and run commands
in parallel. You may run the same command with different arguments, whether
they are filenames, usernames, hostnames, or lines read from files.
For a complete description, refer to the GNU Parallel documentation. A few
examples should provide a brief introduction to its use.
For example, it is easy to prefix each line in a text file with a specified
string:
@example
cat file | parallel -k echo prefix_string
@end example
The @option{-k} option is required to preserve the lines' order.
Similarly, you can append a specified string to each line in a text file:
@example
cat file | parallel -k echo @{@} append_string
@end example
You can use Parallel to move files from the current directory when the
number of files is too large to process with one @code{mv} invocation:
@example
ls | parallel mv @{@} destdir
@end example
As you can see, the @{@} is replaced with each line read from standard input.
This will run as many @code{mv} commands as there are files in the current
directory. You can emulate a parallel @code{xargs} by adding the @option{-X}
option:
@example
ls | parallel -X mv @{@} destdir
@end example
GNU Parallel can replace certain common idioms that operate on lines read
from a file (in this case, filenames):
@example
for x in $(cat list); do
do-something1 $x config-$x
do-something2 < $x
done | process-output
@end example
with a more compact syntax reminiscent of lambdas:
@example
cat list | parallel "do-something1 @{@} config-@{@} ; do-something2 < @{@}" | process-output
@end example
Parallel provides a built-in mechanism to remove filename extensions, which
lends itself to batch file transformations or renaming:
@example
ls *.gz | parallel -j+0 "zcat @{@} | bzip2 >@{.@}.bz2 && rm @{@}"
@end example
This will recompress all files in the current directory with names ending
in .gz using bzip2, running one job per CPU (-j+0) in parallel.
If a command generates output, you may want to preserve the input order in
the output. For instance, the following command
@example
@{ echo foss.org.my ; echo debian.org; echo freenetproject.org; @} | parallel traceroute
@end example
will display as output the traceroute invocation that finishes first. Using
the @option{-k} option, as we saw above
@example
@{ echo foss.org.my ; echo debian.org; echo freenetproject.org; @} | parallel -k traceroute
@end example
will ensure that the output of @code{traceroute foss.org.my} is displayed first.
@node Shell Functions
@section Shell Functions
@cindex shell function
@@ -1198,6 +1284,11 @@ shell option has been enabled.
@xref{Bourne Shell Builtins}, for the description of the
@code{trap} builtin.
The @env{FUNCNEST} variable, if set to a numeric value greater
than 0, defines a maximum function nesting level. Function
invocations that exceed the limit cause the entire command to
abort.
If the builtin command @code{return}
is executed in a function, the function completes and
execution resumes with the next command after the function
@@ -3450,6 +3541,11 @@ If the @code{extdebug} shell option is enabled using @code{shopt}
(@pxref{The Shopt Builtin}), the source file name and line number where
the function is defined are displayed as well.
@option{-F} implies @option{-f}.
The @option{-g} option forces variables to be created or modified at
the global scope, even when \fBdeclare\fP is executed in a shell function.
It is ignored in all other cases.
The following options can be used to restrict output to variables with
the specified attributes or to give variables attributes:
@@ -3498,8 +3594,9 @@ with the exceptions that @samp{+a}
may not be used to destroy an array variable and @samp{+r} will not
remove the readonly attribute.
When used in a function, @code{declare} makes each @var{name} local,
as with the @code{local} command. If a variable name is followed by
=@var{value}, the value of the variable is set to @var{value}.
as with the @code{local} command, unless the @samp{-g} option is used.
If a variable name is followed by =@var{value}, the value of the variable
is set to @var{value}.
The return status is zero unless an invalid option is encountered,
an attempt is made to define a function using @samp{-f foo=bar},
@@ -3557,6 +3654,12 @@ the eight-bit character whose value is the octal value @var{nnn}
@item \x@var{HH}
the eight-bit character whose value is the hexadecimal value @var{HH}
(one or two hex digits)
@item \u@var{HHHH}
the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value
@var{HHHH} (one to four hex digits)
@item \U@var{HHHHHHHH}
the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value
@var{HHHHHHHH} (one to eight hex digits)
@end table
@item enable
@@ -3681,7 +3784,8 @@ Specify the number of lines read between each call to @var{callback}.
If @option{-C} is specified without @option{-c},
the default quantum is 5000.
When @var{callback} is evaluated, it is supplied the index of the next
array element to be assigned as an additional argument.
array element to be assigned and the line to be assigned to that element
as additional arguments.
@var{callback} is evaluated after the line is read but before the
array element is assigned.
@@ -4942,6 +5046,11 @@ Assignments to @env{FUNCNAME} have no effect and return an error status.
If @env{FUNCNAME} is unset, it loses its special properties, even if
it is subsequently reset.
@item FUNCNEST
If set to a numeric value greater than 0, defines a maximum function
nesting level. Function invocations that exceed this nesting level
will cause the current command to abort.
@item GLOBIGNORE
A colon-separated list of patterns defining the set of filenames to
be ignored by filename expansion.
@@ -5843,10 +5952,13 @@ True if @var{file1} is older than @var{file2},
or if @var{file2} exists and @var{file1} does not.
@item -o @var{optname}
True if shell option @var{optname} is enabled.
True if the shell option @var{optname} is enabled.
The list of options appears in the description of the @option{-o}
option to the @code{set} builtin (@pxref{The Set Builtin}).
@item -v @var{varname}
True if the shell variable @var{varname} is set (has been assigned a value).
@item -z @var{string}
True if the length of @var{string} is zero.
@@ -6477,6 +6589,11 @@ is not found.
Non-interactive shells exit if a syntax error in an arithmetic expansion
results in an invalid expression.
@item
Non-interactive shells exit if there is a syntax error in a script read
with the @code{.} or @code{source} builtins, or in a string processed by
the @code{eval} builtin.
@item
Redirection operators do not perform filename expansion on the word
in the redirection unless the shell is interactive.
@@ -6495,6 +6612,19 @@ causes a fatal syntax error in non-interactive shells.
@sc{posix} special builtins are found before shell functions
during command lookup.
@item
The @code{time} reserved word may be used by itself as a command. When
used in this way, it displays timing statistics for the shell and its
completed children. The @env{TIMEFORMAT} variable controls the format
of the timing information.
@item
When parsing and expanding a $@{@dots{}@} expansion that appears within
double quotes, single quotes are no longer special and cannot be used to
quote a closing brace or other special character, unless the operator is
one of those defined to perform pattern removal. In this case, they do
not have to appear as matched pairs.
@item
If a @sc{posix} special builtin returns an error status, a
non-interactive shell exits. The fatal errors are those listed in
+3 -3
View File
@@ -2,9 +2,9 @@
Copyright (C) 1988-2010 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Sat Apr 17 23:23:55 EDT 2010
@set LASTCHANGE Sun May 30 17:03:21 EDT 2010
@set EDITION 4.1
@set VERSION 4.1
@set UPDATED 17 April 2010
@set UPDATED-MONTH April 2010
@set UPDATED 30 May 2010
@set UPDATED-MONTH May 2010
+3 -3
View File
@@ -2,9 +2,9 @@
Copyright (C) 1988-2010 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Fri Jan 15 10:50:20 EST 2010
@set LASTCHANGE Sat May 29 21:00:00 EDT 2010
@set EDITION 4.1
@set VERSION 4.1
@set UPDATED 15 January 2010
@set UPDATED-MONTH January 2010
@set UPDATED 29 May 2010
@set UPDATED-MONTH May 2010
+10 -13
View File
@@ -1,6 +1,6 @@
/* execute_cmd.c -- Execute a COMMAND structure. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -179,7 +179,7 @@ static void execute_subshell_builtin_or_function __P((WORD_LIST *, REDIRECT *,
int, int, int,
struct fd_bitmap *,
int));
static void execute_disk_command __P((WORD_LIST *, REDIRECT *, char *,
static int execute_disk_command __P((WORD_LIST *, REDIRECT *, char *,
int, int, int, struct fd_bitmap *, int));
static char *getinterp __P((char *, int, int *));
@@ -271,7 +271,7 @@ static int showing_function_line;
static int line_number_for_err_trap;
/* A sort of function nesting level counter */
static int funcnest = 0;
int funcnest = 0;
int funcnest_max = 0; /* XXX - bash-4.2 */
struct fd_bitmap *current_fds_to_close = (struct fd_bitmap *)NULL;
@@ -1219,7 +1219,6 @@ time_command (command, asynchronous, pipe_in, pipe_out, fds_to_close)
posix_time = (command->flags & CMD_TIME_POSIX);
#if 0 /* XXX - bash-4.2 */
nullcmd = (command == 0) || (command->type == cm_simple && command->value.Simple->words == 0 && command->value.Simple->redirects == 0);
if (posixly_correct && nullcmd)
{
@@ -1233,7 +1232,6 @@ time_command (command, asynchronous, pipe_in, pipe_out, fds_to_close)
tbefore = shell_start_time;
#endif
}
#endif
old_flags = command->flags;
command->flags &= ~(CMD_TIME_PIPELINE|CMD_TIME_POSIX);
@@ -1289,11 +1287,9 @@ time_command (command, asynchronous, pipe_in, pipe_out, fds_to_close)
time_format = POSIX_TIMEFORMAT;
else if ((time_format = get_string_value ("TIMEFORMAT")) == 0)
{
#if 0 /* XXX - bash-4.2 */
if (posixly_correct && nullcmd)
time_format = "user\t%2lU\nsys\t%2lS";
else
#endif
time_format = BASH_TIMEFORMAT;
}
if (time_format && *time_format)
@@ -3878,7 +3874,7 @@ run_builtin:
simple_command->flags &= ~CMD_NO_FORK;
#endif
execute_disk_command (words, simple_command->redirects, command_line,
result = execute_disk_command (words, simple_command->redirects, command_line,
pipe_in, pipe_out, async, fds_to_close,
simple_command->flags);
@@ -4040,13 +4036,12 @@ execute_function (var, words, flags, fds_to_close, async, subshell)
USE_VAR(fc);
#if 0 /* XXX - bash-4.2 */
if (funcnest_max > 0 && funcnest >= funcnest_max)
{
internal_error ("%s: maximum function nesting level exceeded (%d)", var->name, funcnest);
funcnest = 0; /* XXX - should we reset it somewhere else? */
jump_to_top_level (DISCARD);
}
#endif
#if defined (ARRAY_VARS)
GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
@@ -4505,7 +4500,7 @@ setup_async_signals ()
# define NOTFOUND_HOOK "command_not_found_handle"
#endif
static void
static int
execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
async, fds_to_close, cmdflags)
WORD_LIST *words;
@@ -4516,7 +4511,7 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
int cmdflags;
{
char *pathname, *command, **args;
int nofork;
int nofork, result;
pid_t pid;
SHELL_VAR *hookf;
WORD_LIST *wl;
@@ -4524,13 +4519,14 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
nofork = (cmdflags & CMD_NO_FORK); /* Don't fork, just exec, if no pipes */
pathname = words->word->word;
result = EXECUTION_SUCCESS;
#if defined (RESTRICTED_SHELL)
command = (char *)NULL;
if (restricted && mbschr (pathname, '/'))
{
internal_error (_("%s: restricted: cannot specify `/' in command names"),
pathname);
last_command_exit_value = EXECUTION_FAILURE;
result = last_command_exit_value = EXECUTION_FAILURE;
/* If we're not going to fork below, we must already be in a child
process or a context in which it's safe to call exit(2). */
@@ -4644,6 +4640,7 @@ parent_return:
unlink_fifo_list ();
#endif
FREE (command);
return (result);
}
}
+9 -21
View File
@@ -179,7 +179,7 @@ static void execute_subshell_builtin_or_function __P((WORD_LIST *, REDIRECT *,
int, int, int,
struct fd_bitmap *,
int));
static void execute_disk_command __P((WORD_LIST *, REDIRECT *, char *,
static int execute_disk_command __P((WORD_LIST *, REDIRECT *, char *,
int, int, int, struct fd_bitmap *, int));
static char *getinterp __P((char *, int, int *));
@@ -271,7 +271,7 @@ static int showing_function_line;
static int line_number_for_err_trap;
/* A sort of function nesting level counter */
static int funcnest = 0;
int funcnest = 0;
int funcnest_max = 0; /* XXX - bash-4.2 */
struct fd_bitmap *current_fds_to_close = (struct fd_bitmap *)NULL;
@@ -1219,7 +1219,6 @@ time_command (command, asynchronous, pipe_in, pipe_out, fds_to_close)
posix_time = (command->flags & CMD_TIME_POSIX);
#if 0 /* XXX - bash-4.2 */
nullcmd = (command == 0) || (command->type == cm_simple && command->value.Simple->words == 0 && command->value.Simple->redirects == 0);
if (posixly_correct && nullcmd)
{
@@ -1233,7 +1232,6 @@ time_command (command, asynchronous, pipe_in, pipe_out, fds_to_close)
tbefore = shell_start_time;
#endif
}
#endif
old_flags = command->flags;
command->flags &= ~(CMD_TIME_PIPELINE|CMD_TIME_POSIX);
@@ -1289,11 +1287,9 @@ time_command (command, asynchronous, pipe_in, pipe_out, fds_to_close)
time_format = POSIX_TIMEFORMAT;
else if ((time_format = get_string_value ("TIMEFORMAT")) == 0)
{
#if 0 /* XXX - bash-4.2 */
if (posixly_correct && nullcmd)
time_format = "user\t%2lU\nsys\t%2lS";
else
#endif
time_format = BASH_TIMEFORMAT;
}
if (time_format && *time_format)
@@ -1390,15 +1386,11 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
reset_terminating_signals (); /* in sig.c */
/* Cancel traps, in trap.c. */
#if 0 /* XXX - bash-4.2 */
/* Reset the signal handlers in the child, but don't free the
trap strings. Set a flag noting that we have to free the
trap strings if we run trap to change a signal disposition. */
reset_signal_handlers ();
subshell_environment |= SUBSHELL_RESETTRAP;
#else
restore_original_signals ();
#endif
/* Make sure restore_original_signals doesn't undo the work done by
make_child to ensure that asynchronous children are immune to SIGINT
@@ -3812,16 +3804,11 @@ run_builtin:
if (already_forked)
{
/* reset_terminating_signals (); */ /* XXX */
#if 0 /* XXX - bash-4.2 */
/* Reset the signal handlers in the child, but don't free the
trap strings. Set a flag noting that we have to free the
trap strings if we run trap to change a signal disposition. */
reset_signal_handlers ();
subshell_environment |= SUBSHELL_RESETTRAP;
#else
/* Cancel traps, in trap.c. */
restore_original_signals ();
#endif
if (async)
{
@@ -3887,7 +3874,7 @@ run_builtin:
simple_command->flags &= ~CMD_NO_FORK;
#endif
execute_disk_command (words, simple_command->redirects, command_line,
result = execute_disk_command (words, simple_command->redirects, command_line,
pipe_in, pipe_out, async, fds_to_close,
simple_command->flags);
@@ -4049,13 +4036,12 @@ execute_function (var, words, flags, fds_to_close, async, subshell)
USE_VAR(fc);
#if 0 /* XXX - bash-4.2 */
if (funcnest_max > 0 && funcnest >= funcnest_max)
{
internal_error ("%s: maximum function nesting level exceeded (%d)", var->name, funcnest);
funcnest = 0; /* XXX - should we reset it somewhere else? */
jump_to_top_level (DISCARD);
}
#endif
#if defined (ARRAY_VARS)
GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
@@ -4514,7 +4500,7 @@ setup_async_signals ()
# define NOTFOUND_HOOK "command_not_found_handle"
#endif
static void
static int
execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
async, fds_to_close, cmdflags)
WORD_LIST *words;
@@ -4525,7 +4511,7 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
int cmdflags;
{
char *pathname, *command, **args;
int nofork;
int nofork, result;
pid_t pid;
SHELL_VAR *hookf;
WORD_LIST *wl;
@@ -4533,13 +4519,14 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
nofork = (cmdflags & CMD_NO_FORK); /* Don't fork, just exec, if no pipes */
pathname = words->word->word;
result = EXECUTION_SUCCESS;
#if defined (RESTRICTED_SHELL)
command = (char *)NULL;
if (restricted && mbschr (pathname, '/'))
{
internal_error (_("%s: restricted: cannot specify `/' in command names"),
pathname);
last_command_exit_value = EXECUTION_FAILURE;
result = last_command_exit_value = EXECUTION_FAILURE;
/* If we're not going to fork below, we must already be in a child
process or a context in which it's safe to call exit(2). */
@@ -4653,6 +4640,7 @@ parent_return:
unlink_fifo_list ();
#endif
FREE (command);
return (result);
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
/* expr.c -- arithmetic expression evaluation. */
/* Copyright (C) 1990-2009 Free Software Foundation, Inc.
/* Copyright (C) 1990-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+18 -5
View File
@@ -176,6 +176,10 @@ static struct lvalue lastlval = {0, 0, 0, -1};
static int _is_arithop __P((int));
static void readtok __P((void)); /* lexical analyzer */
static void init_lvalue __P((struct lvalue *));
static struct lvalue *alloc_lvalue __P((void));
static void free_lvalue __P((struct lvalue *));
static intmax_t expr_streval __P((char *, int, struct lvalue *));
static intmax_t strlong __P((char *));
static void evalerror __P((const char *));
@@ -321,7 +325,7 @@ expr_bind_array_element (tok, ind, rhs)
size_t llen;
char ibuf[INT_STRLEN_BOUND (arrayind_t) + 1], *istr;
istr = fmtulong (ind, 10, ibuf, sizeof (ibuf), 0);
istr = fmtumax (ind, 10, ibuf, sizeof (ibuf), 0);
vname = array_variable_name (tok, (char **)NULL, (int *)NULL);
llen = strlen (vname) + sizeof (ibuf) + 3;
@@ -401,12 +405,14 @@ subexpr (expr)
return (0);
pushexp ();
curtok = lasttok = 0;
expression = savestring (expr);
tp = expression;
curtok = lasttok = 0;
tokstr = (char *)NULL;
tokval = 0;
init_lvalue (&curlval);
lastlval = curlval;
readtok ();
@@ -955,15 +961,22 @@ exp0 ()
return (val);
}
static void
init_lvalue (lv)
struct lvalue *lv;
{
lv->tokstr = 0;
lv->tokvar = 0;
lv->tokval = lv->ind = -1;
}
static struct lvalue *
alloc_lvalue ()
{
struct lvalue *lv;
lv = xmalloc (sizeof (struct lvalue));
lv->tokstr = 0;
lv->tokvar = 0;
lv->tokval = lv->ind = -1;
init_lvalue (lv);
return (lv);
}
+1 -1
View File
@@ -1,7 +1,7 @@
/* externs.h -- extern function declarations which do not appear in their
own header file. */
/* Copyright (C) 1993-2009 Free Software Foundation, Inc.
/* Copyright (C) 1993-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+4 -1
View File
@@ -114,7 +114,7 @@ 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((void));
extern char *history_delimiting_chars __P((const char *));
#endif
/* Declarations for functions defined in locale.c */
@@ -455,6 +455,9 @@ extern int uconvert __P((char *, long *, long *));
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 *));
+1 -1
View File
@@ -3,7 +3,7 @@
/* This file works with both POSIX and BSD systems. It implements job
control. */
/* Copyright (C) 1989-2009 Free Software Foundation, Inc.
/* Copyright (C) 1989-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
-1
View File
@@ -2351,7 +2351,6 @@ wait_for (pid)
WAIT s;
register PROCESS *child;
sigset_t set, oset;
register PROCESS *p;
/* In the case that this code is interrupted, and we longjmp () out of it,
we are relying on the code in throw_to_top_level () to restore the
+1 -1
View File
@@ -1,6 +1,6 @@
/* xmbsrtowcs.c -- replacement function for mbsrtowcs */
/* Copyright (C) 2002-2004 Free Software Foundation, Inc.
/* Copyright (C) 2002-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+5 -1
View File
@@ -219,7 +219,6 @@ xdupmbstowcs2 (destp, src)
}
#endif /* HAVE_MBSNRTOWCS */
/* Convert a multibyte string to a wide character string. Memory for the
new wide character string is obtained with malloc.
@@ -255,6 +254,11 @@ xdupmbstowcs (destp, indicesp, src)
return (size_t)-1;
}
#if HAVE_MBSNRTOWCS
if (indicesp == NULL)
return (xdupmbstowcs2 (destp, src));
#endif
memset (&state, '\0', sizeof(mbstate_t));
wsbuf_size = WSBUF_INC;
+2 -1
View File
@@ -1,6 +1,6 @@
/* bind.c -- key binding and startup file support for the readline library. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -1424,6 +1424,7 @@ static const struct {
{ "blink-matching-paren", &rl_blink_matching_paren, V_SPECIAL },
{ "byte-oriented", &rl_byte_oriented, 0 },
{ "completion-ignore-case", &_rl_completion_case_fold, 0 },
{ "completion-map-case", &_rl_completion_case_map, 0 },
{ "convert-meta", &_rl_convert_meta_chars_to_ascii, 0 },
{ "disable-completion", &rl_inhibit_completion, 0 },
{ "echo-control-characters", &_rl_echo_control_chars, 0 },
+6
View File
@@ -1424,6 +1424,7 @@ static const struct {
{ "blink-matching-paren", &rl_blink_matching_paren, V_SPECIAL },
{ "byte-oriented", &rl_byte_oriented, 0 },
{ "completion-ignore-case", &_rl_completion_case_fold, 0 },
{ "completion-map-case", &_rl_completion_case_map, 0 },
{ "convert-meta", &_rl_convert_meta_chars_to_ascii, 0 },
{ "disable-completion", &rl_inhibit_completion, 0 },
{ "echo-control-characters", &_rl_echo_control_chars, 0 },
@@ -2283,6 +2284,11 @@ _rl_get_string_variable_value (name)
}
else if (_rl_stricmp (name, "comment-begin") == 0)
return (_rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
else if (_rl_stricmp (name, "completion-display-width") == 0)
{
sprintf (numbuf, "%d", _rl_completion_columns);
return (numbuf);
}
else if (_rl_stricmp (name, "completion-prefix-display-length") == 0)
{
sprintf (numbuf, "%d", _rl_completion_prefix_display_length);
+64 -17
View File
@@ -119,6 +119,7 @@ static char **remove_duplicate_matches PARAMS((char **));
static void insert_match PARAMS((char *, int, int, char *));
static int append_to_match PARAMS((char *, int, int, int));
static void insert_all_matches PARAMS((char **, int, char *));
static int complete_fncmp PARAMS((const char *, int, const char *, int));
static void display_matches PARAMS((char **));
static int compute_lcd_of_matches PARAMS((char **, int, const char *));
static int postprocess_matches PARAMS((char ***, int));
@@ -158,9 +159,13 @@ int _rl_print_completions_horizontally;
#if defined (__MSDOS__) && !defined (__DJGPP__)
int _rl_completion_case_fold = 1;
#else
int _rl_completion_case_fold;
int _rl_completion_case_fold = 0;
#endif
/* Non-zero means that `-' and `_' are equivalent when comparing filenames
for completion. */
int _rl_completion_case_map = 0;
/* If zero, don't match hidden files (filenames beginning with a `.' on
Unix) when doing filename completion. */
int _rl_match_hidden_files = 1;
@@ -2056,6 +2061,62 @@ rl_username_completion_function (text, state)
#endif /* !__WIN32__ && !__OPENNT */
}
/* Return non-zero if CONVFN matches FILENAME up to the length of FILENAME
(FILENAME_LEN). If _rl_completion_case_fold is set, compare without
regard to the alphabetic case of characters. CONVFN is the possibly-
converted directory entry; FILENAME is what the user typed. */
static int
complete_fncmp (convfn, convlen, filename, filename_len)
const char *convfn;
int convlen;
const char *filename;
int filename_len;
{
register char *s1, *s2;
int d, len;
/* Otherwise, if these match up to the length of filename, then
it is a match. */
if (_rl_completion_case_fold && _rl_completion_case_map)
{
/* Case-insensitive comparison treating _ and - as equivalent */
if (filename_len == 0)
return 1;
if (convlen < filename_len)
return 0;
s1 = convfn;
s2 = filename;
len = filename_len;
do
{
d = _rl_to_lower (*s1) - _rl_to_lower (*s2);
/* *s1 == [-_] && *s2 == [-_] */
if ((*s1 == '-' || *s1 == '_') && (*s2 == '-' || *s2 == '_'))
d = 0;
if (d != 0)
return 0;
s1++; s2++; /* already checked convlen >= filename_len */
}
while (--len != 0);
return 1;
}
else if (_rl_completion_case_fold)
{
if ((_rl_to_lower (convfn[0]) == _rl_to_lower (filename[0])) &&
(convlen >= filename_len) &&
(_rl_strnicmp (filename, convfn, filename_len) == 0))
return 1;
}
else
{
if ((convfn[0] == filename[0]) &&
(convlen >= filename_len) &&
(strncmp (filename, convfn, filename_len) == 0))
return 1;
}
return 0;
}
/* Okay, now we write the entry_function for filename completion. In the
general case. Note that completion in the shell is a little different
because of all the pathnames that must be followed when looking up the
@@ -2198,22 +2259,8 @@ rl_filename_completion_function (text, state)
}
else
{
/* Otherwise, if these match up to the length of filename, then
it is a match. */
if (_rl_completion_case_fold)
{
if ((_rl_to_lower (convfn[0]) == _rl_to_lower (filename[0])) &&
(convlen >= filename_len) &&
(_rl_strnicmp (filename, convfn, filename_len) == 0))
break;
}
else
{
if ((convfn[0] == filename[0]) &&
(convlen >= filename_len) &&
(strncmp (filename, convfn, filename_len) == 0))
break;
}
if (complete_fncmp (convfn, convlen, filename, filename_len))
break;
}
}
+89 -18
View File
@@ -119,6 +119,7 @@ static char **remove_duplicate_matches PARAMS((char **));
static void insert_match PARAMS((char *, int, int, char *));
static int append_to_match PARAMS((char *, int, int, int));
static void insert_all_matches PARAMS((char **, int, char *));
static int complete_fncmp PARAMS((const char *, int, const char *, int));
static void display_matches PARAMS((char **));
static int compute_lcd_of_matches PARAMS((char **, int, const char *));
static int postprocess_matches PARAMS((char ***, int));
@@ -158,9 +159,13 @@ int _rl_print_completions_horizontally;
#if defined (__MSDOS__) && !defined (__DJGPP__)
int _rl_completion_case_fold = 1;
#else
int _rl_completion_case_fold;
int _rl_completion_case_fold = 0;
#endif
/* Non-zero means that `-' and `_' are equivalent when comparing filenames
for completion. */
int _rl_completion_case_map = 1;
/* If zero, don't match hidden files (filenames beginning with a `.' on
Unix) when doing filename completion. */
int _rl_match_hidden_files = 1;
@@ -173,7 +178,7 @@ int _rl_completion_prefix_display_length = 0;
/* The readline-private number of screen columns to use when displaying
matches. If < 0 or > _rl_screenwidth, it is ignored. */
int _rl_completion_columns = 0;
int _rl_completion_columns = -1;
/* Global variables available to applications using readline. */
@@ -1784,6 +1789,9 @@ rl_complete_internal (what_to_do)
int start, end, delimiter, found_quote, i, nontrivial_lcd;
char *text, *saved_line_buffer;
char quote_char;
#if 1
int tlen, mlen;
#endif
RL_SETSTATE(RL_STATE_COMPLETING);
@@ -1811,6 +1819,10 @@ rl_complete_internal (what_to_do)
/* nontrivial_lcd is set if the common prefix adds something to the word
being completed. */
nontrivial_lcd = matches && strcmp (text, matches[0]) != 0;
#if 1
if (what_to_do == '!' || what_to_do == '@')
tlen = strlen (text);
#endif
free (text);
if (matches == 0)
@@ -1844,8 +1856,25 @@ rl_complete_internal (what_to_do)
case '!':
case '@':
/* Insert the first match with proper quoting. */
#if 0
if (*matches[0])
insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
#else
if (what_to_do == TAB)
{
if (*matches[0])
insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
}
else if (*matches[0] && matches[1] == 0)
/* should we perform the check only if there are multiple matches? */
insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
else if (*matches[0]) /* what_to_do != TAB && multiple matches */
{
mlen = *matches[0] ? strlen (matches[0]) : 0;
if (mlen >= tlen)
insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
}
#endif
/* If there are more matches, ring the bell to indicate.
If we are in vi mode, Posix.2 says to not ring the bell.
@@ -2032,6 +2061,62 @@ rl_username_completion_function (text, state)
#endif /* !__WIN32__ && !__OPENNT */
}
/* Return non-zero if CONVFN matches FILENAME up to the length of FILENAME
(FILENAME_LEN). If _rl_completion_case_fold is set, compare without
regard to the alphabetic case of characters. CONVFN is the possibly-
converted directory entry; FILENAME is what the user typed. */
static int
complete_fncmp (convfn, convlen, filename, filename_len)
const char *convfn;
int convlen;
const char *filename;
int filename_len;
{
register char *s1, *s2;
int d, len;
/* Otherwise, if these match up to the length of filename, then
it is a match. */
if (_rl_completion_case_fold && _rl_completion_case_map)
{
/* Case-insensitive comparison treating _ and - as equivalent */
if (filename_len == 0)
return 1;
if (convlen < filename_len)
return 0;
s1 = convfn;
s2 = filename;
len = filename_len;
do
{
d = _rl_to_lower (*s1) - _rl_to_lower (*s2);
/* *s1 == [-_] && *s2 == [-_] */
if ((*s1 == '-' || *s1 == '_') && (*s2 == '-' || *s2 == '_'))
d = 0;
if (d != 0)
return 0;
s1++; s2++; /* already checked convlen >= filename_len */
}
while (--len != 0);
return 1;
}
else if (_rl_completion_case_fold)
{
if ((_rl_to_lower (convfn[0]) == _rl_to_lower (filename[0])) &&
(convlen >= filename_len) &&
(_rl_strnicmp (filename, convfn, filename_len) == 0))
return 1;
}
else
{
if ((convfn[0] == filename[0]) &&
(convlen >= filename_len) &&
(strncmp (filename, convfn, filename_len) == 0))
return 1;
}
return 0;
}
/* Okay, now we write the entry_function for filename completion. In the
general case. Note that completion in the shell is a little different
because of all the pathnames that must be followed when looking up the
@@ -2174,22 +2259,8 @@ rl_filename_completion_function (text, state)
}
else
{
/* Otherwise, if these match up to the length of filename, then
it is a match. */
if (_rl_completion_case_fold)
{
if ((_rl_to_lower (convfn[0]) == _rl_to_lower (filename[0])) &&
(convlen >= filename_len) &&
(_rl_strnicmp (filename, convfn, filename_len) == 0))
break;
}
else
{
if ((convfn[0] == filename[0]) &&
(convlen >= filename_len) &&
(strncmp (filename, convfn, filename_len) == 0))
break;
}
if (complete_fncmp (convfn, convlen, filename, filename_len))
break;
}
}
+6 -1
View File
@@ -8,7 +8,7 @@
.\"
.\" Last Change: Thu Apr 22 18:59:21 EDT 2010
.\"
.TH READLINE 3 "2009 April 22" "GNU Readline 6.1"
.TH READLINE 3 "2010 April 22" "GNU Readline 6.1"
.\"
.\" File Name macro. This used to be `.PN', for Path Name,
.\" but Sun doesn't seem to like that very much.
@@ -373,6 +373,11 @@ The default value is -1.
If set to \fBOn\fP, readline performs filename matching and completion
in a case\-insensitive fashion.
.TP
.B completion\-map\-case (Off)
If set to \fBOn\fP, and \fBcompletion\-ignore\-case\fP is enabled, readline
treats hyphens (\fI\-\fP) and underscores (\fI_\fP) as equivalent when
performing case\-insensitive filename matching and completion.
.TP
.B completion\-prefix\-display\-length (0)
The length in characters of the common prefix of a list of possible
completions that is displayed without modification. When set to a
+11
View File
@@ -373,6 +373,11 @@ The default value is -1.
If set to \fBOn\fP, readline performs filename matching and completion
in a case\-insensitive fashion.
.TP
.B completion\-map\-case (Off)
If set to \fBOn\fP, and \fBcompletion\-ignore\-case\fP is enabled, readline
treats hyphens (\fI\-\fP) and underscores (\fI_\fP) as equivalent when
performing case\-insensitive filename matching and completion.
.TP
.B completion\-prefix\-display\-length (0)
The length in characters of the common prefix of a list of possible
completions that is displayed without modification. When set to a
@@ -931,6 +936,12 @@ only attempts filename completion under certain circumstances.
.TP
.B possible\-completions (M\-?)
List the possible completions of the text before point.
When displaying completions, readline sets the number of columns used
for display to the value of \fBcompletion-display-width\fP, the value of
the environment variable
.SM
.BR COLUMNS ,
or the screen width, in that order.
.TP
.B insert\-completions (M\-*)
Insert all completions of the text before point
+6
View File
@@ -446,6 +446,12 @@ If set to @samp{on}, Readline performs filename matching and completion
in a case-insensitive fashion.
The default value is @samp{off}.
@item completion-map-case
@vindex completion-map-case
If set to @samp{on}, and @var{completion-ignore-case} is enabled, Readline
treats hyphens (@samp{-}) and underscores (@samp{_}) as equivalent when
performing case-insensitive filename matching and completion.
@item completion-prefix-display-length
@vindex completion-prefix-display-length
The length in characters of the common prefix of a list of possible
+3 -3
View File
@@ -4,7 +4,7 @@ Copyright (C) 1988-2010 Free Software Foundation, Inc.
@set EDITION 6.1
@set VERSION 6.1
@set UPDATED April 22 2010
@set UPDATED-MONTH April 2010
@set UPDATED May 292010
@set UPDATED-MONTH May 2010
@set LASTCHANGE Thu Apr 22 18:59:44 EDT 2010
@set LASTCHANGE Sat May 29 17:14:10 EDT 2010
+2 -2
View File
@@ -4,7 +4,7 @@ Copyright (C) 1988-2010 Free Software Foundation, Inc.
@set EDITION 6.1
@set VERSION 6.1
@set UPDATED April 17 2010
@set UPDATED April 22 2010
@set UPDATED-MONTH April 2010
@set LASTCHANGE Sat Apr 17 23:45:29 EDT 2010
@set LASTCHANGE Thu Apr 22 18:59:44 EDT 2010
+6 -1
View File
@@ -1,6 +1,6 @@
/* funmap.c -- attach names to functions. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -148,6 +148,8 @@ static const FUNMAP default_funmap[] = {
{ "vi-append-mode", rl_vi_append_mode },
{ "vi-arg-digit", rl_vi_arg_digit },
{ "vi-back-to-indent", rl_vi_back_to_indent },
{ "vi-backward-bigword", rl_vi_bWord },
{ "vi-backward-word", rl_vi_bword },
{ "vi-bWord", rl_vi_bWord },
{ "vi-bword", rl_vi_bword },
{ "vi-change-case", rl_vi_change_case },
@@ -160,12 +162,15 @@ static const FUNMAP default_funmap[] = {
{ "vi-delete-to", rl_vi_delete_to },
{ "vi-eWord", rl_vi_eWord },
{ "vi-editing-mode", rl_vi_editing_mode },
{ "vi-end-bigword", rl_vi_eWord },
{ "vi-end-word", rl_vi_end_word },
{ "vi-eof-maybe", rl_vi_eof_maybe },
{ "vi-eword", rl_vi_eword },
{ "vi-fWord", rl_vi_fWord },
{ "vi-fetch-history", rl_vi_fetch_history },
{ "vi-first-print", rl_vi_first_print },
{ "vi-forward-bigword", rl_vi_fWord },
{ "vi-forward-word", rl_vi_fword },
{ "vi-fword", rl_vi_fword },
{ "vi-goto-mark", rl_vi_goto_mark },
{ "vi-insert-beg", rl_vi_insert_beg },
+263
View File
@@ -0,0 +1,263 @@
/* funmap.c -- attach names to functions. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#if !defined (BUFSIZ)
#include <stdio.h>
#endif /* BUFSIZ */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include "rlconf.h"
#include "readline.h"
#include "xmalloc.h"
#ifdef __STDC__
typedef int QSFUNC (const void *, const void *);
#else
typedef int QSFUNC ();
#endif
extern int _rl_qsort_string_compare PARAMS((char **, char **));
FUNMAP **funmap;
static int funmap_size;
static int funmap_entry;
/* After initializing the function map, this is the index of the first
program specific function. */
int funmap_program_specific_entry_start;
static const FUNMAP default_funmap[] = {
{ "abort", rl_abort },
{ "accept-line", rl_newline },
{ "arrow-key-prefix", rl_arrow_keys },
{ "backward-byte", rl_backward_byte },
{ "backward-char", rl_backward_char },
{ "backward-delete-char", rl_rubout },
{ "backward-kill-line", rl_backward_kill_line },
{ "backward-kill-word", rl_backward_kill_word },
{ "backward-word", rl_backward_word },
{ "beginning-of-history", rl_beginning_of_history },
{ "beginning-of-line", rl_beg_of_line },
{ "call-last-kbd-macro", rl_call_last_kbd_macro },
{ "capitalize-word", rl_capitalize_word },
{ "character-search", rl_char_search },
{ "character-search-backward", rl_backward_char_search },
{ "clear-screen", rl_clear_screen },
{ "complete", rl_complete },
{ "copy-backward-word", rl_copy_backward_word },
{ "copy-forward-word", rl_copy_forward_word },
{ "copy-region-as-kill", rl_copy_region_to_kill },
{ "delete-char", rl_delete },
{ "delete-char-or-list", rl_delete_or_show_completions },
{ "delete-horizontal-space", rl_delete_horizontal_space },
{ "digit-argument", rl_digit_argument },
{ "do-lowercase-version", rl_do_lowercase_version },
{ "downcase-word", rl_downcase_word },
{ "dump-functions", rl_dump_functions },
{ "dump-macros", rl_dump_macros },
{ "dump-variables", rl_dump_variables },
{ "emacs-editing-mode", rl_emacs_editing_mode },
{ "end-kbd-macro", rl_end_kbd_macro },
{ "end-of-history", rl_end_of_history },
{ "end-of-line", rl_end_of_line },
{ "exchange-point-and-mark", rl_exchange_point_and_mark },
{ "forward-backward-delete-char", rl_rubout_or_delete },
{ "forward-byte", rl_forward_byte },
{ "forward-char", rl_forward_char },
{ "forward-search-history", rl_forward_search_history },
{ "forward-word", rl_forward_word },
{ "history-search-backward", rl_history_search_backward },
{ "history-search-forward", rl_history_search_forward },
{ "insert-comment", rl_insert_comment },
{ "insert-completions", rl_insert_completions },
{ "kill-whole-line", rl_kill_full_line },
{ "kill-line", rl_kill_line },
{ "kill-region", rl_kill_region },
{ "kill-word", rl_kill_word },
{ "menu-complete", rl_menu_complete },
{ "menu-complete-backward", rl_backward_menu_complete },
{ "next-history", rl_get_next_history },
{ "non-incremental-forward-search-history", rl_noninc_forward_search },
{ "non-incremental-reverse-search-history", rl_noninc_reverse_search },
{ "non-incremental-forward-search-history-again", rl_noninc_forward_search_again },
{ "non-incremental-reverse-search-history-again", rl_noninc_reverse_search_again },
{ "old-menu-complete", rl_old_menu_complete },
{ "overwrite-mode", rl_overwrite_mode },
#ifdef __CYGWIN__
{ "paste-from-clipboard", rl_paste_from_clipboard },
#endif
{ "possible-completions", rl_possible_completions },
{ "previous-history", rl_get_previous_history },
{ "quoted-insert", rl_quoted_insert },
{ "re-read-init-file", rl_re_read_init_file },
{ "redraw-current-line", rl_refresh_line},
{ "reverse-search-history", rl_reverse_search_history },
{ "revert-line", rl_revert_line },
{ "self-insert", rl_insert },
{ "set-mark", rl_set_mark },
{ "skip-csi-sequence", rl_skip_csi_sequence },
{ "start-kbd-macro", rl_start_kbd_macro },
{ "tab-insert", rl_tab_insert },
{ "tilde-expand", rl_tilde_expand },
{ "transpose-chars", rl_transpose_chars },
{ "transpose-words", rl_transpose_words },
{ "tty-status", rl_tty_status },
{ "undo", rl_undo_command },
{ "universal-argument", rl_universal_argument },
{ "unix-filename-rubout", rl_unix_filename_rubout },
{ "unix-line-discard", rl_unix_line_discard },
{ "unix-word-rubout", rl_unix_word_rubout },
{ "upcase-word", rl_upcase_word },
{ "yank", rl_yank },
{ "yank-last-arg", rl_yank_last_arg },
{ "yank-nth-arg", rl_yank_nth_arg },
{ "yank-pop", rl_yank_pop },
#if defined (VI_MODE)
{ "vi-append-eol", rl_vi_append_eol },
{ "vi-append-mode", rl_vi_append_mode },
{ "vi-arg-digit", rl_vi_arg_digit },
{ "vi-back-to-indent", rl_vi_back_to_indent },
{ "vi-backward-bigword", rl_vi_bWord },
{ "vi-backward-word", rl_vi_bword },
{ "vi-bWord", rl_vi_bWord },
{ "vi-bword", rl_vi_bword },
{ "vi-change-case", rl_vi_change_case },
{ "vi-change-char", rl_vi_change_char },
{ "vi-change-to", rl_vi_change_to },
{ "vi-char-search", rl_vi_char_search },
{ "vi-column", rl_vi_column },
{ "vi-complete", rl_vi_complete },
{ "vi-delete", rl_vi_delete },
{ "vi-delete-to", rl_vi_delete_to },
{ "vi-eWord", rl_vi_eWord },
{ "vi-editing-mode", rl_vi_editing_mode },
{ "vi-end-bigword", rl_vi_eWord },
{ "vi-end-word", rl_vi_end_word },
{ "vi-eof-maybe", rl_vi_eof_maybe },
{ "vi-eword", rl_vi_eword },
{ "vi-fWord", rl_vi_fWord },
{ "vi-fetch-history", rl_vi_fetch_history },
{ "vi-first-print", rl_vi_first_print },
{ "vi-forward-bigword", rl_vi_fWord },
{ "vi-forward-word", rl_vi_fword },
{ "vi-fword", rl_vi_fword },
{ "vi-goto-mark", rl_vi_goto_mark },
{ "vi-insert-beg", rl_vi_insert_beg },
{ "vi-insertion-mode", rl_vi_insertion_mode },
{ "vi-match", rl_vi_match },
{ "vi-movement-mode", rl_vi_movement_mode },
{ "vi-next-word", rl_vi_next_word },
{ "vi-overstrike", rl_vi_overstrike },
{ "vi-overstrike-delete", rl_vi_overstrike_delete },
{ "vi-prev-word", rl_vi_prev_word },
{ "vi-put", rl_vi_put },
{ "vi-redo", rl_vi_redo },
{ "vi-replace", rl_vi_replace },
{ "vi-rubout", rl_vi_rubout },
{ "vi-search", rl_vi_search },
{ "vi-search-again", rl_vi_search_again },
{ "vi-set-mark", rl_vi_set_mark },
{ "vi-subst", rl_vi_subst },
{ "vi-tilde-expand", rl_vi_tilde_expand },
{ "vi-yank-arg", rl_vi_yank_arg },
{ "vi-yank-to", rl_vi_yank_to },
#endif /* VI_MODE */
{(char *)NULL, (rl_command_func_t *)NULL }
};
int
rl_add_funmap_entry (name, function)
const char *name;
rl_command_func_t *function;
{
if (funmap_entry + 2 >= funmap_size)
{
funmap_size += 64;
funmap = (FUNMAP **)xrealloc (funmap, funmap_size * sizeof (FUNMAP *));
}
funmap[funmap_entry] = (FUNMAP *)xmalloc (sizeof (FUNMAP));
funmap[funmap_entry]->name = name;
funmap[funmap_entry]->function = function;
funmap[++funmap_entry] = (FUNMAP *)NULL;
return funmap_entry;
}
static int funmap_initialized;
/* Make the funmap contain all of the default entries. */
void
rl_initialize_funmap ()
{
register int i;
if (funmap_initialized)
return;
for (i = 0; default_funmap[i].name; i++)
rl_add_funmap_entry (default_funmap[i].name, default_funmap[i].function);
funmap_initialized = 1;
funmap_program_specific_entry_start = i;
}
/* 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. */
const char **
rl_funmap_names ()
{
const char **result;
int result_size, result_index;
/* Make sure that the function map has been initialized. */
rl_initialize_funmap ();
for (result_index = result_size = 0, result = (const char **)NULL; funmap[result_index]; result_index++)
{
if (result_index + 2 > result_size)
{
result_size += 20;
result = (const char **)xrealloc (result, result_size * sizeof (char *));
}
result[result_index] = funmap[result_index]->name;
result[result_index + 1] = (char *)NULL;
}
qsort (result, result_index, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
return (result);
}
+1 -1
View File
@@ -1,6 +1,6 @@
/* histexpand.c -- history expansion. */
/* Copyright (C) 1989-2009 Free Software Foundation, Inc.
/* Copyright (C) 1989-2010 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
+1 -1
View File
@@ -1472,7 +1472,7 @@ history_tokenize_word (string, ind)
}
}
/* same mechanism also used for <(...)/>(...) above */
/* same code also used for $(...)/<(...)/>(...) above */
if (member (string[i], "!@?+*"))
{
int peek = string[i + 1];
+1 -1
View File
@@ -1,6 +1,6 @@
/* histfile.c - functions to manipulate the history file. */
/* Copyright (C) 1989-2009 Free Software Foundation, Inc.
/* Copyright (C) 1989-2010 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
+8 -3
View File
@@ -126,8 +126,12 @@ history_filename (filename)
if (home == 0)
{
#if 0
home = ".";
home_len = 1;
#else
return (NULL);
#endif
}
else
home_len = strlen (home);
@@ -179,7 +183,7 @@ read_history_range (filename, from, to)
buffer = last_ts = (char *)NULL;
input = history_filename (filename);
file = open (input, O_RDONLY|O_BINARY, 0666);
file = input ? open (input, O_RDONLY|O_BINARY, 0666) : -1;
if ((file < 0) || (fstat (file, &finfo) == -1))
goto error_and_exit;
@@ -314,7 +318,7 @@ history_truncate_file (fname, lines)
buffer = (char *)NULL;
filename = history_filename (fname);
file = open (filename, O_RDONLY|O_BINARY, 0666);
file = filename ? open (filename, O_RDONLY|O_BINARY, 0666) : -1;
rv = 0;
/* Don't try to truncate non-regular files. */
@@ -436,9 +440,10 @@ history_do_write (filename, nelements, overwrite)
mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY;
#endif
output = history_filename (filename);
file = output ? open (output, mode, 0600) : -1;
rv = 0;
if ((file = open (output, mode, 0600)) == -1)
if (file == -1)
{
FREE (output);
return (errno);
+1 -1
View File
@@ -1,6 +1,6 @@
/* input.c -- character input functions for readline. */
/* Copyright (C) 1994-2009 Free Software Foundation, Inc.
/* Copyright (C) 1994-2010 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
+7 -6
View File
@@ -133,7 +133,6 @@ rl_get_char (key)
#endif
pop_index = 0;
fprintf(stderr, "rl_get_char: returning 1 (key = %d)\n", *key);
return (1);
}
@@ -428,17 +427,19 @@ rl_read_key ()
/* If the user has an event function, then call it periodically. */
if (rl_event_hook)
{
while (rl_event_hook && rl_get_char (&c) == 0)
while (rl_event_hook)
{
(*rl_event_hook) ();
RL_CHECK_SIGNALS ();
if (rl_done) /* XXX - experimental */
return ('\n');
if (rl_gather_tyi () < 0) /* XXX - EIO */
{
rl_done = 1;
return ('\n');
}
RL_CHECK_SIGNALS ();
if (rl_get_char (&c) != 0)
break;
if (rl_done) /* XXX - experimental */
return ('\n');
(*rl_event_hook) ();
}
}
else
+24 -2
View File
@@ -1,7 +1,7 @@
/* rlprivate.h -- functions and variables global to the readline library,
but not intended for use by applications. */
/* Copyright (C) 1999-2009 Free Software Foundation, Inc.
/* Copyright (C) 1999-2010 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -120,7 +120,28 @@ typedef struct __rl_keyseq_context
int childval;
} _rl_keyseq_cxt;
/* fill in more as needed */
/* vi-mode commands that use result of motion command to define boundaries */
#define VIM_DELETE 0x01
#define VIM_CHANGE 0x02
#define VIM_YANK 0x04
/* various states for vi-mode commands that use motion commands. reflects
RL_READLINE_STATE */
#define VMSTATE_READ 0x01
#define VMSTATE_NUMARG 0x02
typedef struct __rl_vimotion_context
{
int op;
int state;
int flags; /* reserved */
_rl_arg_cxt ncxt;
int numeric_arg;
int start, end; /* rl_point, rl_end */
int key, motion; /* initial key, motion command */
} _rl_vimotion_cxt;
/* fill in more as needed */
/* `Generic' callback data and functions */
typedef struct __rl_callback_generic_arg
{
@@ -388,6 +409,7 @@ extern int _rl_completion_prefix_display_length;
extern int _rl_completion_columns;
extern int _rl_print_completions_horizontally;
extern int _rl_completion_case_fold;
extern int _rl_completion_case_map;
extern int _rl_match_hidden_files;
extern int _rl_page_completions;
extern int _rl_skip_completed_text;
+20 -2
View File
@@ -1,7 +1,7 @@
/* rlprivate.h -- functions and variables global to the readline library,
but not intended for use by applications. */
/* Copyright (C) 1999-2009 Free Software Foundation, Inc.
/* Copyright (C) 1999-2010 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -120,7 +120,23 @@ typedef struct __rl_keyseq_context
int childval;
} _rl_keyseq_cxt;
/* fill in more as needed */
/* vi-mode commands that use result of motion command to define boundaries */
#define VIM_DELETE 0x01
#define VIM_CHANGE 0x02
#define VIM_YANK 0x04
typedef struct __rl_vimotion_context
{
int op;
int state;
int flags; /* reserved */
_rl_arg_cxt ncxt;
int numeric_arg;
int start, end; /* rl_point, rl_end */
int key, motion; /* initial key, motion command */
} _rl_vimotion_cxt;
/* fill in more as needed */
/* `Generic' callback data and functions */
typedef struct __rl_callback_generic_arg
{
@@ -385,8 +401,10 @@ extern int _rl_complete_show_unmodified;
extern int _rl_complete_mark_directories;
extern int _rl_complete_mark_symlink_dirs;
extern int _rl_completion_prefix_display_length;
extern int _rl_completion_columns;
extern int _rl_print_completions_horizontally;
extern int _rl_completion_case_fold;
extern int _rl_completion_case_map;
extern int _rl_match_hidden_files;
extern int _rl_page_completions;
extern int _rl_skip_completed_text;
+1 -1
View File
@@ -1,6 +1,6 @@
/* text.c -- text handling commands for readline. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
+3
View File
@@ -1495,6 +1495,9 @@ _rl_char_search_internal (count, dir, schar)
int prepos;
#endif
if (dir == 0)
return -1;
pos = rl_point;
inc = (dir < 0) ? -1 : 1;
while (count)
+33 -18
View File
@@ -1,6 +1,6 @@
/* util.c -- readline utility functions */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -366,41 +366,56 @@ _rl_strpbrk (string1, string2)
#if !defined (HAVE_STRCASECMP)
/* Compare at most COUNT characters from string1 to string2. Case
doesn't matter. */
doesn't matter (strncasecmp). */
int
_rl_strnicmp (string1, string2, count)
char *string1, *string2;
int count;
{
register char ch1, ch2;
register char *s1, *s2;
int d;
while (count)
if (count <= 0 || (string1 == string2))
return 0;
s1 = string1;
s2 = string2;
do
{
ch1 = *string1++;
ch2 = *string2++;
if (_rl_to_upper(ch1) == _rl_to_upper(ch2))
count--;
else
d = _rl_to_lower (*s1) - _rl_to_lower (*s2); /* XXX - cast to unsigned char? */
if (d != 0)
return d;
if (*s1++ == '\0')
break;
s2++;
}
return (count);
while (--count != 0)
return (0);
}
/* strcmp (), but caseless. */
/* strcmp (), but caseless (strcasecmp). */
int
_rl_stricmp (string1, string2)
char *string1, *string2;
{
register char ch1, ch2;
register char *s1, *s2;
int d;
while (*string1 && *string2)
s1 = string1;
s2 = string2;
if (s1 == s2)
return 0;
while ((d = _rl_to_lower (*s1) - _rl_to_lower (*s2)) == 0)
{
ch1 = *string1++;
ch2 = *string2++;
if (_rl_to_upper(ch1) != _rl_to_upper(ch2))
return (1);
if (*s1++ == '\0')
return 0;
s2++;
}
return (*string1 - *string2);
return (d);
}
#endif /* !HAVE_STRCASECMP */
+526
View File
@@ -0,0 +1,526 @@
/* util.c -- readline utility functions */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
#include "posixjmp.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h> /* for _POSIX_VERSION */
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include <stdio.h>
#include <ctype.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#include "rlmbutil.h"
#if defined (TIOCSTAT_IN_SYS_IOCTL)
# include <sys/ioctl.h>
#endif /* TIOCSTAT_IN_SYS_IOCTL */
/* Some standard library routines. */
#include "readline.h"
#include "rlprivate.h"
#include "xmalloc.h"
/* **************************************************************** */
/* */
/* Utility Functions */
/* */
/* **************************************************************** */
/* Return 0 if C is not a member of the class of characters that belong
in words, or 1 if it is. */
int _rl_allow_pathname_alphabetic_chars = 0;
static const char * const pathname_alphabetic_chars = "/-_=~.#$";
int
rl_alphabetic (c)
int c;
{
if (ALPHABETIC (c))
return (1);
return (_rl_allow_pathname_alphabetic_chars &&
strchr (pathname_alphabetic_chars, c) != NULL);
}
#if defined (HANDLE_MULTIBYTE)
int
_rl_walphabetic (wchar_t wc)
{
int c;
if (iswalnum (wc))
return (1);
c = wc & 0177;
return (_rl_allow_pathname_alphabetic_chars &&
strchr (pathname_alphabetic_chars, c) != NULL);
}
#endif
/* How to abort things. */
int
_rl_abort_internal ()
{
rl_ding ();
rl_clear_message ();
_rl_reset_argument ();
rl_clear_pending_input ();
RL_UNSETSTATE (RL_STATE_MACRODEF);
while (rl_executing_macro)
_rl_pop_executing_macro ();
rl_last_func = (rl_command_func_t *)NULL;
longjmp (_rl_top_level, 1);
return (0);
}
int
rl_abort (count, key)
int count, key;
{
return (_rl_abort_internal ());
}
int
_rl_null_function (count, key)
int count, key;
{
return 0;
}
int
rl_tty_status (count, key)
int count, key;
{
#if defined (TIOCSTAT)
ioctl (1, TIOCSTAT, (char *)0);
rl_refresh_line (count, key);
#else
rl_ding ();
#endif
return 0;
}
/* Return a copy of the string between FROM and TO.
FROM is inclusive, TO is not. */
char *
rl_copy_text (from, to)
int from, to;
{
register int length;
char *copy;
/* Fix it if the caller is confused. */
if (from > to)
SWAP (from, to);
length = to - from;
copy = (char *)xmalloc (1 + length);
strncpy (copy, rl_line_buffer + from, length);
copy[length] = '\0';
return (copy);
}
/* Increase the size of RL_LINE_BUFFER until it has enough space to hold
LEN characters. */
void
rl_extend_line_buffer (len)
int len;
{
while (len >= rl_line_buffer_len)
{
rl_line_buffer_len += DEFAULT_BUFFER_SIZE;
rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len);
}
_rl_set_the_line ();
}
/* A function for simple tilde expansion. */
int
rl_tilde_expand (ignore, key)
int ignore, key;
{
register int start, end;
char *homedir, *temp;
int len;
end = rl_point;
start = end - 1;
if (rl_point == rl_end && rl_line_buffer[rl_point] == '~')
{
homedir = tilde_expand ("~");
_rl_replace_text (homedir, start, end);
xfree (homedir);
return (0);
}
else if (rl_line_buffer[start] != '~')
{
for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--)
;
start++;
}
end = start;
do
end++;
while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end);
if (whitespace (rl_line_buffer[end]) || end >= rl_end)
end--;
/* If the first character of the current word is a tilde, perform
tilde expansion and insert the result. If not a tilde, do
nothing. */
if (rl_line_buffer[start] == '~')
{
len = end - start + 1;
temp = (char *)xmalloc (len + 1);
strncpy (temp, rl_line_buffer + start, len);
temp[len] = '\0';
homedir = tilde_expand (temp);
xfree (temp);
_rl_replace_text (homedir, start, end);
xfree (homedir);
}
return (0);
}
#if defined (USE_VARARGS)
void
#if defined (PREFER_STDARG)
_rl_ttymsg (const char *format, ...)
#else
_rl_ttymsg (va_alist)
va_dcl
#endif
{
va_list args;
#if defined (PREFER_VARARGS)
char *format;
#endif
#if defined (PREFER_STDARG)
va_start (args, format);
#else
va_start (args);
format = va_arg (args, char *);
#endif
fprintf (stderr, "readline: ");
vfprintf (stderr, format, args);
fprintf (stderr, "\n");
fflush (stderr);
va_end (args);
rl_forced_update_display ();
}
void
#if defined (PREFER_STDARG)
_rl_errmsg (const char *format, ...)
#else
_rl_errmsg (va_alist)
va_dcl
#endif
{
va_list args;
#if defined (PREFER_VARARGS)
char *format;
#endif
#if defined (PREFER_STDARG)
va_start (args, format);
#else
va_start (args);
format = va_arg (args, char *);
#endif
fprintf (stderr, "readline: ");
vfprintf (stderr, format, args);
fprintf (stderr, "\n");
fflush (stderr);
va_end (args);
}
#else /* !USE_VARARGS */
void
_rl_ttymsg (format, arg1, arg2)
char *format;
{
fprintf (stderr, "readline: ");
fprintf (stderr, format, arg1, arg2);
fprintf (stderr, "\n");
rl_forced_update_display ();
}
void
_rl_errmsg (format, arg1, arg2)
char *format;
{
fprintf (stderr, "readline: ");
fprintf (stderr, format, arg1, arg2);
fprintf (stderr, "\n");
}
#endif /* !USE_VARARGS */
/* **************************************************************** */
/* */
/* String Utility Functions */
/* */
/* **************************************************************** */
/* Determine if s2 occurs in s1. If so, return a pointer to the
match in s1. The compare is case insensitive. */
char *
_rl_strindex (s1, s2)
register const char *s1, *s2;
{
register int i, l, len;
for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++)
if (_rl_strnicmp (s1 + i, s2, l) == 0)
return ((char *) (s1 + i));
return ((char *)NULL);
}
#ifndef HAVE_STRPBRK
/* Find the first occurrence in STRING1 of any character from STRING2.
Return a pointer to the character in STRING1. */
char *
_rl_strpbrk (string1, string2)
const char *string1, *string2;
{
register const char *scan;
#if defined (HANDLE_MULTIBYTE)
mbstate_t ps;
register int i, v;
memset (&ps, 0, sizeof (mbstate_t));
#endif
for (; *string1; string1++)
{
for (scan = string2; *scan; scan++)
{
if (*string1 == *scan)
return ((char *)string1);
}
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
v = _rl_get_char_len (string1, &ps);
if (v > 1)
string1 += v - 1; /* -1 to account for auto-increment in loop */
}
#endif
}
return ((char *)NULL);
}
#endif
#if !defined (HAVE_STRCASECMP)
/* Compare at most COUNT characters from string1 to string2. Case
doesn't matter (strncasecmp). */
int
_rl_strnicmp (string1, string2, count)
char *string1, *string2;
int count;
{
register char *s1, *s2;
int d;
if (count <= 0 || (string1 == string2))
return 0;
s1 = string1;
s2 = string2;
do
{
d = _rl_to_lower (*s1) - _rl_to_lower (*s2); /* XXX - cast to unsigned char? */
if (d != 0)
return d;
if (*s1++ == '\0')
break;
s2++;
}
while (--count != 0)
return (0);
}
/* strcmp (), but caseless (strcasecmp). */
int
_rl_stricmp (string1, string2)
char *string1, *string2;
{
register char *s1, *s2;
int d;
s1 = string1;
s2 = string2;
if (s1 == s2)
return 0;
while ((d = _rl_to_lower (*s1) - _rl_to_lower (*s2)) == 0)
{
if (*s1++ == '\0')
return 0;
s2++;
}
return (d);
}
#endif /* !HAVE_STRCASECMP */
/* Stupid comparison routine for qsort () ing strings. */
int
_rl_qsort_string_compare (s1, s2)
char **s1, **s2;
{
#if defined (HAVE_STRCOLL)
return (strcoll (*s1, *s2));
#else
int result;
result = **s1 - **s2;
if (result == 0)
result = strcmp (*s1, *s2);
return result;
#endif
}
/* Function equivalents for the macros defined in chardefs.h. */
#define FUNCTION_FOR_MACRO(f) int (f) (c) int c; { return f (c); }
FUNCTION_FOR_MACRO (_rl_digit_p)
FUNCTION_FOR_MACRO (_rl_digit_value)
FUNCTION_FOR_MACRO (_rl_lowercase_p)
FUNCTION_FOR_MACRO (_rl_pure_alphabetic)
FUNCTION_FOR_MACRO (_rl_to_lower)
FUNCTION_FOR_MACRO (_rl_to_upper)
FUNCTION_FOR_MACRO (_rl_uppercase_p)
/* A convenience function, to force memory deallocation to be performed
by readline. DLLs on Windows apparently require this. */
void
rl_free (mem)
void *mem;
{
if (mem)
free (mem);
}
/* Backwards compatibility, now that savestring has been removed from
all `public' readline header files. */
#undef _rl_savestring
char *
_rl_savestring (s)
const char *s;
{
return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s)));
}
#if defined (USE_VARARGS)
static FILE *_rl_tracefp;
void
#if defined (PREFER_STDARG)
_rl_trace (const char *format, ...)
#else
_rl_trace (va_alist)
va_dcl
#endif
{
va_list args;
#if defined (PREFER_VARARGS)
char *format;
#endif
#if defined (PREFER_STDARG)
va_start (args, format);
#else
va_start (args);
format = va_arg (args, char *);
#endif
if (_rl_tracefp == 0)
_rl_tropen ();
vfprintf (_rl_tracefp, format, args);
fprintf (_rl_tracefp, "\n");
fflush (_rl_tracefp);
va_end (args);
}
int
_rl_tropen ()
{
char fnbuf[128];
if (_rl_tracefp)
fclose (_rl_tracefp);
sprintf (fnbuf, "/var/tmp/rltrace.%ld", getpid());
unlink(fnbuf);
_rl_tracefp = fopen (fnbuf, "w+");
return _rl_tracefp != 0;
}
int
_rl_trclose ()
{
int r;
r = fclose (_rl_tracefp);
_rl_tracefp = 0;
return r;
}
#endif
+158 -37
View File
@@ -1,7 +1,7 @@
/* vi_mode.c -- A vi emulation mode for Bash.
Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -65,6 +65,8 @@
int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
_rl_vimotion_cxt *_rl_vimvcxt = 0;
/* Non-zero means enter insertion mode. */
static int _rl_vi_doing_insert;
@@ -128,6 +130,12 @@ static int _rl_vi_callback_change_char PARAMS((_rl_callback_generic_arg *));
static int _rl_vi_callback_char_search PARAMS((_rl_callback_generic_arg *));
#endif
static int vi_change_dispatch PARAMS((_rl_vimotion_cxt *));
static int vi_delete_dispatch PARAMS((_rl_vimotion_cxt *));
static int vi_yank_dispatch PARAMS((_rl_vimotion_cxt *));
static int vidomove_dispatch PARAMS((_rl_vimotion_cxt *));
void
_rl_vi_initialize_line ()
{
@@ -1076,28 +1084,60 @@ rl_digit_loop1 ()
return (0);
}
int
rl_vi_delete_to (count, key)
int count, key;
static void
_rl_mvcxt_init (m, op, key)
_rl_vimotion_cxt *m;
int op, key;
{
int c, start_pos;
m->op = op;
m->state = m->flags = 0;
m->ncxt = 0;
m->numeric_arg = -1;
m->start = rl_point;
m->end = rl_end;
m->key = key;
m->motion = -1;
}
if (_rl_uppercase_p (key))
rl_stuff_char ('$');
else if (vi_redoing)
rl_stuff_char (_rl_vi_last_motion);
static _rl_vimotion_cxt *
_rl_mvcxt_alloc (op, key)
int op, key;
{
_rl_vimotion_cxt *m;
start_pos = rl_point;
m = xmalloc (sizeof (_rl_vimotion_cxt));
_rl_mvcxt_init (m, op, key);
return m;
}
if (rl_vi_domove (key, &c))
{
rl_ding ();
return -1;
}
static void
_rl_mvcxt_dispose (m)
_rl_vimotion_cxt *m;
{
free (m);
}
/*
* 1. Create context, set initial values
* 2. Pass to rl_vi_domove to populate
* 3. Use returned context to finish rest of command
*
* Context:
* op
* state
* flags
* numeric arg
* start, end positions
* initial key (key), motion key (c)
*/
static int
vi_delete_dispatch (m)
_rl_vimotion_cxt *m;
{
/* These are the motion commands that do not require adjusting the
mark. */
if (((strchr (" l|h^0bBFT`", c) == 0) && (rl_point >= start_pos)) &&
if (((strchr (" l|h^0bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
(rl_mark < rl_end))
rl_mark++;
@@ -1106,34 +1146,47 @@ rl_vi_delete_to (count, key)
}
int
rl_vi_change_to (count, key)
rl_vi_delete_to (count, key)
int count, key;
{
int c, start_pos;
int c, r;
if (_rl_uppercase_p (key))
rl_stuff_char ('$');
else if (vi_redoing)
rl_stuff_char (_rl_vi_last_motion);
start_pos = rl_point;
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_DELETE, key);
_rl_vimvcxt->start = rl_point;
/* XXX -- TODO -- pass and use context in rl_vi_domove */
if (rl_vi_domove (key, &c))
{
rl_ding ();
return -1;
}
_rl_vimvcxt->motion = c;
r = vidomove_dispatch (_rl_vimvcxt);
_rl_mvcxt_dispose (_rl_vimvcxt);
_rl_vimvcxt = 0;
return r;
}
static int
vi_change_dispatch (m)
_rl_vimotion_cxt *m;
{
/* These are the motion commands that do not require adjusting the
mark. c[wW] are handled by special-case code in rl_vi_domove(),
and already leave the mark at the correct location. */
if (((strchr (" l|hwW^0bBFT`", c) == 0) && (rl_point >= start_pos)) &&
if (((strchr (" l|hwW^0bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
(rl_mark < rl_end))
rl_mark++;
/* The cursor never moves with c[wW]. */
if ((_rl_to_upper (c) == 'W') && rl_point < start_pos)
rl_point = start_pos;
if ((_rl_to_upper (m->motion) == 'W') && rl_point < m->start)
rl_point = m->start;
if (vi_redoing)
{
@@ -1151,44 +1204,112 @@ rl_vi_change_to (count, key)
rl_begin_undo_group (); /* to make the `u' command work */
rl_kill_text (rl_point, rl_mark);
/* `C' does not save the text inserted for undoing or redoing. */
if (_rl_uppercase_p (key) == 0)
if (_rl_uppercase_p (m->key) == 0)
_rl_vi_doing_insert = 1;
rl_vi_start_inserting (key, rl_numeric_arg, rl_arg_sign);
/* XXX -- TODO -- use m->numericarg? */
rl_vi_start_inserting (m->key, rl_numeric_arg, rl_arg_sign);
}
return (0);
}
int
rl_vi_change_to (count, key)
int count, key;
{
int c, r;
if (_rl_uppercase_p (key))
rl_stuff_char ('$');
else if (vi_redoing)
rl_stuff_char (_rl_vi_last_motion);
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_CHANGE, key);
_rl_vimvcxt->start = rl_point;
/* XXX -- TODO -- pass and use context in rl_vi_domove */
if (rl_vi_domove (key, &c))
{
rl_ding ();
return -1;
}
_rl_vimvcxt->motion = c;
r = vidomove_dispatch (_rl_vimvcxt);
_rl_mvcxt_dispose (_rl_vimvcxt);
_rl_vimvcxt = 0;
return r;
}
static int
vi_yank_dispatch (m)
_rl_vimotion_cxt *m;
{
/* These are the motion commands that do not require adjusting the
mark. */
if (((strchr (" l|h^0%bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
(rl_mark < rl_end))
rl_mark++;
rl_begin_undo_group ();
rl_kill_text (rl_point, rl_mark);
rl_end_undo_group ();
rl_do_undo ();
rl_point = m->start;
return (0);
}
int
rl_vi_yank_to (count, key)
int count, key;
{
int c, start_pos;
int c, r;
if (_rl_uppercase_p (key))
rl_stuff_char ('$');
start_pos = rl_point;
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_YANK, key);
_rl_vimvcxt->start = rl_point;
/* XXX -- TODO -- pass and use context in rl_vi_domove */
if (rl_vi_domove (key, &c))
{
rl_ding ();
return -1;
}
_rl_vimvcxt->motion = c;
/* These are the motion commands that do not require adjusting the
mark. */
if (((strchr (" l|h^0%bBFT`", c) == 0) && (rl_point >= start_pos)) &&
(rl_mark < rl_end))
rl_mark++;
r = vidomove_dispatch (_rl_vimvcxt);
_rl_mvcxt_dispose (_rl_vimvcxt);
_rl_vimvcxt = 0;
return r;
}
rl_begin_undo_group ();
rl_kill_text (rl_point, rl_mark);
rl_end_undo_group ();
rl_do_undo ();
rl_point = start_pos;
static int
vidomove_dispatch (m)
_rl_vimotion_cxt *m;
{
int r;
return (0);
switch (m->op)
{
case VIM_DELETE:
r = vi_delete_dispatch (m);
break;
case VIM_CHANGE:
r = vi_change_dispatch (m);
break;
case VIM_YANK:
r = vi_yank_dispatch (m);
break;
default:
fprintf (stderr, "vidomove_dispatch: unknown operator %d", m->op);
r = 1;
break;
}
return r;
}
int
File diff suppressed because it is too large Load Diff
+170 -48
View File
@@ -1,7 +1,7 @@
/* vi_mode.c -- A vi emulation mode for Bash.
Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -65,6 +65,8 @@
int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
_rl_vimotion_cxt *_rl_vimvcxt = 0;
/* Non-zero means enter insertion mode. */
static int _rl_vi_doing_insert;
@@ -128,6 +130,12 @@ static int _rl_vi_callback_change_char PARAMS((_rl_callback_generic_arg *));
static int _rl_vi_callback_char_search PARAMS((_rl_callback_generic_arg *));
#endif
static int vi_change_dispatch PARAMS((_rl_vimotion_cxt *));
static int vi_delete_dispatch PARAMS((_rl_vimotion_cxt *));
static int vi_yank_dispatch PARAMS((_rl_vimotion_cxt *));
static int vidomove_dispatch PARAMS((_rl_vimotion_cxt *));
void
_rl_vi_initialize_line ()
{
@@ -1076,28 +1084,60 @@ rl_digit_loop1 ()
return (0);
}
int
rl_vi_delete_to (count, key)
int count, key;
static void
_rl_mvcxt_init (m, op, key)
_rl_vimotion_cxt *m;
int op, key;
{
int c, start_pos;
m->op = op;
m->state = m->flags = 0;
m->ncxt = 0;
m->numeric_arg = -1;
m->start = rl_point;
m->end = rl_end;
m->key = key;
m->motion = -1;
}
if (_rl_uppercase_p (key))
rl_stuff_char ('$');
else if (vi_redoing)
rl_stuff_char (_rl_vi_last_motion);
static _rl_vimotion_cxt *
_rl_mvcxt_alloc (op, key)
int op, key;
{
_rl_vimotion_cxt *m;
start_pos = rl_point;
m = xmalloc (sizeof (_rl_vimotion_cxt));
_rl_mvcxt_init (m, op, key);
return m;
}
if (rl_vi_domove (key, &c))
{
rl_ding ();
return -1;
}
static void
_rl_mvcxt_dispose (m)
_rl_vimotion_cxt *m;
{
free (m);
}
/*
* 1. Create context, set initial values
* 2. Pass to rl_vi_domove to populate
* 3. Use returned context to finish rest of command
*
* Context:
* op
* state
* flags
* numeric arg
* start, end positions
* initial key (key), motion key (c)
*/
static int
vi_delete_dispatch (m)
_rl_vimotion_cxt *m;
{
/* These are the motion commands that do not require adjusting the
mark. */
if (((strchr (" l|h^0bBFT`", c) == 0) && (rl_point >= start_pos)) &&
if (((strchr (" l|h^0bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
(rl_mark < rl_end))
rl_mark++;
@@ -1106,34 +1146,47 @@ rl_vi_delete_to (count, key)
}
int
rl_vi_change_to (count, key)
rl_vi_delete_to (count, key)
int count, key;
{
int c, start_pos;
int c, r;
if (_rl_uppercase_p (key))
rl_stuff_char ('$');
else if (vi_redoing)
rl_stuff_char (_rl_vi_last_motion);
start_pos = rl_point;
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_DELETE, key);
_rl_vimvcxt->start = rl_point;
/* XXX -- TODO -- pass and use context in rl_vi_domove */
if (rl_vi_domove (key, &c))
{
rl_ding ();
return -1;
}
_rl_vimvcxt->motion = c;
r = vidomove_dispatch (_rl_vimvcxt);
_rl_mvcxt_dispose (_rl_vimvcxt);
_rl_vimvcxt = 0;
return r;
}
static int
vi_change_dispatch (m)
_rl_vimotion_cxt *m;
{
/* These are the motion commands that do not require adjusting the
mark. c[wW] are handled by special-case code in rl_vi_domove(),
and already leave the mark at the correct location. */
if (((strchr (" l|hwW^0bBFT`", c) == 0) && (rl_point >= start_pos)) &&
if (((strchr (" l|hwW^0bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
(rl_mark < rl_end))
rl_mark++;
/* The cursor never moves with c[wW]. */
if ((_rl_to_upper (c) == 'W') && rl_point < start_pos)
rl_point = start_pos;
if ((_rl_to_upper (m->motion) == 'W') && rl_point < m->start)
rl_point = m->start;
if (vi_redoing)
{
@@ -1151,44 +1204,112 @@ rl_vi_change_to (count, key)
rl_begin_undo_group (); /* to make the `u' command work */
rl_kill_text (rl_point, rl_mark);
/* `C' does not save the text inserted for undoing or redoing. */
if (_rl_uppercase_p (key) == 0)
if (_rl_uppercase_p (m->key) == 0)
_rl_vi_doing_insert = 1;
rl_vi_start_inserting (key, rl_numeric_arg, rl_arg_sign);
/* XXX -- TODO -- use m->numericarg? */
rl_vi_start_inserting (m->key, rl_numeric_arg, rl_arg_sign);
}
return (0);
}
int
rl_vi_change_to (count, key)
int count, key;
{
int c, r;
if (_rl_uppercase_p (key))
rl_stuff_char ('$');
else if (vi_redoing)
rl_stuff_char (_rl_vi_last_motion);
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_CHANGE, key);
_rl_vimvcxt->start = rl_point;
/* XXX -- TODO -- pass and use context in rl_vi_domove */
if (rl_vi_domove (key, &c))
{
rl_ding ();
return -1;
}
_rl_vimvcxt->motion = c;
r = vidomove_dispatch (_rl_vimvcxt);
_rl_mvcxt_dispose (_rl_vimvcxt);
_rl_vimvcxt = 0;
return r;
}
static int
vi_yank_dispatch (m)
_rl_vimotion_cxt *m;
{
/* These are the motion commands that do not require adjusting the
mark. */
if (((strchr (" l|h^0%bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
(rl_mark < rl_end))
rl_mark++;
rl_begin_undo_group ();
rl_kill_text (rl_point, rl_mark);
rl_end_undo_group ();
rl_do_undo ();
rl_point = m->start;
return (0);
}
int
rl_vi_yank_to (count, key)
int count, key;
{
int c, start_pos;
int c, r;
if (_rl_uppercase_p (key))
rl_stuff_char ('$');
start_pos = rl_point;
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_YANK, key);
_rl_vimvcxt->start = rl_point;
/* XXX -- TODO -- pass and use context in rl_vi_domove */
if (rl_vi_domove (key, &c))
{
rl_ding ();
return -1;
}
_rl_vimvcxt->motion = c;
/* These are the motion commands that do not require adjusting the
mark. */
if (((strchr (" l|h^0%bBFT`", c) == 0) && (rl_point >= start_pos)) &&
(rl_mark < rl_end))
rl_mark++;
r = vidomove_dispatch (_rl_vimvcxt);
_rl_mvcxt_dispose (_rl_vimvcxt);
_rl_vimvcxt = 0;
return r;
}
rl_begin_undo_group ();
rl_kill_text (rl_point, rl_mark);
rl_end_undo_group ();
rl_do_undo ();
rl_point = start_pos;
static int
vidomove_dispatch (m)
_rl_vimotion_cxt *m;
{
int r;
return (0);
switch (m->op)
{
case VIM_DELETE:
r = vi_delete_callback (m);
break;
case VIM_CHANGE:
r = vi_change_callback (m);
break;
case VIM_YANK:
r = vi_yank_callback (m);
break;
default:
fprintf (stderr, "vidomove_dispatch: unknown operator %d", m->op);
r = 1;
break;
}
return r;
}
int
@@ -1316,18 +1437,19 @@ rl_vi_char_search (count, key)
static char target;
#endif
if (_rl_cs_orig_dir == 0)
return -1;
#if defined (HANDLE_MULTIBYTE)
if (_rl_vi_last_search_mblen == 0)
return -1;
#else
if (_rl_vi_last_search_char == 0)
return -1;
#endif
if (key == ';' || key == ',')
_rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir;
{
if (_rl_cs_orig_dir == 0)
return -1;
#if defined (HANDLE_MULTIBYTE)
if (_rl_vi_last_search_mblen == 0)
return -1;
#else
if (_rl_vi_last_search_char == 0)
return -1;
#endif
_rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir;
}
else
{
switch (key)
+1 -1
View File
@@ -1,6 +1,6 @@
/* dprintf -- printf to a file descriptor */
/* Copyright (C) 2008,2009 Free Software Foundation, Inc.
/* Copyright (C) 2008-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+3 -3
View File
@@ -1,4 +1,4 @@
/* fdprintf -- printf to a file descriptor */
/* dprintf -- printf to a file descriptor */
/* Copyright (C) 2008,2009 Free Software Foundation, Inc.
@@ -38,9 +38,9 @@
int
#if defined (PREFER_STDARG)
fdprintf(int fd, const char *format, ...)
dprintf(int fd, const char *format, ...)
#else
fdprintf(fd, format, va_alist)
dprintf(fd, format, va_alist)
int fd;
const char *format;
va_dcl
+1 -1
View File
@@ -1,6 +1,6 @@
/* eaccess.c - eaccess replacement for the shell, plus other access functions. */
/* Copyright (C) 2006 Free Software Foundation, Inc.
/* Copyright (C) 2006-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+6 -1
View File
@@ -206,7 +206,12 @@ sh_eaccess (path, mode)
#if defined (HAVE_FACCESSAT) && defined (AT_EACCESS)
return (faccessat (AT_FDCWD, path, mode, AT_EACCESS));
#elif defined (HAVE_EACCESS) /* FreeBSD */
return (eaccess (path, mode)); /* XXX -- not always correct for X_OK */
ret = eaccess (path, mode); /* XXX -- not always correct for X_OK */
# if defined (__FreeBSD__)
if (ret == 0 && current_user.euid == 0 && mode == X_OK)
return (sh_stataccess (path, mode));
# endif
return ret;
#elif defined (EFF_ONLY_OK) /* SVR4(?), SVR4.2 */
return access (path, mode|EFF_ONLY_OK);
#else

Some files were not shown because too many files have changed in this diff Show More