commit bash-20141128 snapshot

This commit is contained in:
Chet Ramey
2014-12-02 16:15:47 -05:00
parent 0a233f3ec4
commit 09f70f2f67
59 changed files with 54337 additions and 2021 deletions
+112
View File
@@ -7409,3 +7409,115 @@ shell.c
isn't interactive (interactive_shell == 0)
- start_debugger: call force_execute_file instead of maybe_execute_file;
turn off debugging mode if it returns value < 0
11/24
-----
hashlib.h
- DEFAULT_HASH_BUCKETS: doubled to 128, cost in memory use is small but
changes traversal order when not sorting results
11/25
-----
doc/{bash.1,bashref.texi}
- make it clearer, by breaking it out into a separate paragraph, that
referencing an array without a subscript is equivalent to referencing
it with subscript 0
- add text saying that referencing any variable using a valid subscript
is OK
11/28
-----
arrayfunc.c
- bind_array_variable, bind_assoc_variable: allow binding value to a
readonly variable if the ASS_FORCE flag is set in the FLAGS
argument
subst.h
- ASS_FORCE: new assignment flag; means to allow assignment even if
variable is marked readonly
builtins/declare.def
- when assigning a value to an array or assoc variable using
something like `declare -r foo=bar' where foo is an existing array
variable, pass the ASS_FORCE to assign_array_var_from_string so
the assignment is allowed. Fixes debian bug 765759
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=765759
builtins/setattr.def
- var_attribute_string: new function to return (as argument) a char
array with attribute flag values for a given variable; returns the
length of the array
lib/sh/shquote.c
- sh_quote_reusable: function returning a version of its string
argument that is quoted for reuse
externs.h
- sh_quote_reusable: extern declaration
builtins/common.h
- MAX_ATTRIBUTES: define used to size arrays for attribute flag
characters
- var_attribute_string: new extern function declaration
subst.c
- array_remove_pattern: fixed a bug where `var' instead of `v' was
tested for invisible attribute
- get_var_and_type: fill in a valid *VARP if returning VT_VARIABLE
because callers may need to use it
- parameter_brace_transform: family of functions to implement the new
mksh-inspired ${param@spec} transformation word expansions. Some
of the operators transform the (expanded) value of the parameter,
the rest expand to information about the parameter itself
(array_transform, parameter_list_transform, list_transform,
string_transform, pos_params_assignment, array_var_assignment,
string_var_assignment)
- parameter_brace_expand: changes to parse the new `@' word expansion
operator and call parameter_brace_transform appropriately
- parameter_brace_expand: make sure we handle ${#@} as we have before
even in the presence of the new `@' operator
variables.c
- push_temp_var: make sure to call bind_variable_internal with the
ASS_FORCE flag so we override readonly variables created with
something like `tempvar=foo declare -r foo'.
- bind_variable_internal: honor ASS_FORCE flag to allow binding even
if a variable is readonly
execute_cmd.c
- struct func_array_state: new state to save state of BASH_LINENO,
BASH_SOURCE, and FUNCNAME during function execution so it can be
restored on a jump to top level
- restore_funcarray_state: new function to restore func_array_state
- execute_function: fill in func_array_state variable, add unwind-
protect to restore it on jump to top level, call explicitly at
end of function if subshell != 0 (may not be necessary, but safe
for now). Fixes bug with local assignments to FUNCNAME reported
by Arfrever Frehtes Taifersar Arahesis <arfrever.fta@gmail.com>
11/29
-----
arrayfunc.c
- assign_compound_array_list: turn off ASS_APPEND flag when processing
each individual assignment inside the parens in var+=(...). The
outer += should not affect assignments to existing subscripts;
those should be treated like usual assignments unless += supplied
inside the parens. Bug report from Maarten Billemont
<lhunath@lyndir.com>, fix from Eduardo A. Bustamante López
<dualbus@gmail.com>
config.h.in
- HAVE_PSELECT: define if pselect(2) available
configure.ac
- check for pselect(2), define HAVE_PSELECT if found
lib/readline/input.c
- rl_getc: use pselect(2) to wait for input ready on readline's
input fd or for a signal to arrive, will handle SIGWINCH (which
does not interrupt read(2)) and thus allow resize to happen without
having to wait to read more input. Only works if pselect available
and returns -1/EINTR on a signal even if the signal was installed
with SA_RESTART. From a suggestion from Egmont Koblinger
<egmont@gmail.com>
+127
View File
@@ -7392,3 +7392,130 @@ builtins/source.def
- maybe_pop_dollar_vars: call invalidate_cached_quoted_dollar_at just
to be safe
11/23
-----
builtins/evalfile.c
- _evalfile: return -1 if errno == ENOENT and the flags don't include
FEVAL_ENOENTOK. If we print an error message we should return an
error
- force_execute_file: new function, reads and executes commands from
a file but returns an error if file doesn't exist
builtins/common.h
- force_execute_file: new extern declaration
shell.c
- main: call start_debugger even if dollar_vars[1] == 0 if the shell
isn't interactive (interactive_shell == 0)
- start_debugger: call force_execute_file instead of maybe_execute_file;
turn off debugging mode if it returns value < 0
11/24
-----
hashlib.h
- DEFAULT_HASH_BUCKETS: doubled to 128, cost in memory use is small but
changes traversal order when not sorting results
11/25
-----
doc/{bash.1,bashref.texi}
- make it clearer, by breaking it out into a separate paragraph, that
referencing an array without a subscript is equivalent to referencing
it with subscript 0
- add text saying that referencing any variable using a valid subscript
is OK
11/28
-----
arrayfunc.c
- bind_array_variable, bind_assoc_variable: allow binding value to a
readonly variable if the ASS_FORCE flag is set in the FLAGS
argument
subst.h
- ASS_FORCE: new assignment flag; means to allow assignment even if
variable is marked readonly
builtins/declare.def
- when assigning a value to an array or assoc variable using
something like `declare -r foo=bar' where foo is an existing array
variable, pass the ASS_FORCE to assign_array_var_from_string so
the assignment is allowed. Fixes debian bug 765759
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=765759
builtins/setattr.def
- var_attribute_string: new function to return (as argument) a char
array with attribute flag values for a given variable; returns the
length of the array
lib/sh/shquote.c
- sh_quote_reusable: function returning a version of its string
argument that is quoted for reuse
externs.h
- sh_quote_reusable: extern declaration
builtins/common.h
- MAX_ATTRIBUTES: define used to size arrays for attribute flag
characters
- var_attribute_string: new extern function declaration
subst.c
- array_remove_pattern: fixed a bug where `var' instead of `v' was
tested for invisible attribute
- get_var_and_type: fill in a valid *VARP if returning VT_VARIABLE
because callers may need to use it
- parameter_brace_transform: family of functions to implement the new
mksh-inspired ${param@spec} transformation word expansions. Some
of the operators transform the (expanded) value of the parameter,
the rest expand to information about the parameter itself
(array_transform, parameter_list_transform, list_transform,
string_transform, pos_params_assignment, array_var_assignment,
string_var_assignment)
- parameter_brace_expand: changes to parse the new `@' word expansion
operator and call parameter_brace_transform appropriately
- parameter_brace_expand: make sure we handle ${#@} as we have before
even in the presence of the new `@' operator
variables.c
- push_temp_var: make sure to call bind_variable_internal with the
ASS_FORCE flag so we override readonly variables created with
something like `tempvar=foo declare -r foo'.
- bind_variable_internal: honor ASS_FORCE flag to allow binding even
if a variable is readonly
execute_cmd.c
- struct func_array_state: new state to save state of BASH_LINENO,
BASH_SOURCE, and FUNCNAME during function execution so it can be
restored on a jump to top level
- restore_funcarray_state: new function to restore func_array_state
- execute_function: fill in func_array_state variable, add unwind-
protect to restore it on jump to top level, call explicitly at
end of function if subshell != 0 (may not be necessary, but safe
for now). Fixes bug with local assignments to FUNCNAME reported
by Arfrever Frehtes Taifersar Arahesis <arfrever.fta@gmail.com>
11/29
-----
arrayfunc.c
- assign_compound_array_list: turn off ASS_APPEND flag when processing
each individual assignment inside the parens in var+=(...). The
outer += should not affect assignments to existing subscripts;
those should be treated like usual assignments unless += supplied
inside the parens. Bug report from Maarten Billemont
<lhunath@lyndir.com>, fix from Eduardo A. Bustamante López
<dualbus@gmail.com>
config.h.in
- HAVE_PSELECT: define if pselect(2) available
configure.ac
- check for pselect(2), define HAVE_PSELECT if found
lib/readline/input.c
- rl_getc: use pselect(2) to wait for input ready on readline's
input fd or for a signal to arrive, will handle SIGWINCH (which
does not interrupt read(2)) and thus allow resize to happen without
having to wait to read more input. From a suggestion from Egmont
Koblinger <egmont@gmail.com>
+2
View File
@@ -1048,6 +1048,7 @@ tests/new-exp6.sub f
tests/new-exp7.sub f
tests/new-exp8.sub f
tests/new-exp9.sub f
tests/new-exp10.sub f
tests/new-exp.right f
tests/nquote.tests f
tests/nquote.right f
@@ -1241,6 +1242,7 @@ tests/varenv3.sub f
tests/varenv4.sub f
tests/varenv5.sub f
tests/varenv6.sub f
tests/varenv7.sub f
tests/version f
tests/version.mini f
tests/vredir.tests f
+3
View File
@@ -972,6 +972,8 @@ tests/getopts4.sub f
tests/getopts5.sub f
tests/getopts6.sub f
tests/getopts7.sub f
tests/getopts8.sub f
tests/getopts9.sub f
tests/glob.tests f
tests/glob1.sub f
tests/glob.right f
@@ -1046,6 +1048,7 @@ tests/new-exp6.sub f
tests/new-exp7.sub f
tests/new-exp8.sub f
tests/new-exp9.sub f
tests/new-exp10.sub f
tests/new-exp.right f
tests/nquote.tests f
tests/nquote.right f
+1 -1
View File
@@ -882,7 +882,7 @@ depends: force
#### PRIVATE TARGETS ####
hashtest: hashlib.c
$(CC) -DTEST_HASHING $(CCFLAGS) -o $@ $(srcdir)/hashlib.c
$(CC) -DTEST_HASHING $(CCFLAGS) $(TEST_NBUCKETS) -o $@ $(srcdir)/hashlib.c xmalloc.o $(INTL_LIB)
############################ DEPENDENCIES ###############################
+5 -3
View File
@@ -203,7 +203,7 @@ bind_array_variable (name, ind, value, flags)
if (entry == (SHELL_VAR *) 0)
entry = make_new_array_variable (name);
else if (readonly_p (entry) || noassign_p (entry))
else if ((readonly_p (entry) && (flags&ASS_FORCE) == 0) || noassign_p (entry))
{
if (readonly_p (entry))
err_readonly (name);
@@ -237,7 +237,7 @@ bind_assoc_variable (entry, name, key, value, flags)
SHELL_VAR *dentry;
char *newval;
if (readonly_p (entry) || noassign_p (entry))
if ((readonly_p (entry) && (flags&ASS_FORCE) == 0) || noassign_p (entry))
{
if (readonly_p (entry))
err_readonly (name);
@@ -498,7 +498,9 @@ assign_compound_array_list (var, nlist, flags)
for (list = nlist; list; list = list->next)
{
iflags = flags;
/* Don't allow var+=(values) to make assignments in VALUES append to
existing values by default. */
iflags = flags & ~ASS_APPEND;
w = list->word->word;
/* We have a word of the form [ind]=value */
+1143
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -1,5 +1,5 @@
@%:@! /bin/sh
@%:@ From configure.ac for Bash 4.3, version 4.065.
@%:@ From configure.ac for Bash 4.3, version 4.066.
@%:@ Guess values for system-dependent variables and create Makefiles.
@%:@ Generated by GNU Autoconf 2.69 for bash 4.3-maint.
@%:@
@@ -9815,7 +9815,7 @@ fi
for ac_func in dup2 eaccess fcntl getdtablesize getgroups gethostname \
getpagesize getpeername getrlimit getrusage gettimeofday \
kill killpg lstat readlink sbrk select setdtablesize \
kill killpg lstat pselect readlink sbrk select setdtablesize \
setitimer tcgetpgrp uname ulimit waitpid
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+19 -19
View File
@@ -15,57 +15,57 @@
'configure.ac'
],
{
'_LT_AC_TAGCONFIG' => 1,
'AM_PROG_F77_C_O' => 1,
'AC_INIT' => 1,
'_LT_AC_TAGCONFIG' => 1,
'm4_pattern_forbid' => 1,
'_AM_COND_IF' => 1,
'AC_INIT' => 1,
'AC_CANONICAL_TARGET' => 1,
'AC_SUBST' => 1,
'_AM_COND_IF' => 1,
'AC_CONFIG_LIBOBJ_DIR' => 1,
'AC_FC_SRCEXT' => 1,
'AC_SUBST' => 1,
'AC_CANONICAL_HOST' => 1,
'AC_FC_SRCEXT' => 1,
'AC_PROG_LIBTOOL' => 1,
'AM_INIT_AUTOMAKE' => 1,
'AM_PATH_GUILE' => 1,
'AC_CONFIG_SUBDIRS' => 1,
'AM_PATH_GUILE' => 1,
'AM_AUTOMAKE_VERSION' => 1,
'LT_CONFIG_LTDL_DIR' => 1,
'AC_REQUIRE_AUX_FILE' => 1,
'AC_CONFIG_LINKS' => 1,
'm4_sinclude' => 1,
'AC_REQUIRE_AUX_FILE' => 1,
'LT_SUPPORTED_TAG' => 1,
'm4_sinclude' => 1,
'AM_MAINTAINER_MODE' => 1,
'AM_NLS' => 1,
'AC_FC_PP_DEFINE' => 1,
'AM_GNU_GETTEXT_INTL_SUBDIR' => 1,
'AM_MAKEFILE_INCLUDE' => 1,
'_m4_warn' => 1,
'AM_MAKEFILE_INCLUDE' => 1,
'AM_PROG_CXX_C_O' => 1,
'_AM_COND_ENDIF' => 1,
'_AM_MAKEFILE_INCLUDE' => 1,
'_AM_COND_ENDIF' => 1,
'AM_ENABLE_MULTILIB' => 1,
'AM_SILENT_RULES' => 1,
'AM_PROG_MOC' => 1,
'AC_CONFIG_FILES' => 1,
'include' => 1,
'LT_INIT' => 1,
'AM_PROG_AR' => 1,
'include' => 1,
'AM_GNU_GETTEXT' => 1,
'AM_PROG_AR' => 1,
'AC_LIBSOURCE' => 1,
'AM_PROG_FC_C_O' => 1,
'AC_CANONICAL_BUILD' => 1,
'AM_PROG_FC_C_O' => 1,
'AC_FC_FREEFORM' => 1,
'AH_OUTPUT' => 1,
'AC_FC_PP_SRCEXT' => 1,
'_AM_SUBST_NOTMAKE' => 1,
'AH_OUTPUT' => 1,
'AC_CONFIG_AUX_DIR' => 1,
'sinclude' => 1,
'AM_PROG_CC_C_O' => 1,
'_AM_SUBST_NOTMAKE' => 1,
'm4_pattern_allow' => 1,
'AM_XGETTEXT_OPTION' => 1,
'AC_CANONICAL_SYSTEM' => 1,
'AM_PROG_CC_C_O' => 1,
'sinclude' => 1,
'AM_CONDITIONAL' => 1,
'AC_CANONICAL_SYSTEM' => 1,
'AM_XGETTEXT_OPTION' => 1,
'AC_CONFIG_HEADERS' => 1,
'AC_DEFINE_TRACE_LITERAL' => 1,
'AM_POT_TOOLS' => 1,
+2
View File
@@ -1386,6 +1386,8 @@ m4trace:configure.ac:773: -1- AH_OUTPUT([HAVE_KILLPG], [/* Define to 1 if you ha
@%:@undef HAVE_KILLPG])
m4trace:configure.ac:773: -1- AH_OUTPUT([HAVE_LSTAT], [/* Define to 1 if you have the `lstat\' function. */
@%:@undef HAVE_LSTAT])
m4trace:configure.ac:773: -1- AH_OUTPUT([HAVE_PSELECT], [/* Define to 1 if you have the `pselect\' function. */
@%:@undef HAVE_PSELECT])
m4trace:configure.ac:773: -1- AH_OUTPUT([HAVE_READLINK], [/* Define to 1 if you have the `readlink\' function. */
@%:@undef HAVE_READLINK])
m4trace:configure.ac:773: -1- AH_OUTPUT([HAVE_SBRK], [/* Define to 1 if you have the `sbrk\' function. */
+4
View File
@@ -74,6 +74,9 @@ do { \
#define ARGS_FUNC 0x02
#define ARGS_SETBLTIN 0x04
/* Maximum number of attribute letters */
#define MAX_ATTRIBUTES 16
/* 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)));
@@ -180,6 +183,7 @@ extern int show_var_attributes __P((SHELL_VAR *, int, int));
extern int show_name_attributes __P((char *, int));
extern int show_func_attributes __P((char *, int));
extern void set_var_attribute __P((char *, int, int));
extern int var_attribute_string __P((SHELL_VAR *, int, char *));
/* Functions from pushd.def */
extern char *get_dirstack_from_string __P((char *));
+1
View File
@@ -195,6 +195,7 @@ 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 force_execute_file __P((const char *, int));
extern int source_file __P((const char *, int));
extern int fc_execute_file __P((const char *));
+1
View File
@@ -605,6 +605,7 @@ declare_internal (list, local_var)
VUNSETATTR (var, flags_off);
#if defined (ARRAY_VARS)
aflags |= ASS_FORCE;
if (offset && compound_array_assign)
assign_array_var_from_string (var, value, aflags);
else if (simple_array_assign && subscript_start)
+21 -9
View File
@@ -348,18 +348,12 @@ show_all_var_attributes (v, nodefs)
return (any_failed == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
/* Show the attributes for shell variable VAR. If NODEFS is non-zero,
don't show function definitions along with the name. If PATTR is
non-zero, it indicates we're being called from `export' or `readonly'.
In POSIX mode, this prints the name of the calling builtin (`export'
or `readonly') instead of `declare', and doesn't print function defs
when called by `export' or `readonly'. */
int
show_var_attributes (var, pattr, nodefs)
var_attribute_string (var, pattr, flags)
SHELL_VAR *var;
int pattr, nodefs;
int pattr;
char *flags; /* filled in with attributes */
{
char flags[16], *x;
int i;
i = 0;
@@ -417,6 +411,24 @@ show_var_attributes (var, pattr, nodefs)
}
flags[i] = '\0';
return i;
}
/* Show the attributes for shell variable VAR. If NODEFS is non-zero,
don't show function definitions along with the name. If PATTR is
non-zero, it indicates we're being called from `export' or `readonly'.
In POSIX mode, this prints the name of the calling builtin (`export'
or `readonly') instead of `declare', and doesn't print function defs
when called by `export' or `readonly'. */
int
show_var_attributes (var, pattr, nodefs)
SHELL_VAR *var;
int pattr, nodefs;
{
char flags[MAX_ATTRIBUTES], *x;
int i;
i = var_attribute_string (var, pattr, flags);
/* If we're printing functions with definitions, print the function def
first, then the attributes, instead of printing output that can't be
+3
View File
@@ -728,6 +728,9 @@
/* Define if you have the pathconf function. */
#undef HAVE_PATHCONF
/* Define if you have the pselect function. */
#undef HAVE_PSELECT
/* Define if you have the putenv function. */
#undef HAVE_PUTENV
+1160
View File
File diff suppressed because it is too large Load Diff
Vendored
+2 -2
View File
@@ -1,5 +1,5 @@
#! /bin/sh
# From configure.ac for Bash 4.3, version 4.065.
# From configure.ac for Bash 4.3, version 4.066.
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for bash 4.3-maint.
#
@@ -9815,7 +9815,7 @@ fi
for ac_func in dup2 eaccess fcntl getdtablesize getgroups gethostname \
getpagesize getpeername getrlimit getrusage gettimeofday \
kill killpg lstat readlink sbrk select setdtablesize \
kill killpg lstat pselect readlink sbrk select setdtablesize \
setitimer tcgetpgrp uname ulimit waitpid
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+2 -2
View File
@@ -21,7 +21,7 @@ dnl Process this file with autoconf to produce a configure script.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AC_REVISION([for Bash 4.3, version 4.065])dnl
AC_REVISION([for Bash 4.3, version 4.066])dnl
define(bashvers, 4.3)
define(relstatus, maint)
@@ -772,7 +772,7 @@ AC_CHECK_FUNC(mkfifo,AC_DEFINE(HAVE_MKFIFO),AC_DEFINE(MKFIFO_MISSING))
dnl checks for system calls
AC_CHECK_FUNCS(dup2 eaccess fcntl getdtablesize getgroups gethostname \
getpagesize getpeername getrlimit getrusage gettimeofday \
kill killpg lstat readlink sbrk select setdtablesize \
kill killpg lstat pselect readlink sbrk select setdtablesize \
setitimer tcgetpgrp uname ulimit waitpid)
AC_REPLACE_FUNCS(rename)
+1218
View File
File diff suppressed because it is too large Load Diff
+161 -154
View File
@@ -367,7 +367,7 @@ SSHHEELLLL GGRRAAMMMMAARR
of the operator is considered a pattern and matched according to
the rules described below under PPaatttteerrnn MMaattcchhiinngg, as if the eexxtt--
gglloobb shell option were enabled. The == operator is equivalent to
====. If the shell option nnooccaasseemmaattcchh is enabled, the match is
====. If the nnooccaasseemmaattcchh shell option is enabled, the match is
performed without regard to the case of alphabetic characters.
The return value is 0 if the string matches (====) or does not
match (!!==) the pattern, and 1 otherwise. Any part of the pat-
@@ -380,7 +380,7 @@ SSHHEELLLL GGRRAAMMMMAARR
sion and matched accordingly (as in _r_e_g_e_x(3)). The return value
is 0 if the string matches the pattern, and 1 otherwise. If the
regular expression is syntactically incorrect, the conditional
expression's return value is 2. If the shell option nnooccaasseemmaattcchh
expression's return value is 2. If the nnooccaasseemmaattcchh shell option
is enabled, the match is performed without regard to the case of
alphabetic characters. Any part of the pattern may be quoted to
force the quoted portion to be matched as a string. Bracket
@@ -458,7 +458,7 @@ SSHHEELLLL GGRRAAMMMMAARR
stitution and quote removal. Each _p_a_t_t_e_r_n examined is expanded
using tilde expansion, parameter and variable expansion, arith-
metic expansion, command substitution, and process substitution.
If the shell option nnooccaasseemmaattcchh is enabled, the match is per-
If the nnooccaasseemmaattcchh shell option is enabled, the match is per-
formed without regard to the case of alphabetic characters.
When a match is found, the corresponding _l_i_s_t is executed. If
the ;;;; operator is used, no subsequent matches are attempted
@@ -1667,12 +1667,14 @@ EEXXPPAANNSSIIOONN
ning of the expanded value of _p_a_r_a_m_e_t_e_r. If _p_a_t_t_e_r_n begins with
%%, it must match at the end of the expanded value of _p_a_r_a_m_e_t_e_r.
If _s_t_r_i_n_g is null, matches of _p_a_t_t_e_r_n are deleted and the // fol-
lowing _p_a_t_t_e_r_n may be omitted. If _p_a_r_a_m_e_t_e_r is @@ or **, the sub-
stitution operation is applied to each positional parameter in
turn, and the expansion is the resultant list. If _p_a_r_a_m_e_t_e_r is
an array variable subscripted with @@ or **, the substitution
operation is applied to each member of the array in turn, and
the expansion is the resultant list.
lowing _p_a_t_t_e_r_n may be omitted. If the nnooccaasseemmaattcchh shell option
is enabled, the match is performed without regard to the case of
alphabetic characters. If _p_a_r_a_m_e_t_e_r is @@ or **, the substitution
operation is applied to each positional parameter in turn, and
the expansion is the resultant list. If _p_a_r_a_m_e_t_e_r is an array
variable subscripted with @@ or **, the substitution operation is
applied to each member of the array in turn, and the expansion
is the resultant list.
${_p_a_r_a_m_e_t_e_r^^_p_a_t_t_e_r_n}
${_p_a_r_a_m_e_t_e_r^^^^_p_a_t_t_e_r_n}
@@ -1805,13 +1807,15 @@ EEXXPPAANNSSIIOONN
The GGLLOOBBIIGGNNOORREE shell variable may be used to restrict the set of file-
names matching a _p_a_t_t_e_r_n. If GGLLOOBBIIGGNNOORREE is set, each matching filename
that also matches one of the patterns in GGLLOOBBIIGGNNOORREE is removed from the
list of matches. The filenames ````..'''' and ````....'''' are always ignored
when GGLLOOBBIIGGNNOORREE is set and not null. However, setting GGLLOOBBIIGGNNOORREE to a
non-null value has the effect of enabling the ddoottgglloobb shell option, so
all other filenames beginning with a ````..'''' will match. To get the old
behavior of ignoring filenames beginning with a ````..'''', make ````..**'''' one
of the patterns in GGLLOOBBIIGGNNOORREE. The ddoottgglloobb option is disabled when
GGLLOOBBIIGGNNOORREE is unset.
list of matches. If the nnooccaasseegglloobb option is set, the matching against
the patterns in GGLLOOBBIIGGNNOORREE is performed without regard to case. The
filenames ````..'''' and ````....'''' are always ignored when GGLLOOBBIIGGNNOORREE is set
and not null. However, setting GGLLOOBBIIGGNNOORREE to a non-null value has the
effect of enabling the ddoottgglloobb shell option, so all other filenames
beginning with a ````..'''' will match. To get the old behavior of ignor-
ing filenames beginning with a ````..'''', make ````..**'''' one of the patterns
in GGLLOOBBIIGGNNOORREE. The ddoottgglloobb option is disabled when GGLLOOBBIIGGNNOORREE is
unset.
PPaatttteerrnn MMaattcchhiinngg
@@ -3689,7 +3693,9 @@ RREEAADDLLIINNEE
with a backslash; the backslash is removed before attempting a match.
Any completion that matches the pattern will be removed from the list.
A leading !! negates the pattern; in this case any completion not match-
ing the pattern will be removed.
ing the pattern will be removed. If the nnooccaasseemmaattcchh shell option is
enabled, the match is performed without regard to the case of alpha-
betic characters.
Finally, any prefix and suffix specified with the --PP and --SS options are
added to each member of the completion list, and the result is returned
@@ -5379,10 +5385,11 @@ SSHHEELLLL BBUUIILLTTIINN CCOOMMMMAANNDDSS
nnooccaasseemmaattcchh
If set, bbaasshh matches patterns in a case-insensitive
fashion when performing matching while executing ccaassee or
[[[[ conditional commands.
[[[[ conditional commands, or when filtering possible com-
pletions as part of programmable completion.
nnuullllgglloobb
If set, bbaasshh allows patterns which match no files (see
PPaatthhnnaammee EExxppaannssiioonn above) to expand to a null string,
If set, bbaasshh allows patterns which match no files (see
PPaatthhnnaammee EExxppaannssiioonn above) to expand to a null string,
rather than themselves.
pprrooggccoommpp
If set, the programmable completion facilities (see PPrroo--
@@ -5390,50 +5397,50 @@ SSHHEELLLL BBUUIILLTTIINN CCOOMMMMAANNDDSS
enabled by default.
pprroommppttvvaarrss
If set, prompt strings undergo parameter expansion, com-
mand substitution, arithmetic expansion, and quote
removal after being expanded as described in PPRROOMMPPTTIINNGG
mand substitution, arithmetic expansion, and quote
removal after being expanded as described in PPRROOMMPPTTIINNGG
above. This option is enabled by default.
rreessttrriicctteedd__sshheellll
The shell sets this option if it is started in
The shell sets this option if it is started in
restricted mode (see RREESSTTRRIICCTTEEDD SSHHEELLLL below). The value
may not be changed. This is not reset when the startup
files are executed, allowing the startup files to dis-
may not be changed. This is not reset when the startup
files are executed, allowing the startup files to dis-
cover whether or not a shell is restricted.
sshhiifftt__vveerrbboossee
If set, the sshhiifftt builtin prints an error message when
If set, the sshhiifftt builtin prints an error message when
the shift count exceeds the number of positional parame-
ters.
ssoouurrcceeppaatthh
If set, the ssoouurrccee (..) builtin uses the value of PPAATTHH to
find the directory containing the file supplied as an
find the directory containing the file supplied as an
argument. This option is enabled by default.
xxppgg__eecchhoo
If set, the eecchhoo builtin expands backslash-escape
If set, the eecchhoo builtin expands backslash-escape
sequences by default.
ssuussppeenndd [--ff]
Suspend the execution of this shell until it receives a SSIIGGCCOONNTT
Suspend the execution of this shell until it receives a SSIIGGCCOONNTT
signal. A login shell cannot be suspended; the --ff option can be
used to override this and force the suspension. The return sta-
tus is 0 unless the shell is a login shell and --ff is not sup-
tus is 0 unless the shell is a login shell and --ff is not sup-
plied, or if job control is not enabled.
tteesstt _e_x_p_r
[[ _e_x_p_r ]]
Return a status of 0 (true) or 1 (false) depending on the evalu-
ation of the conditional expression _e_x_p_r. Each operator and op-
erand must be a separate argument. Expressions are composed of
the primaries described above under CCOONNDDIITTIIOONNAALL EEXXPPRREESSSSIIOONNSS.
tteesstt does not accept any options, nor does it accept and ignore
erand must be a separate argument. Expressions are composed of
the primaries described above under CCOONNDDIITTIIOONNAALL EEXXPPRREESSSSIIOONNSS.
tteesstt does not accept any options, nor does it accept and ignore
an argument of ---- as signifying the end of options.
Expressions may be combined using the following operators,
Expressions may be combined using the following operators,
listed in decreasing order of precedence. The evaluation
depends on the number of arguments; see below. Operator prece-
depends on the number of arguments; see below. Operator prece-
dence is used when there are five or more arguments.
!! _e_x_p_r True if _e_x_p_r is false.
(( _e_x_p_r ))
Returns the value of _e_x_p_r. This may be used to override
Returns the value of _e_x_p_r. This may be used to override
the normal precedence of operators.
_e_x_p_r_1 -aa _e_x_p_r_2
True if both _e_x_p_r_1 and _e_x_p_r_2 are true.
@@ -5450,120 +5457,120 @@ SSHHEELLLL BBUUIILLTTIINN CCOOMMMMAANNDDSS
null.
2 arguments
If the first argument is !!, the expression is true if and
only if the second argument is null. If the first argu-
ment is one of the unary conditional operators listed
above under CCOONNDDIITTIIOONNAALL EEXXPPRREESSSSIIOONNSS, the expression is
only if the second argument is null. If the first argu-
ment is one of the unary conditional operators listed
above under CCOONNDDIITTIIOONNAALL EEXXPPRREESSSSIIOONNSS, the expression is
true if the unary test is true. If the first argument is
not a valid unary conditional operator, the expression is
false.
3 arguments
The following conditions are applied in the order listed.
If the second argument is one of the binary conditional
If the second argument is one of the binary conditional
operators listed above under CCOONNDDIITTIIOONNAALL EEXXPPRREESSSSIIOONNSS, the
result of the expression is the result of the binary test
using the first and third arguments as operands. The --aa
and --oo operators are considered binary operators when
there are three arguments. If the first argument is !!,
the value is the negation of the two-argument test using
using the first and third arguments as operands. The --aa
and --oo operators are considered binary operators when
there are three arguments. If the first argument is !!,
the value is the negation of the two-argument test using
the second and third arguments. If the first argument is
exactly (( and the third argument is exactly )), the result
is the one-argument test of the second argument. Other-
is the one-argument test of the second argument. Other-
wise, the expression is false.
4 arguments
If the first argument is !!, the result is the negation of
the three-argument expression composed of the remaining
the three-argument expression composed of the remaining
arguments. Otherwise, the expression is parsed and eval-
uated according to precedence using the rules listed
uated according to precedence using the rules listed
above.
5 or more arguments
The expression is parsed and evaluated according to
The expression is parsed and evaluated according to
precedence using the rules listed above.
When used with tteesstt or [[, the << and >> operators sort lexico-
When used with tteesstt or [[, the << and >> operators sort lexico-
graphically using ASCII ordering.
ttiimmeess Print the accumulated user and system times for the shell and
ttiimmeess Print the accumulated user and system times for the shell and
for processes run from the shell. The return status is 0.
ttrraapp [--llpp] [[_a_r_g] _s_i_g_s_p_e_c ...]
The command _a_r_g is to be read and executed when the shell
receives signal(s) _s_i_g_s_p_e_c. If _a_r_g is absent (and there is a
single _s_i_g_s_p_e_c) or --, each specified signal is reset to its
original disposition (the value it had upon entrance to the
shell). If _a_r_g is the null string the signal specified by each
_s_i_g_s_p_e_c is ignored by the shell and by the commands it invokes.
If _a_r_g is not present and --pp has been supplied, then the trap
commands associated with each _s_i_g_s_p_e_c are displayed. If no
arguments are supplied or if only --pp is given, ttrraapp prints the
list of commands associated with each signal. The --ll option
causes the shell to print a list of signal names and their cor-
responding numbers. Each _s_i_g_s_p_e_c is either a signal name
defined in <_s_i_g_n_a_l_._h>, or a signal number. Signal names are
The command _a_r_g is to be read and executed when the shell
receives signal(s) _s_i_g_s_p_e_c. If _a_r_g is absent (and there is a
single _s_i_g_s_p_e_c) or --, each specified signal is reset to its
original disposition (the value it had upon entrance to the
shell). If _a_r_g is the null string the signal specified by each
_s_i_g_s_p_e_c is ignored by the shell and by the commands it invokes.
If _a_r_g is not present and --pp has been supplied, then the trap
commands associated with each _s_i_g_s_p_e_c are displayed. If no
arguments are supplied or if only --pp is given, ttrraapp prints the
list of commands associated with each signal. The --ll option
causes the shell to print a list of signal names and their cor-
responding numbers. Each _s_i_g_s_p_e_c is either a signal name
defined in <_s_i_g_n_a_l_._h>, or a signal number. Signal names are
case insensitive and the SSIIGG prefix is optional.
If a _s_i_g_s_p_e_c is EEXXIITT (0) the command _a_r_g is executed on exit
from the shell. If a _s_i_g_s_p_e_c is DDEEBBUUGG, the command _a_r_g is exe-
cuted before every _s_i_m_p_l_e _c_o_m_m_a_n_d, _f_o_r command, _c_a_s_e command,
_s_e_l_e_c_t command, every arithmetic _f_o_r command, and before the
first command executes in a shell function (see SSHHEELLLL GGRRAAMMMMAARR
above). Refer to the description of the eexxttddeebbuugg option to the
If a _s_i_g_s_p_e_c is EEXXIITT (0) the command _a_r_g is executed on exit
from the shell. If a _s_i_g_s_p_e_c is DDEEBBUUGG, the command _a_r_g is exe-
cuted before every _s_i_m_p_l_e _c_o_m_m_a_n_d, _f_o_r command, _c_a_s_e command,
_s_e_l_e_c_t command, every arithmetic _f_o_r command, and before the
first command executes in a shell function (see SSHHEELLLL GGRRAAMMMMAARR
above). Refer to the description of the eexxttddeebbuugg option to the
sshhoopptt builtin for details of its effect on the DDEEBBUUGG trap. If a
_s_i_g_s_p_e_c is RREETTUURRNN, the command _a_r_g is executed each time a shell
function or a script executed with the .. or ssoouurrccee builtins fin-
ishes executing.
If a _s_i_g_s_p_e_c is EERRRR, the command _a_r_g is executed whenever a a
If a _s_i_g_s_p_e_c is EERRRR, the command _a_r_g is executed whenever a a
pipeline (which may consist of a single simple command), a list,
or a compound command returns a non-zero exit status, subject to
the following conditions. The EERRRR trap is not executed if the
the following conditions. The EERRRR trap is not executed if the
failed command is part of the command list immediately following
a wwhhiillee or uunnttiill keyword, part of the test in an _i_f statement,
a wwhhiillee or uunnttiill keyword, part of the test in an _i_f statement,
part of a command executed in a &&&& or |||| list except the command
following the final &&&& or ||||, any command in a pipeline but the
last, or if the command's return value is being inverted using
!!. These are the same conditions obeyed by the eerrrreexxiitt (--ee)
following the final &&&& or ||||, any command in a pipeline but the
last, or if the command's return value is being inverted using
!!. These are the same conditions obeyed by the eerrrreexxiitt (--ee)
option.
Signals ignored upon entry to the shell cannot be trapped or
reset. Trapped signals that are not being ignored are reset to
Signals ignored upon entry to the shell cannot be trapped or
reset. Trapped signals that are not being ignored are reset to
their original values in a subshell or subshell environment when
one is created. The return status is false if any _s_i_g_s_p_e_c is
one is created. The return status is false if any _s_i_g_s_p_e_c is
invalid; otherwise ttrraapp returns true.
ttyyppee [--aaffttppPP] _n_a_m_e [_n_a_m_e ...]
With no options, indicate how each _n_a_m_e would be interpreted if
With no options, indicate how each _n_a_m_e would be interpreted if
used as a command name. If the --tt option is used, ttyyppee prints a
string which is one of _a_l_i_a_s, _k_e_y_w_o_r_d, _f_u_n_c_t_i_o_n, _b_u_i_l_t_i_n, or
_f_i_l_e if _n_a_m_e is an alias, shell reserved word, function,
builtin, or disk file, respectively. If the _n_a_m_e is not found,
then nothing is printed, and an exit status of false is
returned. If the --pp option is used, ttyyppee either returns the
string which is one of _a_l_i_a_s, _k_e_y_w_o_r_d, _f_u_n_c_t_i_o_n, _b_u_i_l_t_i_n, or
_f_i_l_e if _n_a_m_e is an alias, shell reserved word, function,
builtin, or disk file, respectively. If the _n_a_m_e is not found,
then nothing is printed, and an exit status of false is
returned. If the --pp option is used, ttyyppee either returns the
name of the disk file that would be executed if _n_a_m_e were speci-
fied as a command name, or nothing if ``type -t name'' would not
return _f_i_l_e. The --PP option forces a PPAATTHH search for each _n_a_m_e,
return _f_i_l_e. The --PP option forces a PPAATTHH search for each _n_a_m_e,
even if ``type -t name'' would not return _f_i_l_e. If a command is
hashed, --pp and --PP print the hashed value, which is not necessar-
ily the file that appears first in PPAATTHH. If the --aa option is
used, ttyyppee prints all of the places that contain an executable
ily the file that appears first in PPAATTHH. If the --aa option is
used, ttyyppee prints all of the places that contain an executable
named _n_a_m_e. This includes aliases and functions, if and only if
the --pp option is not also used. The table of hashed commands is
not consulted when using --aa. The --ff option suppresses shell
not consulted when using --aa. The --ff option suppresses shell
function lookup, as with the ccoommmmaanndd builtin. ttyyppee returns true
if all of the arguments are found, false if any are not found.
uulliimmiitt [--HHSSaabbccddeeffiikkllmmnnppqqrrssttuuvvxxPPTT [_l_i_m_i_t]]
Provides control over the resources available to the shell and
to processes started by it, on systems that allow such control.
Provides control over the resources available to the shell and
to processes started by it, on systems that allow such control.
The --HH and --SS options specify that the hard or soft limit is set
for the given resource. A hard limit cannot be increased by a
non-root user once it is set; a soft limit may be increased up
to the value of the hard limit. If neither --HH nor --SS is speci-
for the given resource. A hard limit cannot be increased by a
non-root user once it is set; a soft limit may be increased up
to the value of the hard limit. If neither --HH nor --SS is speci-
fied, both the soft and hard limits are set. The value of _l_i_m_i_t
can be a number in the unit specified for the resource or one of
the special values hhaarrdd, ssoofftt, or uunnlliimmiitteedd, which stand for the
current hard limit, the current soft limit, and no limit,
respectively. If _l_i_m_i_t is omitted, the current value of the
soft limit of the resource is printed, unless the --HH option is
current hard limit, the current soft limit, and no limit,
respectively. If _l_i_m_i_t is omitted, the current value of the
soft limit of the resource is printed, unless the --HH option is
given. When more than one resource is specified, the limit name
and unit are printed before the value. Other options are inter-
preted as follows:
@@ -5572,12 +5579,12 @@ SSHHEELLLL BBUUIILLTTIINN CCOOMMMMAANNDDSS
--cc The maximum size of core files created
--dd The maximum size of a process's data segment
--ee The maximum scheduling priority ("nice")
--ff The maximum size of files written by the shell and its
--ff The maximum size of files written by the shell and its
children
--ii The maximum number of pending signals
--kk The maximum number of kqueues that may be allocated
--ll The maximum size that may be locked into memory
--mm The maximum resident set size (many systems do not honor
--mm The maximum resident set size (many systems do not honor
this limit)
--nn The maximum number of open file descriptors (most systems
do not allow this value to be set)
@@ -5586,52 +5593,52 @@ SSHHEELLLL BBUUIILLTTIINN CCOOMMMMAANNDDSS
--rr The maximum real-time scheduling priority
--ss The maximum stack size
--tt The maximum amount of cpu time in seconds
--uu The maximum number of processes available to a single
--uu The maximum number of processes available to a single
user
--vv The maximum amount of virtual memory available to the
--vv The maximum amount of virtual memory available to the
shell and, on some systems, to its children
--xx The maximum number of file locks
--PP The maximum number of pseudoterminals
--TT The maximum number of threads
If _l_i_m_i_t is given, and the --aa option is not used, _l_i_m_i_t is the
new value of the specified resource. If no option is given,
then --ff is assumed. Values are in 1024-byte increments, except
for --tt, which is in seconds; --pp, which is in units of 512-byte
blocks; and --PP, --TT, --bb, --kk, --nn, and --uu, which are unscaled val-
ues. The return status is 0 unless an invalid option or argu-
If _l_i_m_i_t is given, and the --aa option is not used, _l_i_m_i_t is the
new value of the specified resource. If no option is given,
then --ff is assumed. Values are in 1024-byte increments, except
for --tt, which is in seconds; --pp, which is in units of 512-byte
blocks; and --PP, --TT, --bb, --kk, --nn, and --uu, which are unscaled val-
ues. The return status is 0 unless an invalid option or argu-
ment is supplied, or an error occurs while setting a new limit.
uummaasskk [--pp] [--SS] [_m_o_d_e]
The user file-creation mask is set to _m_o_d_e. If _m_o_d_e begins with
a digit, it is interpreted as an octal number; otherwise it is
interpreted as a symbolic mode mask similar to that accepted by
_c_h_m_o_d(1). If _m_o_d_e is omitted, the current value of the mask is
printed. The --SS option causes the mask to be printed in sym-
bolic form; the default output is an octal number. If the --pp
a digit, it is interpreted as an octal number; otherwise it is
interpreted as a symbolic mode mask similar to that accepted by
_c_h_m_o_d(1). If _m_o_d_e is omitted, the current value of the mask is
printed. The --SS option causes the mask to be printed in sym-
bolic form; the default output is an octal number. If the --pp
option is supplied, and _m_o_d_e is omitted, the output is in a form
that may be reused as input. The return status is 0 if the mode
was successfully changed or if no _m_o_d_e argument was supplied,
was successfully changed or if no _m_o_d_e argument was supplied,
and false otherwise.
uunnaalliiaass [-aa] [_n_a_m_e ...]
Remove each _n_a_m_e from the list of defined aliases. If --aa is
supplied, all alias definitions are removed. The return value
Remove each _n_a_m_e from the list of defined aliases. If --aa is
supplied, all alias definitions are removed. The return value
is true unless a supplied _n_a_m_e is not a defined alias.
uunnsseett [-ffvv] [-nn] [_n_a_m_e ...]
For each _n_a_m_e, remove the corresponding variable or function.
For each _n_a_m_e, remove the corresponding variable or function.
If the --vv option is given, each _n_a_m_e refers to a shell variable,
and that variable is removed. Read-only variables may not be
unset. If --ff is specified, each _n_a_m_e refers to a shell func-
tion, and the function definition is removed. If the --nn option
is supplied, and _n_a_m_e is a variable with the _n_a_m_e_r_e_f attribute,
_n_a_m_e will be unset rather than the variable it references. --nn
has no effect if the --ff option is supplied. If no options are
supplied, each _n_a_m_e refers to a variable; if there is no vari-
able by that name, any function with that name is unset. Each
unset variable or function is removed from the environment
passed to subsequent commands. If any of CCOOMMPP__WWOORRDDBBRREEAAKKSS, RRAANN--
and that variable is removed. Read-only variables may not be
unset. If --ff is specified, each _n_a_m_e refers to a shell func-
tion, and the function definition is removed. If the --nn option
is supplied, and _n_a_m_e is a variable with the _n_a_m_e_r_e_f attribute,
_n_a_m_e will be unset rather than the variable it references. --nn
has no effect if the --ff option is supplied. If no options are
supplied, each _n_a_m_e refers to a variable; if there is no vari-
able by that name, any function with that name is unset. Each
unset variable or function is removed from the environment
passed to subsequent commands. If any of CCOOMMPP__WWOORRDDBBRREEAAKKSS, RRAANN--
DDOOMM, SSEECCOONNDDSS, LLIINNEENNOO, HHIISSTTCCMMDD, FFUUNNCCNNAAMMEE, GGRROOUUPPSS, or DDIIRRSSTTAACCKK are
unset, they lose their special properties, even if they are sub-
sequently reset. The exit status is true unless a _n_a_m_e is read-
@@ -5640,19 +5647,19 @@ SSHHEELLLL BBUUIILLTTIINN CCOOMMMMAANNDDSS
wwaaiitt [--nn] [_n _._._.]
Wait for each specified child process and return its termination
status. Each _n may be a process ID or a job specification; if a
job spec is given, all processes in that job's pipeline are
waited for. If _n is not given, all currently active child pro-
job spec is given, all processes in that job's pipeline are
waited for. If _n is not given, all currently active child pro-
cesses are waited for, and the return status is zero. If the --nn
option is supplied, wwaaiitt waits for any job to terminate and
returns its exit status. If _n specifies a non-existent process
or job, the return status is 127. Otherwise, the return status
option is supplied, wwaaiitt waits for any job to terminate and
returns its exit status. If _n specifies a non-existent process
or job, the return status is 127. Otherwise, the return status
is the exit status of the last process or job waited for.
RREESSTTRRIICCTTEEDD SSHHEELLLL
If bbaasshh is started with the name rrbbaasshh, or the --rr option is supplied at
invocation, the shell becomes restricted. A restricted shell is used
to set up an environment more controlled than the standard shell. It
behaves identically to bbaasshh with the exception that the following are
invocation, the shell becomes restricted. A restricted shell is used
to set up an environment more controlled than the standard shell. It
behaves identically to bbaasshh with the exception that the following are
disallowed or not performed:
+o changing directories with ccdd
@@ -5661,16 +5668,16 @@ RREESSTTRRIICCTTEEDD SSHHEELLLL
+o specifying command names containing //
+o specifying a filename containing a // as an argument to the ..
+o specifying a filename containing a // as an argument to the ..
builtin command
+o specifying a filename containing a slash as an argument to the
+o specifying a filename containing a slash as an argument to the
--pp option to the hhaasshh builtin command
+o importing function definitions from the shell environment at
+o importing function definitions from the shell environment at
startup
+o parsing the value of SSHHEELLLLOOPPTTSS from the shell environment at
+o parsing the value of SSHHEELLLLOOPPTTSS from the shell environment at
startup
+o redirecting output using the >, >|, <>, >&, &>, and >> redirect-
@@ -5679,10 +5686,10 @@ RREESSTTRRIICCTTEEDD SSHHEELLLL
+o using the eexxeecc builtin command to replace the shell with another
command
+o adding or deleting builtin commands with the --ff and --dd options
+o adding or deleting builtin commands with the --ff and --dd options
to the eennaabbllee builtin command
+o using the eennaabbllee builtin command to enable disabled shell
+o using the eennaabbllee builtin command to enable disabled shell
builtins
+o specifying the --pp option to the ccoommmmaanndd builtin command
@@ -5692,14 +5699,14 @@ RREESSTTRRIICCTTEEDD SSHHEELLLL
These restrictions are enforced after any startup files are read.
When a command that is found to be a shell script is executed (see CCOOMM--
MMAANNDD EEXXEECCUUTTIIOONN above), rrbbaasshh turns off any restrictions in the shell
MMAANNDD EEXXEECCUUTTIIOONN above), rrbbaasshh turns off any restrictions in the shell
spawned to execute the script.
SSEEEE AALLSSOO
_B_a_s_h _R_e_f_e_r_e_n_c_e _M_a_n_u_a_l, Brian Fox and Chet Ramey
_T_h_e _G_n_u _R_e_a_d_l_i_n_e _L_i_b_r_a_r_y, Brian Fox and Chet Ramey
_T_h_e _G_n_u _H_i_s_t_o_r_y _L_i_b_r_a_r_y, Brian Fox and Chet Ramey
_P_o_r_t_a_b_l_e _O_p_e_r_a_t_i_n_g _S_y_s_t_e_m _I_n_t_e_r_f_a_c_e _(_P_O_S_I_X_) _P_a_r_t _2_: _S_h_e_l_l _a_n_d _U_t_i_l_i_-
_P_o_r_t_a_b_l_e _O_p_e_r_a_t_i_n_g _S_y_s_t_e_m _I_n_t_e_r_f_a_c_e _(_P_O_S_I_X_) _P_a_r_t _2_: _S_h_e_l_l _a_n_d _U_t_i_l_i_-
_t_i_e_s, IEEE --
http://pubs.opengroup.org/onlinepubs/9699919799/
http://tiswww.case.edu/~chet/bash/POSIX -- a description of posix mode
@@ -5717,7 +5724,7 @@ FFIILLEESS
_~_/_._b_a_s_h_r_c
The individual per-interactive-shell startup file
_~_/_._b_a_s_h___l_o_g_o_u_t
The individual login shell cleanup file, executed when a login
The individual login shell cleanup file, executed when a login
shell exits
_~_/_._i_n_p_u_t_r_c
Individual _r_e_a_d_l_i_n_e initialization file
@@ -5731,14 +5738,14 @@ AAUUTTHHOORRSS
BBUUGG RREEPPOORRTTSS
If you find a bug in bbaasshh,, you should report it. But first, you should
make sure that it really is a bug, and that it appears in the latest
version of bbaasshh. The latest version is always available from
make sure that it really is a bug, and that it appears in the latest
version of bbaasshh. The latest version is always available from
_f_t_p_:_/_/_f_t_p_._g_n_u_._o_r_g_/_p_u_b_/_g_n_u_/_b_a_s_h_/.
Once you have determined that a bug actually exists, use the _b_a_s_h_b_u_g
command to submit a bug report. If you have a fix, you are encouraged
to mail that as well! Suggestions and `philosophical' bug reports may
be mailed to _b_u_g_-_b_a_s_h_@_g_n_u_._o_r_g or posted to the Usenet newsgroup
Once you have determined that a bug actually exists, use the _b_a_s_h_b_u_g
command to submit a bug report. If you have a fix, you are encouraged
to mail that as well! Suggestions and `philosophical' bug reports may
be mailed to _b_u_g_-_b_a_s_h_@_g_n_u_._o_r_g or posted to the Usenet newsgroup
ggnnuu..bbaasshh..bbuugg.
ALL bug reports should include:
@@ -5749,7 +5756,7 @@ BBUUGG RREEPPOORRTTSS
A description of the bug behaviour
A short script or `recipe' which exercises the bug
_b_a_s_h_b_u_g inserts the first three items automatically into the template
_b_a_s_h_b_u_g inserts the first three items automatically into the template
it provides for filing a bug report.
Comments and bug reports concerning this manual page should be directed
@@ -5766,10 +5773,10 @@ BBUUGGSS
Shell builtin commands and functions are not stoppable/restartable.
Compound commands and command sequences of the form `a ; b ; c' are not
handled gracefully when process suspension is attempted. When a
process is stopped, the shell immediately executes the next command in
the sequence. It suffices to place the sequence of commands between
parentheses to force it into a subshell, which may be stopped as a
handled gracefully when process suspension is attempted. When a
process is stopped, the shell immediately executes the next command in
the sequence. It suffices to place the sequence of commands between
parentheses to force it into a subshell, which may be stopped as a
unit.
Array variables may not (yet) be exported.
@@ -5778,4 +5785,4 @@ BBUUGGSS
GNU Bash 4.3 2014 November 19 BASH(1)
GNU Bash 4.3 2014 November 21 BASH(1)
+60 -4
View File
@@ -5,12 +5,12 @@
.\" Case Western Reserve University
.\" chet.ramey@case.edu
.\"
.\" Last Change: Fri Nov 21 08:07:56 EST 2014
.\" Last Change: Fri Nov 28 18:21:13 EST 2014
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
.TH BASH 1 "2014 November 21" "GNU Bash 4.3"
.TH BASH 1 "2014 November 28" "GNU Bash 4.3"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -2542,8 +2542,6 @@ of the special parameters \fB*\fP and \fB@\fP (see
above). ${#\fIname\fP[\fIsubscript\fP]} expands to the length of
${\fIname\fP[\fIsubscript\fP]}. If \fIsubscript\fP is \fB*\fP or
\fB@\fP, the expansion is the number of elements in the array.
Referencing an array variable without a subscript is equivalent to
referencing the array with a subscript of 0.
If the
.I subscript
used to reference an element of an indexed array
@@ -2552,6 +2550,12 @@ interpreted as relative to one greater than the maximum index of the array,
so negative indices count back from the end of the
array, and an index of \-1 references the last element.
.PP
Referencing an array variable without a subscript is equivalent to
referencing the array with a subscript of 0.
Any reference to a variable using a valid subscript is legal, and
.B bash
will create an array if necessary.
.PP
An array variable is considered set if a subscript has been assigned a
value. The null string is a valid value.
.PP
@@ -3118,6 +3122,57 @@ or
.BR * ,
the case modification operation is applied to each member of the
array in turn, and the expansion is the resultant list.
.TP
${\fIparameter\fP\fB@\fP\fIoperator\fP}
\fBParameter transformation\fP.
The expansion is either a transformation of the value of \fIparameter\fP
or information about \fIparameter\fP itself, depending on the value of
\fIoperator\fP. Each \fIoperator\fP is a single letter:
.sp 1
.RS
.PD 0
.TP
.B Q
The expansion is a string that is the value of \fIparameter\fP quoted in a
format that can be reused as input.
.TP
.B E
The expansion is a string that is the value of \fIparameter\fP with backslash
escape sequences expanded as with the \fB$'...'\fP quoting mechansim.
.TP
.B P
The expansion is a string that is the result of expanding the value of
\fIparameter\fP as if it were a prompt string (see \fBPROMPTING\fP below).
.TP
.B A
The expansion is a string in the form of a \fBdeclare\fP command that, if
evaluated, will recreate \fIparameter\fP with its attributes and value.
.TP
.B a
The expansion is a string consisting of flag values representing
\fIparameter\fP's attributes.
.PD
.PP
If
.I parameter
is
.B @
or
.BR * ,
the operation is applied to each positional
parameter in turn, and the expansion is the resultant list.
If
.I parameter
is an array variable subscripted with
.B @
or
.BR * ,
the case modification operation is applied to each member of the
array in turn, and the expansion is the resultant list.
.sp 1
The result of the expansion is subject to word splitting and pathname
expansion as described below.
.RE
.SS Command Substitution
.PP
\fICommand substitution\fP allows the output of a command to replace
@@ -9610,6 +9665,7 @@ If set,
.B bash
matches patterns in a case\-insensitive fashion when performing matching
while executing \fBcase\fP or \fB[[\fP conditional commands,
when performing pattern substitution word expansions,
or when filtering possible completions as part of programmable completion.
.TP 8
.B nullglob
+10471
View File
File diff suppressed because it is too large Load Diff
+40 -2
View File
@@ -2186,6 +2186,40 @@ If @var{parameter}
is an array variable subscripted with @samp{@@} or @samp{*},
the case modification operation is applied to each member of the
array in turn, and the expansion is the resultant list.
@item $@{@var{parameter}@@@var{operator}@}
The expansion is either a transformation of the value of @var{parameter}
or information about @var{parameter} itself, depending on the value of
@var{operator}. Each @var{operator} is a single letter:
@table @code
@item Q
The expansion is a string that is the value of @var{parameter} quoted in a
format that can be reused as input.
@item E
The expansion is a string that is the value of @var{parameter} with backslash
escape sequences expanded as with the @code{$'@dots{}'} quoting mechansim.
@item P
The expansion is a string that is the result of expanding the value of
@var{parameter} as if it were a prompt string (@pxref{Controlling the Prompt}).
@item A
The expansion is a string in the form of a @code{declare} command that, if
evaluated, will recreate @var{parameter} with its attributes and value.
@item a
The expansion is a string consisting of flag values representing
@var{parameter}'s attributes.
@end table
If @var{parameter} is @samp{@@} or @samp{*},
the operation is applied to each positional
parameter in turn, and the expansion is the resultant list.
If @var{parameter}
is an array variable subscripted with @samp{@@} or @samp{*},
the operation is applied to each member of the
array in turn, and the expansion is the resultant list.
The result of the expansion is subject to word splitting and pathname
expansion as described below.
@end table
@node Command Substitution
@@ -5185,6 +5219,7 @@ performing filename expansion.
If set, Bash matches patterns in a case-insensitive fashion when
performing matching while executing @code{case} or @code{[[}
conditional commands,
when performing pattern substitution word expansions,
or when filtering possible completions as part of programmable completion.
@item nullglob
@@ -6864,8 +6899,6 @@ expansion of the special parameters @samp{@@} and @samp{*}.
@code{$@{@var{name}[@var{subscript}]@}}.
If @var{subscript} is @samp{@@} or
@samp{*}, the expansion is the number of elements in the array.
Referencing an array variable without a subscript is equivalent to
referencing with a subscript of 0.
If the @var{subscript}
used to reference an element of an indexed array
evaluates to a number less than zero, it is
@@ -6873,6 +6906,11 @@ interpreted as relative to one greater than the maximum index of the array,
so negative indices count back from the end of the array,
and an index of -1 refers to the last element.
Referencing an array variable without a subscript is equivalent to
referencing with a subscript of 0.
Any reference to a variable using a valid subscript is legal, and
@code{bash} will create an array if necessary.
An array variable is considered set if a subscript has been assigned a
value. The null string is a valid value.
+8824
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -2,10 +2,10 @@
Copyright (C) 1988-2014 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Fri Nov 21 08:07:43 EST 2014
@set LASTCHANGE Fri Nov 28 18:36:44 EST 2014
@set EDITION 4.3
@set VERSION 4.3
@set UPDATED 21 November 2014
@set UPDATED 28 November 2014
@set UPDATED-MONTH November 2014
+11
View File
@@ -0,0 +1,11 @@
@ignore
Copyright (C) 1988-2014 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Fri Nov 21 08:07:43 EST 2014
@set EDITION 4.3
@set VERSION 4.3
@set UPDATED 21 November 2014
@set UPDATED-MONTH November 2014
+47 -12
View File
@@ -100,6 +100,18 @@ extern int errno;
# include "bashhist.h"
#endif
#if defined (ARRAY_VARS)
struct func_array_state
{
ARRAY *funcname_a;
SHELL_VAR *funcname_v;
ARRAY *source_a;
SHELL_VAR *source_v;
ARRAY *lineno_a;
SHELL_VAR *lineno_v;
};
#endif
extern int dollar_dollar_pid;
extern int posixly_correct;
extern int expand_aliases;
@@ -4461,6 +4473,25 @@ maybe_restore_getopt_state (gs)
free (gs);
}
#if defined (ARRAY_VARS)
static void
restore_funcarray_state (fa)
struct func_array_state *fa;
{
SHELL_VAR *nfv;
ARRAY *funcname_a;
array_pop (fa->source_a);
array_pop (fa->lineno_a);
GET_ARRAY_FROM_VAR ("FUNCNAME", nfv, funcname_a);
if (nfv == fa->funcname_v)
array_pop (funcname_a);
free (fa);
}
#endif
static int
execute_function (var, words, flags, fds_to_close, async, subshell)
SHELL_VAR *var;
@@ -4477,6 +4508,7 @@ execute_function (var, words, flags, fds_to_close, async, subshell)
ARRAY *funcname_a;
volatile ARRAY *bash_source_a;
volatile ARRAY *bash_lineno_a;
struct func_array_state *fa;
#endif
FUNCTION_DEF *shell_fn;
char *sfile, *t;
@@ -4591,6 +4623,18 @@ execute_function (var, words, flags, fds_to_close, async, subshell)
free (t);
#endif
#if defined (ARRAY_VARS)
fa = (struct func_array_state *)xmalloc (sizeof (struct func_array_state));
fa->source_a = bash_source_a;
fa->source_v = bash_source_v;
fa->lineno_a = bash_lineno_a;
fa->lineno_v = bash_lineno_v;
fa->funcname_a = funcname_a;
fa->funcname_v = funcname_v;
if (subshell == 0)
add_unwind_protect (restore_funcarray_state, fa);
#endif
/* The temporary environment for a function is supposed to apply to
all commands executed within the function body. */
@@ -4668,20 +4712,11 @@ execute_function (var, words, flags, fds_to_close, async, subshell)
if (subshell == 0)
run_unwind_frame ("function_calling");
#if defined (ARRAY_VARS)
/* These two variables cannot be unset, and cannot be affected by the
function. */
array_pop ((ARRAY *)bash_source_a);
array_pop ((ARRAY *)bash_lineno_a);
/* FUNCNAME can be unset, and so can potentially be changed by the
function. */
GET_ARRAY_FROM_VAR ("FUNCNAME", nfv, funcname_a);
if (nfv == funcname_v)
array_pop (funcname_a);
else
restore_funcarray_state (fa);
#endif
if (variable_context == 0 || this_shell_function == 0)
{
make_funcname_visible (0);
+5601
View File
File diff suppressed because it is too large Load Diff
+5601
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -323,6 +323,7 @@ extern char *sh_mkdoublequoted __P((const char *, int, int));
extern char *sh_un_double_quote __P((char *));
extern char *sh_backslash_quote __P((char *, const char *, int));
extern char *sh_backslash_quote_for_double_quotes __P((char *));
extern char *sh_quote_reusable __P((char *, int));
extern int sh_contains_shell_metas __P((char *));
extern int sh_contains_quotes __P((char *));
+517
View File
@@ -0,0 +1,517 @@
/* externs.h -- extern function declarations which do not appear in their
own header file. */
/* Copyright (C) 1993-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
/* Make sure that this is included *after* config.h! */
#if !defined (_EXTERNS_H_)
# define _EXTERNS_H_
#include "stdc.h"
/* Functions from expr.c. */
extern intmax_t evalexp __P((char *, int *));
/* Functions from print_cmd.c. */
#define FUNC_MULTILINE 0x01
#define FUNC_EXTERNAL 0x02
extern char *make_command_string __P((COMMAND *));
extern char *named_function_string __P((char *, COMMAND *, int));
extern void print_command __P((COMMAND *));
extern void print_simple_command __P((SIMPLE_COM *));
extern void print_word_list __P((WORD_LIST *, char *));
/* debugger support */
extern void print_for_command_head __P((FOR_COM *));
#if defined (SELECT_COMMAND)
extern void print_select_command_head __P((SELECT_COM *));
#endif
extern void print_case_command_head __P((CASE_COM *));
#if defined (DPAREN_ARITHMETIC)
extern void print_arith_command __P((WORD_LIST *));
#endif
#if defined (COND_COMMAND)
extern void print_cond_command __P((COND_COM *));
#endif
/* set -x support */
extern void xtrace_init __P((void));
#ifdef NEED_XTRACE_SET_DECL
extern void xtrace_set __P((int, FILE *));
#endif
extern void xtrace_fdchk __P((int));
extern void xtrace_reset __P((void));
extern char *indirection_level_string __P((void));
extern void xtrace_print_assignment __P((char *, char *, int, int));
extern void xtrace_print_word_list __P((WORD_LIST *, int));
extern void xtrace_print_for_command_head __P((FOR_COM *));
#if defined (SELECT_COMMAND)
extern void xtrace_print_select_command_head __P((SELECT_COM *));
#endif
extern void xtrace_print_case_command_head __P((CASE_COM *));
#if defined (DPAREN_ARITHMETIC)
extern void xtrace_print_arith_cmd __P((WORD_LIST *));
#endif
#if defined (COND_COMMAND)
extern void xtrace_print_cond_term __P((int, int, WORD_DESC *, char *, char *));
#endif
/* Functions from shell.c. */
extern void exit_shell __P((int)) __attribute__((__noreturn__));
extern void sh_exit __P((int)) __attribute__((__noreturn__));
extern void subshell_exit __P((int)) __attribute__((__noreturn__));
extern void disable_priv_mode __P((void));
extern void unbind_args __P((void));
#if defined (RESTRICTED_SHELL)
extern int shell_is_restricted __P((char *));
extern int maybe_make_restricted __P((char *));
#endif
extern void unset_bash_input __P((int));
extern void get_current_user_info __P((void));
/* Functions from eval.c. */
extern int reader_loop __P((void));
extern int parse_command __P((void));
extern int read_command __P((void));
/* Functions from braces.c. */
#if defined (BRACE_EXPANSION)
extern char **brace_expand __P((char *));
#endif
/* Miscellaneous functions from parse.y */
extern int yyparse __P((void));
extern int return_EOF __P((void));
extern char *xparse_dolparen __P((char *, char *, int *, int));
extern void reset_parser __P((void));
extern WORD_LIST *parse_string_to_word_list __P((char *, int, const char *));
extern int parser_in_command_position __P((void));
extern void free_pushed_string_input __P((void));
extern int parser_expanding_alias __P((void));
extern void parser_save_alias __P((void));
extern void parser_restore_alias __P((void));
extern char *decode_prompt_string __P((char *));
extern int get_current_prompt_level __P((void));
extern void set_current_prompt_level __P((int));
#if defined (HISTORY)
extern char *history_delimiting_chars __P((const char *));
#endif
/* Declarations for functions defined in locale.c */
extern void set_default_locale __P((void));
extern void set_default_locale_vars __P((void));
extern int set_locale_var __P((char *, char *));
extern int set_lang __P((char *, char *));
extern void set_default_lang __P((void));
extern char *get_locale_var __P((char *));
extern char *localetrans __P((char *, int, int *));
extern char *mk_msgstr __P((char *, int *));
extern char *localeexpand __P((char *, int, int, int, int *));
/* Declarations for functions defined in list.c. */
extern void list_walk __P((GENERIC_LIST *, sh_glist_func_t *));
extern void wlist_walk __P((WORD_LIST *, sh_icpfunc_t *));
extern GENERIC_LIST *list_reverse ();
extern int list_length ();
extern GENERIC_LIST *list_append ();
extern GENERIC_LIST *list_remove ();
/* Declarations for functions defined in stringlib.c */
extern int find_string_in_alist __P((char *, STRING_INT_ALIST *, int));
extern char *find_token_in_alist __P((int, STRING_INT_ALIST *, int));
extern int find_index_in_alist __P((char *, STRING_INT_ALIST *, int));
extern char *substring __P((const char *, int, int));
extern char *strsub __P((char *, char *, char *, int));
extern char *strcreplace __P((char *, int, char *, int));
extern void strip_leading __P((char *));
extern void strip_trailing __P((char *, int, int));
extern void xbcopy __P((char *, char *, int));
/* Functions from version.c. */
extern char *shell_version_string __P((void));
extern void show_shell_version __P((int));
/* Functions from the bash library, lib/sh/libsh.a. These should really
go into a separate include file. */
/* declarations for functions defined in lib/sh/casemod.c */
extern char *sh_modcase __P((const char *, char *, int));
/* Defines for flags argument to sh_modcase. These need to agree with what's
in lib/sh/casemode.c */
#define CASE_LOWER 0x0001
#define CASE_UPPER 0x0002
#define CASE_CAPITALIZE 0x0004
#define CASE_UNCAP 0x0008
#define CASE_TOGGLE 0x0010
#define CASE_TOGGLEALL 0x0020
#define CASE_UPFIRST 0x0040
#define CASE_LOWFIRST 0x0080
#define CASE_USEWORDS 0x1000
/* declarations for functions defined in lib/sh/clktck.c */
extern long get_clk_tck __P((void));
/* declarations for functions defined in lib/sh/clock.c */
extern void clock_t_to_secs ();
extern void print_clock_t ();
/* Declarations for functions defined in lib/sh/dprintf.c */
#if !defined (HAVE_DPRINTF)
extern void dprintf __P((int, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
#endif
/* Declarations for functions defined in lib/sh/fmtulong.c */
#define FL_PREFIX 0x01 /* add 0x, 0X, or 0 prefix as appropriate */
#define FL_ADDBASE 0x02 /* add base# prefix to converted value */
#define FL_HEXUPPER 0x04 /* use uppercase when converting to hex */
#define FL_UNSIGNED 0x08 /* don't add any sign */
extern char *fmtulong __P((unsigned long int, int, char *, size_t, int));
/* Declarations for functions defined in lib/sh/fmtulong.c */
#if defined (HAVE_LONG_LONG)
extern char *fmtullong __P((unsigned long long int, int, char *, size_t, int));
#endif
/* Declarations for functions defined in lib/sh/fmtumax.c */
extern char *fmtumax __P((uintmax_t, int, char *, size_t, int));
/* Declarations for functions defined in lib/sh/fnxform.c */
extern char *fnx_fromfs __P((char *, size_t));
extern char *fnx_tofs __P((char *, size_t));
/* Declarations for functions defined in lib/sh/fpurge.c */
#if defined NEED_FPURGE_DECL
#if !HAVE_DECL_FPURGE
#if HAVE_FPURGE
# define fpurge _bash_fpurge
#endif
extern int fpurge __P((FILE *stream));
#endif /* HAVE_DECL_FPURGE */
#endif /* NEED_FPURGE_DECL */
/* Declarations for functions defined in lib/sh/getcwd.c */
#if !defined (HAVE_GETCWD)
extern char *getcwd __P((char *, size_t));
#endif
/* Declarations for functions defined in lib/sh/input_avail.c */
extern int input_avail __P((int));
/* Declarations for functions defined in lib/sh/itos.c */
extern char *inttostr __P((intmax_t, char *, size_t));
extern char *itos __P((intmax_t));
extern char *mitos __P((intmax_t));
extern char *uinttostr __P((uintmax_t, char *, size_t));
extern char *uitos __P((uintmax_t));
/* declarations for functions defined in lib/sh/makepath.c */
#define MP_DOTILDE 0x01
#define MP_DOCWD 0x02
#define MP_RMDOT 0x04
#define MP_IGNDOT 0x08
extern char *sh_makepath __P((const char *, const char *, int));
/* declarations for functions defined in lib/sh/mbscasecmp.c */
#if !defined (HAVE_MBSCASECMP)
extern char *mbscasecmp __P((const char *, const char *));
#endif
/* declarations for functions defined in lib/sh/mbschr.c */
#if !defined (HAVE_MBSCHR)
extern char *mbschr __P((const char *, int));
#endif
/* declarations for functions defined in lib/sh/mbscmp.c */
#if !defined (HAVE_MBSCMP)
extern char *mbscmp __P((const char *, const char *));
#endif
/* declarations for functions defined in lib/sh/netconn.c */
extern int isnetconn __P((int));
/* declarations for functions defined in lib/sh/netopen.c */
extern int netopen __P((char *));
/* Declarations for functions defined in lib/sh/oslib.c */
#if !defined (HAVE_DUP2) || defined (DUP2_BROKEN)
extern int dup2 __P((int, int));
#endif
#if !defined (HAVE_GETDTABLESIZE)
extern int getdtablesize __P((void));
#endif /* !HAVE_GETDTABLESIZE */
#if !defined (HAVE_GETHOSTNAME)
extern int gethostname __P((char *, int));
#endif /* !HAVE_GETHOSTNAME */
extern int getmaxgroups __P((void));
extern long getmaxchild __P((void));
/* declarations for functions defined in lib/sh/pathcanon.c */
#define PATH_CHECKDOTDOT 0x0001
#define PATH_CHECKEXISTS 0x0002
#define PATH_HARDPATH 0x0004
#define PATH_NOALLOC 0x0008
extern char *sh_canonpath __P((char *, int));
/* declarations for functions defined in lib/sh/pathphys.c */
extern char *sh_physpath __P((char *, int));
extern char *sh_realpath __P((const char *, char *));
/* declarations for functions defined in lib/sh/setlinebuf.c */
#ifdef NEED_SH_SETLINEBUF_DECL
extern int sh_setlinebuf __P((FILE *));
#endif
/* declarations for functions defined in lib/sh/shaccess.c */
extern int sh_eaccess __P((char *, int));
/* declarations for functions defined in lib/sh/shmatch.c */
extern int sh_regmatch __P((const char *, const char *, int));
/* defines for flags argument to sh_regmatch. */
#define SHMAT_SUBEXP 0x001 /* save subexpressions in SH_REMATCH */
#define SHMAT_PWARN 0x002 /* print a warning message on invalid regexp */
/* declarations for functions defined in lib/sh/shmbchar.c */
extern size_t mbstrlen __P((const char *));
extern char *mbsmbchar __P((const char *));
extern int sh_mbsnlen __P((const char *, size_t, int));
/* declarations for functions defined in lib/sh/shquote.c */
extern char *sh_single_quote __P((const char *));
extern char *sh_double_quote __P((const char *));
extern char *sh_mkdoublequoted __P((const char *, int, int));
extern char *sh_un_double_quote __P((char *));
extern char *sh_backslash_quote __P((char *, const char *, int));
extern char *sh_backslash_quote_for_double_quotes __P((char *));
extern int sh_contains_shell_metas __P((char *));
extern int sh_contains_quotes __P((char *));
/* declarations for functions defined in lib/sh/spell.c */
extern int spname __P((char *, char *));
extern char *dirspell __P((char *));
/* declarations for functions defined in lib/sh/strcasecmp.c */
#if !defined (HAVE_STRCASECMP)
extern int strncasecmp __P((const char *, const char *, int));
extern int strcasecmp __P((const char *, const char *));
#endif /* HAVE_STRCASECMP */
/* declarations for functions defined in lib/sh/strcasestr.c */
#if ! HAVE_STRCASESTR
extern char *strcasestr __P((const char *, const char *));
#endif
/* declarations for functions defined in lib/sh/strchrnul.c */
#if ! HAVE_STRCHRNUL
extern char *strchrnul __P((const char *, int));
#endif
/* declarations for functions defined in lib/sh/strerror.c */
#if !defined (HAVE_STRERROR) && !defined (strerror)
extern char *strerror __P((int));
#endif
/* declarations for functions defined in lib/sh/strftime.c */
#if !defined (HAVE_STRFTIME) && defined (NEED_STRFTIME_DECL)
extern size_t strftime __P((char *, size_t, const char *, const struct tm *));
#endif
/* declarations for functions and structures defined in lib/sh/stringlist.c */
/* This is a general-purpose argv-style array struct. */
typedef struct _list_of_strings {
char **list;
int list_size;
int list_len;
} STRINGLIST;
typedef int sh_strlist_map_func_t __P((char *));
extern STRINGLIST *strlist_create __P((int));
extern STRINGLIST *strlist_resize __P((STRINGLIST *, int));
extern void strlist_flush __P((STRINGLIST *));
extern void strlist_dispose __P((STRINGLIST *));
extern int strlist_remove __P((STRINGLIST *, char *));
extern STRINGLIST *strlist_copy __P((STRINGLIST *));
extern STRINGLIST *strlist_merge __P((STRINGLIST *, STRINGLIST *));
extern STRINGLIST *strlist_append __P((STRINGLIST *, STRINGLIST *));
extern STRINGLIST *strlist_prefix_suffix __P((STRINGLIST *, char *, char *));
extern void strlist_print __P((STRINGLIST *, char *));
extern void strlist_walk __P((STRINGLIST *, sh_strlist_map_func_t *));
extern void strlist_sort __P((STRINGLIST *));
/* declarations for functions defined in lib/sh/stringvec.c */
extern char **strvec_create __P((int));
extern char **strvec_resize __P((char **, int));
extern char **strvec_mcreate __P((int));
extern char **strvec_mresize __P((char **, int));
extern void strvec_flush __P((char **));
extern void strvec_dispose __P((char **));
extern int strvec_remove __P((char **, char *));
extern int strvec_len __P((char **));
extern int strvec_search __P((char **, char *));
extern char **strvec_copy __P((char **));
extern int strvec_strcmp __P((char **, char **));
extern void strvec_sort __P((char **));
extern char **strvec_from_word_list __P((WORD_LIST *, int, int, int *));
extern WORD_LIST *strvec_to_word_list __P((char **, int, int));
/* declarations for functions defined in lib/sh/strnlen.c */
#if !defined (HAVE_STRNLEN)
extern size_t strnlen __P((const char *, size_t));
#endif
/* declarations for functions defined in lib/sh/strpbrk.c */
#if !defined (HAVE_STRPBRK)
extern char *strpbrk __P((const char *, const char *));
#endif
/* declarations for functions defined in lib/sh/strtod.c */
#if !defined (HAVE_STRTOD)
extern double strtod __P((const char *, char **));
#endif
/* declarations for functions defined in lib/sh/strtol.c */
#if !HAVE_DECL_STRTOL
extern long strtol __P((const char *, char **, int));
#endif
/* declarations for functions defined in lib/sh/strtoll.c */
#if defined (HAVE_LONG_LONG) && !HAVE_DECL_STRTOLL
extern long long strtoll __P((const char *, char **, int));
#endif
/* declarations for functions defined in lib/sh/strtoul.c */
#if !HAVE_DECL_STRTOUL
extern unsigned long strtoul __P((const char *, char **, int));
#endif
/* declarations for functions defined in lib/sh/strtoull.c */
#if defined (HAVE_LONG_LONG) && !HAVE_DECL_STRTOULL
extern unsigned long long strtoull __P((const char *, char **, int));
#endif
/* declarations for functions defined in lib/sh/strimax.c */
#if !HAVE_DECL_STRTOIMAX
extern intmax_t strtoimax __P((const char *, char **, int));
#endif
/* declarations for functions defined in lib/sh/strumax.c */
#if !HAVE_DECL_STRTOUMAX
extern uintmax_t strtoumax __P((const char *, char **, int));
#endif
/* declarations for functions defined in lib/sh/strtrans.c */
extern char *ansicstr __P((char *, int, int, int *, int *));
extern char *ansic_quote __P((char *, int, int *));
extern int ansic_shouldquote __P((const char *));
extern char *ansiexpand __P((char *, int, int, int *));
/* declarations for functions defined in lib/sh/timeval.c. No prototypes
so we don't have to count on having a definition of struct timeval in
scope when this file is included. */
extern void timeval_to_secs ();
extern void print_timeval ();
/* declarations for functions defined in lib/sh/tmpfile.c */
#define MT_USETMPDIR 0x0001
#define MT_READWRITE 0x0002
#define MT_USERANDOM 0x0004
extern char *sh_mktmpname __P((char *, int));
extern int sh_mktmpfd __P((char *, int, char **));
/* extern FILE *sh_mktmpfp __P((char *, int, char **)); */
/* declarations for functions defined in lib/sh/uconvert.c */
extern int uconvert __P((char *, long *, long *));
/* declarations for functions defined in lib/sh/ufuncs.c */
extern unsigned int falarm __P((unsigned int, unsigned int));
extern unsigned int fsleep __P((unsigned int, unsigned int));
/* declarations for functions defined in lib/sh/unicode.c */
extern int u32cconv __P((unsigned long, char *));
extern void u32reset __P((void));
/* declarations for functions defined in lib/sh/wcsnwidth.c */
#if defined (HANDLE_MULTIBYTE)
extern int wcsnwidth __P((const wchar_t *, size_t, int));
#endif
/* declarations for functions defined in lib/sh/winsize.c */
extern void get_new_window_size __P((int, int *, int *));
/* declarations for functions defined in lib/sh/zcatfd.c */
extern int zcatfd __P((int, int, char *));
/* declarations for functions defined in lib/sh/zgetline.c */
extern ssize_t zgetline __P((int, char **, size_t *, int, int));
/* declarations for functions defined in lib/sh/zmapfd.c */
extern int zmapfd __P((int, char **, char *));
/* declarations for functions defined in lib/sh/zread.c */
extern ssize_t zread __P((int, char *, size_t));
extern ssize_t zreadretry __P((int, char *, size_t));
extern ssize_t zreadintr __P((int, char *, size_t));
extern ssize_t zreadc __P((int, char *));
extern ssize_t zreadcintr __P((int, char *));
extern ssize_t zreadn __P((int, char *, size_t));
extern void zreset __P((void));
extern void zsyncfd __P((int));
/* declarations for functions defined in lib/sh/zwrite.c */
extern int zwrite __P((int, char *, size_t));
/* declarations for functions defined in lib/glob/gmisc.c */
extern int match_pattern_char __P((char *, char *, int));
extern int umatchlen __P((char *, size_t));
#if defined (HANDLE_MULTIBYTE)
extern int match_pattern_wchar __P((wchar_t *, wchar_t *, int));
extern int wmatchlen __P((wchar_t *, size_t));
#endif
#endif /* _EXTERNS_H_ */
+10
View File
@@ -179,6 +179,7 @@ hash_search (string, table, flags)
for (list = table->bucket_array ? table->bucket_array[bucket] : 0; list; list = list->next)
{
/* This is the comparison function */
if (hv == list->khash && STREQ (list->key, string))
{
list->times_found++;
@@ -402,13 +403,22 @@ fatal_error (const char *format, ...)
abort();
}
void
internal_warning (const char *format, ...)
{
}
main ()
{
char string[256];
int count = 0;
BUCKET_CONTENTS *tt;
#if defined (TEST_NBUCKETS)
table = hash_create (TEST_NBUCKETS);
#else
table = hash_create (0);
#endif
for (;;)
{
+1 -1
View File
@@ -73,7 +73,7 @@ extern unsigned int hash_string __P((const char *));
(BUCKET_CONTENTS *)NULL)
/* Default number of buckets in the hash table. */
#define DEFAULT_HASH_BUCKETS 64 /* was 107, then 53, must be power of two now */
#define DEFAULT_HASH_BUCKETS 128 /* must be power of two */
#define HASH_ENTRIES(ht) ((ht) ? (ht)->nentries : 0)
+23 -3
View File
@@ -477,6 +477,10 @@ rl_getc (stream)
{
int result;
unsigned char c;
#if defined (HAVE_PSELECT)
sigset_t empty_set;
fd_set readfds;
#endif
while (1)
{
@@ -488,7 +492,19 @@ rl_getc (stream)
if (isatty (fileno (stream)))
return (getch ());
#endif
result = read (fileno (stream), &c, sizeof (unsigned char));
result = 0;
#if defined (HAVE_PSELECT)
sigemptyset (&empty_set);
FD_ZERO (&readfds);
FD_SET (fileno (stream), &readfds);
result = pselect (fileno (stream) + 1, &readfds, NULL, NULL, NULL, &empty_set);
# if 0
if (result < 0 && errno == EINTR)
goto handle_error;
# endif
#endif
if (result >= 0)
result = read (fileno (stream), &c, sizeof (unsigned char));
if (result == sizeof (unsigned char))
return (c);
@@ -527,20 +543,24 @@ rl_getc (stream)
/* fprintf(stderr, "rl_getc: result = %d errno = %d\n", result, errno); */
handle_error:
/* If the error that we received was EINTR, then try again,
this is simply an interrupted system call to read (). We allow
the read to be interrupted if we caught SIGHUP or SIGTERM (but
not SIGINT; let the signal handler deal with that), but if the
the read to be interrupted if we caught SIGHUP, SIGTERM, or any
of the other signals readline treats specially. If the
application sets an event hook, call it for other signals.
Otherwise (not EINTR), some error occurred, also signifying EOF. */
if (errno != EINTR)
return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
/* fatal signals of interest */
else if (_rl_caught_signal == SIGHUP || _rl_caught_signal == SIGTERM)
return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
/* keyboard-generated signals of interest */
else if (_rl_caught_signal == SIGINT || _rl_caught_signal == SIGQUIT)
RL_CHECK_SIGNALS ();
/* non-keyboard-generated signals of interest */
else if (_rl_caught_signal == SIGWINCH)
RL_CHECK_SIGNALS ();
else if (_rl_caught_signal == SIGALRM
#if defined (SIGVTALRM)
|| _rl_caught_signal == SIGVTALRM
+657
View File
@@ -0,0 +1,657 @@
/* input.c -- character input functions for readline. */
/* Copyright (C) 1994-2013 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 (__TANDEM)
# include <floss.h>
#endif
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
#if defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
#endif /* HAVE_SYS_FILE_H */
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include <signal.h>
#include "posixselect.h"
#if defined (FIONREAD_IN_SYS_IOCTL)
# include <sys/ioctl.h>
#endif
#include <stdio.h>
#include <errno.h>
#if !defined (errno)
extern int errno;
#endif /* !errno */
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#include "rlmbutil.h"
/* Some standard library routines. */
#include "readline.h"
#include "rlprivate.h"
#include "rlshell.h"
#include "xmalloc.h"
/* What kind of non-blocking I/O do we have? */
#if !defined (O_NDELAY) && defined (O_NONBLOCK)
# define O_NDELAY O_NONBLOCK /* Posix style */
#endif
/* Non-null means it is a pointer to a function to run while waiting for
character input. */
rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL;
/* A function to call if a read(2) is interrupted by a signal. */
rl_hook_func_t *rl_signal_event_hook = (rl_hook_func_t *)NULL;
/* A function to replace _rl_input_available for applications using the
callback interface. */
rl_hook_func_t *rl_input_available_hook = (rl_hook_func_t *)NULL;
rl_getc_func_t *rl_getc_function = rl_getc;
static int _keyboard_input_timeout = 100000; /* 0.1 seconds; it's in usec */
static int ibuffer_space PARAMS((void));
static int rl_get_char PARAMS((int *));
static int rl_gather_tyi PARAMS((void));
/* **************************************************************** */
/* */
/* Character Input Buffering */
/* */
/* **************************************************************** */
static int pop_index, push_index;
static unsigned char ibuffer[512];
static int ibuffer_len = sizeof (ibuffer) - 1;
#define any_typein (push_index != pop_index)
int
_rl_any_typein ()
{
return any_typein;
}
int
_rl_pushed_input_available ()
{
return (push_index != pop_index);
}
/* Return the amount of space available in the buffer for stuffing
characters. */
static int
ibuffer_space ()
{
if (pop_index > push_index)
return (pop_index - push_index - 1);
else
return (ibuffer_len - (push_index - pop_index));
}
/* Get a key from the buffer of characters to be read.
Return the key in KEY.
Result is non-zero if there was a key, or 0 if there wasn't. */
static int
rl_get_char (key)
int *key;
{
if (push_index == pop_index)
return (0);
*key = ibuffer[pop_index++];
#if 0
if (pop_index >= ibuffer_len)
#else
if (pop_index > ibuffer_len)
#endif
pop_index = 0;
return (1);
}
/* Stuff KEY into the *front* of the input buffer.
Returns non-zero if successful, zero if there is
no space left in the buffer. */
int
_rl_unget_char (key)
int key;
{
if (ibuffer_space ())
{
pop_index--;
if (pop_index < 0)
pop_index = ibuffer_len;
ibuffer[pop_index] = key;
return (1);
}
return (0);
}
/* If a character is available to be read, then read it and stuff it into
IBUFFER. Otherwise, just return. Returns number of characters read
(0 if none available) and -1 on error (EIO). */
static int
rl_gather_tyi ()
{
int tty;
register int tem, result;
int chars_avail, k;
char input;
#if defined(HAVE_SELECT)
fd_set readfds, exceptfds;
struct timeval timeout;
#endif
chars_avail = 0;
input = 0;
tty = fileno (rl_instream);
#if defined (HAVE_SELECT)
FD_ZERO (&readfds);
FD_ZERO (&exceptfds);
FD_SET (tty, &readfds);
FD_SET (tty, &exceptfds);
USEC_TO_TIMEVAL (_keyboard_input_timeout, timeout);
result = select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout);
if (result <= 0)
return 0; /* Nothing to read. */
#endif
result = -1;
#if defined (FIONREAD)
errno = 0;
result = ioctl (tty, FIONREAD, &chars_avail);
if (result == -1 && errno == EIO)
return -1;
if (result == -1)
chars_avail = 0;
#endif
#if defined (O_NDELAY)
if (result == -1)
{
tem = fcntl (tty, F_GETFL, 0);
fcntl (tty, F_SETFL, (tem | O_NDELAY));
chars_avail = read (tty, &input, 1);
fcntl (tty, F_SETFL, tem);
if (chars_avail == -1 && errno == EAGAIN)
return 0;
if (chars_avail == 0) /* EOF */
{
rl_stuff_char (EOF);
return (0);
}
}
#endif /* O_NDELAY */
#if defined (__MINGW32__)
/* Use getch/_kbhit to check for available console input, in the same way
that we read it normally. */
chars_avail = isatty (tty) ? _kbhit () : 0;
result = 0;
#endif
/* If there's nothing available, don't waste time trying to read
something. */
if (chars_avail <= 0)
return 0;
tem = ibuffer_space ();
if (chars_avail > tem)
chars_avail = tem;
/* One cannot read all of the available input. I can only read a single
character at a time, or else programs which require input can be
thwarted. If the buffer is larger than one character, I lose.
Damn! */
if (tem < ibuffer_len)
chars_avail = 0;
if (result != -1)
{
while (chars_avail--)
{
RL_CHECK_SIGNALS ();
k = (*rl_getc_function) (rl_instream);
if (rl_stuff_char (k) == 0)
break; /* some problem; no more room */
if (k == NEWLINE || k == RETURN)
break;
}
}
else
{
if (chars_avail)
rl_stuff_char (input);
}
return 1;
}
int
rl_set_keyboard_input_timeout (u)
int u;
{
int o;
o = _keyboard_input_timeout;
if (u >= 0)
_keyboard_input_timeout = u;
return (o);
}
/* Is there input available to be read on the readline input file
descriptor? Only works if the system has select(2) or FIONREAD.
Uses the value of _keyboard_input_timeout as the timeout; if another
readline function wants to specify a timeout and not leave it up to
the user, it should use _rl_input_queued(timeout_value_in_microseconds)
instead. */
int
_rl_input_available ()
{
#if defined(HAVE_SELECT)
fd_set readfds, exceptfds;
struct timeval timeout;
#endif
#if !defined (HAVE_SELECT) && defined(FIONREAD)
int chars_avail;
#endif
int tty;
if (rl_input_available_hook)
return (*rl_input_available_hook) ();
tty = fileno (rl_instream);
#if defined (HAVE_SELECT)
FD_ZERO (&readfds);
FD_ZERO (&exceptfds);
FD_SET (tty, &readfds);
FD_SET (tty, &exceptfds);
timeout.tv_sec = 0;
timeout.tv_usec = _keyboard_input_timeout;
return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0);
#else
#if defined (FIONREAD)
if (ioctl (tty, FIONREAD, &chars_avail) == 0)
return (chars_avail);
#endif
#endif
#if defined (__MINGW32__)
if (isatty (tty))
return (_kbhit ());
#endif
return 0;
}
int
_rl_input_queued (t)
int t;
{
int old_timeout, r;
old_timeout = rl_set_keyboard_input_timeout (t);
r = _rl_input_available ();
rl_set_keyboard_input_timeout (old_timeout);
return r;
}
void
_rl_insert_typein (c)
int c;
{
int key, t, i;
char *string;
i = key = 0;
string = (char *)xmalloc (ibuffer_len + 1);
string[i++] = (char) c;
while ((t = rl_get_char (&key)) &&
_rl_keymap[key].type == ISFUNC &&
_rl_keymap[key].function == rl_insert)
string[i++] = key;
if (t)
_rl_unget_char (key);
string[i] = '\0';
rl_insert_text (string);
xfree (string);
}
/* Add KEY to the buffer of characters to be read. Returns 1 if the
character was stuffed correctly; 0 otherwise. */
int
rl_stuff_char (key)
int key;
{
if (ibuffer_space () == 0)
return 0;
if (key == EOF)
{
key = NEWLINE;
rl_pending_input = EOF;
RL_SETSTATE (RL_STATE_INPUTPENDING);
}
ibuffer[push_index++] = key;
#if 0
if (push_index >= ibuffer_len)
#else
if (push_index > ibuffer_len)
#endif
push_index = 0;
return 1;
}
/* Make C be the next command to be executed. */
int
rl_execute_next (c)
int c;
{
rl_pending_input = c;
RL_SETSTATE (RL_STATE_INPUTPENDING);
return 0;
}
/* Clear any pending input pushed with rl_execute_next() */
int
rl_clear_pending_input ()
{
rl_pending_input = 0;
RL_UNSETSTATE (RL_STATE_INPUTPENDING);
return 0;
}
/* **************************************************************** */
/* */
/* Character Input */
/* */
/* **************************************************************** */
/* Read a key, including pending input. */
int
rl_read_key ()
{
int c, r;
if (rl_pending_input)
{
c = rl_pending_input;
rl_clear_pending_input ();
}
else
{
/* If input is coming from a macro, then use that. */
if (c = _rl_next_macro_key ())
return (c);
/* If the user has an event function, then call it periodically. */
if (rl_event_hook)
{
while (rl_event_hook)
{
if (rl_get_char (&c) != 0)
break;
if ((r = rl_gather_tyi ()) < 0) /* XXX - EIO */
{
rl_done = 1;
return ('\n');
}
else if (r > 0) /* read something */
continue;
RL_CHECK_SIGNALS ();
if (rl_done) /* XXX - experimental */
return ('\n');
(*rl_event_hook) ();
}
}
else
{
if (rl_get_char (&c) == 0)
c = (*rl_getc_function) (rl_instream);
/* fprintf(stderr, "rl_read_key: calling RL_CHECK_SIGNALS: _rl_caught_signal = %d", _rl_caught_signal); */
RL_CHECK_SIGNALS ();
}
}
return (c);
}
int
rl_getc (stream)
FILE *stream;
{
int result;
unsigned char c;
#if defined (HAVE_PSELECT)
sigset_t empty_set;
fd_set readfds;
#endif
while (1)
{
RL_CHECK_SIGNALS ();
/* We know at this point that _rl_caught_signal == 0 */
#if defined (__MINGW32__)
if (isatty (fileno (stream)))
return (getch ());
#endif
result = 0;
#if defined (HAVE_PSELECT)
sigemptyset (&empty_set);
FD_ZERO (&readfds);
FD_SET (fileno (stream), &readfds);
result = pselect (fileno (stream) + 1, &readfds, NULL, NULL, NULL, &empty_set);
if (result < 0 && errno == EINTR)
{
fprintf(stderr, "\r\npselect returns -1 errno == EINTR signal = %d\n", _rl_caught_signal);
/* goto handle_error; */
}
#endif
if (result >= 0)
result = read (fileno (stream), &c, sizeof (unsigned char));
if (result == sizeof (unsigned char))
return (c);
/* If zero characters are returned, then the file that we are
reading from is empty! Return EOF in that case. */
if (result == 0)
return (EOF);
#if defined (__BEOS__)
if (errno == EINTR)
continue;
#endif
#if defined (EWOULDBLOCK)
# define X_EWOULDBLOCK EWOULDBLOCK
#else
# define X_EWOULDBLOCK -99
#endif
#if defined (EAGAIN)
# define X_EAGAIN EAGAIN
#else
# define X_EAGAIN -99
#endif
if (errno == X_EWOULDBLOCK || errno == X_EAGAIN)
{
if (sh_unset_nodelay_mode (fileno (stream)) < 0)
return (EOF);
continue;
}
#undef X_EWOULDBLOCK
#undef X_EAGAIN
/* fprintf(stderr, "rl_getc: result = %d errno = %d\n", result, errno); */
handle_error:
/* If the error that we received was EINTR, then try again,
this is simply an interrupted system call to read (). We allow
the read to be interrupted if we caught SIGHUP, SIGTERM, or any
of the other signals readline treats specially. If the
application sets an event hook, call it for other signals.
Otherwise (not EINTR), some error occurred, also signifying EOF. */
if (errno != EINTR)
return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
/* fatal signals of interest */
else if (_rl_caught_signal == SIGHUP || _rl_caught_signal == SIGTERM)
return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
/* keyboard-generated signals of interest */
else if (_rl_caught_signal == SIGINT || _rl_caught_signal == SIGQUIT)
RL_CHECK_SIGNALS ();
/* non-keyboard-generated signals of interest */
else if (_rl_caught_signal == SIGWINCH)
RL_CHECK_SIGNALS ();
else if (_rl_caught_signal == SIGALRM
#if defined (SIGVTALRM)
|| _rl_caught_signal == SIGVTALRM
#endif
)
RL_CHECK_SIGNALS ();
if (rl_signal_event_hook)
(*rl_signal_event_hook) ();
}
}
#if defined (HANDLE_MULTIBYTE)
/* read multibyte char */
int
_rl_read_mbchar (mbchar, size)
char *mbchar;
int size;
{
int mb_len, c;
size_t mbchar_bytes_length;
wchar_t wc;
mbstate_t ps, ps_back;
memset(&ps, 0, sizeof (mbstate_t));
memset(&ps_back, 0, sizeof (mbstate_t));
mb_len = 0;
while (mb_len < size)
{
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (c < 0)
break;
mbchar[mb_len++] = c;
mbchar_bytes_length = mbrtowc (&wc, mbchar, mb_len, &ps);
if (mbchar_bytes_length == (size_t)(-1))
break; /* invalid byte sequence for the current locale */
else if (mbchar_bytes_length == (size_t)(-2))
{
/* shorted bytes */
ps = ps_back;
continue;
}
else if (mbchar_bytes_length == 0)
{
mbchar[0] = '\0'; /* null wide character */
mb_len = 1;
break;
}
else if (mbchar_bytes_length > (size_t)(0))
break;
}
return mb_len;
}
/* Read a multibyte-character string whose first character is FIRST into
the buffer MB of length MLEN. Returns the last character read, which
may be FIRST. Used by the search functions, among others. Very similar
to _rl_read_mbchar. */
int
_rl_read_mbstring (first, mb, mlen)
int first;
char *mb;
int mlen;
{
int i, c;
mbstate_t ps;
c = first;
memset (mb, 0, mlen);
for (i = 0; c >= 0 && i < mlen; i++)
{
mb[i] = (char)c;
memset (&ps, 0, sizeof (mbstate_t));
if (_rl_get_char_len (mb, &ps) == -2)
{
/* Read more for multibyte character */
RL_SETSTATE (RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE (RL_STATE_MOREINPUT);
}
else
break;
}
return c;
}
#endif /* HANDLE_MULTIBYTE */
+28
View File
@@ -28,10 +28,13 @@
#endif
#include <stdio.h>
#include <stdc.h>
#include "syntax.h"
#include <xmalloc.h>
extern char *ansic_quote __P((char *, int, int *));
/* Default set of characters that should be backslash-quoted in strings */
static const char bstab[256] =
{
@@ -277,6 +280,31 @@ sh_backslash_quote_for_double_quotes (string)
}
#endif /* PROMPT_STRING_DECODE */
char *
sh_quote_reusable (s, flags)
char *s;
int flags;
{
char *ret;
if (s == 0)
return s;
else if (*s == 0)
{
ret = (char *)xmalloc (3);
ret[0] = ret[1] = '\'';
ret[2] = '\0';
}
else if (ansic_shouldquote (s))
ret = ansic_quote (s, 0, (int *)0);
else if (flags)
ret = sh_backslash_quote (s, 0, 1);
else
ret = sh_single_quote (s);
return ret;
}
int
sh_contains_shell_metas (string)
char *string;
+352
View File
@@ -0,0 +1,352 @@
/* shquote - functions to quote and dequote strings */
/* Copyright (C) 1999 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 "syntax.h"
#include <xmalloc.h>
/* Default set of characters that should be backslash-quoted in strings */
static const char bstab[256] =
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 0, 0, 0, 0, 0, /* TAB, NL */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 0, 1, 0, 1, 1, /* SPACE, !, DQUOTE, DOL, AMP, SQUOTE */
1, 1, 1, 0, 1, 0, 0, 0, /* LPAR, RPAR, STAR, COMMA */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 0, 1, 1, /* SEMI, LESSTHAN, GREATERTHAN, QUEST */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 1, 0, /* LBRACK, BS, RBRACK, CARAT */
1, 0, 0, 0, 0, 0, 0, 0, /* BACKQ */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 0, 0, /* LBRACE, BAR, RBRACE */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
/* **************************************************************** */
/* */
/* Functions for quoting strings to be re-read as input */
/* */
/* **************************************************************** */
/* Return a new string which is the single-quoted version of STRING.
Used by alias and trap, among others. */
char *
sh_single_quote (string)
const char *string;
{
register int c;
char *result, *r;
const char *s;
result = (char *)xmalloc (3 + (4 * strlen (string)));
r = result;
if (string[0] == '\'' && string[1] == 0)
{
*r++ = '\\';
*r++ = '\'';
*r++ = 0;
return result;
}
*r++ = '\'';
for (s = string; s && (c = *s); s++)
{
*r++ = c;
if (c == '\'')
{
*r++ = '\\'; /* insert escaped single quote */
*r++ = '\'';
*r++ = '\''; /* start new quoted string */
}
}
*r++ = '\'';
*r = '\0';
return (result);
}
/* Quote STRING using double quotes. Return a new string. */
char *
sh_double_quote (string)
const char *string;
{
register unsigned char c;
char *result, *r;
const char *s;
result = (char *)xmalloc (3 + (2 * strlen (string)));
r = result;
*r++ = '"';
for (s = string; s && (c = *s); s++)
{
/* Backslash-newline disappears within double quotes, so don't add one. */
if ((sh_syntaxtab[c] & CBSDQUOTE) && c != '\n')
*r++ = '\\';
else if (c == CTLESC || c == CTLNUL)
*r++ = CTLESC; /* could be '\\'? */
*r++ = c;
}
*r++ = '"';
*r = '\0';
return (result);
}
/* Turn S into a simple double-quoted string. If FLAGS is non-zero, quote
double quote characters in S with backslashes. */
char *
sh_mkdoublequoted (s, slen, flags)
const char *s;
int slen, flags;
{
char *r, *ret;
int rlen;
rlen = (flags == 0) ? slen + 3 : (2 * slen) + 1;
ret = r = (char *)xmalloc (rlen);
*r++ = '"';
while (*s)
{
if (flags && *s == '"')
*r++ = '\\';
*r++ = *s++;
}
*r++ = '"';
*r = '\0';
return ret;
}
/* Remove backslashes that are quoting characters that are special between
double quotes. Return a new string. XXX - should this handle CTLESC
and CTLNUL? */
char *
sh_un_double_quote (string)
char *string;
{
register int c, pass_next;
char *result, *r, *s;
r = result = (char *)xmalloc (strlen (string) + 1);
for (pass_next = 0, s = string; s && (c = *s); s++)
{
if (pass_next)
{
*r++ = c;
pass_next = 0;
continue;
}
if (c == '\\' && (sh_syntaxtab[(unsigned char) s[1]] & CBSDQUOTE))
{
pass_next = 1;
continue;
}
*r++ = c;
}
*r = '\0';
return result;
}
/* Quote special characters in STRING using backslashes. Return a new
string. NOTE: if the string is to be further expanded, we need a
way to protect the CTLESC and CTLNUL characters. As I write this,
the current callers will never cause the string to be expanded without
going through the shell parser, which will protect the internal
quoting characters. TABLE, if set, points to a map of the ascii code
set with char needing to be backslash-quoted if table[char]==1. FLAGS,
if 1, causes tildes to be quoted as well. */
char *
sh_backslash_quote (string, table, flags)
char *string;
char *table;
int flags;
{
int c;
char *result, *r, *s, *backslash_table;
result = (char *)xmalloc (2 * strlen (string) + 1);
backslash_table = table ? table : (char *)bstab;
for (r = result, s = string; s && (c = *s); s++)
{
if (backslash_table[c] == 1)
*r++ = '\\';
else if (c == '#' && s == string) /* comment char */
*r++ = '\\';
else if ((flags&1) && c == '~' && (s == string || s[-1] == ':' || s[-1] == '='))
/* Tildes are special at the start of a word or after a `:' or `='
(technically unquoted, but it doesn't make a difference in practice) */
*r++ = '\\';
*r++ = c;
}
*r = '\0';
return (result);
}
#if defined (PROMPT_STRING_DECODE)
/* Quote characters that get special treatment when in double quotes in STRING
using backslashes. Return a new string. */
char *
sh_backslash_quote_for_double_quotes (string)
char *string;
{
unsigned char c;
char *result, *r, *s;
result = (char *)xmalloc (2 * strlen (string) + 1);
for (r = result, s = string; s && (c = *s); s++)
{
if (sh_syntaxtab[c] & CBSDQUOTE)
*r++ = '\\';
/* I should probably add flags for these to sh_syntaxtab[] */
else if (c == CTLESC || c == CTLNUL)
*r++ = CTLESC; /* could be '\\'? */
*r++ = c;
}
*r = '\0';
return (result);
}
#endif /* PROMPT_STRING_DECODE */
char *
sh_quote_reusable (s, flags)
char *s;
int flags;
{
char *ret;
if (s == 0)
return s;
else if (*s == 0)
{
ret = (char *)xmalloc (3);
ret[0] = ret[1] = '\'';
ret[2] = '\0';
}
else if (ansic_shouldquote (s))
ret = ansic_quote (s, 0, (int *)0);
else if (flags)
ret = sh_backslash_quote (s, 0, 1);
else
ret = sh_single_quote (s);
return ret;
}
int
sh_contains_shell_metas (string)
char *string;
{
char *s;
for (s = string; s && *s; s++)
{
switch (*s)
{
case ' ': case '\t': case '\n': /* IFS white space */
case '\'': case '"': case '\\': /* quoting chars */
case '|': case '&': case ';': /* shell metacharacters */
case '(': case ')': case '<': case '>':
case '!': case '{': case '}': /* reserved words */
case '*': case '[': case '?': case ']': /* globbing chars */
case '^':
case '$': case '`': /* expansion chars */
return (1);
case '~': /* tilde expansion */
if (s == string || s[-1] == '=' || s[-1] == ':')
return (1);
break;
case '#':
if (s == string) /* comment char */
return (1);
/* FALLTHROUGH */
default:
break;
}
}
return (0);
}
int
sh_contains_quotes (string)
char *string;
{
char *s;
for (s = string; s && *s; s++)
{
if (*s == '\'' || *s == '"' || *s == '\\')
return 1;
}
return 0;
}
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+1058 -1772
View File
File diff suppressed because it is too large Load Diff
+313 -7
View File
@@ -107,7 +107,7 @@ extern int errno;
/* Evaluates to 1 if C is one of the shell's special parameters whose length
can be taken, but is also one of the special expansion characters. */
#define VALID_SPECIAL_LENGTH_PARAM(c) \
((c) == '-' || (c) == '?' || (c) == '#')
((c) == '-' || (c) == '?' || (c) == '#' || (c) == '@')
/* Evaluates to 1 if C is one of the shell's special parameters for which an
indirect variable reference may be made. */
@@ -270,6 +270,19 @@ static char *array_remove_pattern __P((SHELL_VAR *, char *, int, char *, int));
#endif
static char *parameter_brace_remove_pattern __P((char *, char *, int, char *, int, int, int));
static char *string_var_assignment __P((SHELL_VAR *, char *));
#if defined (ARRAY_VARS)
static char *array_var_assignment __P((SHELL_VAR *, int, int));
#endif
static char *pos_params_assignment __P((WORD_LIST *, int, int));
static char *string_transform __P((int, SHELL_VAR *, char *));
static char *list_transform __P((int, SHELL_VAR *, WORD_LIST *, int, int));
static char *parameter_list_transform __P((int, int, int));
#if defined ARRAY_VARS
static char *array_transform __P((int, SHELL_VAR *, char *, int));
#endif
static char *parameter_brace_transform __P((char *, char *, int, char *, int, int, int));
static char *process_substitute __P((char *, int));
static char *read_comsub __P((int, int, int *));
@@ -4586,7 +4599,7 @@ array_remove_pattern (var, pattern, patspec, varname, quoted)
v = array_variable_part (varname, &ret, 0);
/* XXX */
if (v && invisible_p (var))
if (v && invisible_p (v))
return ((char *)NULL);
itype = ret[0];
@@ -4680,6 +4693,270 @@ parameter_brace_remove_pattern (varname, value, ind, patstr, rtype, quoted, flag
return temp1;
}
static char *
string_var_assignment (v, s)
SHELL_VAR *v;
char *s;
{
char flags[MAX_ATTRIBUTES], *ret, *val;
int i;
val = sh_quote_reusable (s, 0);
i = var_attribute_string (v, 0, flags);
ret = (char *)xmalloc (i + strlen (val) + strlen (v->name) + 16);
if (i > 0)
sprintf (ret, "declare -%s %s=%s", flags, v->name, val);
else
sprintf (ret, "%s=%s", v->name, val);
free (val);
return ret;
}
#if defined (ARRAY_VARS)
static char *
array_var_assignment (v, itype, quoted)
SHELL_VAR *v;
int itype, quoted;
{
char *ret, *val, flags[MAX_ATTRIBUTES];
int i;
if (v == 0)
return (char *)NULL;
val = array_p (v) ? array_to_assign (array_cell (v), 0)
: assoc_to_assign (assoc_cell (v), 0);
if (val == 0)
{
val = (char *)xmalloc (3);
val[0] = '(';
val[1] = ')';
val[2] = 0;
}
i = var_attribute_string (v, 0, flags);
ret = (char *)xmalloc (i + strlen (val) + strlen (v->name) + 16);
sprintf (ret, "declare -%s %s=%s", flags, v->name, val);
free (val);
return ret;
}
#endif
static char *
pos_params_assignment (list, itype, quoted)
WORD_LIST *list;
int itype;
int quoted;
{
char *temp, *ret;
/* first, we transform the list to quote each word. */
temp = list_transform ('Q', (SHELL_VAR *)0, list, itype, quoted);
ret = (char *)xmalloc (strlen (temp) + 8);
strcpy (ret, "set -- ");
strcpy (ret + 7, temp);
free (temp);
return ret;
}
static char *
string_transform (xc, v, s)
int xc;
SHELL_VAR *v;
char *s;
{
char *ret, flags[MAX_ATTRIBUTES];
int i;
if (((xc == 'A' || xc == 'a') && v == 0) || (xc != 'a' && s == 0))
return (char *)NULL;
switch (xc)
{
/* Transformations that interrogate the variable */
case 'a':
i = var_attribute_string (v, 0, flags);
ret = (i > 0) ? savestring (flags) : (char *)NULL;
break;
case 'A':
ret = string_var_assignment (v, s);
break;
/* Transformations that modify the variable's value */
case 'E':
ret = ansiexpand (s, 0, strlen (s), (int *)0);
break;
case 'P':
ret = decode_prompt_string (s);
break;
case 'Q':
ret = sh_quote_reusable (s, 0);
break;
default:
ret = (char *)NULL;
break;
}
return ret;
}
static char *
list_transform (xc, v, list, itype, quoted)
int xc;
SHELL_VAR *v;
WORD_LIST *list;
int itype, quoted;
{
WORD_LIST *new, *l;
WORD_DESC *w;
char *tword;
for (new = (WORD_LIST *)NULL, l = list; l; l = l->next)
{
tword = string_transform (xc, v, l->word->word);
w = alloc_word_desc ();
w->word = tword ? tword : savestring (""); /* XXX */
new = make_word_list (w, new);
}
l = REVERSE_LIST (new, WORD_LIST *);
tword = string_list_pos_params (itype, l, quoted);
dispose_words (l);
return (tword);
}
static char *
parameter_list_transform (xc, itype, quoted)
int xc;
int itype;
int quoted;
{
char *ret;
WORD_LIST *list;
list = list_rest_of_args ();
if (list == 0)
return ((char *)NULL);
if (xc == 'A')
return (pos_params_assignment (list, itype, quoted));
ret = list_transform (xc, (SHELL_VAR *)0, list, itype, quoted);
dispose_words (list);
return (ret);
}
#if defined (ARRAY_VARS)
static char *
array_transform (xc, var, varname, quoted)
int xc;
SHELL_VAR *var;
char *varname; /* so we can figure out how it's indexed */
int quoted;
{
ARRAY *a;
HASH_TABLE *h;
int itype;
char *ret;
WORD_LIST *list;
SHELL_VAR *v;
/* compute itype from varname here */
v = array_variable_part (varname, &ret, 0);
/* XXX */
if (v && invisible_p (v))
return ((char *)NULL);
itype = ret[0];
if (xc == 'A')
return (array_var_assignment (v, itype, quoted));
a = (v && array_p (v)) ? array_cell (v) : 0;
h = (v && assoc_p (v)) ? assoc_cell (v) : 0;
list = a ? array_to_word_list (a) : (h ? assoc_to_word_list (h) : 0);
if (list == 0)
return ((char *)NULL);
ret = list_transform (xc, v, list, itype, quoted);
dispose_words (list);
return ret;
}
#endif /* ARRAY_VARS */
static char *
parameter_brace_transform (varname, value, ind, xform, rtype, quoted, flags)
char *varname, *value;
int ind;
char *xform;
int rtype, quoted, flags;
{
int vtype, xc;
char *temp1, *val;
SHELL_VAR *v;
xc = xform[0];
if (value == 0 && xc != 'A' && xc != 'a')
return ((char *)NULL);
this_command_name = varname;
vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
if (vtype == -1)
return ((char *)NULL);
/* check for valid values of xc */
switch (xc)
{
case 'a': /* expand to a string with just attributes */
case 'A': /* expand as an assignment statement with attributes */
case 'E': /* expand like $'...' */
case 'P': /* expand like prompt string */
case 'Q': /* quote reusably */
break;
default:
return &expand_param_error;
}
temp1 = (char *)NULL; /* shut up gcc */
switch (vtype & ~VT_STARSUB)
{
case VT_VARIABLE:
case VT_ARRAYMEMBER:
temp1 = string_transform (xc, v, val);
if (vtype == VT_VARIABLE)
FREE (val);
if (temp1)
{
val = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
? quote_string (temp1)
: quote_escapes (temp1);
free (temp1);
temp1 = val;
}
break;
#if defined (ARRAY_VARS)
case VT_ARRAYVAR:
temp1 = array_transform (xc, v, varname, quoted);
if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
{
val = quote_escapes (temp1);
free (temp1);
temp1 = val;
}
break;
#endif
case VT_POSPARMS:
temp1 = parameter_list_transform (xc, varname[0], quoted);
if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
{
val = quote_escapes (temp1);
free (temp1);
temp1 = val;
}
break;
}
return temp1;
}
/*******************************************
* *
* Functions to expand WORD_DESCs *
@@ -6545,6 +6822,7 @@ get_var_and_type (varname, value, ind, quoted, flags, varp, valp)
{
if (value && vtype == VT_VARIABLE)
{
*varp = v;
if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
*valp = dequote_string (value);
else
@@ -7240,14 +7518,24 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta
/* To enable case-toggling expansions using the `~' operator character
change the 1 to 0. */
# if defined (CASEMOD_CAPCASE)
name = string_extract (string, &t_index, "#%^,~:-=?+/}", SX_VARNAME);
name = string_extract (string, &t_index, "#%^,~:-=?+/@}", SX_VARNAME);
# else
name = string_extract (string, &t_index, "#%^,:-=?+/}", SX_VARNAME);
name = string_extract (string, &t_index, "#%^,:-=?+/@}", SX_VARNAME);
# endif /* CASEMOD_CAPCASE */
#else
name = string_extract (string, &t_index, "#%:-=?+/}", SX_VARNAME);
name = string_extract (string, &t_index, "#%:-=?+/@}", SX_VARNAME);
#endif /* CASEMOD_EXPANSIONS */
/* Handle ${@[stuff]} now that @ is a word expansion operator. Not exactly
the cleanest code ever. */
if (*name == 0 && sindex == t_index && string[sindex] == '@')
{
name = (char *)xrealloc (name, 2);
name[0] = '@';
name[1] = '\0';
t_index++;
}
ret = 0;
tflag = 0;
@@ -7255,12 +7543,15 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta
/* If the name really consists of a special variable, then make sure
that we have the entire name. We don't allow indirect references
to special variables except `#', `?', `@' and `*'. */
to special variables except `#', `?', `@' and `*'. This clause is
designed to handle ${#SPECIAL} and ${!SPECIAL}, not anything more
general. */
if ((sindex == t_index && VALID_SPECIAL_LENGTH_PARAM (string[t_index])) ||
(sindex == t_index && string[sindex] == '#' && VALID_SPECIAL_LENGTH_PARAM (string[sindex + 1])) ||
(sindex == t_index - 1 && string[sindex] == '!' && VALID_INDIR_PARAM (string[t_index])))
{
t_index++;
temp1 = string_extract (string, &t_index, "#%:-=?+/}", 0);
temp1 = string_extract (string, &t_index, "#%:-=?+/@}", 0);
name = (char *)xrealloc (name, 3 + (strlen (temp1)));
*name = string[sindex];
if (string[sindex] == '!')
@@ -7618,6 +7909,21 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta
case RBRACE:
break;
case '@':
temp1 = parameter_brace_transform (name, temp, ind, value, c, quoted, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
if (temp1 == &expand_param_error || temp1 == &expand_param_fatal)
goto bad_substitution;
free (temp);
free (value);
free (name);
ret = alloc_word_desc ();
ret->word = temp1;
if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
return ret;
case '#': /* ${param#[#]pattern} */
case '%': /* ${param%[%]pattern} */
if (value == 0 || *value == '\0' || temp == 0 || *temp == '\0')
+10207
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -49,6 +49,7 @@
#define ASS_MKASSOC 0x0004
#define ASS_MKGLOBAL 0x0008 /* force global assignment */
#define ASS_NAMEREF 0x0010 /* assigning to nameref variable */
#define ASS_FORCE 0x0020 /* force assignment even to readonly variable */
/* Flags for the string extraction functions. */
#define SX_NOALLOC 0x0001 /* just skip; don't return substring */
+3 -3
View File
@@ -16,9 +16,9 @@
9
16
./appendop.tests: line 84: x: readonly variable
declare -A foo='([one]="bar" [two]="baz" [three]="quux" )'
declare -A foo='([one]="bar" [two]="baz" [0]="zero" [three]="quux" )'
declare -A foo='([four]="four" [one]="bar" [two]="baz" [0]="zero" [three]="quux" )'
declare -A foo='([two]="baz" [three]="quux" [one]="bar" )'
declare -A foo='([two]="baz" [0]="zero" [three]="quux" [one]="bar" )'
declare -A foo='([two]="baz" [0]="zero" [three]="quux" [four]="four" [one]="bar" )'
declare -ai iarr='([0]="3" [1]="2" [2]="3")'
declare -ai iarr='([0]="3" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6")'
25 25
+3 -3
View File
@@ -351,8 +351,8 @@ version[agent]
version.agent
version[agent] foo[bar]
version.agent bowl
foobar] foo foo[bar]
bleh bbb bleh
foo foobar] foo[bar]
bbb bleh bleh
ab]
bar
1
@@ -371,7 +371,7 @@ declare -a x='([0]="0" [1]="1" [2]="2" [4]="4")'
declare -a x='([0]="0" [1]="1" [2]="2" [3]="3" [4]="4")'
declare -a x='([0]="0" [1]="1" [2]="2" [3]="3" [4]="4" [5]="five")'
declare -a x='([0]="0" [1]="1" [2]="2" [3]="3" [4]="4" [5]="5")'
declare -a x='([0]="0" [1]="1" [2]="2" [3]="3" [4]="4" [5]="5foo")'
declare -a x='([0]="0" [1]="1" [2]="2" [3]="3" [4]="4" [5]="foo")'
declare -a x='([0]="0" [1]="1" [2]="2" [3]="3" [4]="4" [5]="5")'
declare -a x='([0]="0" [1]="1" [2]="2" [3]="3" [4]="4four" [5]="5")'
strlen(4four) = 5
+15 -15
View File
@@ -12,7 +12,7 @@ declare -A BASH_ALIASES='()'
declare -A BASH_CMDS='()'
declare -Ai chaff='([one]="10" [zero]="5" )'
declare -Ar waste='([version]="4.0-devel" [source]="./assoc.tests" [lineno]="28" [pid]="42134" )'
declare -A wheat='([one]="a" [zero]="0" [two]="b" [three]="c" )'
declare -A wheat='([two]="b" [three]="c" [one]="a" [zero]="0" )'
declare -A chaff='([one]="10" ["hello world"]="flip" [zero]="5" )'
./assoc.tests: line 38: unset: waste: cannot unset: readonly variable
./assoc.tests: line 39: chaff[*]: bad array subscript
@@ -47,16 +47,16 @@ argv[3] = <blat>
argv[1] = <qux qix blat>
argv[1] = <16>
argv[1] = <16>
argv[1] = <flix>
argv[2] = <6>
argv[1] = <6>
argv[2] = <flix>
argv[1] = <six>
argv[2] = <foo>
argv[3] = <bar>
argv[1] = <six>
argv[2] = <foo bar>
8
/usr/local/bin . /bin /sbin /usr/sbin /usr/bin /bin /usr/ucb
bin . bin sbin sbin bin bin ucb
. /sbin /usr/bin /bin /usr/ucb /usr/local/bin /bin /usr/sbin
. sbin bin bin ucb bin bin sbin
bin
/ / / / / / /
/
@@ -65,16 +65,16 @@ argv[1] = </>
argv[1] = <sbin>
argv[1] = </>
8
/usr/local/bin . /bin /sbin /usr/sbin /usr/bin /bin /usr/ucb
bin . bin sbin sbin bin bin ucb
. /sbin /usr/bin /bin /usr/ucb /usr/local/bin /bin /usr/sbin
. sbin bin bin ucb bin bin sbin
/ / / / / / /
8
4 -- /bin
^usr^local^bin . ^bin ^sbin ^usr^sbin ^usr^bin ^bin ^usr^ucb
^usr^local^bin . ^bin ^sbin ^usr^sbin ^usr^bin ^bin ^usr^ucb
\usr/local/bin . \bin \sbin \usr/sbin \usr/bin \bin \usr/ucb
\usr\local\bin . \bin \sbin \usr\sbin \usr\bin \bin \usr\ucb
\usr\local\bin . \bin \sbin \usr\sbin \usr\bin \bin \usr\ucb
. ^sbin ^usr^bin ^bin ^usr^ucb ^usr^local^bin ^bin ^usr^sbin
. ^sbin ^usr^bin ^bin ^usr^ucb ^usr^local^bin ^bin ^usr^sbin
. \sbin \usr/bin \bin \usr/ucb \usr/local/bin \bin \usr/sbin
. \sbin \usr\bin \bin \usr\ucb \usr\local\bin \bin \usr\sbin
. \sbin \usr\bin \bin \usr\ucb \usr\local\bin \bin \usr\sbin
([a]=1)
qux foo
@@ -137,11 +137,11 @@ abc
def
def
./assoc5.sub: line 13: declare: `myarray[foo[bar]=bleh': not a valid identifier
abc def bleh
myarray=(["a]a"]="abc" ["]"]="def" ["a]=test1;#a"]="123" [foo]="bleh" )
bleh abc def
myarray=(["a]=test1;#a"]="123" [foo]="bleh" ["a]a"]="abc" ["]"]="def" )
123
myarray=(["a]a"]="abc" ["a]=test2;#a"]="def" ["]"]="def" ["a]=test1;#a"]="123" [foo]="bleh" )
myarray=(["a]=test1;#a"]="123" [foo]="bleh" ["a]a"]="abc" ["a]=test2;#a"]="def" ["]"]="def" )
bar"bie
doll
declare -A foo='(["bar\"bie"]="doll" )'
+1 -1
View File
@@ -163,7 +163,7 @@ declare -A d
declare -a c='([0]="4")'
declare -A c='([0]="4" )'
declare -a c='([0]="1" [1]="2" [2]="3")'
declare -A c='([one]="1" [two]="2" [three]="3" )'
declare -A c='([two]="2" [three]="3" [one]="1" )'
declare -a c='([0]="1" [1]="2" [2]="3")'
declare -a c='([0]="1" [1]="2" [2]="3")'
unset
+33 -1
View File
@@ -570,6 +570,38 @@ c Value = 10 20 40 80
c Sub = 0 2 4 8
<1> <2> <3> <4> <5>
<10> <20> <40> <80>
<>
<>
<>
<>
<'ab '\''cd'\'' ef'>
./new-exp10.sub: line 11: ${x@C}: bad substitution
<'ab'> <'cd ef'> <''> <'gh'>
<'ab' 'cd ef' '' 'gh'>
<'ab'> <'cd> <ef'> <''> <'gh'>
<'ab'> <'cd> <ef'> <''> <'gh'>
<'ab cd'>
<'4'> <'ab cd'>
<>
argv[1] = <host(2)[4.3]$ >
<
>
<' \t\n'>
<
>
<$' \t\n'>
declare -r x='ab '\''cd'\'' ef'
set -- 'ab' 'cd ef' '' 'gh'
declare -a A=([0]="ab" [1]="cd ef" [2]="" [3]="gh")
declare -a B=()
declare -A A=([two]="b c" [three]="" [four]="de" [one]="1" )
r
a
A
ir
a b c d e
5
a5b
argv[1] = </>
argv[1] = </>
./new-exp.tests: line 584: ABXD: parameter unset
./new-exp.tests: line 587: ABXD: parameter unset
+3
View File
@@ -573,6 +573,9 @@ ${THIS_SH} ./new-exp8.sub
# value is 'anothervar[@]' stop working
${THIS_SH} ./new-exp9.sub
# new parameter transformation `@' expansion operator
${THIS_SH} ./new-exp10.sub
# problems with stray CTLNUL in bash-4.0-alpha
unset a
a=/a
+584
View File
@@ -0,0 +1,584 @@
# must do this because posix mode causes process substitution to be disabled
# and flagged as a syntax error, which causes the shell to exit
set +o posix
expect()
{
echo expect "$@"
}
HOME=/usr/homes/chet # to make the check against new-exp.right work
expect '<foo bar>'
recho "${undef-"foo bar"}" # should be foo bar
expect '<foo>'
recho "${und="foo"}" # should be foo
expect "<$HOME>"
recho ${HOME-"}"}
expect "<$HOME>"
recho "${HOME-'}'}"
expect "<$HOME>"
recho "${HOME-"}"}"
expect $0: 'HOME: }: syntax error: operand expected (error token is "}")'
recho "${HOME:`echo }`}" # should be a math error -- bad substring substitution
expect unset
_ENV=oops
x=${_ENV[(_$-=0)+(_=1)-_${-%%*i*}]}
echo ${x:-unset}
expect "<$HOME>"
recho ${HOME}
expect "<$HOME>"
recho ${HOME:-`echo }`}
expect "<$HOME>"
recho ${HOME:-`echo "}"`}
expect "<$HOME>"
recho "${HOME:-`echo "}"`}"
expect "<$HOME>"
recho "$(echo "${HOME}")"
expect "<$HOME>"
recho "$(echo "$(echo ${HOME})")"
expect "<$HOME>"
recho "$(echo "$(echo "${HOME}")")"
P=*@*
expect '<*@>'
recho "${P%"*"}" #
expect '<*@>'
recho "${P%'*'}" #
expect '<@*>'
recho "${P#\*}" # should be @*
expect '<)>'
recho "$(echo ")")" # should be )
expect '<")">'
recho "$(echo "\")\"")" # should be ")"
foo='abcd '
expect '<-abcd> <->'
recho -${foo}- # should be -abcd -
expect '<-abcd> <->'
recho -${foo% *}- # should be -abcd -
expect '<-abcd->'
recho -${foo%% *}- # should be -abcd-
foo=bar
expect '<bar foo>'
echo -n $foo' ' ; echo foo
expect '<bar foo>'
echo -n $foo" " ; echo foo
expect '<bar foo>'
echo -n "$foo " ; echo foo
expect '<barfoo>'
echo -e "$foo\c " ; echo foo
expect '<barfoo>'
echo -e $foo"\c " ; echo foo
# make sure backslashes are preserved in front of characters that are not
# valid backslash escapes
expect '<\x>'
echo -e '\x'
# substring tests
z=abcdefghijklmnop
expect '<abcd>'
recho ${z:0:4}
expect '<efg> <nop>'
recho ${z:4:3} ${z:${#z}-3:3}
expect '<efg> <nop>'
recho ${z:4:3} ${z: -3:3}
expect '<hijklmnop>'
recho ${z:7:30}
expect '<abcdefghijklmnop>'
recho ${z:0:100}
expect '<abcdefghijklmnop>'
recho ${z:0:${#z}}
set 'ab cd' 'ef' 'gh ij' 'kl mn' 'op'
expect '<ab cd> <ef>'
recho "${@:1:2}"
expect '<gh ij> <kl mn>'
recho "${@:3:2}"
expect '<gh ij> <kl mn> <op>'
recho "${@:3:4}"
expect '<ab cd> <ef> <gh ij> <kl mn> <op>'
recho "${@:1:$#}"
# code to ad-hoc parse arithmetic expressions in substring expansions was
# broken until post-2.04
base=/home/chet/foo//bar
string1=$base/abcabcabc
x=1 j=4
expect '</home/chet/foo//bar/abcabcabc>'
recho ${string1:0}
expect '<home/chet/foo//bar/abcabcabc>'
recho ${string1:1}
expect '<home>'
recho ${string1:(j?1:0):j}
expect '<home>'
recho ${string1:j?1:0:j}
expect '<home>'
recho ${string1:(j?(x?1:0):0):j}
expect '<home>'
recho ${string1:j?(x?1:0):0:j}
unset base string1 x j
# indirect variable references
expect '<abcdefghijklmnop>'
recho ${!9:-$z}
ef=4
expect '<4>'
recho ${!2}
expect '<op>'
recho ${!#}
set a b c d e
a=
expect '<abcdefghijklmnop>'
recho ${a:-$z}
expect '<abcdefghijklmnop>'
recho ${!1:-$z}
expect nothing
recho ${a-$z}
expect nothing
recho ${!1-$z}
set -u
expect $0: ABX: unbound variable
( recho ${ABX} )
set +u
expect $0: '$6: cannot assign in this way'
recho ${6="arg6"}
v=abcde
# sed-like variable substitution
expect '<xxcde>'
recho ${v/a[a-z]/xx}
expect '<axxde>'
recho ${v/a??/axx}
expect '<abxyz>'
recho ${v/c??/xyz}
expect '<abbcde>'
recho ${v/#a/ab}
expect '<abcde>'
recho ${v/#d/ab}
expect '<abcabe>'
recho ${v/d/ab}
expect '<abcdlast>'
recho ${v/%?/last}
expect '<abcde>'
recho ${v/%x/last}
av=(abcd efgh ijkl mnop qrst uvwx)
expect '<xxcd>'
recho ${av/??/xx}
expect '<abxx>'
recho ${av/%??/xx}
expect '<xxgh>'
recho ${av[1]/??/xx}
expect '<efgh>'
recho ${av[1]/%ab/xx}
expect '<xxfgh>'
recho ${av[1]/#?/xx}
expect '<zagh>'
recho ${av[1]/??/za}
expect '<zaza>'
recho ${av[1]//??/za}
expect '<zagh>'
recho ${av[1]/#??/za}
expect '<efza>'
recho ${av[1]/%??/za}
expect '<yyy> <yyy> <yyy> <yyy> <yyy> <yyy>'
recho ${av[@]/*/yyy}
expect '<yyy> <yyy> <yyy> <yyy> <yyy> <yyy>'
recho ${av[@]/#*/yyy}
expect '<yyy> <yyy> <yyy> <yyy> <yyy> <yyy>'
recho ${av[@]/%*/yyy}
expect '<yyy> <efgh> <ijkl> <mnop> <qrst> <uvwx>'
recho ${av[@]/a*/yyy}
expect '<abxx> <efxx> <ijxx> <mnxx> <qrxx> <uvxx>'
recho ${av[@]/%??/xx}
set abcd efgh ijkl mnop qrst uvwx
expect '<xxcd>'
recho ${1/??/xx}
expect '<xxcd> <xxgh> <xxkl> <xxop> <xxst> <xxwx>'
recho ${@/??/xx}
expect '<xxcd> <xxgh> <xxkl> <xxop> <xxst> <xxwx>'
recho ${@/%??/xx}
expect '<zaza>'
recho ${3//??/za}
expect '<efza>'
recho ${3/%??/za}
expect '<zaza> <zaza> <zaza> <zaza> <zaza> <zaza>'
recho ${@//??/za}
expect '<zacd> <zagh> <zakl> <zaop> <zast> <zawx>'
recho ${@/#??/za}
expect '<yyy> <yyy> <yyy> <yyy> <yyy> <yyy>'
recho ${@//*/yyy}
expect '<yyy> <efgh> <ijkl> <mnop> <qrst> <uvwx>'
recho ${@//a*/yyy}
expect '<abcd> <efgh> <ijkl> <mnop> <qrst> <uvwyyy>'
recho ${@/%x*/yyy}
expect a newline
echo $abmcde
# sneaky way to replace a newline in a variable value with something else
AVAR=$'This\nstring\nhas\nmultiple\nlines.'
echo "${AVAR}"
eval BVAR=\"\${AVAR//$'\n'/-}\"
echo "$BVAR"
unset AVAR BVAR
# run process substitution tests in a subshell so that syntax errors
# caused by a shell not implementing process substitution (e.g., one
# built on a NeXT) will not cause the whole test to exit prematurely
${THIS_SH} ./new-exp1.sub
# run the tests of $(<filename) in a subshell to avoid cluttering up
# this script
${THIS_SH} ./new-exp2.sub
expect '<6>'
recho ${#:-foo}
expect $0: '${#:}: bad substitution'
echo ${#:}
expect "<'>"
recho "'"
expect '<">'
recho '"'
expect '<"hello">'
recho "\"hello\""
shift $#
unset foo
z=abcdef
z1='abc def'
expect '<>'
recho ${foo:-""}
expect nothing
recho ${foo:-"$@"}
expect '<>'
recho "${foo:-$@}"
# unset var
expect '<>'
recho ${foo:-"$zbcd"}
expect nothing
recho ${foo:-$zbcd}
# set var
expect '<abcdef>'
recho ${foo:-"$z"}
expect '<abc def>'
recho ${foo:-"$z1"}
expect '<abcdef>'
recho ${foo:-$z}
expect '<abc> <def>'
recho ${foo:-$z1}
expect '<abcdef>'
recho "${foo:-$z}"
expect '<abc def>'
recho "${foo:-$z1}"
expect '<abcdef>'
recho "${foo:-"$z"}"
# this disagrees with sh and ksh, but I think it is right according
# to posix.2.
expect '<abc def>'
recho "${foo:-"$z1"}"
set ab cd ef gh
expect '<ab> <cd> <ef> <gh>'
recho ${foo:-"$@"}
expect '<ab> <cd> <ef> <gh>'
recho "${foo:-$@}"
expect '<ab> <cd> <ef> <gh>'
recho "${foo:-"$@"}"
shift $#
expect nothing
recho $xxx"$@"
expect nothing
recho ${foo:-$xxx"$@"}
expect '<>'
recho "${foo:-$xxx$@}"
expect '<>'
recho "${foo:-$xxx"$@"}"
expect nothing
recho $xxx"$@"
expect nothing
recho "$xxx$@"
expect nothing
recho "$@"$xxx
expect '<>'
recho $xxx""
expect '<>'
recho $xxx''
expect '<>'
recho ''$xxx
expect '<>'
recho ""$xxx
AB='abcdefghijklmnopqrstuvwxyz'
recho ${AB:7:15}
recho ${AB:15:7}
recho ${AB:20}
recho ${AB:0}
recho ${AB:0:20}
recho ${AB:10:7}
recho ${AB:10:3+4}
recho ${AB:20/2:3+4}
set 1 2 3 4 5 6
recho \""${*:2:2}"\"
IFS=:
recho \""${*:2:2}"\"
IFS=$' \t\n'
z=123456
recho \""${z:2:2}"\"
recho \""${z:2}"\"
recho \""${z:2:4}"\"
recho \""${z:2:6}"\"
set $'\1' $'\2' $'\177'
recho $*
recho $@
recho ${*}
recho ${@}
xx=one/two/two
recho ${xx%/*}
recho ${xx/\/two}
yy=oneonetwo
recho ${yy//one}
recho ${yy/\/one}
xx=oneonetwo
recho ${xx/one}
recho ${xx//one}
recho ${xx/\/one}
# out-of-range substrings
var=abc
c=${var:3}
expect nothing
recho $c
c=${var:4}
expect nothing
recho $c
# as of bash-4.2, negative LENGTH means offset from the end
c=${var:0:-2}
expect '<a>'
recho $c
var=abcdefghi
c=${var:3:12}
recho $c
c=${var:4:20}
recho $c
# make sure null patterns work
xxx=endocrine
yyy=n
unset zzz
recho ${xxx/$yyy/*}
recho ${xxx//$yyy/*}
recho ${xxx/$zzz/*}
recho ${xxx//$zzz/*}
recho ${xxx//%${zzz}/}
recho ${xxx//%${zzz}}
recho ${xxx//#${zzz}/}
recho ${xxx//#${zzz}}
# another case that caused a core dump in bash-2.0
XPATH=/usr/bin:/bin:/usr/local/bin:/usr/gnu/bin::/usr/bin/X11:/sbin:/usr/sbin
recho ${XPATH//:/ }
xx=(ar as at au av aw ax ay az)
recho ${xx[@]/a/}
recho ${xx[@]//a/}
recho ${xx[*]/a/}
recho ${xx[*]//a/}
recho ${xx[@]%?}
recho ${xx[*]%?}
recho ${xx[@]#?}
recho ${xx[*]#?}
set -- ar as at au av aw ax ay az
recho ${@/a/}
recho ${@//a/}
recho ${*/a/}
recho ${*//a/}
recho ${@%?}
recho ${*%?}
recho ${@#?}
recho ${*#?}
shift $#
set -u
( recho $9 ; echo after 1)
( recho ${9} ; echo after 2)
( recho $UNSET ; echo after 3)
( recho ${UNSET} ; echo after 4)
( recho "$UNSET" ; echo after 5)
( recho "${UNSET}" ; echo after 6)
( recho "${#UNSET}" ; echo after 7)
set +u
RECEIVED="12345"
recho "${RECEIVED:$((${#RECEIVED}-1)):1}"
RECEIVED="12345#"
recho "${RECEIVED:$((${#RECEIVED}-1)):1}"
RECEIVED="#"
recho "${RECEIVED:$((${#RECEIVED}-1)):1}"
RECEIVED=""
recho "${RECEIVED:$((${#RECEIVED}-1)):1}"
# tests of new prefix expansion ${!prefix*}
${THIS_SH} ./new-exp3.sub
# bug with indirect expansion through bash-2.05b
${THIS_SH} ./new-exp4.sub
# these caused errors and core dumps in versions before bash-2.04
c=""
echo ${c//${$(($#-1))}/x/}
set a b c d e f g
recho "$@"
set -- ${@:1:$(($# - 2))}
recho "$@"
set a b
recho ${@:1:$(($# - 2))}
recho ${@:1:0}
recho ${@:1:1}
recho ${@:1:2}
recho "${*:1:0}"
# this is an error -- negative expression
set a
recho ${@:1:$(($# - 2))}
XPATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:.:/sbin:/usr/sbin
set $( IFS=: ; echo $XPATH )
recho ${@##*/}
recho ${@%%[!/]*}
recho ${@#/*}
recho ${@%*/}
set /full/path/to/x16 /another/full/path
recho ${1%/*}
recho ${1%%[!/]*}
recho ${1#*/}
recho ${1##*/}
${THIS_SH} ./new-exp5.sub
unset var
var=blah
# these had better agree
echo ${var[@]:3}
echo ${var:3}
echo ${var[@]/#/--}
echo ${var/#/--}
echo ${var[@]##?}
echo ${var##?}
unset var
var=(abcde abcfg abchi)
# problems with anchoring pattern replacements
echo ${var[*]//#abc/foo}
echo ${var[*]/#abc/foo}
unset var
${THIS_SH} ./new-exp6.sub
${THIS_SH} ./new-exp7.sub
${THIS_SH} ./new-exp8.sub
# tests to check whether things like indirect expansion of a variable whose
# value is 'anothervar[@]' stop working
${THIS_SH} ./new-exp9.sub
# problems with stray CTLNUL in bash-4.0-alpha
unset a
a=/a
recho "/${a%/*}"
recho "/${a///a/}"
# this must be last!
expect $0: 'ABXD: parameter unset'
recho ${ABXD:?"parameter unset"}
+86
View File
@@ -0,0 +1,86 @@
# new framework for parameter transformations, post bash-4.3
printf "<%s>" "${x@Q}" ; echo
printf "<%s>" "${x@E}" ; echo
printf "<%s>" "${x@P}" ; echo
printf "<%s>" "${x@A}" ; echo
x="ab 'cd' ef"
printf "<%s> " "${x@Q}" ; echo
printf "<%s>" "${x@C}"
# if unquoted, normal word splitting happens
set -- ab 'cd ef' '' gh
printf "<%s> " "${@@Q}" ; echo
printf "<%s> " "${*@Q}" ; echo
printf "<%s> " ${@@Q} ; echo
printf "<%s> " ${*@Q} ; echo
y[0]=4
y[1]='ab cd'
printf "<%s> " "${y[1]@Q}" ; echo
printf "<%s> " "${y[@]@Q}" ; echo # mksh doesn't like @ or * or arrays subscripted with them
printf "<%s> " "${z@Q}" ; echo # empty string?
recho ${z@Q} # this disappears
#
HOST=host
SHELL_LEVEL=2
NPS1='\[\]${HOST}($SHELL_LEVEL)[\v]\$ '
recho "${NPS1@P}"
#
D=' \t\n'
printf "<%s>" "${D@E}" ; echo
printf "<%s>" "${D@Q}" ; echo
E=$' \t\n'
printf "<%s>" "${E@E}" ; echo
printf "<%s>" "${E@Q}" ; echo
declare x
declare -r x="ab 'cd' ef"
printf "%s" "${x@A}" ; echo
set -- ab 'cd ef' '' gh
printf "%s " "${@@A}" ; echo
A=( "$@" )
printf "%s " "${A[@]@A}" ; echo
B=()
printf "%s " "${B[@]@A}" ; echo
unset A
declare -A A
A=( [one]=1 [two]='b c' [three]='' [four]=de )
printf "%s " "${A[@]@A}" ; echo
unset X
declare X
declare -r X="ab 'cd' ef"
printf "%s" "${X@a}" ; echo
set -- 1 2 3 4
unset A
A=( "$@" )
printf "%s " "${A@a}" ; echo
unset A
declare -A A
A=( [one]=1 [two]='b c' [three]='' [four]=de )
printf "%s " "${A@a}" ; echo
declare -ir Y=0
printf "%s" "${Y@a}" ; echo
# make sure we still handle ${#@} and ${@} as posix requires
set -- a b c d e
echo ${@}
echo ${#@}
echo a${#@}b
+85
View File
@@ -0,0 +1,85 @@
# new framework for parameter transformations, post bash-4.3
printf "<%s>" "${x@Q}" ; echo
printf "<%s>" "${x@E}" ; echo
printf "<%s>" "${x@P}" ; echo
printf "<%s>" "${x@A}" ; echo
x="ab 'cd' ef"
printf "<%s> " "${x@Q}" ; echo
printf "<%s>" "${x@C}"
# if unquoted, normal word splitting happens
set -- ab 'cd ef' '' gh
printf "<%s> " "${@@Q}" ; echo
printf "<%s> " "${*@Q}" ; echo
printf "<%s> " ${@@Q} ; echo
printf "<%s> " ${*@Q} ; echo
y[0]=4
y[1]='ab cd'
printf "<%s> " "${y[1]@Q}" ; echo
printf "<%s> " "${y[@]@Q}" ; echo # mksh doesn't like @ or * or arrays subscripted with them
printf "<%s> " "${z@Q}" ; echo # empty string?
recho ${z@Q} # this disappears
#
HOST=host
PS1='\[\]${HOST}($SHLVL)[\v]\$ '
recho "${PS1@P}"
#
D=' \t\n'
printf "<%s>" "${D@E}" ; echo
printf "<%s>" "${D@Q}" ; echo
E=$' \t\n'
printf "<%s>" "${E@E}" ; echo
printf "<%s>" "${E@Q}" ; echo
declare x
declare -r x="ab 'cd' ef"
printf "%s" "${x@A}" ; echo
set -- ab 'cd ef' '' gh
printf "%s " "${@@A}" ; echo
A=( "$@" )
printf "%s " "${A[@]@A}" ; echo
B=()
printf "%s " "${B[@]@A}" ; echo
unset A
declare -A A
A=( [one]=1 [two]='b c' [three]='' [four]=de )
printf "%s " "${A[@]@A}" ; echo
unset X
declare X
declare -r X="ab 'cd' ef"
printf "%s" "${X@a}" ; echo
set -- 1 2 3 4
unset A
A=( "$@" )
printf "%s " "${A@a}" ; echo
unset A
declare -A A
A=( [one]=1 [two]='b c' [three]='' [four]=de )
printf "%s " "${A@a}" ; echo
declare -ir Y=0
printf "%s" "${Y@a}" ; echo
# make sure we still handle ${#@} and ${@} as posix requires
set -- a b c d e
echo ${@}
echo ${#@}
echo a${#@}b
+9
View File
@@ -66,6 +66,15 @@ declare -ar FOOBAR2='([0]="bar")'
declare -ar FOOBAR2='([0]="bar")'
F OUTSIDE
F OUTSIDE
declare -ar outside='()'
declare -ir outside1="1"
tempenv = foo
0
declare -ar myvar='([0]="0")'
1
declare -ir myvar="1"
declare -rx tempvar1='foo'
declare -rx tempvar2='qux'
a=z
a=b
a=z
+3 -1
View File
@@ -214,6 +214,8 @@ ${THIS_SH} ./varenv5.sub
# variable scoping in the presence of nameref
${THIS_SH} ./varenv6.sub
# variable declaration problems with arrays and readonly local variables
${THIS_SH} ./varenv7.sub
# make sure variable scoping is done right
tt() { typeset a=b;echo a=$a; };a=z;echo a=$a;tt;echo a=$a
+219
View File
@@ -0,0 +1,219 @@
#
# varenv.sh
#
# Test the behavior of the shell with respect to variable and environment
# assignments
#
expect()
{
echo expect "$@"
}
a=1
b=2
c=3
d=4
e=5
f=6 g=7 h=8
a=3 b=4 $CHMOD $MODE $FN
# This should echo "3 4" according to Posix.2
expect "3 4"
echo $a $b
set -k
# Assignment statements made when no words are left affect the shell's
# environment
a=5 b=6 $CHMOD c=7 $MODE d=8 $FN e=9
expect "5 6 7 8 9"
echo $a $b $c $d $e
$CHMOD f=7 $MODE g=8 $FN h=9
expect "7 8 9"
echo $f $g $h
set +k
# The temporary environment does not affect variable expansion, only the
# environment given to the command
export HOME=/usr/chet
expect $HOME
echo $HOME
expect $HOME
HOME=/a/b/c /bin/echo $HOME
expect $HOME
echo $HOME
# This should echo /a/b/c
expect /a/b/c
HOME=/a/b/c printenv HOME
set -k
# This should echo $HOME 9, NOT /a/b/c 9
expect "$HOME"
HOME=/a/b/c /bin/echo $HOME c=9
expect "$HOME 7"
echo $HOME $c
# I claim the next two echo calls should give identical output.
# ksh agrees, the System V.3 sh does not
expect "/a/b/c 9 /a/b/c"
HOME=/a/b/c $ECHO a=$HOME c=9
echo $HOME $c $a
expect "/a/b/c 9 /a/b/c"
HOME=/a/b/c a=$HOME c=9
echo $HOME $c $a
set +k
# How do assignment statements affect subsequent assignments on the same
# line?
expect "/a/b/c /a/b/c"
HOME=/a/b/c a=$HOME
echo $HOME $a
# The system V.3 sh does this wrong; the last echo should output "1 1",
# but the system V.3 sh has it output "2 2". Posix.2 says the assignment
# statements are processed left-to-right. bash and ksh output the right
# thing
c=1
d=2
expect "1 2"
echo $c $d
d=$c c=$d
expect "1 1"
echo $c $d
# just for completeness
unset d c
expect unset
echo ${d-unset}
# no output
export a
a=bcde
export a
/bin/true 2>/dev/null
func()
{
local YYZ
YYZ="song by rush"
echo $YYZ
echo $A
}
YYZ="toronto airport"
A="AVAR"
echo $YYZ
echo $A
A=BVAR func
echo $YYZ
echo $A
export A
# Make sure expansion doesn't use assignment statements preceding a builtin
A=ZVAR echo $A
XPATH=/bin:/usr/bin:/usr/local/bin:.
func2()
{
local z=yy
local -a avar=( ${XPATH//: } )
echo ${avar[@]}
local
}
avar=42
echo $avar
func2
echo $avar
# try to set an attribute for an unset variable; make sure it persists
# when the variable is assigned a value
declare -i ivar
ivar=10
declare -p ivar
unset ivar
# export an unset variable, make sure it is not suddenly set, but make
# sure the export attribute persists when the variable is assigned a
# value
export ivar
echo ${ivar-unset}
ivar=42
declare -p ivar
# make sure set [-+]o ignoreeof and $IGNOREEOF are reflected
unset IGNOREEOF
set +o ignoreeof
set -o ignoreeof
if [ "$IGNOREEOF" -ne 10 ]; then
echo "./varenv.sh: set -o ignoreeof is not reflected in IGNOREEOF" >&2
fi
unset IGNOREEOF
set +o ignoreeof
# older versions of bash used to not reset RANDOM in subshells correctly
[[ $RANDOM -eq $(echo $RANDOM) ]] && echo "RANDOM: problem with subshells"
# make sure that shopt -o is reflected in $SHELLOPTS
# first, get rid of things that might be set automatically via shell
# variables
set +o posix
set +o ignoreeof
set +o monitor
echo $-
echo ${SHELLOPTS}
shopt -so physical
echo $-
echo ${SHELLOPTS}
# and make sure it is readonly
readonly -p | grep SHELLOPTS
# This was an error in bash versions prior to bash-2.04. The `set -a'
# should cause the assignment statement that's an argument to typeset
# to create an exported variable
unset FOOFOO
FOOFOO=bar
set -a
typeset FOOFOO=abcde
printenv FOOFOO
# test out export behavior of variable assignments preceding builtins and
# functions
$THIS_SH ./varenv1.sub
# more tests; bugs in bash up to version 2.05a
$THIS_SH ./varenv2.sub
# more tests; bugs in bash IFS scoping up through version 4.2
$THIS_SH ./varenv3.sub
# scoping problems with declare -g through bash-4.2
${THIS_SH} ./varenv4.sub
# more scoping and declaration problems with -g and arrays through bash-4.2
${THIS_SH} ./varenv5.sub
# variable scoping in the presence of nameref
${THIS_SH} ./varenv6.sub
# make sure variable scoping is done right
tt() { typeset a=b;echo a=$a; };a=z;echo a=$a;tt;echo a=$a
+37
View File
@@ -0,0 +1,37 @@
foo()
{
local -a myvar=()
local -r myvar=0
echo "${myvar[@]}"
declare -p myvar
}
foo2()
{
local -i myvar=0
local -r myvar=1
echo "${myvar}"
declare -p myvar
}
declare -a outside=()
declare -r outside
declare -p outside
outside1=1
declare -ir outside1
declare -p outside1
tempenv=foo declare -r tempenv
echo tempenv = $tempenv
foo
foo2
tempvar1=foo declare -r tempvar1
echo ${tempvar1@A}
tempvar2=bar declare -r tempvar2=qux
echo ${tempvar2@A}
+2 -2
View File
@@ -2634,7 +2634,7 @@ bind_variable_internal (name, value, table, hflags, aflags)
else
{
assign_value:
if (readonly_p (entry) || noassign_p (entry))
if ((readonly_p (entry) && (aflags & ASS_FORCE) == 0) || noassign_p (entry))
{
if (readonly_p (entry))
err_readonly (name);
@@ -3840,7 +3840,7 @@ push_temp_var (data)
binding_table = shell_variables->table = hash_create (TEMPENV_HASH_BUCKETS);
}
v = bind_variable_internal (var->name, value_cell (var), binding_table, 0, 0);
v = bind_variable_internal (var->name, value_cell (var), binding_table, 0, ASS_FORCE);
/* XXX - should we set the context here? It shouldn't matter because of how
assign_in_env works, but might want to check. */
+5440
View File
File diff suppressed because it is too large Load Diff