mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-28 07:59:50 +02:00
commit bash-20141128 snapshot
This commit is contained in:
+112
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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,
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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 *));
|
||||
|
||||
@@ -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 *));
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+161
-154
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+40
-2
@@ -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
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -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
|
||||
|
||||
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+5601
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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_ */
|
||||
@@ -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 (;;)
|
||||
{
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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,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;
|
||||
|
||||
@@ -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
Binary file not shown.
BIN
Binary file not shown.
@@ -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')
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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
@@ -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" )'
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user