summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChet Ramey <chet.ramey@case.edu>2017-04-03 10:31:01 -0400
committerChet Ramey <chet.ramey@case.edu>2017-04-03 10:31:01 -0400
commit7c4ef411b5f1a458c2908efe503e075e5a682040 (patch)
tree650fbdcd69b1700204eced0243833a43021e87a2
parent124d67cde092330257c69e8c9bd64af40ffd9b73 (diff)
downloadbash-7c4ef411b5f1a458c2908efe503e075e5a682040.tar.gz
commit bash-20170331 snapshot
-rw-r--r--CWRU/CWRU.chlog73
-rw-r--r--MANIFEST3
-rw-r--r--array.c18
-rw-r--r--doc/bash.111
-rw-r--r--doc/bashref.aux176
-rw-r--r--doc/bashref.bt118
-rw-r--r--doc/bashref.bts118
-rw-r--r--doc/bashref.cp94
-rw-r--r--doc/bashref.cps94
-rw-r--r--doc/bashref.fn220
-rw-r--r--doc/bashref.fns220
-rw-r--r--doc/bashref.info312
-rw-r--r--doc/bashref.log80
-rw-r--r--doc/bashref.pdfbin741335 -> 742807 bytes
-rw-r--r--doc/bashref.rw4
-rw-r--r--doc/bashref.rws4
-rw-r--r--doc/bashref.texi29
-rw-r--r--doc/bashref.toc170
-rw-r--r--doc/bashref.vr292
-rw-r--r--doc/bashref.vrs292
-rw-r--r--subst.c953
-rw-r--r--subst.h1
-rwxr-xr-xtests/dollar-at-star9
-rw-r--r--tests/dollar-at7.sub46
-rw-r--r--tests/dollar-star9.sub16
-rw-r--r--tests/dollar.right50
-rw-r--r--tests/exp.right11
-rw-r--r--tests/exp.tests1
-rw-r--r--tests/exp10.sub26
29 files changed, 1892 insertions, 1549 deletions
diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog
index b0b5c1b..25a0ac4 100644
--- a/CWRU/CWRU.chlog
+++ b/CWRU/CWRU.chlog
@@ -13509,3 +13509,76 @@ subst.c
so that splitting on spaces is performed on the already-quoted word.
Fixes bug reported by Grisha Levit <grishalevit@gmail.com>
+ 3/28
+ ----
+subst.c
+ - process_substitute: change so the subshell doesn't inherit the 'v'
+ option, like command substitution now does (as of bash-4.4).
+ Suggested by Grisha Levit <grishalevit@gmail.com>
+
+ 3/30
+ ----
+subst.c
+ - parameter_brace_casemod: now takes a pflags parameter, like
+ parameter_brace_patsub; changed callers
+ - parameter_brace_transform: now takes a pflags parameter, like
+ parameter_brace_patsub; changed callers
+ - pos_params_pat_subst,pos_params_modcase: if mflags indicates we're
+ on the rhs of an assignment statement and not going to perform
+ word splitting, we're expanding $*, and $IFS is null, make sure
+ string_list_pos_params treats the expansion as double-quoted, so
+ the positional parameters will be concatenated. Fixes bug reported
+ by Grisha Levit <grishalevit@gmail.com>
+
+ 3/31
+ ----
+doc/{bash.1,bashref.texi}
+ - add notes to the description of pipelines emphasizing that each
+ element of a pipeline is executed in a subshell, referring to the
+ description of a command execution environment, and that the
+ lastpipe option can modify that behavior. From a discussion with
+ Jean Delvare <jdelvare@suse.de>
+
+ 4/1
+ ---
+subst.c
+ - expand_word_internal: set had_quoted_null to note for later if we
+ expand '', "", or "$x" when x is unset
+ - expand_word_internal: if we expand "$param" (or "${param}") and we
+ come back with a single word with the W_HAVEQUOTEDNULL flag set,
+ make sure we set had_quoted_null to remember it for later. In this
+ case, if we already have seen a quoted null and we expanded $@ in
+ this (sub)string expansion, we don't want to do any of the special
+ $@ handling. In particular, we don't want to set *expanded_something,
+ because that will result in word splitting and quoted null removal.
+ Fixes bug reported by Grisha Levit <grishalevit@gmail.com>
+ - parameter_brace_patsub: when expanding ${*/pat/sub} in the case
+ where ifs_is_null != 0 and (pflags & PF_NOSPLIT2) (meaning we aren't
+ going to be doing word splitting), pass MATCH_ASSIGNRHS so we do
+ the right thing in this case. Part of a set of cases inspired by
+ Grisha Levit <grishalevit@gmail.com>
+ - param_expand: case '*': if we are on the rhs of an assignment
+ (PF_ASSIGNRHS) and ifs is unset, and $1 == " ", we need to make sure
+ string_list_dollar_at gets called with Q_DOUBLE_QUOTES so it quotes
+ the positional parameters before joining them into a string with
+ string_list_internal. Otherwise, that first space gets removed by
+ the implicit word splitting that gets performed. Reported by
+ Grisha Levit <grishalevit@gmail.com>
+
+array.c
+ - array_patsub,array_modcase: handle ${A[*]} identically to $* when
+ not quoted and IFS is null (separate with spaces). Makes things
+ like ${A[*]/x/y} behave the same as ${*/x/y} when IFS is null
+
+subst.c
+ - parameter_brace_patsub,parameter_brace_casemod: if expanding ${A[*]}
+ when the match is on the rhs of an assignment statement (PF_ASSIGNRHS)
+ and ifs is null, make sure the match is performed as if it were
+ quoted
+ - parameter_brace_substring: now takes a PFLAGS argument
+ - parameter_brace_substring: if expanding $* in a context where we
+ don't want to do word splitting (expand_no_split_dollar_star &&
+ PF_NOSPLIT2), make sure we expand $* as if it were quoted
+ - parameter_brace_substring: if expanding an unquoted $* on the rhs of
+ an assignment statement when IFS is null, make sure we expand the $*
+ as if it were quoted
diff --git a/MANIFEST b/MANIFEST
index 76bc713..2a34842 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -945,6 +945,7 @@ tests/dollar-at3.sub f
tests/dollar-at4.sub f
tests/dollar-at5.sub f
tests/dollar-at6.sub f
+tests/dollar-at7.sub f
tests/dollar-star1.sub f
tests/dollar-star2.sub f
tests/dollar-star3.sub f
@@ -953,6 +954,7 @@ tests/dollar-star5.sub f
tests/dollar-star6.sub f
tests/dollar-star7.sub f
tests/dollar-star8.sub f
+tests/dollar-star9.sub f
tests/dollar.right f
tests/dstack.tests f
tests/dstack.right f
@@ -994,6 +996,7 @@ tests/exp6.sub f
tests/exp7.sub f
tests/exp8.sub f
tests/exp9.sub f
+tests/exp10.sub f
tests/exportfunc.tests f
tests/exportfunc.right f
tests/exportfunc1.sub f
diff --git a/array.c b/array.c
index 040fb79..34f022e 100644
--- a/array.c
+++ b/array.c
@@ -63,6 +63,8 @@
static char *array_to_string_internal __P((ARRAY_ELEMENT *, ARRAY_ELEMENT *, char *, int));
+static char *spacesep = " ";
+
#define IS_LASTREF(a) (a->lastref)
#define LASTREF_START(a, i) \
@@ -489,9 +491,13 @@ int mflags;
if (mflags & MATCH_STARSUB) {
array_remove_quoted_nulls (a2);
- sifs = ifs_firstchar((int *)NULL);
+ if ((mflags & MATCH_QUOTED) == 0 && ifs_is_null)
+ sifs = spacesep;
+ else
+ sifs = ifs_firstchar((int *)NULL);
t = array_to_string (a2, sifs, 0);
- free(sifs);
+ if (sifs != spacesep)
+ free(sifs);
} else if (mflags & MATCH_QUOTED) {
/* ${array[@]} */
sifs = ifs_firstchar (&slen);
@@ -540,9 +546,13 @@ int mflags;
if (mflags & MATCH_STARSUB) {
array_remove_quoted_nulls (a2);
- sifs = ifs_firstchar((int *)NULL);
+ if ((mflags & MATCH_QUOTED) == 0 && ifs_is_null)
+ sifs = spacesep;
+ else
+ sifs = ifs_firstchar((int *)NULL);
t = array_to_string (a2, sifs, 0);
- free(sifs);
+ if (sifs != spacesep)
+ free(sifs);
} else if (mflags & MATCH_QUOTED) {
/* ${array[@]} */
sifs = ifs_firstchar (&slen);
diff --git a/doc/bash.1 b/doc/bash.1
index 12f263e..8657900 100644
--- a/doc/bash.1
+++ b/doc/bash.1
@@ -590,6 +590,13 @@ the time information.
.PP
Each command in a pipeline is executed as a separate process (i.e., in a
subshell).
+See
+.SM
+\fBCOMMAND EXECUTION ENVIRONMENT\fP
+for a description of a subshell environment.
+If the \fBlastpipe\fP option is enabled using the \fBshopt\fP builtin
+(see the description of \fBshopt\fP below),
+the last element of a pipeline may be run by the shell process.
.SS Lists
.PP
A \fIlist\fP is a sequence of one or more pipelines separated by one
@@ -640,7 +647,7 @@ An AND list has the form
.I command2
is executed if, and only if,
.I command1
-returns an exit status of zero.
+returns an exit status of zero (success).
.PP
An OR list has the form
.RS
@@ -1142,7 +1149,7 @@ question mark
.TP
.B \e\fInnn\fP
the eight-bit character whose value is the octal value \fInnn\fP
-(one to three digits)
+(one to three octal digits)
.TP
.B \ex\fIHH\fP
the eight-bit character whose value is the hexadecimal value \fIHH\fP
diff --git a/doc/bashref.aux b/doc/bashref.aux
index 1ef93b7..0ab9aaf 100644
--- a/doc/bashref.aux
+++ b/doc/bashref.aux
@@ -81,30 +81,30 @@
@xrdef{Special Parameters-title}{Special Parameters}
@xrdef{Special Parameters-snt}{Section@tie 3.4.2}
@xrdef{Positional Parameters-pg}{20}
-@xrdef{Special Parameters-pg}{20}
@xrdef{Shell Expansions-title}{Shell Expansions}
@xrdef{Shell Expansions-snt}{Section@tie 3.5}
-@xrdef{Shell Expansions-pg}{21}
+@xrdef{Special Parameters-pg}{21}
@xrdef{Brace Expansion-title}{Brace Expansion}
@xrdef{Brace Expansion-snt}{Section@tie 3.5.1}
+@xrdef{Shell Expansions-pg}{22}
@xrdef{Brace Expansion-pg}{22}
@xrdef{Tilde Expansion-title}{Tilde Expansion}
@xrdef{Tilde Expansion-snt}{Section@tie 3.5.2}
+@xrdef{Tilde Expansion-pg}{23}
@xrdef{Shell Parameter Expansion-title}{Shell Parameter Expansion}
@xrdef{Shell Parameter Expansion-snt}{Section@tie 3.5.3}
-@xrdef{Tilde Expansion-pg}{23}
@xrdef{Shell Parameter Expansion-pg}{24}
@xrdef{Command Substitution-title}{Command Substitution}
@xrdef{Command Substitution-snt}{Section@tie 3.5.4}
-@xrdef{Command Substitution-pg}{29}
@xrdef{Arithmetic Expansion-title}{Arithmetic Expansion}
@xrdef{Arithmetic Expansion-snt}{Section@tie 3.5.5}
@xrdef{Process Substitution-title}{Process Substitution}
@xrdef{Process Substitution-snt}{Section@tie 3.5.6}
-@xrdef{Word Splitting-title}{Word Splitting}
-@xrdef{Word Splitting-snt}{Section@tie 3.5.7}
+@xrdef{Command Substitution-pg}{30}
@xrdef{Arithmetic Expansion-pg}{30}
@xrdef{Process Substitution-pg}{30}
+@xrdef{Word Splitting-title}{Word Splitting}
+@xrdef{Word Splitting-snt}{Section@tie 3.5.7}
@xrdef{Filename Expansion-title}{Filename Expansion}
@xrdef{Filename Expansion-snt}{Section@tie 3.5.8}
@xrdef{Word Splitting-pg}{31}
@@ -122,10 +122,10 @@
@xrdef{Executing Commands-snt}{Section@tie 3.7}
@xrdef{Simple Command Expansion-title}{Simple Command Expansion}
@xrdef{Simple Command Expansion-snt}{Section@tie 3.7.1}
-@xrdef{Command Search and Execution-title}{Command Search and Execution}
-@xrdef{Command Search and Execution-snt}{Section@tie 3.7.2}
@xrdef{Executing Commands-pg}{37}
@xrdef{Simple Command Expansion-pg}{37}
+@xrdef{Command Search and Execution-title}{Command Search and Execution}
+@xrdef{Command Search and Execution-snt}{Section@tie 3.7.2}
@xrdef{Command Execution Environment-title}{Command Execution Environment}
@xrdef{Command Execution Environment-snt}{Section@tie 3.7.3}
@xrdef{Command Search and Execution-pg}{38}
@@ -146,92 +146,92 @@
@xrdef{Shell Builtin Commands-snt}{Chapter@tie 4}
@xrdef{Bourne Shell Builtins-title}{Bourne Shell Builtins}
@xrdef{Bourne Shell Builtins-snt}{Section@tie 4.1}
-@xrdef{Shell Builtin Commands-pg}{42}
-@xrdef{Bourne Shell Builtins-pg}{42}
+@xrdef{Shell Builtin Commands-pg}{43}
+@xrdef{Bourne Shell Builtins-pg}{43}
@xrdef{Bash Builtins-title}{Bash Builtin Commands}
@xrdef{Bash Builtins-snt}{Section@tie 4.2}
-@xrdef{Bash Builtins-pg}{49}
+@xrdef{Bash Builtins-pg}{50}
@xrdef{Modifying Shell Behavior-title}{Modifying Shell Behavior}
@xrdef{Modifying Shell Behavior-snt}{Section@tie 4.3}
@xrdef{The Set Builtin-title}{The Set Builtin}
@xrdef{The Set Builtin-snt}{Section@tie 4.3.1}
-@xrdef{Modifying Shell Behavior-pg}{60}
-@xrdef{The Set Builtin-pg}{60}
+@xrdef{Modifying Shell Behavior-pg}{61}
+@xrdef{The Set Builtin-pg}{61}
@xrdef{The Shopt Builtin-title}{The Shopt Builtin}
@xrdef{The Shopt Builtin-snt}{Section@tie 4.3.2}
-@xrdef{The Shopt Builtin-pg}{64}
+@xrdef{The Shopt Builtin-pg}{65}
@xrdef{Special Builtins-title}{Special Builtins}
@xrdef{Special Builtins-snt}{Section@tie 4.4}
-@xrdef{Special Builtins-pg}{70}
+@xrdef{Special Builtins-pg}{71}
@xrdef{Shell Variables-title}{Shell Variables}
@xrdef{Shell Variables-snt}{Chapter@tie 5}
@xrdef{Bourne Shell Variables-title}{Bourne Shell Variables}
@xrdef{Bourne Shell Variables-snt}{Section@tie 5.1}
@xrdef{Bash Variables-title}{Bash Variables}
@xrdef{Bash Variables-snt}{Section@tie 5.2}
-@xrdef{Shell Variables-pg}{71}
-@xrdef{Bourne Shell Variables-pg}{71}
-@xrdef{Bash Variables-pg}{71}
+@xrdef{Shell Variables-pg}{72}
+@xrdef{Bourne Shell Variables-pg}{72}
+@xrdef{Bash Variables-pg}{72}
@xrdef{Bash Features-title}{Bash Features}
@xrdef{Bash Features-snt}{Chapter@tie 6}
@xrdef{Invoking Bash-title}{Invoking Bash}
@xrdef{Invoking Bash-snt}{Section@tie 6.1}
-@xrdef{Bash Features-pg}{83}
-@xrdef{Invoking Bash-pg}{83}
+@xrdef{Bash Features-pg}{84}
+@xrdef{Invoking Bash-pg}{84}
@xrdef{Bash Startup Files-title}{Bash Startup Files}
@xrdef{Bash Startup Files-snt}{Section@tie 6.2}
-@xrdef{Bash Startup Files-pg}{85}
+@xrdef{Bash Startup Files-pg}{86}
@xrdef{Interactive Shells-title}{Interactive Shells}
@xrdef{Interactive Shells-snt}{Section@tie 6.3}
@xrdef{What is an Interactive Shell?-title}{What is an Interactive Shell?}
@xrdef{What is an Interactive Shell?-snt}{Section@tie 6.3.1}
-@xrdef{Interactive Shells-pg}{86}
+@xrdef{Interactive Shells-pg}{87}
@xrdef{Is this Shell Interactive?-title}{Is this Shell Interactive?}
@xrdef{Is this Shell Interactive?-snt}{Section@tie 6.3.2}
@xrdef{Interactive Shell Behavior-title}{Interactive Shell Behavior}
@xrdef{Interactive Shell Behavior-snt}{Section@tie 6.3.3}
-@xrdef{What is an Interactive Shell?-pg}{87}
-@xrdef{Is this Shell Interactive?-pg}{87}
-@xrdef{Interactive Shell Behavior-pg}{87}
+@xrdef{What is an Interactive Shell?-pg}{88}
+@xrdef{Is this Shell Interactive?-pg}{88}
+@xrdef{Interactive Shell Behavior-pg}{88}
@xrdef{Bash Conditional Expressions-title}{Bash Conditional Expressions}
@xrdef{Bash Conditional Expressions-snt}{Section@tie 6.4}
-@xrdef{Bash Conditional Expressions-pg}{88}
+@xrdef{Bash Conditional Expressions-pg}{89}
@xrdef{Shell Arithmetic-title}{Shell Arithmetic}
@xrdef{Shell Arithmetic-snt}{Section@tie 6.5}
-@xrdef{Shell Arithmetic-pg}{90}
+@xrdef{Shell Arithmetic-pg}{91}
@xrdef{Aliases-title}{Aliases}
@xrdef{Aliases-snt}{Section@tie 6.6}
-@xrdef{Aliases-pg}{91}
+@xrdef{Aliases-pg}{92}
@xrdef{Arrays-title}{Arrays}
@xrdef{Arrays-snt}{Section@tie 6.7}
-@xrdef{Arrays-pg}{92}
+@xrdef{Arrays-pg}{93}
@xrdef{The Directory Stack-title}{The Directory Stack}
@xrdef{The Directory Stack-snt}{Section@tie 6.8}
@xrdef{Directory Stack Builtins-title}{Directory Stack Builtins}
@xrdef{Directory Stack Builtins-snt}{Section@tie 6.8.1}
-@xrdef{The Directory Stack-pg}{94}
-@xrdef{Directory Stack Builtins-pg}{94}
+@xrdef{The Directory Stack-pg}{95}
+@xrdef{Directory Stack Builtins-pg}{95}
@xrdef{Controlling the Prompt-title}{Controlling the Prompt}
@xrdef{Controlling the Prompt-snt}{Section@tie 6.9}
-@xrdef{Controlling the Prompt-pg}{95}
+@xrdef{Controlling the Prompt-pg}{96}
@xrdef{The Restricted Shell-title}{The Restricted Shell}
@xrdef{The Restricted Shell-snt}{Section@tie 6.10}
-@xrdef{The Restricted Shell-pg}{96}
+@xrdef{The Restricted Shell-pg}{97}
@xrdef{Bash POSIX Mode-title}{Bash POSIX Mode}
@xrdef{Bash POSIX Mode-snt}{Section@tie 6.11}
-@xrdef{Bash POSIX Mode-pg}{97}
+@xrdef{Bash POSIX Mode-pg}{98}
@xrdef{Job Control-title}{Job Control}
@xrdef{Job Control-snt}{Chapter@tie 7}
@xrdef{Job Control Basics-title}{Job Control Basics}
@xrdef{Job Control Basics-snt}{Section@tie 7.1}
-@xrdef{Job Control-pg}{101}
-@xrdef{Job Control Basics-pg}{101}
+@xrdef{Job Control-pg}{102}
+@xrdef{Job Control Basics-pg}{102}
@xrdef{Job Control Builtins-title}{Job Control Builtins}
@xrdef{Job Control Builtins-snt}{Section@tie 7.2}
-@xrdef{Job Control Builtins-pg}{102}
+@xrdef{Job Control Builtins-pg}{103}
@xrdef{Job Control Variables-title}{Job Control Variables}
@xrdef{Job Control Variables-snt}{Section@tie 7.3}
-@xrdef{Job Control Variables-pg}{104}
+@xrdef{Job Control Variables-pg}{105}
@xrdef{Command Line Editing-title}{Command Line Editing}
@xrdef{Command Line Editing-snt}{Chapter@tie 8}
@xrdef{Introduction and Notation-title}{Introduction to Line Editing}
@@ -240,145 +240,145 @@
@xrdef{Readline Interaction-snt}{Section@tie 8.2}
@xrdef{Readline Bare Essentials-title}{Readline Bare Essentials}
@xrdef{Readline Bare Essentials-snt}{Section@tie 8.2.1}
-@xrdef{Command Line Editing-pg}{105}
-@xrdef{Introduction and Notation-pg}{105}
-@xrdef{Readline Interaction-pg}{105}
+@xrdef{Command Line Editing-pg}{106}
+@xrdef{Introduction and Notation-pg}{106}
+@xrdef{Readline Interaction-pg}{106}
@xrdef{Readline Movement Commands-title}{Readline Movement Commands}
@xrdef{Readline Movement Commands-snt}{Section@tie 8.2.2}
@xrdef{Readline Killing Commands-title}{Readline Killing Commands}
@xrdef{Readline Killing Commands-snt}{Section@tie 8.2.3}
-@xrdef{Readline Bare Essentials-pg}{106}
-@xrdef{Readline Movement Commands-pg}{106}
+@xrdef{Readline Bare Essentials-pg}{107}
+@xrdef{Readline Movement Commands-pg}{107}
@xrdef{Readline Arguments-title}{Readline Arguments}
@xrdef{Readline Arguments-snt}{Section@tie 8.2.4}
@xrdef{Searching-title}{Searching for Commands in the History}
@xrdef{Searching-snt}{Section@tie 8.2.5}
-@xrdef{Readline Killing Commands-pg}{107}
-@xrdef{Readline Arguments-pg}{107}
-@xrdef{Searching-pg}{107}
+@xrdef{Readline Killing Commands-pg}{108}
+@xrdef{Readline Arguments-pg}{108}
+@xrdef{Searching-pg}{108}
@xrdef{Readline Init File-title}{Readline Init File}
@xrdef{Readline Init File-snt}{Section@tie 8.3}
@xrdef{Readline Init File Syntax-title}{Readline Init File Syntax}
@xrdef{Readline Init File Syntax-snt}{Section@tie 8.3.1}
-@xrdef{Readline Init File-pg}{108}
-@xrdef{Readline Init File Syntax-pg}{108}
+@xrdef{Readline Init File-pg}{109}
+@xrdef{Readline Init File Syntax-pg}{109}
@xrdef{Conditional Init Constructs-title}{Conditional Init Constructs}
@xrdef{Conditional Init Constructs-snt}{Section@tie 8.3.2}
-@xrdef{Conditional Init Constructs-pg}{116}
+@xrdef{Conditional Init Constructs-pg}{117}
@xrdef{Sample Init File-title}{Sample Init File}
@xrdef{Sample Init File-snt}{Section@tie 8.3.3}
-@xrdef{Sample Init File-pg}{117}
+@xrdef{Sample Init File-pg}{118}
@xrdef{Bindable Readline Commands-title}{Bindable Readline Commands}
@xrdef{Bindable Readline Commands-snt}{Section@tie 8.4}
@xrdef{Commands For Moving-title}{Commands For Moving}
@xrdef{Commands For Moving-snt}{Section@tie 8.4.1}
-@xrdef{Bindable Readline Commands-pg}{120}
-@xrdef{Commands For Moving-pg}{120}
+@xrdef{Bindable Readline Commands-pg}{121}
+@xrdef{Commands For Moving-pg}{121}
@xrdef{Commands For History-title}{Commands For Manipulating The History}
@xrdef{Commands For History-snt}{Section@tie 8.4.2}
-@xrdef{Commands For History-pg}{121}
+@xrdef{Commands For History-pg}{122}
@xrdef{Commands For Text-title}{Commands For Changing Text}
@xrdef{Commands For Text-snt}{Section@tie 8.4.3}
-@xrdef{Commands For Text-pg}{122}
+@xrdef{Commands For Text-pg}{123}
@xrdef{Commands For Killing-title}{Killing And Yanking}
@xrdef{Commands For Killing-snt}{Section@tie 8.4.4}
-@xrdef{Commands For Killing-pg}{124}
+@xrdef{Commands For Killing-pg}{125}
@xrdef{Numeric Arguments-title}{Specifying Numeric Arguments}
@xrdef{Numeric Arguments-snt}{Section@tie 8.4.5}
@xrdef{Commands For Completion-title}{Letting Readline Type For You}
@xrdef{Commands For Completion-snt}{Section@tie 8.4.6}
-@xrdef{Numeric Arguments-pg}{125}
-@xrdef{Commands For Completion-pg}{125}
+@xrdef{Numeric Arguments-pg}{126}
+@xrdef{Commands For Completion-pg}{126}
@xrdef{Keyboard Macros-title}{Keyboard Macros}
@xrdef{Keyboard Macros-snt}{Section@tie 8.4.7}
@xrdef{Miscellaneous Commands-title}{Some Miscellaneous Commands}
@xrdef{Miscellaneous Commands-snt}{Section@tie 8.4.8}
-@xrdef{Keyboard Macros-pg}{127}
-@xrdef{Miscellaneous Commands-pg}{127}
+@xrdef{Keyboard Macros-pg}{128}
+@xrdef{Miscellaneous Commands-pg}{128}
@xrdef{Readline vi Mode-title}{Readline vi Mode}
@xrdef{Readline vi Mode-snt}{Section@tie 8.5}
-@xrdef{Readline vi Mode-pg}{129}
+@xrdef{Readline vi Mode-pg}{130}
@xrdef{Programmable Completion-title}{Programmable Completion}
@xrdef{Programmable Completion-snt}{Section@tie 8.6}
-@xrdef{Programmable Completion-pg}{130}
+@xrdef{Programmable Completion-pg}{131}
@xrdef{Programmable Completion Builtins-title}{Programmable Completion Builtins}
@xrdef{Programmable Completion Builtins-snt}{Section@tie 8.7}
-@xrdef{Programmable Completion Builtins-pg}{132}
+@xrdef{Programmable Completion Builtins-pg}{133}
@xrdef{A Programmable Completion Example-title}{A Programmable Completion Example}
@xrdef{A Programmable Completion Example-snt}{Section@tie 8.8}
-@xrdef{A Programmable Completion Example-pg}{136}
+@xrdef{A Programmable Completion Example-pg}{137}
@xrdef{Using History Interactively-title}{Using History Interactively}
@xrdef{Using History Interactively-snt}{Chapter@tie 9}
@xrdef{Bash History Facilities-title}{Bash History Facilities}
@xrdef{Bash History Facilities-snt}{Section@tie 9.1}
@xrdef{Bash History Builtins-title}{Bash History Builtins}
@xrdef{Bash History Builtins-snt}{Section@tie 9.2}
-@xrdef{Using History Interactively-pg}{139}
-@xrdef{Bash History Facilities-pg}{139}
-@xrdef{Bash History Builtins-pg}{139}
+@xrdef{Using History Interactively-pg}{140}
+@xrdef{Bash History Facilities-pg}{140}
+@xrdef{Bash History Builtins-pg}{140}
@xrdef{History Interaction-title}{History Expansion}
@xrdef{History Interaction-snt}{Section@tie 9.3}
-@xrdef{History Interaction-pg}{141}
+@xrdef{History Interaction-pg}{142}
@xrdef{Event Designators-title}{Event Designators}
@xrdef{Event Designators-snt}{Section@tie 9.3.1}
@xrdef{Word Designators-title}{Word Designators}
@xrdef{Word Designators-snt}{Section@tie 9.3.2}
-@xrdef{Event Designators-pg}{142}
-@xrdef{Word Designators-pg}{142}
+@xrdef{Event Designators-pg}{143}
+@xrdef{Word Designators-pg}{143}
@xrdef{Modifiers-title}{Modifiers}
@xrdef{Modifiers-snt}{Section@tie 9.3.3}
-@xrdef{Modifiers-pg}{143}
+@xrdef{Modifiers-pg}{144}
@xrdef{Installing Bash-title}{Installing Bash}
@xrdef{Installing Bash-snt}{Chapter@tie 10}
@xrdef{Basic Installation-title}{Basic Installation}
@xrdef{Basic Installation-snt}{Section@tie 10.1}
@xrdef{Compilers and Options-title}{Compilers and Options}
@xrdef{Compilers and Options-snt}{Section@tie 10.2}
-@xrdef{Installing Bash-pg}{144}
-@xrdef{Basic Installation-pg}{144}
+@xrdef{Installing Bash-pg}{145}
+@xrdef{Basic Installation-pg}{145}
@xrdef{Compiling For Multiple Architectures-title}{Compiling For Multiple Architectures}
@xrdef{Compiling For Multiple Architectures-snt}{Section@tie 10.3}
@xrdef{Installation Names-title}{Installation Names}
@xrdef{Installation Names-snt}{Section@tie 10.4}
@xrdef{Specifying the System Type-title}{Specifying the System Type}
@xrdef{Specifying the System Type-snt}{Section@tie 10.5}
-@xrdef{Compilers and Options-pg}{145}
-@xrdef{Compiling For Multiple Architectures-pg}{145}
-@xrdef{Installation Names-pg}{145}
-@xrdef{Specifying the System Type-pg}{145}
+@xrdef{Compilers and Options-pg}{146}
+@xrdef{Compiling For Multiple Architectures-pg}{146}
+@xrdef{Installation Names-pg}{146}
+@xrdef{Specifying the System Type-pg}{146}
@xrdef{Sharing Defaults-title}{Sharing Defaults}
@xrdef{Sharing Defaults-snt}{Section@tie 10.6}
@xrdef{Operation Controls-title}{Operation Controls}
@xrdef{Operation Controls-snt}{Section@tie 10.7}
@xrdef{Optional Features-title}{Optional Features}
@xrdef{Optional Features-snt}{Section@tie 10.8}
-@xrdef{Sharing Defaults-pg}{146}
-@xrdef{Operation Controls-pg}{146}
-@xrdef{Optional Features-pg}{146}
+@xrdef{Sharing Defaults-pg}{147}
+@xrdef{Operation Controls-pg}{147}
+@xrdef{Optional Features-pg}{147}
@xrdef{Reporting Bugs-title}{Reporting Bugs}
@xrdef{Reporting Bugs-snt}{Appendix@tie @char65{}}
-@xrdef{Reporting Bugs-pg}{152}
+@xrdef{Reporting Bugs-pg}{153}
@xrdef{Major Differences From The Bourne Shell-title}{Major Differences From The Bourne Shell}
@xrdef{Major Differences From The Bourne Shell-snt}{Appendix@tie @char66{}}
-@xrdef{Major Differences From The Bourne Shell-pg}{153}
+@xrdef{Major Differences From The Bourne Shell-pg}{154}
@xrdef{GNU Free Documentation License-title}{GNU Free Documentation License}
@xrdef{GNU Free Documentation License-snt}{Appendix@tie @char67{}}
-@xrdef{GNU Free Documentation License-pg}{159}
+@xrdef{GNU Free Documentation License-pg}{160}
@xrdef{Indexes-title}{Indexes}
@xrdef{Indexes-snt}{Appendix@tie @char68{}}
@xrdef{Builtin Index-title}{Index of Shell Builtin Commands}
@xrdef{Builtin Index-snt}{Section@tie @char68.1}
-@xrdef{Indexes-pg}{167}
-@xrdef{Builtin Index-pg}{167}
+@xrdef{Indexes-pg}{168}
+@xrdef{Builtin Index-pg}{168}
@xrdef{Reserved Word Index-title}{Index of Shell Reserved Words}
@xrdef{Reserved Word Index-snt}{Section@tie @char68.2}
@xrdef{Variable Index-title}{Parameter and Variable Index}
@xrdef{Variable Index-snt}{Section@tie @char68.3}
-@xrdef{Reserved Word Index-pg}{168}
-@xrdef{Variable Index-pg}{169}
+@xrdef{Reserved Word Index-pg}{169}
+@xrdef{Variable Index-pg}{170}
@xrdef{Function Index-title}{Function Index}
@xrdef{Function Index-snt}{Section@tie @char68.4}
-@xrdef{Function Index-pg}{171}
+@xrdef{Function Index-pg}{172}
@xrdef{Concept Index-title}{Concept Index}
@xrdef{Concept Index-snt}{Section@tie @char68.5}
-@xrdef{Concept Index-pg}{173}
+@xrdef{Concept Index-pg}{174}
diff --git a/doc/bashref.bt b/doc/bashref.bt
index 1d49b61..2e207aa 100644
--- a/doc/bashref.bt
+++ b/doc/bashref.bt
@@ -1,59 +1,59 @@
-\entry{:}{42}{\code {:}}
-\entry{.}{42}{\code {.}}
-\entry{break}{43}{\code {break}}
-\entry{cd}{43}{\code {cd}}
-\entry{continue}{43}{\code {continue}}
-\entry{eval}{43}{\code {eval}}
-\entry{exec}{44}{\code {exec}}
-\entry{exit}{44}{\code {exit}}
-\entry{export}{44}{\code {export}}
-\entry{getopts}{44}{\code {getopts}}
-\entry{hash}{45}{\code {hash}}
-\entry{pwd}{45}{\code {pwd}}
-\entry{readonly}{45}{\code {readonly}}
-\entry{return}{46}{\code {return}}
-\entry{shift}{46}{\code {shift}}
-\entry{test}{46}{\code {test}}
-\entry{[}{46}{\code {[}}
-\entry{times}{48}{\code {times}}
-\entry{trap}{48}{\code {trap}}
-\entry{umask}{48}{\code {umask}}
-\entry{unset}{49}{\code {unset}}
-\entry{alias}{49}{\code {alias}}
-\entry{bind}{49}{\code {bind}}
-\entry{builtin}{50}{\code {builtin}}
-\entry{caller}{51}{\code {caller}}
-\entry{command}{51}{\code {command}}
-\entry{declare}{51}{\code {declare}}
-\entry{echo}{53}{\code {echo}}
-\entry{enable}{53}{\code {enable}}
-\entry{help}{54}{\code {help}}
-\entry{let}{54}{\code {let}}
-\entry{local}{54}{\code {local}}
-\entry{logout}{55}{\code {logout}}
-\entry{mapfile}{55}{\code {mapfile}}
-\entry{printf}{55}{\code {printf}}
-\entry{read}{56}{\code {read}}
-\entry{readarray}{57}{\code {readarray}}
-\entry{source}{58}{\code {source}}
-\entry{type}{58}{\code {type}}
-\entry{typeset}{58}{\code {typeset}}
-\entry{ulimit}{58}{\code {ulimit}}
-\entry{unalias}{60}{\code {unalias}}
-\entry{set}{60}{\code {set}}
-\entry{shopt}{64}{\code {shopt}}
-\entry{dirs}{94}{\code {dirs}}
-\entry{popd}{94}{\code {popd}}
-\entry{pushd}{95}{\code {pushd}}
-\entry{bg}{102}{\code {bg}}
-\entry{fg}{102}{\code {fg}}
-\entry{jobs}{102}{\code {jobs}}
-\entry{kill}{103}{\code {kill}}
-\entry{wait}{103}{\code {wait}}
-\entry{disown}{103}{\code {disown}}
-\entry{suspend}{104}{\code {suspend}}
-\entry{compgen}{132}{\code {compgen}}
-\entry{complete}{132}{\code {complete}}
-\entry{compopt}{135}{\code {compopt}}
-\entry{fc}{139}{\code {fc}}
-\entry{history}{140}{\code {history}}
+\entry{:}{43}{\code {:}}
+\entry{.}{43}{\code {.}}
+\entry{break}{44}{\code {break}}
+\entry{cd}{44}{\code {cd}}
+\entry{continue}{44}{\code {continue}}
+\entry{eval}{44}{\code {eval}}
+\entry{exec}{45}{\code {exec}}
+\entry{exit}{45}{\code {exit}}
+\entry{export}{45}{\code {export}}
+\entry{getopts}{45}{\code {getopts}}
+\entry{hash}{46}{\code {hash}}
+\entry{pwd}{46}{\code {pwd}}
+\entry{readonly}{46}{\code {readonly}}
+\entry{return}{47}{\code {return}}
+\entry{shift}{47}{\code {shift}}
+\entry{test}{47}{\code {test}}
+\entry{[}{47}{\code {[}}
+\entry{times}{49}{\code {times}}
+\entry{trap}{49}{\code {trap}}
+\entry{umask}{49}{\code {umask}}
+\entry{unset}{50}{\code {unset}}
+\entry{alias}{50}{\code {alias}}
+\entry{bind}{50}{\code {bind}}
+\entry{builtin}{51}{\code {builtin}}
+\entry{caller}{52}{\code {caller}}
+\entry{command}{52}{\code {command}}
+\entry{declare}{52}{\code {declare}}
+\entry{echo}{54}{\code {echo}}
+\entry{enable}{54}{\code {enable}}
+\entry{help}{55}{\code {help}}
+\entry{let}{55}{\code {let}}
+\entry{local}{55}{\code {local}}
+\entry{logout}{56}{\code {logout}}
+\entry{mapfile}{56}{\code {mapfile}}
+\entry{printf}{56}{\code {printf}}
+\entry{read}{57}{\code {read}}
+\entry{readarray}{58}{\code {readarray}}
+\entry{source}{59}{\code {source}}
+\entry{type}{59}{\code {type}}
+\entry{typeset}{59}{\code {typeset}}
+\entry{ulimit}{59}{\code {ulimit}}
+\entry{unalias}{61}{\code {unalias}}
+\entry{set}{61}{\code {set}}
+\entry{shopt}{65}{\code {shopt}}
+\entry{dirs}{95}{\code {dirs}}
+\entry{popd}{95}{\code {popd}}
+\entry{pushd}{96}{\code {pushd}}
+\entry{bg}{103}{\code {bg}}
+\entry{fg}{103}{\code {fg}}
+\entry{jobs}{103}{\code {jobs}}
+\entry{kill}{104}{\code {kill}}
+\entry{wait}{104}{\code {wait}}
+\entry{disown}{104}{\code {disown}}
+\entry{suspend}{105}{\code {suspend}}
+\entry{compgen}{133}{\code {compgen}}
+\entry{complete}{133}{\code {complete}}
+\entry{compopt}{136}{\code {compopt}}
+\entry{fc}{140}{\code {fc}}
+\entry{history}{141}{\code {history}}
diff --git a/doc/bashref.bts b/doc/bashref.bts
index fb2d4b0..765b1e3 100644
--- a/doc/bashref.bts
+++ b/doc/bashref.bts
@@ -1,80 +1,80 @@
\initial {.}
-\entry {\code {.}}{42}
+\entry {\code {.}}{43}
\initial {:}
-\entry {\code {:}}{42}
+\entry {\code {:}}{43}
\initial {[}
-\entry {\code {[}}{46}
+\entry {\code {[}}{47}
\initial {A}
-\entry {\code {alias}}{49}
+\entry {\code {alias}}{50}
\initial {B}
-\entry {\code {bg}}{102}
-\entry {\code {bind}}{49}
-\entry {\code {break}}{43}
-\entry {\code {builtin}}{50}
+\entry {\code {bg}}{103}
+\entry {\code {bind}}{50}
+\entry {\code {break}}{44}
+\entry {\code {builtin}}{51}
\initial {C}
-\entry {\code {caller}}{51}
-\entry {\code {cd}}{43}
-\entry {\code {command}}{51}
-\entry {\code {compgen}}{132}
-\entry {\code {complete}}{132}
-\entry {\code {compopt}}{135}
-\entry {\code {continue}}{43}
+\entry {\code {caller}}{52}
+\entry {\code {cd}}{44}
+\entry {\code {command}}{52}
+\entry {\code {compgen}}{133}
+\entry {\code {complete}}{133}
+\entry {\code {compopt}}{136}
+\entry {\code {continue}}{44}
\initial {D}
-\entry {\code {declare}}{51}
-\entry {\code {dirs}}{94}
-\entry {\code {disown}}{103}
+\entry {\code {declare}}{52}
+\entry {\code {dirs}}{95}
+\entry {\code {disown}}{104}
\initial {E}
-\entry {\code {echo}}{53}
-\entry {\code {enable}}{53}
-\entry {\code {eval}}{43}
-\entry {\code {exec}}{44}
-\entry {\code {exit}}{44}
-\entry {\code {export}}{44}
+\entry {\code {echo}}{54}
+\entry {\code {enable}}{54}
+\entry {\code {eval}}{44}
+\entry {\code {exec}}{45}
+\entry {\code {exit}}{45}
+\entry {\code {export}}{45}
\initial {F}
-\entry {\code {fc}}{139}
-\entry {\code {fg}}{102}
+\entry {\code {fc}}{140}
+\entry {\code {fg}}{103}
\initial {G}
-\entry {\code {getopts}}{44}
+\entry {\code {getopts}}{45}
\initial {H}
-\entry {\code {hash}}{45}
-\entry {\code {help}}{54}
-\entry {\code {history}}{140}
+\entry {\code {hash}}{46}
+\entry {\code {help}}{55}
+\entry {\code {history}}{141}
\initial {J}
-\entry {\code {jobs}}{102}
+\entry {\code {jobs}}{103}
\initial {K}
-\entry {\code {kill}}{103}
+\entry {\code {kill}}{104}
\initial {L}
-\entry {\code {let}}{54}
-\entry {\code {local}}{54}
-\entry {\code {logout}}{55}
+\entry {\code {let}}{55}
+\entry {\code {local}}{55}
+\entry {\code {logout}}{56}
\initial {M}
-\entry {\code {mapfile}}{55}
+\entry {\code {mapfile}}{56}
\initial {P}
-\entry {\code {popd}}{94}
-\entry {\code {printf}}{55}
-\entry {\code {pushd}}{95}
-\entry {\code {pwd}}{45}
+\entry {\code {popd}}{95}
+\entry {\code {printf}}{56}
+\entry {\code {pushd}}{96}
+\entry {\code {pwd}}{46}
\initial {R}
-\entry {\code {read}}{56}
-\entry {\code {readarray}}{57}
-\entry {\code {readonly}}{45}
-\entry {\code {return}}{46}
+\entry {\code {read}}{57}
+\entry {\code {readarray}}{58}
+\entry {\code {readonly}}{46}
+\entry {\code {return}}{47}
\initial {S}
-\entry {\code {set}}{60}
-\entry {\code {shift}}{46}
-\entry {\code {shopt}}{64}
-\entry {\code {source}}{58}
-\entry {\code {suspend}}{104}
+\entry {\code {set}}{61}
+\entry {\code {shift}}{47}
+\entry {\code {shopt}}{65}
+\entry {\code {source}}{59}
+\entry {\code {suspend}}{105}
\initial {T}
-\entry {\code {test}}{46}
-\entry {\code {times}}{48}
-\entry {\code {trap}}{48}
-\entry {\code {type}}{58}
-\entry {\code {typeset}}{58}
+\entry {\code {test}}{47}
+\entry {\code {times}}{49}
+\entry {\code {trap}}{49}
+\entry {\code {type}}{59}
+\entry {\code {typeset}}{59}
\initial {U}
-\entry {\code {ulimit}}{58}
-\entry {\code {umask}}{48}
-\entry {\code {unalias}}{60}
-\entry {\code {unset}}{49}
+\entry {\code {ulimit}}{59}
+\entry {\code {umask}}{49}
+\entry {\code {unalias}}{61}
+\entry {\code {unset}}{50}
\initial {W}
-\entry {\code {wait}}{103}
+\entry {\code {wait}}{104}
diff --git a/doc/bashref.cp b/doc/bashref.cp
index 0970f8f..10a74b1 100644
--- a/doc/bashref.cp
+++ b/doc/bashref.cp
@@ -43,15 +43,15 @@
\entry{variable, shell}{19}{variable, shell}
\entry{shell variable}{19}{shell variable}
\entry{parameters, positional}{20}{parameters, positional}
-\entry{parameters, special}{20}{parameters, special}
-\entry{expansion}{21}{expansion}
+\entry{parameters, special}{21}{parameters, special}
+\entry{expansion}{22}{expansion}
\entry{brace expansion}{22}{brace expansion}
\entry{expansion, brace}{22}{expansion, brace}
\entry{tilde expansion}{23}{tilde expansion}
\entry{expansion, tilde}{23}{expansion, tilde}
\entry{parameter expansion}{24}{parameter expansion}
\entry{expansion, parameter}{24}{expansion, parameter}
-\entry{command substitution}{29}{command substitution}
+\entry{command substitution}{30}{command substitution}
\entry{expansion, arithmetic}{30}{expansion, arithmetic}
\entry{arithmetic expansion}{30}{arithmetic expansion}
\entry{process substitution}{30}{process substitution}
@@ -71,48 +71,48 @@
\entry{exit status}{40}{exit status}
\entry{signal handling}{40}{signal handling}
\entry{shell script}{41}{shell script}
-\entry{special builtin}{70}{special builtin}
-\entry{login shell}{85}{login shell}
-\entry{interactive shell}{85}{interactive shell}
-\entry{startup files}{85}{startup files}
+\entry{special builtin}{71}{special builtin}
+\entry{login shell}{86}{login shell}
\entry{interactive shell}{86}{interactive shell}
-\entry{shell, interactive}{86}{shell, interactive}
-\entry{expressions, conditional}{88}{expressions, conditional}
-\entry{arithmetic, shell}{90}{arithmetic, shell}
-\entry{shell arithmetic}{90}{shell arithmetic}
-\entry{expressions, arithmetic}{90}{expressions, arithmetic}
-\entry{evaluation, arithmetic}{90}{evaluation, arithmetic}
-\entry{arithmetic evaluation}{90}{arithmetic evaluation}
-\entry{alias expansion}{91}{alias expansion}
-\entry{arrays}{92}{arrays}
-\entry{directory stack}{94}{directory stack}
-\entry{prompting}{95}{prompting}
-\entry{restricted shell}{96}{restricted shell}
-\entry{POSIX Mode}{97}{POSIX Mode}
-\entry{job control}{101}{job control}
-\entry{foreground}{101}{foreground}
-\entry{background}{101}{background}
-\entry{suspending jobs}{101}{suspending jobs}
-\entry{Readline, how to use}{104}{Readline, how to use}
-\entry{interaction, readline}{105}{interaction, readline}
-\entry{notation, readline}{106}{notation, readline}
-\entry{command editing}{106}{command editing}
-\entry{editing command lines}{106}{editing command lines}
-\entry{killing text}{107}{killing text}
-\entry{yanking text}{107}{yanking text}
-\entry{kill ring}{107}{kill ring}
-\entry{initialization file, readline}{108}{initialization file, readline}
-\entry{variables, readline}{109}{variables, readline}
-\entry{programmable completion}{130}{programmable completion}
-\entry{completion builtins}{132}{completion builtins}
-\entry{History, how to use}{138}{History, how to use}
-\entry{command history}{139}{command history}
-\entry{history list}{139}{history list}
-\entry{history builtins}{139}{history builtins}
-\entry{history expansion}{141}{history expansion}
-\entry{event designators}{142}{event designators}
-\entry{history events}{142}{history events}
-\entry{installation}{144}{installation}
-\entry{configuration}{144}{configuration}
-\entry{Bash installation}{144}{Bash installation}
-\entry{Bash configuration}{144}{Bash configuration}
+\entry{startup files}{86}{startup files}
+\entry{interactive shell}{87}{interactive shell}
+\entry{shell, interactive}{87}{shell, interactive}
+\entry{expressions, conditional}{89}{expressions, conditional}
+\entry{arithmetic, shell}{91}{arithmetic, shell}
+\entry{shell arithmetic}{91}{shell arithmetic}
+\entry{expressions, arithmetic}{91}{expressions, arithmetic}
+\entry{evaluation, arithmetic}{91}{evaluation, arithmetic}
+\entry{arithmetic evaluation}{91}{arithmetic evaluation}
+\entry{alias expansion}{92}{alias expansion}
+\entry{arrays}{93}{arrays}
+\entry{directory stack}{95}{directory stack}
+\entry{prompting}{96}{prompting}
+\entry{restricted shell}{97}{restricted shell}
+\entry{POSIX Mode}{98}{POSIX Mode}
+\entry{job control}{102}{job control}
+\entry{foreground}{102}{foreground}
+\entry{background}{102}{background}
+\entry{suspending jobs}{102}{suspending jobs}
+\entry{Readline, how to use}{105}{Readline, how to use}
+\entry{interaction, readline}{106}{interaction, readline}
+\entry{notation, readline}{107}{notation, readline}
+\entry{command editing}{107}{command editing}
+\entry{editing command lines}{107}{editing command lines}
+\entry{killing text}{108}{killing text}
+\entry{yanking text}{108}{yanking text}
+\entry{kill ring}{108}{kill ring}
+\entry{initialization file, readline}{109}{initialization file, readline}
+\entry{variables, readline}{110}{variables, readline}
+\entry{programmable completion}{131}{programmable completion}
+\entry{completion builtins}{133}{completion builtins}
+\entry{History, how to use}{139}{History, how to use}
+\entry{command history}{140}{command history}
+\entry{history list}{140}{history list}
+\entry{history builtins}{140}{history builtins}
+\entry{history expansion}{142}{history expansion}
+\entry{event designators}{143}{event designators}
+\entry{history events}{143}{history events}
+\entry{installation}{145}{installation}
+\entry{configuration}{145}{configuration}
+\entry{Bash installation}{145}{Bash installation}
+\entry{Bash configuration}{145}{Bash configuration}
diff --git a/doc/bashref.cps b/doc/bashref.cps
index df6c7e0..3ffd545 100644
--- a/doc/bashref.cps
+++ b/doc/bashref.cps
@@ -1,23 +1,23 @@
\initial {A}
-\entry {alias expansion}{91}
-\entry {arithmetic evaluation}{90}
+\entry {alias expansion}{92}
+\entry {arithmetic evaluation}{91}
\entry {arithmetic expansion}{30}
-\entry {arithmetic, shell}{90}
-\entry {arrays}{92}
+\entry {arithmetic, shell}{91}
+\entry {arrays}{93}
\initial {B}
-\entry {background}{101}
-\entry {Bash configuration}{144}
-\entry {Bash installation}{144}
+\entry {background}{102}
+\entry {Bash configuration}{145}
+\entry {Bash installation}{145}
\entry {Bourne shell}{5}
\entry {brace expansion}{22}
\entry {builtin}{3}
\initial {C}
-\entry {command editing}{106}
+\entry {command editing}{107}
\entry {command execution}{38}
\entry {command expansion}{37}
-\entry {command history}{139}
+\entry {command history}{140}
\entry {command search}{38}
-\entry {command substitution}{29}
+\entry {command substitution}{30}
\entry {command timing}{8}
\entry {commands, compound}{9}
\entry {commands, conditional}{10}
@@ -28,109 +28,109 @@
\entry {commands, shell}{8}
\entry {commands, simple}{8}
\entry {comments, shell}{7}
-\entry {completion builtins}{132}
-\entry {configuration}{144}
+\entry {completion builtins}{133}
+\entry {configuration}{145}
\entry {control operator}{3}
\entry {coprocess}{15}
\initial {D}
-\entry {directory stack}{94}
+\entry {directory stack}{95}
\initial {E}
-\entry {editing command lines}{106}
+\entry {editing command lines}{107}
\entry {environment}{39}
-\entry {evaluation, arithmetic}{90}
-\entry {event designators}{142}
+\entry {evaluation, arithmetic}{91}
+\entry {event designators}{143}
\entry {execution environment}{38}
\entry {exit status}{3, 40}
-\entry {expansion}{21}
+\entry {expansion}{22}
\entry {expansion, arithmetic}{30}
\entry {expansion, brace}{22}
\entry {expansion, filename}{31}
\entry {expansion, parameter}{24}
\entry {expansion, pathname}{31}
\entry {expansion, tilde}{23}
-\entry {expressions, arithmetic}{90}
-\entry {expressions, conditional}{88}
+\entry {expressions, arithmetic}{91}
+\entry {expressions, conditional}{89}
\initial {F}
\entry {field}{3}
\entry {filename}{3}
\entry {filename expansion}{31}
-\entry {foreground}{101}
+\entry {foreground}{102}
\entry {functions, shell}{17}
\initial {H}
-\entry {history builtins}{139}
-\entry {history events}{142}
-\entry {history expansion}{141}
-\entry {history list}{139}
-\entry {History, how to use}{138}
+\entry {history builtins}{140}
+\entry {history events}{143}
+\entry {history expansion}{142}
+\entry {history list}{140}
+\entry {History, how to use}{139}
\initial {I}
\entry {identifier}{3}
-\entry {initialization file, readline}{108}
-\entry {installation}{144}
-\entry {interaction, readline}{105}
-\entry {interactive shell}{85, 86}
+\entry {initialization file, readline}{109}
+\entry {installation}{145}
+\entry {interaction, readline}{106}
+\entry {interactive shell}{86, 87}
\entry {internationalization}{7}
\initial {J}
\entry {job}{3}
-\entry {job control}{3, 101}
+\entry {job control}{3, 102}
\initial {K}
-\entry {kill ring}{107}
-\entry {killing text}{107}
+\entry {kill ring}{108}
+\entry {killing text}{108}
\initial {L}
\entry {localization}{7}
-\entry {login shell}{85}
+\entry {login shell}{86}
\initial {M}
\entry {matching, pattern}{32}
\entry {metacharacter}{3}
\initial {N}
\entry {name}{3}
\entry {native languages}{7}
-\entry {notation, readline}{106}
+\entry {notation, readline}{107}
\initial {O}
\entry {operator, shell}{3}
\initial {P}
\entry {parameter expansion}{24}
\entry {parameters}{19}
\entry {parameters, positional}{20}
-\entry {parameters, special}{20}
+\entry {parameters, special}{21}
\entry {pathname expansion}{31}
\entry {pattern matching}{32}
\entry {pipeline}{8}
\entry {POSIX}{3}
-\entry {POSIX Mode}{97}
+\entry {POSIX Mode}{98}
\entry {process group}{3}
\entry {process group ID}{3}
\entry {process substitution}{30}
-\entry {programmable completion}{130}
-\entry {prompting}{95}
+\entry {programmable completion}{131}
+\entry {prompting}{96}
\initial {Q}
\entry {quoting}{6}
\entry {quoting, ANSI}{6}
\initial {R}
-\entry {Readline, how to use}{104}
+\entry {Readline, how to use}{105}
\entry {redirection}{33}
\entry {reserved word}{3}
-\entry {restricted shell}{96}
+\entry {restricted shell}{97}
\entry {return status}{4}
\initial {S}
-\entry {shell arithmetic}{90}
+\entry {shell arithmetic}{91}
\entry {shell function}{17}
\entry {shell script}{41}
\entry {shell variable}{19}
-\entry {shell, interactive}{86}
+\entry {shell, interactive}{87}
\entry {signal}{4}
\entry {signal handling}{40}
-\entry {special builtin}{4, 70}
-\entry {startup files}{85}
-\entry {suspending jobs}{101}
+\entry {special builtin}{4, 71}
+\entry {startup files}{86}
+\entry {suspending jobs}{102}
\initial {T}
\entry {tilde expansion}{23}
\entry {token}{4}
\entry {translation, native languages}{7}
\initial {V}
\entry {variable, shell}{19}
-\entry {variables, readline}{109}
+\entry {variables, readline}{110}
\initial {W}
\entry {word}{4}
\entry {word splitting}{31}
\initial {Y}
-\entry {yanking text}{107}
+\entry {yanking text}{108}
diff --git a/doc/bashref.fn b/doc/bashref.fn
index d42a7af..5dcc1b1 100644
--- a/doc/bashref.fn
+++ b/doc/bashref.fn
@@ -1,110 +1,110 @@
-\entry{beginning-of-line (C-a)}{120}{\code {beginning-of-line (C-a)}}
-\entry{end-of-line (C-e)}{120}{\code {end-of-line (C-e)}}
-\entry{forward-char (C-f)}{120}{\code {forward-char (C-f)}}
-\entry{backward-char (C-b)}{120}{\code {backward-char (C-b)}}
-\entry{forward-word (M-f)}{120}{\code {forward-word (M-f)}}
-\entry{backward-word (M-b)}{120}{\code {backward-word (M-b)}}
-\entry{shell-forward-word ()}{120}{\code {shell-forward-word ()}}
-\entry{shell-backward-word ()}{120}{\code {shell-backward-word ()}}
-\entry{previous-screen-line ()}{120}{\code {previous-screen-line ()}}
-\entry{next-screen-line ()}{121}{\code {next-screen-line ()}}
-\entry{clear-screen (C-l)}{121}{\code {clear-screen (C-l)}}
-\entry{redraw-current-line ()}{121}{\code {redraw-current-line ()}}
-\entry{accept-line (Newline or Return)}{121}{\code {accept-line (Newline or Return)}}
-\entry{previous-history (C-p)}{121}{\code {previous-history (C-p)}}
-\entry{next-history (C-n)}{121}{\code {next-history (C-n)}}
-\entry{beginning-of-history (M-<)}{121}{\code {beginning-of-history (M-<)}}
-\entry{end-of-history (M->)}{121}{\code {end-of-history (M->)}}
-\entry{reverse-search-history (C-r)}{121}{\code {reverse-search-history (C-r)}}
-\entry{forward-search-history (C-s)}{121}{\code {forward-search-history (C-s)}}
-\entry{non-incremental-reverse-search-history (M-p)}{121}{\code {non-incremental-reverse-search-history (M-p)}}
-\entry{non-incremental-forward-search-history (M-n)}{121}{\code {non-incremental-forward-search-history (M-n)}}
-\entry{history-search-forward ()}{121}{\code {history-search-forward ()}}
-\entry{history-search-backward ()}{122}{\code {history-search-backward ()}}
-\entry{history-substring-search-forward ()}{122}{\code {history-substring-search-forward ()}}
-\entry{history-substring-search-backward ()}{122}{\code {history-substring-search-backward ()}}
-\entry{yank-nth-arg (M-C-y)}{122}{\code {yank-nth-arg (M-C-y)}}
-\entry{yank-last-arg (M-. or M-_)}{122}{\code {yank-last-arg (M-. or M-_)}}
-\entry{end-of-file (usually C-d)}{122}{\code {\i {end-of-file} (usually C-d)}}
-\entry{delete-char (C-d)}{122}{\code {delete-char (C-d)}}
-\entry{backward-delete-char (Rubout)}{123}{\code {backward-delete-char (Rubout)}}
-\entry{forward-backward-delete-char ()}{123}{\code {forward-backward-delete-char ()}}
-\entry{quoted-insert (C-q or C-v)}{123}{\code {quoted-insert (C-q or C-v)}}
-\entry{self-insert (a, b, A, 1, !, ...{})}{123}{\code {self-insert (a, b, A, 1, !, \dots {})}}
-\entry{bracketed-paste-begin ()}{123}{\code {bracketed-paste-begin ()}}
-\entry{transpose-chars (C-t)}{123}{\code {transpose-chars (C-t)}}
-\entry{transpose-words (M-t)}{123}{\code {transpose-words (M-t)}}
-\entry{upcase-word (M-u)}{123}{\code {upcase-word (M-u)}}
-\entry{downcase-word (M-l)}{123}{\code {downcase-word (M-l)}}
-\entry{capitalize-word (M-c)}{123}{\code {capitalize-word (M-c)}}
-\entry{overwrite-mode ()}{123}{\code {overwrite-mode ()}}
-\entry{kill-line (C-k)}{124}{\code {kill-line (C-k)}}
-\entry{backward-kill-line (C-x Rubout)}{124}{\code {backward-kill-line (C-x Rubout)}}
-\entry{unix-line-discard (C-u)}{124}{\code {unix-line-discard (C-u)}}
-\entry{kill-whole-line ()}{124}{\code {kill-whole-line ()}}
-\entry{kill-word (M-d)}{124}{\code {kill-word (M-d)}}
-\entry{backward-kill-word (M-DEL)}{124}{\code {backward-kill-word (M-\key {DEL})}}
-\entry{shell-kill-word ()}{124}{\code {shell-kill-word ()}}
-\entry{shell-backward-kill-word ()}{124}{\code {shell-backward-kill-word ()}}
-\entry{unix-word-rubout (C-w)}{124}{\code {unix-word-rubout (C-w)}}
-\entry{unix-filename-rubout ()}{124}{\code {unix-filename-rubout ()}}
-\entry{delete-horizontal-space ()}{124}{\code {delete-horizontal-space ()}}
-\entry{kill-region ()}{124}{\code {kill-region ()}}
-\entry{copy-region-as-kill ()}{124}{\code {copy-region-as-kill ()}}
-\entry{copy-backward-word ()}{124}{\code {copy-backward-word ()}}
-\entry{copy-forward-word ()}{125}{\code {copy-forward-word ()}}
-\entry{yank (C-y)}{125}{\code {yank (C-y)}}
-\entry{yank-pop (M-y)}{125}{\code {yank-pop (M-y)}}
-\entry{digit-argument (M-0, M-1, ...{} M--)}{125}{\code {digit-argument (\kbd {M-0}, \kbd {M-1}, \dots {} \kbd {M--})}}
-\entry{universal-argument ()}{125}{\code {universal-argument ()}}
-\entry{complete (TAB)}{125}{\code {complete (\key {TAB})}}
-\entry{possible-completions (M-?)}{125}{\code {possible-completions (M-?)}}
-\entry{insert-completions (M-*)}{125}{\code {insert-completions (M-*)}}
-\entry{menu-complete ()}{125}{\code {menu-complete ()}}
-\entry{menu-complete-backward ()}{126}{\code {menu-complete-backward ()}}
-\entry{delete-char-or-list ()}{126}{\code {delete-char-or-list ()}}
-\entry{complete-filename (M-/)}{126}{\code {complete-filename (M-/)}}
-\entry{possible-filename-completions (C-x /)}{126}{\code {possible-filename-completions (C-x /)}}
-\entry{complete-username (M-~)}{126}{\code {complete-username (M-~)}}
-\entry{possible-username-completions (C-x ~)}{126}{\code {possible-username-completions (C-x ~)}}
-\entry{complete-variable (M-$)}{126}{\code {complete-variable (M-$)}}
-\entry{possible-variable-completions (C-x $)}{126}{\code {possible-variable-completions (C-x $)}}
-\entry{complete-hostname (M-@)}{126}{\code {complete-hostname (M-@)}}
-\entry{possible-hostname-completions (C-x @)}{126}{\code {possible-hostname-completions (C-x @)}}
-\entry{complete-command (M-!)}{126}{\code {complete-command (M-!)}}
-\entry{possible-command-completions (C-x !)}{126}{\code {possible-command-completions (C-x !)}}
-\entry{dynamic-complete-history (M-TAB)}{126}{\code {dynamic-complete-history (M-\key {TAB})}}
-\entry{dabbrev-expand ()}{127}{\code {dabbrev-expand ()}}
-\entry{complete-into-braces (M-{\indexlbrace })}{127}{\code {complete-into-braces (M-{\tt \char 123})}}
-\entry{start-kbd-macro (C-x ()}{127}{\code {start-kbd-macro (C-x ()}}
-\entry{end-kbd-macro (C-x ))}{127}{\code {end-kbd-macro (C-x ))}}
-\entry{call-last-kbd-macro (C-x e)}{127}{\code {call-last-kbd-macro (C-x e)}}
-\entry{print-last-kbd-macro ()}{127}{\code {print-last-kbd-macro ()}}
-\entry{re-read-init-file (C-x C-r)}{127}{\code {re-read-init-file (C-x C-r)}}
-\entry{abort (C-g)}{127}{\code {abort (C-g)}}
-\entry{do-lowercase-version (M-A, M-B, M-x, ...{})}{127}{\code {do-lowercase-version (M-A, M-B, M-\var {x}, \dots {})}}
-\entry{prefix-meta (ESC)}{127}{\code {prefix-meta (\key {ESC})}}
-\entry{undo (C-_ or C-x C-u)}{127}{\code {undo (C-_ or C-x C-u)}}
-\entry{revert-line (M-r)}{127}{\code {revert-line (M-r)}}
-\entry{tilde-expand (M-&)}{127}{\code {tilde-expand (M-&)}}
-\entry{set-mark (C-@)}{128}{\code {set-mark (C-@)}}
-\entry{exchange-point-and-mark (C-x C-x)}{128}{\code {exchange-point-and-mark (C-x C-x)}}
-\entry{character-search (C-])}{128}{\code {character-search (C-])}}
-\entry{character-search-backward (M-C-])}{128}{\code {character-search-backward (M-C-])}}
-\entry{skip-csi-sequence ()}{128}{\code {skip-csi-sequence ()}}
-\entry{insert-comment (M-#)}{128}{\code {insert-comment (M-#)}}
-\entry{dump-functions ()}{128}{\code {dump-functions ()}}
-\entry{dump-variables ()}{128}{\code {dump-variables ()}}
-\entry{dump-macros ()}{128}{\code {dump-macros ()}}
-\entry{glob-complete-word (M-g)}{129}{\code {glob-complete-word (M-g)}}
-\entry{glob-expand-word (C-x *)}{129}{\code {glob-expand-word (C-x *)}}
-\entry{glob-list-expansions (C-x g)}{129}{\code {glob-list-expansions (C-x g)}}
-\entry{display-shell-version (C-x C-v)}{129}{\code {display-shell-version (C-x C-v)}}
-\entry{shell-expand-line (M-C-e)}{129}{\code {shell-expand-line (M-C-e)}}
-\entry{history-expand-line (M-^)}{129}{\code {history-expand-line (M-^)}}
-\entry{magic-space ()}{129}{\code {magic-space ()}}
-\entry{alias-expand-line ()}{129}{\code {alias-expand-line ()}}
-\entry{history-and-alias-expand-line ()}{129}{\code {history-and-alias-expand-line ()}}
-\entry{insert-last-argument (M-. or M-_)}{129}{\code {insert-last-argument (M-. or M-_)}}
-\entry{operate-and-get-next (C-o)}{129}{\code {operate-and-get-next (C-o)}}
-\entry{edit-and-execute-command (C-x C-e)}{129}{\code {edit-and-execute-command (C-x C-e)}}
+\entry{beginning-of-line (C-a)}{121}{\code {beginning-of-line (C-a)}}
+\entry{end-of-line (C-e)}{121}{\code {end-of-line (C-e)}}
+\entry{forward-char (C-f)}{121}{\code {forward-char (C-f)}}
+\entry{backward-char (C-b)}{121}{\code {backward-char (C-b)}}
+\entry{forward-word (M-f)}{121}{\code {forward-word (M-f)}}
+\entry{backward-word (M-b)}{121}{\code {backward-word (M-b)}}
+\entry{shell-forward-word ()}{121}{\code {shell-forward-word ()}}
+\entry{shell-backward-word ()}{121}{\code {shell-backward-word ()}}
+\entry{previous-screen-line ()}{121}{\code {previous-screen-line ()}}
+\entry{next-screen-line ()}{122}{\code {next-screen-line ()}}
+\entry{clear-screen (C-l)}{122}{\code {clear-screen (C-l)}}
+\entry{redraw-current-line ()}{122}{\code {redraw-current-line ()}}
+\entry{accept-line (Newline or Return)}{122}{\code {accept-line (Newline or Return)}}
+\entry{previous-history (C-p)}{122}{\code {previous-history (C-p)}}
+\entry{next-history (C-n)}{122}{\code {next-history (C-n)}}
+\entry{beginning-of-history (M-<)}{122}{\code {beginning-of-history (M-<)}}
+\entry{end-of-history (M->)}{122}{\code {end-of-history (M->)}}
+\entry{reverse-search-history (C-r)}{122}{\code {reverse-search-history (C-r)}}
+\entry{forward-search-history (C-s)}{122}{\code {forward-search-history (C-s)}}
+\entry{non-incremental-reverse-search-history (M-p)}{122}{\code {non-incremental-reverse-search-history (M-p)}}
+\entry{non-incremental-forward-search-history (M-n)}{122}{\code {non-incremental-forward-search-history (M-n)}}
+\entry{history-search-forward ()}{122}{\code {history-search-forward ()}}
+\entry{history-search-backward ()}{123}{\code {history-search-backward ()}}
+\entry{history-substring-search-forward ()}{123}{\code {history-substring-search-forward ()}}
+\entry{history-substring-search-backward ()}{123}{\code {history-substring-search-backward ()}}
+\entry{yank-nth-arg (M-C-y)}{123}{\code {yank-nth-arg (M-C-y)}}
+\entry{yank-last-arg (M-. or M-_)}{123}{\code {yank-last-arg (M-. or M-_)}}
+\entry{end-of-file (usually C-d)}{123}{\code {\i {end-of-file} (usually C-d)}}
+\entry{delete-char (C-d)}{123}{\code {delete-char (C-d)}}
+\entry{backward-delete-char (Rubout)}{124}{\code {backward-delete-char (Rubout)}}
+\entry{forward-backward-delete-char ()}{124}{\code {forward-backward-delete-char ()}}
+\entry{quoted-insert (C-q or C-v)}{124}{\code {quoted-insert (C-q or C-v)}}
+\entry{self-insert (a, b, A, 1, !, ...{})}{124}{\code {self-insert (a, b, A, 1, !, \dots {})}}
+\entry{bracketed-paste-begin ()}{124}{\code {bracketed-paste-begin ()}}
+\entry{transpose-chars (C-t)}{124}{\code {transpose-chars (C-t)}}
+\entry{transpose-words (M-t)}{124}{\code {transpose-words (M-t)}}
+\entry{upcase-word (M-u)}{124}{\code {upcase-word (M-u)}}
+\entry{downcase-word (M-l)}{124}{\code {downcase-word (M-l)}}
+\entry{capitalize-word (M-c)}{124}{\code {capitalize-word (M-c)}}
+\entry{overwrite-mode ()}{124}{\code {overwrite-mode ()}}
+\entry{kill-line (C-k)}{125}{\code {kill-line (C-k)}}
+\entry{backward-kill-line (C-x Rubout)}{125}{\code {backward-kill-line (C-x Rubout)}}
+\entry{unix-line-discard (C-u)}{125}{\code {unix-line-discard (C-u)}}
+\entry{kill-whole-line ()}{125}{\code {kill-whole-line ()}}
+\entry{kill-word (M-d)}{125}{\code {kill-word (M-d)}}
+\entry{backward-kill-word (M-DEL)}{125}{\code {backward-kill-word (M-\key {DEL})}}
+\entry{shell-kill-word ()}{125}{\code {shell-kill-word ()}}
+\entry{shell-backward-kill-word ()}{125}{\code {shell-backward-kill-word ()}}
+\entry{unix-word-rubout (C-w)}{125}{\code {unix-word-rubout (C-w)}}
+\entry{unix-filename-rubout ()}{125}{\code {unix-filename-rubout ()}}
+\entry{delete-horizontal-space ()}{125}{\code {delete-horizontal-space ()}}
+\entry{kill-region ()}{125}{\code {kill-region ()}}
+\entry{copy-region-as-kill ()}{125}{\code {copy-region-as-kill ()}}
+\entry{copy-backward-word ()}{125}{\code {copy-backward-word ()}}
+\entry{copy-forward-word ()}{126}{\code {copy-forward-word ()}}
+\entry{yank (C-y)}{126}{\code {yank (C-y)}}
+\entry{yank-pop (M-y)}{126}{\code {yank-pop (M-y)}}
+\entry{digit-argument (M-0, M-1, ...{} M--)}{126}{\code {digit-argument (\kbd {M-0}, \kbd {M-1}, \dots {} \kbd {M--})}}
+\entry{universal-argument ()}{126}{\code {universal-argument ()}}
+\entry{complete (TAB)}{126}{\code {complete (\key {TAB})}}
+\entry{possible-completions (M-?)}{126}{\code {possible-completions (M-?)}}
+\entry{insert-completions (M-*)}{126}{\code {insert-completions (M-*)}}
+\entry{menu-complete ()}{126}{\code {menu-complete ()}}
+\entry{menu-complete-backward ()}{127}{\code {menu-complete-backward ()}}
+\entry{delete-char-or-list ()}{127}{\code {delete-char-or-list ()}}
+\entry{complete-filename (M-/)}{127}{\code {complete-filename (M-/)}}
+\entry{possible-filename-completions (C-x /)}{127}{\code {possible-filename-completions (C-x /)}}
+\entry{complete-username (M-~)}{127}{\code {complete-username (M-~)}}
+\entry{possible-username-completions (C-x ~)}{127}{\code {possible-username-completions (C-x ~)}}
+\entry{complete-variable (M-$)}{127}{\code {complete-variable (M-$)}}
+\entry{possible-variable-completions (C-x $)}{127}{\code {possible-variable-completions (C-x $)}}
+\entry{complete-hostname (M-@)}{127}{\code {complete-hostname (M-@)}}
+\entry{possible-hostname-completions (C-x @)}{127}{\code {possible-hostname-completions (C-x @)}}
+\entry{complete-command (M-!)}{127}{\code {complete-command (M-!)}}
+\entry{possible-command-completions (C-x !)}{127}{\code {possible-command-completions (C-x !)}}
+\entry{dynamic-complete-history (M-TAB)}{127}{\code {dynamic-complete-history (M-\key {TAB})}}
+\entry{dabbrev-expand ()}{128}{\code {dabbrev-expand ()}}
+\entry{complete-into-braces (M-{\indexlbrace })}{128}{\code {complete-into-braces (M-{\tt \char 123})}}
+\entry{start-kbd-macro (C-x ()}{128}{\code {start-kbd-macro (C-x ()}}
+\entry{end-kbd-macro (C-x ))}{128}{\code {end-kbd-macro (C-x ))}}
+\entry{call-last-kbd-macro (C-x e)}{128}{\code {call-last-kbd-macro (C-x e)}}
+\entry{print-last-kbd-macro ()}{128}{\code {print-last-kbd-macro ()}}
+\entry{re-read-init-file (C-x C-r)}{128}{\code {re-read-init-file (C-x C-r)}}
+\entry{abort (C-g)}{128}{\code {abort (C-g)}}
+\entry{do-lowercase-version (M-A, M-B, M-x, ...{})}{128}{\code {do-lowercase-version (M-A, M-B, M-\var {x}, \dots {})}}
+\entry{prefix-meta (ESC)}{128}{\code {prefix-meta (\key {ESC})}}
+\entry{undo (C-_ or C-x C-u)}{128}{\code {undo (C-_ or C-x C-u)}}
+\entry{revert-line (M-r)}{128}{\code {revert-line (M-r)}}
+\entry{tilde-expand (M-&)}{128}{\code {tilde-expand (M-&)}}
+\entry{set-mark (C-@)}{129}{\code {set-mark (C-@)}}
+\entry{exchange-point-and-mark (C-x C-x)}{129}{\code {exchange-point-and-mark (C-x C-x)}}
+\entry{character-search (C-])}{129}{\code {character-search (C-])}}
+\entry{character-search-backward (M-C-])}{129}{\code {character-search-backward (M-C-])}}
+\entry{skip-csi-sequence ()}{129}{\code {skip-csi-sequence ()}}
+\entry{insert-comment (M-#)}{129}{\code {insert-comment (M-#)}}
+\entry{dump-functions ()}{129}{\code {dump-functions ()}}
+\entry{dump-variables ()}{129}{\code {dump-variables ()}}
+\entry{dump-macros ()}{129}{\code {dump-macros ()}}
+\entry{glob-complete-word (M-g)}{130}{\code {glob-complete-word (M-g)}}
+\entry{glob-expand-word (C-x *)}{130}{\code {glob-expand-word (C-x *)}}
+\entry{glob-list-expansions (C-x g)}{130}{\code {glob-list-expansions (C-x g)}}
+\entry{display-shell-version (C-x C-v)}{130}{\code {display-shell-version (C-x C-v)}}
+\entry{shell-expand-line (M-C-e)}{130}{\code {shell-expand-line (M-C-e)}}
+\entry{history-expand-line (M-^)}{130}{\code {history-expand-line (M-^)}}
+\entry{magic-space ()}{130}{\code {magic-space ()}}
+\entry{alias-expand-line ()}{130}{\code {alias-expand-line ()}}
+\entry{history-and-alias-expand-line ()}{130}{\code {history-and-alias-expand-line ()}}
+\entry{insert-last-argument (M-. or M-_)}{130}{\code {insert-last-argument (M-. or M-_)}}
+\entry{operate-and-get-next (C-o)}{130}{\code {operate-and-get-next (C-o)}}
+\entry{edit-and-execute-command (C-x C-e)}{130}{\code {edit-and-execute-command (C-x C-e)}}
diff --git a/doc/bashref.fns b/doc/bashref.fns
index 45a3570..92b419b 100644
--- a/doc/bashref.fns
+++ b/doc/bashref.fns
@@ -1,130 +1,130 @@
\initial {A}
-\entry {\code {abort (C-g)}}{127}
-\entry {\code {accept-line (Newline or Return)}}{121}
-\entry {\code {alias-expand-line ()}}{129}
+\entry {\code {abort (C-g)}}{128}
+\entry {\code {accept-line (Newline or Return)}}{122}
+\entry {\code {alias-expand-line ()}}{130}
\initial {B}
-\entry {\code {backward-char (C-b)}}{120}
-\entry {\code {backward-delete-char (Rubout)}}{123}
-\entry {\code {backward-kill-line (C-x Rubout)}}{124}
-\entry {\code {backward-kill-word (M-\key {DEL})}}{124}
-\entry {\code {backward-word (M-b)}}{120}
-\entry {\code {beginning-of-history (M-<)}}{121}
-\entry {\code {beginning-of-line (C-a)}}{120}
-\entry {\code {bracketed-paste-begin ()}}{123}
+\entry {\code {backward-char (C-b)}}{121}
+\entry {\code {backward-delete-char (Rubout)}}{124}
+\entry {\code {backward-kill-line (C-x Rubout)}}{125}
+\entry {\code {backward-kill-word (M-\key {DEL})}}{125}
+\entry {\code {backward-word (M-b)}}{121}
+\entry {\code {beginning-of-history (M-<)}}{122}
+\entry {\code {beginning-of-line (C-a)}}{121}
+\entry {\code {bracketed-paste-begin ()}}{124}
\initial {C}
-\entry {\code {call-last-kbd-macro (C-x e)}}{127}
-\entry {\code {capitalize-word (M-c)}}{123}
-\entry {\code {character-search (C-])}}{128}
-\entry {\code {character-search-backward (M-C-])}}{128}
-\entry {\code {clear-screen (C-l)}}{121}
-\entry {\code {complete (\key {TAB})}}{125}
-\entry {\code {complete-command (M-!)}}{126}
-\entry {\code {complete-filename (M-/)}}{126}
-\entry {\code {complete-hostname (M-@)}}{126}
-\entry {\code {complete-into-braces (M-{\tt \char 123})}}{127}
-\entry {\code {complete-username (M-~)}}{126}
-\entry {\code {complete-variable (M-$)}}{126}
-\entry {\code {copy-backward-word ()}}{124}
-\entry {\code {copy-forward-word ()}}{125}
-\entry {\code {copy-region-as-kill ()}}{124}
+\entry {\code {call-last-kbd-macro (C-x e)}}{128}
+\entry {\code {capitalize-word (M-c)}}{124}
+\entry {\code {character-search (C-])}}{129}
+\entry {\code {character-search-backward (M-C-])}}{129}
+\entry {\code {clear-screen (C-l)}}{122}
+\entry {\code {complete (\key {TAB})}}{126}
+\entry {\code {complete-command (M-!)}}{127}
+\entry {\code {complete-filename (M-/)}}{127}
+\entry {\code {complete-hostname (M-@)}}{127}
+\entry {\code {complete-into-braces (M-{\tt \char 123})}}{128}
+\entry {\code {complete-username (M-~)}}{127}
+\entry {\code {complete-variable (M-$)}}{127}
+\entry {\code {copy-backward-word ()}}{125}
+\entry {\code {copy-forward-word ()}}{126}
+\entry {\code {copy-region-as-kill ()}}{125}
\initial {D}
-\entry {\code {dabbrev-expand ()}}{127}
-\entry {\code {delete-char (C-d)}}{122}
-\entry {\code {delete-char-or-list ()}}{126}
-\entry {\code {delete-horizontal-space ()}}{124}
-\entry {\code {digit-argument (\kbd {M-0}, \kbd {M-1}, \dots {} \kbd {M--})}}{125}
-\entry {\code {display-shell-version (C-x C-v)}}{129}
-\entry {\code {do-lowercase-version (M-A, M-B, M-\var {x}, \dots {})}}{127}
-\entry {\code {downcase-word (M-l)}}{123}
-\entry {\code {dump-functions ()}}{128}
-\entry {\code {dump-macros ()}}{128}
-\entry {\code {dump-variables ()}}{128}
-\entry {\code {dynamic-complete-history (M-\key {TAB})}}{126}
+\entry {\code {dabbrev-expand ()}}{128}
+\entry {\code {delete-char (C-d)}}{123}
+\entry {\code {delete-char-or-list ()}}{127}
+\entry {\code {delete-horizontal-space ()}}{125}
+\entry {\code {digit-argument (\kbd {M-0}, \kbd {M-1}, \dots {} \kbd {M--})}}{126}
+\entry {\code {display-shell-version (C-x C-v)}}{130}
+\entry {\code {do-lowercase-version (M-A, M-B, M-\var {x}, \dots {})}}{128}
+\entry {\code {downcase-word (M-l)}}{124}
+\entry {\code {dump-functions ()}}{129}
+\entry {\code {dump-macros ()}}{129}
+\entry {\code {dump-variables ()}}{129}
+\entry {\code {dynamic-complete-history (M-\key {TAB})}}{127}
\initial {E}
-\entry {\code {edit-and-execute-command (C-x C-e)}}{129}
-\entry {\code {end-kbd-macro (C-x ))}}{127}
-\entry {\code {\i {end-of-file} (usually C-d)}}{122}
-\entry {\code {end-of-history (M->)}}{121}
-\entry {\code {end-of-line (C-e)}}{120}
-\entry {\code {exchange-point-and-mark (C-x C-x)}}{128}
+\entry {\code {edit-and-execute-command (C-x C-e)}}{130}
+\entry {\code {end-kbd-macro (C-x ))}}{128}
+\entry {\code {\i {end-of-file} (usually C-d)}}{123}
+\entry {\code {end-of-history (M->)}}{122}
+\entry {\code {end-of-line (C-e)}}{121}
+\entry {\code {exchange-point-and-mark (C-x C-x)}}{129}
\initial {F}
-\entry {\code {forward-backward-delete-char ()}}{123}
-\entry {\code {forward-char (C-f)}}{120}
-\entry {\code {forward-search-history (C-s)}}{121}
-\entry {\code {forward-word (M-f)}}{120}
+\entry {\code {forward-backward-delete-char ()}}{124}
+\entry {\code {forward-char (C-f)}}{121}
+\entry {\code {forward-search-history (C-s)}}{122}
+\entry {\code {forward-word (M-f)}}{121}
\initial {G}
-\entry {\code {glob-complete-word (M-g)}}{129}
-\entry {\code {glob-expand-word (C-x *)}}{129}
-\entry {\code {glob-list-expansions (C-x g)}}{129}
+\entry {\code {glob-complete-word (M-g)}}{130}
+\entry {\code {glob-expand-word (C-x *)}}{130}
+\entry {\code {glob-list-expansions (C-x g)}}{130}
\initial {H}
-\entry {\code {history-and-alias-expand-line ()}}{129}
-\entry {\code {history-expand-line (M-^)}}{129}
-\entry {\code {history-search-backward ()}}{122}
-\entry {\code {history-search-forward ()}}{121}
-\entry {\code {history-substring-search-backward ()}}{122}
-\entry {\code {history-substring-search-forward ()}}{122}
+\entry {\code {history-and-alias-expand-line ()}}{130}
+\entry {\code {history-expand-line (M-^)}}{130}
+\entry {\code {history-search-backward ()}}{123}
+\entry {\code {history-search-forward ()}}{122}
+\entry {\code {history-substring-search-backward ()}}{123}
+\entry {\code {history-substring-search-forward ()}}{123}
\initial {I}
-\entry {\code {insert-comment (M-#)}}{128}
-\entry {\code {insert-completions (M-*)}}{125}
-\entry {\code {insert-last-argument (M-. or M-_)}}{129}
+\entry {\code {insert-comment (M-#)}}{129}
+\entry {\code {insert-completions (M-*)}}{126}
+\entry {\code {insert-last-argument (M-. or M-_)}}{130}
\initial {K}
-\entry {\code {kill-line (C-k)}}{124}
-\entry {\code {kill-region ()}}{124}
-\entry {\code {kill-whole-line ()}}{124}
-\entry {\code {kill-word (M-d)}}{124}
+\entry {\code {kill-line (C-k)}}{125}
+\entry {\code {kill-region ()}}{125}
+\entry {\code {kill-whole-line ()}}{125}
+\entry {\code {kill-word (M-d)}}{125}
\initial {M}
-\entry {\code {magic-space ()}}{129}
-\entry {\code {menu-complete ()}}{125}
-\entry {\code {menu-complete-backward ()}}{126}
+\entry {\code {magic-space ()}}{130}
+\entry {\code {menu-complete ()}}{126}
+\entry {\code {menu-complete-backward ()}}{127}
\initial {N}
-\entry {\code {next-history (C-n)}}{121}
-\entry {\code {next-screen-line ()}}{121}
-\entry {\code {non-incremental-forward-search-history (M-n)}}{121}
-\entry {\code {non-incremental-reverse-search-history (M-p)}}{121}
+\entry {\code {next-history (C-n)}}{122}
+\entry {\code {next-screen-line ()}}{122}
+\entry {\code {non-incremental-forward-search-history (M-n)}}{122}
+\entry {\code {non-incremental-reverse-search-history (M-p)}}{122}
\initial {O}
-\entry {\code {operate-and-get-next (C-o)}}{129}
-\entry {\code {overwrite-mode ()}}{123}
+\entry {\code {operate-and-get-next (C-o)}}{130}
+\entry {\code {overwrite-mode ()}}{124}
\initial {P}
-\entry {\code {possible-command-completions (C-x !)}}{126}
-\entry {\code {possible-completions (M-?)}}{125}
-\entry {\code {possible-filename-completions (C-x /)}}{126}
-\entry {\code {possible-hostname-completions (C-x @)}}{126}
-\entry {\code {possible-username-completions (C-x ~)}}{126}
-\entry {\code {possible-variable-completions (C-x $)}}{126}
-\entry {\code {prefix-meta (\key {ESC})}}{127}
-\entry {\code {previous-history (C-p)}}{121}
-\entry {\code {previous-screen-line ()}}{120}
-\entry {\code {print-last-kbd-macro ()}}{127}
+\entry {\code {possible-command-completions (C-x !)}}{127}
+\entry {\code {possible-completions (M-?)}}{126}
+\entry {\code {possible-filename-completions (C-x /)}}{127}
+\entry {\code {possible-hostname-completions (C-x @)}}{127}
+\entry {\code {possible-username-completions (C-x ~)}}{127}
+\entry {\code {possible-variable-completions (C-x $)}}{127}
+\entry {\code {prefix-meta (\key {ESC})}}{128}
+\entry {\code {previous-history (C-p)}}{122}
+\entry {\code {previous-screen-line ()}}{121}
+\entry {\code {print-last-kbd-macro ()}}{128}
\initial {Q}
-\entry {\code {quoted-insert (C-q or C-v)}}{123}
+\entry {\code {quoted-insert (C-q or C-v)}}{124}
\initial {R}
-\entry {\code {re-read-init-file (C-x C-r)}}{127}
-\entry {\code {redraw-current-line ()}}{121}
-\entry {\code {reverse-search-history (C-r)}}{121}
-\entry {\code {revert-line (M-r)}}{127}
+\entry {\code {re-read-init-file (C-x C-r)}}{128}
+\entry {\code {redraw-current-line ()}}{122}
+\entry {\code {reverse-search-history (C-r)}}{122}
+\entry {\code {revert-line (M-r)}}{128}
\initial {S}
-\entry {\code {self-insert (a, b, A, 1, !, \dots {})}}{123}
-\entry {\code {set-mark (C-@)}}{128}
-\entry {\code {shell-backward-kill-word ()}}{124}
-\entry {\code {shell-backward-word ()}}{120}
-\entry {\code {shell-expand-line (M-C-e)}}{129}
-\entry {\code {shell-forward-word ()}}{120}
-\entry {\code {shell-kill-word ()}}{124}
-\entry {\code {skip-csi-sequence ()}}{128}
-\entry {\code {start-kbd-macro (C-x ()}}{127}
+\entry {\code {self-insert (a, b, A, 1, !, \dots {})}}{124}
+\entry {\code {set-mark (C-@)}}{129}
+\entry {\code {shell-backward-kill-word ()}}{125}
+\entry {\code {shell-backward-word ()}}{121}
+\entry {\code {shell-expand-line (M-C-e)}}{130}
+\entry {\code {shell-forward-word ()}}{121}
+\entry {\code {shell-kill-word ()}}{125}
+\entry {\code {skip-csi-sequence ()}}{129}
+\entry {\code {start-kbd-macro (C-x ()}}{128}
\initial {T}
-\entry {\code {tilde-expand (M-&)}}{127}
-\entry {\code {transpose-chars (C-t)}}{123}
-\entry {\code {transpose-words (M-t)}}{123}
+\entry {\code {tilde-expand (M-&)}}{128}
+\entry {\code {transpose-chars (C-t)}}{124}
+\entry {\code {transpose-words (M-t)}}{124}
\initial {U}
-\entry {\code {undo (C-_ or C-x C-u)}}{127}
-\entry {\code {universal-argument ()}}{125}
-\entry {\code {unix-filename-rubout ()}}{124}
-\entry {\code {unix-line-discard (C-u)}}{124}
-\entry {\code {unix-word-rubout (C-w)}}{124}
-\entry {\code {upcase-word (M-u)}}{123}
+\entry {\code {undo (C-_ or C-x C-u)}}{128}
+\entry {\code {universal-argument ()}}{126}
+\entry {\code {unix-filename-rubout ()}}{125}
+\entry {\code {unix-line-discard (C-u)}}{125}
+\entry {\code {unix-word-rubout (C-w)}}{125}
+\entry {\code {upcase-word (M-u)}}{124}
\initial {Y}
-\entry {\code {yank (C-y)}}{125}
-\entry {\code {yank-last-arg (M-. or M-_)}}{122}
-\entry {\code {yank-nth-arg (M-C-y)}}{122}
-\entry {\code {yank-pop (M-y)}}{125}
+\entry {\code {yank (C-y)}}{126}
+\entry {\code {yank-last-arg (M-. or M-_)}}{123}
+\entry {\code {yank-nth-arg (M-C-y)}}{123}
+\entry {\code {yank-pop (M-y)}}{126}
diff --git a/doc/bashref.info b/doc/bashref.info
index d26e46b..bf84eb4 100644
--- a/doc/bashref.info
+++ b/doc/bashref.info
@@ -451,7 +451,7 @@ decoded as follows:
question mark
'\NNN'
the eight-bit character whose value is the octal value NNN (one to
- three digits)
+ three octal digits)
'\xHH'
the eight-bit character whose value is the hexadecimal value HH
(one or two hex digits)
@@ -633,7 +633,7 @@ executed with left associativity.
COMMAND1 && COMMAND2
COMMAND2 is executed if, and only if, COMMAND1 returns an exit status of
-zero.
+zero (success).
An OR list has the form
COMMAND1 || COMMAND2
@@ -656,11 +656,12 @@ File: bashref.info, Node: Compound Commands, Next: Coprocesses, Prev: Lists,
* Conditional Constructs:: Shell commands for conditional execution.
* Command Grouping:: Ways to group commands.
-Compound commands are the shell programming constructs. Each construct
-begins with a reserved word or control operator and is terminated by a
-corresponding reserved word or operator. Any redirections (*note
-Redirections::) associated with a compound command apply to all commands
-within that compound command unless explicitly overridden.
+Compound commands are the shell programming language constructs. Each
+construct begins with a reserved word or control operator and is
+terminated by a corresponding reserved word or operator. Any
+redirections (*note Redirections::) associated with a compound command
+apply to all commands within that compound command unless explicitly
+overridden.
In most cases a list of commands in a compound command's description
may be separated from the rest of the command by one or more newlines,
@@ -705,14 +706,16 @@ syntax, it may be replaced with one or more newlines.
for NAME [ [in [WORDS ...] ] ; ] do COMMANDS; done
- Expand WORDS, and execute COMMANDS once for each member in the
- resultant list, with NAME bound to the current member. If 'in
- WORDS' is not present, the 'for' command executes the COMMANDS once
- for each positional parameter that is set, as if 'in "$@"' had been
- specified (*note Special Parameters::). The return status is the
- exit status of the last command that executes. If there are no
- items in the expansion of WORDS, no commands are executed, and the
- return status is zero.
+ Expand WORDS (*note Shell Expansions::), and execute COMMANDS once
+ for each member in the resultant list, with NAME bound to the
+ current member. If 'in WORDS' is not present, the 'for' command
+ executes the COMMANDS once for each positional parameter that is
+ set, as if 'in "$@"' had been specified (*note Special
+ Parameters::).
+
+ The return status is the exit status of the last command that
+ executes. If there are no items in the expansion of WORDS, no
+ commands are executed, and the return status is zero.
An alternate form of the 'for' command is also supported:
@@ -764,20 +767,21 @@ File: bashref.info, Node: Conditional Constructs, Next: Command Grouping, Pre
case WORD in [ [(] PATTERN [| PATTERN]...) COMMAND-LIST ;;]... esac
'case' will selectively execute the COMMAND-LIST corresponding to
- the first PATTERN that matches WORD. If the 'nocasematch' shell
- option (see the description of 'shopt' in *note The Shopt
- Builtin::) is enabled, the match is performed without regard to the
- case of alphabetic characters. The '|' is used to separate
- multiple patterns, and the ')' operator terminates a pattern list.
- A list of patterns and an associated command-list is known as a
- CLAUSE.
+ the first PATTERN that matches WORD. The match is performed
+ according to the rules described below in *note Pattern Matching::.
+ If the 'nocasematch' shell option (see the description of 'shopt'
+ in *note The Shopt Builtin::) is enabled, the match is performed
+ without regard to the case of alphabetic characters. The '|' is
+ used to separate multiple patterns, and the ')' operator terminates
+ a pattern list. A list of patterns and an associated command-list
+ is known as a CLAUSE.
Each clause must be terminated with ';;', ';&', or ';;&'. The WORD
undergoes tilde expansion, parameter expansion, command
- substitution, arithmetic expansion, and quote removal before
- matching is attempted. Each PATTERN undergoes tilde expansion,
- parameter expansion, command substitution, and arithmetic
- expansion.
+ substitution, arithmetic expansion, and quote removal (*note Shell
+ Parameter Expansion::) before matching is attempted. Each PATTERN
+ undergoes tilde expansion, parameter expansion, command
+ substitution, and arithmetic expansion.
There may be an arbitrary number of 'case' clauses, each terminated
by a ';;', ';&', or ';;&'. The first pattern that matches
@@ -904,7 +908,7 @@ File: bashref.info, Node: Conditional Constructs, Next: Command Grouping, Pre
variable LINE) if there is a sequence of characters in the value
consisting of any number, including zero, of space characters, zero
or one instances of 'a', then a 'b':
- [[ $line =~ [[:space:]]*(a)?b ]]
+ [[ $line =~ [[:space:]]*?(a)b ]]
That means values like 'aab' and ' aaaaaab' will match, as will a
line containing a 'b' anywhere in its value.
@@ -917,7 +921,7 @@ File: bashref.info, Node: Conditional Constructs, Next: Command Grouping, Pre
to the shell's quote removal. Using a shell variable to store the
pattern decreases these problems. For example, the following is
equivalent to the above:
- pattern='[[:space:]]*(a)?b'
+ pattern='[[:space:]]*?(a)b'
[[ $line =~ $pattern ]]
If you want to match a character that's special to the regular
@@ -1252,6 +1256,14 @@ script displays
var=global
func1
+ The 'unset' builtin also acts using the same dynamic scope: if a
+variable is local to the current scope, 'unset' will unset it; otherwise
+the unset will refer to the variable found in any calling scope as
+described above. If a variable at the local scope is unset, it will
+remain so until it is reset in that scope or until the function returns.
+If the unset acts on a variable at a previous scope, any instance of a
+variable with that name that had been shadowed will become visible.
+
Function names and definitions may be listed with the '-f' option to
the 'declare' ('typeset') builtin command (*note Bash Builtins::). The
'-F' option to 'declare' or 'typeset' will list the function names only
@@ -6205,8 +6217,10 @@ quotes.
NAME[SUBSCRIPT]' destroys the array element at index SUBSCRIPT.
Negative subscripts to indexed arrays are interpreted as described
above. Care must be taken to avoid unwanted side effects caused by
-filename expansion. 'unset NAME', where NAME is an array, removes the
-entire array. A subscript of '*' or '@' also removes the entire array.
+filename expansion. Unsetting the last element of an array variable
+does not unset the variable. 'unset NAME', where NAME is an array,
+removes the entire array. A subscript of '*' or '@' also removes the
+entire array.
The 'declare', 'local', and 'readonly' builtins each accept a '-a'
option to specify an indexed array and a '-A' option to specify an
@@ -10854,9 +10868,9 @@ D.2 Index of Shell Reserved Words
* !: Pipelines. (line 9)
* [[: Conditional Constructs.
- (line 121)
+ (line 122)
* ]]: Conditional Constructs.
- (line 121)
+ (line 122)
* {: Command Grouping. (line 21)
* }: Command Grouping. (line 21)
* case: Conditional Constructs.
@@ -10878,7 +10892,7 @@ D.2 Index of Shell Reserved Words
* in: Conditional Constructs.
(line 28)
* select: Conditional Constructs.
- (line 79)
+ (line 80)
* then: Conditional Constructs.
(line 7)
* time: Pipelines. (line 9)
@@ -11485,121 +11499,121 @@ Node: Escape Character14462
Node: Single Quotes14947
Node: Double Quotes15295
Node: ANSI-C Quoting16573
-Node: Locale Translation17826
-Node: Comments18722
-Node: Shell Commands19340
-Node: Simple Commands20212
-Node: Pipelines20843
-Node: Lists23586
-Node: Compound Commands25315
-Node: Looping Constructs26318
-Node: Conditional Constructs28781
-Node: Command Grouping39703
-Node: Coprocesses41182
-Node: GNU Parallel43014
-Node: Shell Functions46987
-Node: Shell Parameters53696
-Node: Positional Parameters58109
-Node: Special Parameters59009
-Node: Shell Expansions62346
-Node: Brace Expansion64440
-Node: Tilde Expansion67274
-Node: Shell Parameter Expansion69622
-Node: Command Substitution83754
-Node: Arithmetic Expansion85109
-Node: Process Substitution86041
-Node: Word Splitting87161
-Node: Filename Expansion89105
-Node: Pattern Matching91479
-Node: Quote Removal95465
-Node: Redirections95760
-Node: Executing Commands105318
-Node: Simple Command Expansion105988
-Node: Command Search and Execution107918
-Node: Command Execution Environment110254
-Node: Environment113238
-Node: Exit Status114897
-Node: Signals116567
-Node: Shell Scripts118534
-Node: Shell Builtin Commands121049
-Node: Bourne Shell Builtins123083
-Node: Bash Builtins143683
-Node: Modifying Shell Behavior172328
-Node: The Set Builtin172673
-Node: The Shopt Builtin183086
-Node: Special Builtins198984
-Node: Shell Variables199963
-Node: Bourne Shell Variables200400
-Node: Bash Variables202504
-Node: Bash Features232297
-Node: Invoking Bash233196
-Node: Bash Startup Files239145
-Node: Interactive Shells244248
-Node: What is an Interactive Shell?244658
-Node: Is this Shell Interactive?245307
-Node: Interactive Shell Behavior246122
-Node: Bash Conditional Expressions249610
-Node: Shell Arithmetic253976
-Node: Aliases256793
-Node: Arrays259341
-Node: The Directory Stack264425
-Node: Directory Stack Builtins265209
-Node: Controlling the Prompt268177
-Node: The Restricted Shell270939
-Node: Bash POSIX Mode272764
-Node: Job Control283115
-Node: Job Control Basics283575
-Node: Job Control Builtins288543
-Node: Job Control Variables293270
-Node: Command Line Editing294426
-Node: Introduction and Notation296097
-Node: Readline Interaction297720
-Node: Readline Bare Essentials298911
-Node: Readline Movement Commands300694
-Node: Readline Killing Commands301654
-Node: Readline Arguments303572
-Node: Searching304616
-Node: Readline Init File306802
-Node: Readline Init File Syntax307949
-Node: Conditional Init Constructs328136
-Node: Sample Init File330661
-Node: Bindable Readline Commands333778
-Node: Commands For Moving334982
-Node: Commands For History336831
-Node: Commands For Text341126
-Node: Commands For Killing344515
-Node: Numeric Arguments346996
-Node: Commands For Completion348135
-Node: Keyboard Macros352326
-Node: Miscellaneous Commands353013
-Node: Readline vi Mode358889
-Node: Programmable Completion359796
-Node: Programmable Completion Builtins367257
-Node: A Programmable Completion Example377143
-Node: Using History Interactively382395
-Node: Bash History Facilities383079
-Node: Bash History Builtins386080
-Node: History Interaction390372
-Node: Event Designators393336
-Node: Word Designators394555
-Node: Modifiers396192
-Node: Installing Bash397594
-Node: Basic Installation398731
-Node: Compilers and Options401422
-Node: Compiling For Multiple Architectures402163
-Node: Installation Names403826
-Node: Specifying the System Type404644
-Node: Sharing Defaults405360
-Node: Operation Controls406033
-Node: Optional Features406991
-Node: Reporting Bugs417517
-Node: Major Differences From The Bourne Shell418711
-Node: GNU Free Documentation License435563
-Node: Indexes460740
-Node: Builtin Index461194
-Node: Reserved Word Index468021
-Node: Variable Index470469
-Node: Function Index486147
-Node: Concept Index499450
+Node: Locale Translation17832
+Node: Comments18728
+Node: Shell Commands19346
+Node: Simple Commands20218
+Node: Pipelines20849
+Node: Lists23592
+Node: Compound Commands25331
+Node: Looping Constructs26343
+Node: Conditional Constructs28838
+Node: Command Grouping39893
+Node: Coprocesses41372
+Node: GNU Parallel43204
+Node: Shell Functions47177
+Node: Shell Parameters54376
+Node: Positional Parameters58789
+Node: Special Parameters59689
+Node: Shell Expansions63026
+Node: Brace Expansion65120
+Node: Tilde Expansion67954
+Node: Shell Parameter Expansion70302
+Node: Command Substitution84434
+Node: Arithmetic Expansion85789
+Node: Process Substitution86721
+Node: Word Splitting87841
+Node: Filename Expansion89785
+Node: Pattern Matching92159
+Node: Quote Removal96145
+Node: Redirections96440
+Node: Executing Commands105998
+Node: Simple Command Expansion106668
+Node: Command Search and Execution108598
+Node: Command Execution Environment110934
+Node: Environment113918
+Node: Exit Status115577
+Node: Signals117247
+Node: Shell Scripts119214
+Node: Shell Builtin Commands121729
+Node: Bourne Shell Builtins123763
+Node: Bash Builtins144363
+Node: Modifying Shell Behavior173008
+Node: The Set Builtin173353
+Node: The Shopt Builtin183766
+Node: Special Builtins199664
+Node: Shell Variables200643
+Node: Bourne Shell Variables201080
+Node: Bash Variables203184
+Node: Bash Features232977
+Node: Invoking Bash233876
+Node: Bash Startup Files239825
+Node: Interactive Shells244928
+Node: What is an Interactive Shell?245338
+Node: Is this Shell Interactive?245987
+Node: Interactive Shell Behavior246802
+Node: Bash Conditional Expressions250290
+Node: Shell Arithmetic254656
+Node: Aliases257473
+Node: Arrays260021
+Node: The Directory Stack265183
+Node: Directory Stack Builtins265967
+Node: Controlling the Prompt268935
+Node: The Restricted Shell271697
+Node: Bash POSIX Mode273522
+Node: Job Control283873
+Node: Job Control Basics284333
+Node: Job Control Builtins289301
+Node: Job Control Variables294028
+Node: Command Line Editing295184
+Node: Introduction and Notation296855
+Node: Readline Interaction298478
+Node: Readline Bare Essentials299669
+Node: Readline Movement Commands301452
+Node: Readline Killing Commands302412
+Node: Readline Arguments304330
+Node: Searching305374
+Node: Readline Init File307560
+Node: Readline Init File Syntax308707
+Node: Conditional Init Constructs328894
+Node: Sample Init File331419
+Node: Bindable Readline Commands334536
+Node: Commands For Moving335740
+Node: Commands For History337589
+Node: Commands For Text341884
+Node: Commands For Killing345273
+Node: Numeric Arguments347754
+Node: Commands For Completion348893
+Node: Keyboard Macros353084
+Node: Miscellaneous Commands353771
+Node: Readline vi Mode359647
+Node: Programmable Completion360554
+Node: Programmable Completion Builtins368015
+Node: A Programmable Completion Example377901
+Node: Using History Interactively383153
+Node: Bash History Facilities383837
+Node: Bash History Builtins386838
+Node: History Interaction391130
+Node: Event Designators394094
+Node: Word Designators395313
+Node: Modifiers396950
+Node: Installing Bash398352
+Node: Basic Installation399489
+Node: Compilers and Options402180
+Node: Compiling For Multiple Architectures402921
+Node: Installation Names404584
+Node: Specifying the System Type405402
+Node: Sharing Defaults406118
+Node: Operation Controls406791
+Node: Optional Features407749
+Node: Reporting Bugs418275
+Node: Major Differences From The Bourne Shell419469
+Node: GNU Free Documentation License436321
+Node: Indexes461498
+Node: Builtin Index461952
+Node: Reserved Word Index468779
+Node: Variable Index471227
+Node: Function Index486905
+Node: Concept Index500208

End Tag Table
diff --git a/doc/bashref.log b/doc/bashref.log
index 4042664..83808f7 100644
--- a/doc/bashref.log
+++ b/doc/bashref.log
@@ -1,4 +1,4 @@
-This is pdfTeX, Version 3.14159265-2.6-1.40.17 (TeX Live 2016/MacPorts 2016_4) (preloaded format=pdfetex 2017.1.6) 22 MAR 2017 16:20
+This is pdfTeX, Version 3.14159265-2.6-1.40.17 (TeX Live 2016/MacPorts 2016_4) (preloaded format=pdfetex 2017.1.6) 28 MAR 2017 14:25
entering extended mode
restricted \write18 enabled.
file:line:error style messages enabled.
@@ -185,7 +185,7 @@ p/pdftex/updmap/pdftex.map}] [2] (/Users/chet/src/bash/src/doc/bashref.toc
\openout4 = `bashref.rw'.
[8] [9] [10]
-Overfull \hbox (38.26587pt too wide) in paragraph at lines 872--872
+Overfull \hbox (38.26587pt too wide) in paragraph at lines 874--874
[]@texttt case @textttsl word @texttt in [ [(] @textttsl pat-tern @texttt [| @
textttsl pattern@texttt ][]) @textttsl command-list @texttt ;;][] esac[]
@@ -198,7 +198,7 @@ textttsl pattern@texttt ][]) @textttsl command-list @texttt ;;][] esac[]
.etc.
[11] [12] [13] [14] [15]
-Overfull \hbox (89.6747pt too wide) in paragraph at lines 1274--1274
+Overfull \hbox (89.6747pt too wide) in paragraph at lines 1280--1280
[]@texttt cat list | parallel "do-something1 {} config-{} ; do-something2 < {}
" | process-output[]
@@ -211,7 +211,7 @@ Overfull \hbox (89.6747pt too wide) in paragraph at lines 1274--1274
.etc.
-Overfull \hbox (89.6747pt too wide) in paragraph at lines 1297--1297
+Overfull \hbox (89.6747pt too wide) in paragraph at lines 1303--1303
[]@texttt { echo foss.org.my ; echo debian.org; echo freenetproject.org; } | p
arallel traceroute[]
@@ -223,8 +223,8 @@ arallel traceroute[]
.@glue 5.74869
.etc.
-
-Overfull \hbox (106.92076pt too wide) in paragraph at lines 1303--1303
+[16]
+Overfull \hbox (106.92076pt too wide) in paragraph at lines 1309--1309
[]@texttt { echo foss.org.my ; echo debian.org; echo freenetproject.org; } | p
arallel -k traceroute[]
@@ -236,14 +236,14 @@ arallel -k traceroute[]
.@glue 5.74869
.etc.
-[16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]
-[31] [32] [33] [34] [35] [36] [37] [38] [39] [40] Chapter 4 [41]
+[17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31]
+[32] [33] [34] [35] [36] [37] [38] [39] [40] [41] Chapter 4 [42]
@btindfile=@write5
\openout5 = `bashref.bt'.
- [42] [43]
-[44] [45] [46] [47] [48] [49] [50] [51] [52] [53] [54]
-Overfull \hbox (26.76846pt too wide) in paragraph at lines 4328--4328
+ [43] [44]
+[45] [46] [47] [48] [49] [50] [51] [52] [53] [54] [55]
+Overfull \hbox (26.76846pt too wide) in paragraph at lines 4343--4343
[]@texttt mapfile [-d @textttsl de-lim@texttt ] [-n @textttsl count@texttt ] [
-O @textttsl ori-gin@texttt ] [-s @textttsl count@texttt ] [-t] [-u @textttsl f
d@texttt ][]
@@ -256,8 +256,8 @@ d@texttt ][]
.@texttt p
.etc.
-[55] [56]
-Overfull \hbox (38.26584pt too wide) in paragraph at lines 4532--4532
+[56] [57]
+Overfull \hbox (38.26584pt too wide) in paragraph at lines 4547--4547
[]@texttt readarray [-d @textttsl de-lim@texttt ] [-n @textttsl count@texttt ]
[-O @textttsl ori-gin@texttt ] [-s @textttsl count@texttt ] [-t] [-u @textttsl
fd@texttt ][]
@@ -270,9 +270,9 @@ Overfull \hbox (38.26584pt too wide) in paragraph at lines 4532--4532
.@texttt a
.etc.
-[57] [58] [59] [60] [61] [62] [63] [64] [65] [66] [67] [68] [69] Chapter 5
-[70] [71] [72] [73] [74] [75] [76] [77] [78] [79] [80] [81] Chapter 6 [82]
-Overfull \hbox (49.43388pt too wide) in paragraph at lines 6279--6279
+[58] [59] [60] [61] [62] [63] [64] [65] [66] [67] [68] [69] [70] Chapter 5
+[71] [72] [73] [74] [75] [76] [77] [78] [79] [80] [81] [82] Chapter 6 [83]
+Overfull \hbox (49.43388pt too wide) in paragraph at lines 6294--6294
[]@texttt bash [long-opt] [-ir] [-abefhkmnptuvxdBCDHP] [-o @textttsl op-tion@t
exttt ] [-O @textttsl shopt_option@texttt ] [@textttsl ar-
@@ -285,7 +285,7 @@ exttt ] [-O @textttsl shopt_option@texttt ] [@textttsl ar-
.etc.
-Overfull \hbox (72.42863pt too wide) in paragraph at lines 6280--6280
+Overfull \hbox (72.42863pt too wide) in paragraph at lines 6295--6295
[]@texttt bash [long-opt] [-abefhkmnptuvxdBCDHP] [-o @textttsl op-tion@texttt
] [-O @textttsl shopt_option@texttt ] -c @textttsl string @texttt [@textttsl ar
-
@@ -299,7 +299,7 @@ Overfull \hbox (72.42863pt too wide) in paragraph at lines 6280--6280
.etc.
-Overfull \hbox (32.18782pt too wide) in paragraph at lines 6281--6281
+Overfull \hbox (32.18782pt too wide) in paragraph at lines 6296--6296
[]@texttt bash [long-opt] -s [-abefhkmnptuvxdBCDHP] [-o @textttsl op-tion@text
tt ] [-O @textttsl shopt_option@texttt ] [@textttsl ar-
@@ -311,13 +311,13 @@ tt ] [-O @textttsl shopt_option@texttt ] [@textttsl ar-
.@texttt s
.etc.
-[83] [84] [85] [86] [87] [88] [89] [90] [91] [92] [93] [94] [95] [96] [97]
-[98] [99] Chapter 7 [100] [101] [102] [103]
+[84] [85] [86] [87] [88] [89] [90] [91] [92] [93] [94] [95] [96] [97] [98]
+[99] [100] Chapter 7 [101] [102] [103] [104]
texinfo.tex: doing @include of rluser.texi
-(/usr/homes/chet/src/bash/src/lib/readline/doc/rluser.texi Chapter 8 [104]
-[105] [106] [107] [108] [109] [110] [111] [112] [113] [114]
+(/usr/homes/chet/src/bash/src/lib/readline/doc/rluser.texi Chapter 8 [105]
+[106] [107] [108] [109] [110] [111] [112] [113] [114] [115]
Underfull \hbox (badness 7540) in paragraph at lines 802--808
[]@textrm In the above ex-am-ple, @textttsl C-u[] @textrm is bound to the func
-tion
@@ -343,7 +343,7 @@ e func-tion
.@texttt v
.etc.
-[115] [116] [117]
+[116] [117] [118]
Overfull \hbox (26.43913pt too wide) in paragraph at lines 997--997
[]@texttt Meta-Control-h: backward-kill-word Text after the function name is i
gnored[]
@@ -356,12 +356,12 @@ gnored[]
.@texttt t
.etc.
-[118] [119]
+[119] [120]
@fnindfile=@write6
\openout6 = `bashref.fn'.
- [120] [121] [122] [123] [124] [125] [126] [127] [128] [129]
-[130] [131] [132] [133] [134] [135]
+ [121] [122] [123] [124] [125] [126] [127] [128] [129] [130]
+[131] [132] [133] [134] [135] [136]
Overfull \hbox (26.43913pt too wide) in paragraph at lines 2247--2247
[] @texttt # Tilde expansion, with side effect of expanding tilde to full p
athname[]
@@ -374,22 +374,22 @@ athname[]
.@penalty 10000
.etc.
-[136] [137])
+[137] [138])
texinfo.tex: doing @include of hsuser.texi
(/usr/homes/chet/src/bash/src/lib/readline/doc/hsuser.texi
-Chapter 9 [138] [139] [140] [141] [142]) Chapter 10 [143] [144] [145] [146]
-[147] [148] [149] [150] Appendix A [151] Appendix B [152] [153] [154] [155]
-[156] [157] Appendix C [158]
+Chapter 9 [139] [140] [141] [142] [143]) Chapter 10 [144] [145] [146] [147]
+[148] [149] [150] [151] Appendix A [152] Appendix B [153] [154] [155] [156]
+[157] [158] Appendix C [159]
texinfo.tex: doing @include of fdl.texi
- (/Users/chet/src/bash/src/doc/fdl.texi [159]
-[160] [161] [162] [163] [164] [165]) Appendix D [166] [167] [168] [169]
-[170] [171] [172] [173] [174] [175] )
+ (/Users/chet/src/bash/src/doc/fdl.texi [160]
+[161] [162] [163] [164] [165] [166]) Appendix D [167] [168] [169] [170]
+[171] [172] [173] [174] [175] [176] )
Here is how much of TeX's memory you used:
- 4063 strings out of 497105
- 47066 string characters out of 6206776
- 137574 words of memory out of 5000000
+ 4064 strings out of 497105
+ 47069 string characters out of 6206776
+ 136585 words of memory out of 5000000
4846 multiletter control sequences out of 15000+600000
34315 words of font info for 116 fonts, out of 8000000 for 9000
51 hyphenation exceptions out of 8191
@@ -411,10 +411,10 @@ e/fonts/type1/public/amsfonts/cm/cmtt12.pfb></opt/local/share/texmf-texlive/fon
ts/type1/public/amsfonts/cm/cmtt9.pfb></opt/local/share/texmf-texlive/fonts/typ
e1/public/cm-super/sfrm1095.pfb></opt/local/share/texmf-texlive/fonts/type1/pub
lic/cm-super/sfrm1440.pfb>
-Output written on bashref.pdf (181 pages, 741335 bytes).
+Output written on bashref.pdf (182 pages, 742807 bytes).
PDF statistics:
- 2600 PDF objects out of 2984 (max. 8388607)
- 2374 compressed objects within 24 object streams
- 307 named destinations out of 1000 (max. 500000)
+ 2607 PDF objects out of 2984 (max. 8388607)
+ 2380 compressed objects within 24 object streams
+ 308 named destinations out of 1000 (max. 500000)
1125 words of extra memory for PDF output out of 10000 (max. 10000000)
diff --git a/doc/bashref.pdf b/doc/bashref.pdf
index 272b6c6..cdc49ed 100644
--- a/doc/bashref.pdf
+++ b/doc/bashref.pdf
Binary files differ
diff --git a/doc/bashref.rw b/doc/bashref.rw
index dc9f911..3d6b650 100644
--- a/doc/bashref.rw
+++ b/doc/bashref.rw
@@ -16,6 +16,6 @@
\entry{select}{12}{\code {select}}
\entry{[[}{12}{\code {[[}}
\entry{]]}{12}{\code {]]}}
-\entry{{\indexlbrace }}{14}{\code {{\tt \char 123}}}
-\entry{{\indexrbrace }}{14}{\code {{\tt \char 125}}}
+\entry{{\indexlbrace }}{15}{\code {{\tt \char 123}}}
+\entry{{\indexrbrace }}{15}{\code {{\tt \char 125}}}
\entry{function}{17}{\code {function}}
diff --git a/doc/bashref.rws b/doc/bashref.rws
index d45cf99..8c05033 100644
--- a/doc/bashref.rws
+++ b/doc/bashref.rws
@@ -5,9 +5,9 @@
\initial {]}
\entry {\code {]]}}{12}
\initial {{\indexlbrace }}
-\entry {\code {{\tt \char 123}}}{14}
+\entry {\code {{\tt \char 123}}}{15}
\initial {{\indexrbrace }}
-\entry {\code {{\tt \char 125}}}{14}
+\entry {\code {{\tt \char 125}}}{15}
\initial {C}
\entry {\code {case}}{11}
\initial {D}
diff --git a/doc/bashref.texi b/doc/bashref.texi
index 84f20e7..f09f879 100644
--- a/doc/bashref.texi
+++ b/doc/bashref.texi
@@ -508,7 +508,7 @@ double quote
question mark
@item \@var{nnn}
the eight-bit character whose value is the octal value @var{nnn}
-(one to three digits)
+(one to three octal digits)
@item \x@var{HH}
the eight-bit character whose value is the hexadecimal value @var{HH}
(one or two hex digits)
@@ -659,8 +659,13 @@ the time information.
If the pipeline is not executed asynchronously (@pxref{Lists}), the
shell waits for all commands in the pipeline to complete.
-Each command in a pipeline is executed in its own subshell
-(@pxref{Command Execution Environment}). The exit
+Each command in a pipeline is executed in its own subshell, which is a
+separate process (@pxref{Command Execution Environment}).
+If the @code{lastpipe} option is enabled using the @code{shopt} builtin
+(@pxref{The Shopt Builtin}),
+the last element of a pipeline may be run by the shell process.
+
+The exit
status of a pipeline is the exit status of the last command in the
pipeline, unless the @code{pipefail} option is enabled
(@pxref{The Set Builtin}).
@@ -714,7 +719,7 @@ An @sc{and} list has the form
@noindent
@var{command2} is executed if, and only if, @var{command1}
-returns an exit status of zero.
+returns an exit status of zero (success).
An @sc{or} list has the form
@example
@@ -739,7 +744,7 @@ executed in the list.
* Command Grouping:: Ways to group commands.
@end menu
-Compound commands are the shell programming constructs.
+Compound commands are the shell programming language constructs.
Each construct begins with a reserved word or control operator and is
terminated by a corresponding reserved word or operator.
Any redirections (@pxref{Redirections}) associated with a compound command
@@ -798,12 +803,14 @@ The syntax of the @code{for} command is:
for @var{name} [ [in [@var{words} @dots{}] ] ; ] do @var{commands}; done
@end example
-Expand @var{words}, and execute @var{commands} once for each member
+Expand @var{words} (@pxref{Shell Expansions}), and execute @var{commands}
+once for each member
in the resultant list, with @var{name} bound to the current member.
If @samp{in @var{words}} is not present, the @code{for} command
executes the @var{commands} once for each positional parameter that is
set, as if @samp{in "$@@"} had been specified
(@pxref{Special Parameters}).
+
The return status is the exit status of the last command that executes.
If there are no items in the expansion of @var{words}, no commands are
executed, and the return status is zero.
@@ -874,6 +881,8 @@ case @var{word} in [ [(] @var{pattern} [| @var{pattern}]@dots{}) @var{command-li
@code{case} will selectively execute the @var{command-list} corresponding to
the first @var{pattern} that matches @var{word}.
+The match is performed according
+to the rules described below in @ref{Pattern Matching}.
If the @code{nocasematch} shell option
(see the description of @code{shopt} in @ref{The Shopt Builtin})
is enabled, the match is performed without regard to the case
@@ -885,7 +894,9 @@ as a @var{clause}.
Each clause must be terminated with @samp{;;}, @samp{;&}, or @samp{;;&}.
The @var{word} undergoes tilde expansion, parameter expansion, command
-substitution, arithmetic expansion, and quote removal before matching is
+substitution, arithmetic expansion, and quote removal
+(@pxref{Shell Parameter Expansion})
+before matching is
attempted. Each @var{pattern} undergoes tilde expansion, parameter
expansion, command substitution, and arithmetic expansion.
@@ -1045,7 +1056,7 @@ if there is a sequence of characters in the value consisting of
any number, including zero, of
space characters, zero or one instances of @samp{a}, then a @samp{b}:
@example
-[[ $line =~ [[:space:]]*(a)?b ]]
+[[ $line =~ [[:space:]]*?(a)b ]]
@end example
@noindent
@@ -1061,7 +1072,7 @@ expressions while paying attention to the shell's quote removal.
Using a shell variable to store the pattern decreases these problems.
For example, the following is equivalent to the above:
@example
-pattern='[[:space:]]*(a)?b'
+pattern='[[:space:]]*?(a)b'
[[ $line =~ $pattern ]]
@end example
diff --git a/doc/bashref.toc b/doc/bashref.toc
index f3a2c9d..45920cd 100644
--- a/doc/bashref.toc
+++ b/doc/bashref.toc
@@ -25,12 +25,12 @@
@numsecentry{Shell Functions}{3.3}{Shell Functions}{17}
@numsecentry{Shell Parameters}{3.4}{Shell Parameters}{19}
@numsubsecentry{Positional Parameters}{3.4.1}{Positional Parameters}{20}
-@numsubsecentry{Special Parameters}{3.4.2}{Special Parameters}{20}
-@numsecentry{Shell Expansions}{3.5}{Shell Expansions}{21}
+@numsubsecentry{Special Parameters}{3.4.2}{Special Parameters}{21}
+@numsecentry{Shell Expansions}{3.5}{Shell Expansions}{22}
@numsubsecentry{Brace Expansion}{3.5.1}{Brace Expansion}{22}
@numsubsecentry{Tilde Expansion}{3.5.2}{Tilde Expansion}{23}
@numsubsecentry{Shell Parameter Expansion}{3.5.3}{Shell Parameter Expansion}{24}
-@numsubsecentry{Command Substitution}{3.5.4}{Command Substitution}{29}
+@numsubsecentry{Command Substitution}{3.5.4}{Command Substitution}{30}
@numsubsecentry{Arithmetic Expansion}{3.5.5}{Arithmetic Expansion}{30}
@numsubsecentry{Process Substitution}{3.5.6}{Process Substitution}{30}
@numsubsecentry{Word Splitting}{3.5.7}{Word Splitting}{31}
@@ -38,7 +38,7 @@
@numsubsubsecentry{Pattern Matching}{3.5.8.1}{Pattern Matching}{32}
@numsubsecentry{Quote Removal}{3.5.9}{Quote Removal}{33}
@numsecentry{Redirections}{3.6}{Redirections}{33}
-@numsubsecentry{Redirecting Input}{3.6.1}{}{34}
+@numsubsecentry{Redirecting Input}{3.6.1}{}{35}
@numsubsecentry{Redirecting Output}{3.6.2}{}{35}
@numsubsecentry{Appending Redirected Output}{3.6.3}{}{35}
@numsubsecentry{Redirecting Standard Output and Standard Error}{3.6.4}{}{35}
@@ -56,84 +56,84 @@
@numsubsecentry{Exit Status}{3.7.5}{Exit Status}{40}
@numsubsecentry{Signals}{3.7.6}{Signals}{40}
@numsecentry{Shell Scripts}{3.8}{Shell Scripts}{41}
-@numchapentry{Shell Builtin Commands}{4}{Shell Builtin Commands}{42}
-@numsecentry{Bourne Shell Builtins}{4.1}{Bourne Shell Builtins}{42}
-@numsecentry{Bash Builtin Commands}{4.2}{Bash Builtins}{49}
-@numsecentry{Modifying Shell Behavior}{4.3}{Modifying Shell Behavior}{60}
-@numsubsecentry{The Set Builtin}{4.3.1}{The Set Builtin}{60}
-@numsubsecentry{The Shopt Builtin}{4.3.2}{The Shopt Builtin}{64}
-@numsecentry{Special Builtins}{4.4}{Special Builtins}{70}
-@numchapentry{Shell Variables}{5}{Shell Variables}{71}
-@numsecentry{Bourne Shell Variables}{5.1}{Bourne Shell Variables}{71}
-@numsecentry{Bash Variables}{5.2}{Bash Variables}{71}
-@numchapentry{Bash Features}{6}{Bash Features}{83}
-@numsecentry{Invoking Bash}{6.1}{Invoking Bash}{83}
-@numsecentry{Bash Startup Files}{6.2}{Bash Startup Files}{85}
-@numsecentry{Interactive Shells}{6.3}{Interactive Shells}{86}
-@numsubsecentry{What is an Interactive Shell?}{6.3.1}{What is an Interactive Shell?}{87}
-@numsubsecentry{Is this Shell Interactive?}{6.3.2}{Is this Shell Interactive?}{87}
-@numsubsecentry{Interactive Shell Behavior}{6.3.3}{Interactive Shell Behavior}{87}
-@numsecentry{Bash Conditional Expressions}{6.4}{Bash Conditional Expressions}{88}
-@numsecentry{Shell Arithmetic}{6.5}{Shell Arithmetic}{90}
-@numsecentry{Aliases}{6.6}{Aliases}{91}
-@numsecentry{Arrays}{6.7}{Arrays}{92}
-@numsecentry{The Directory Stack}{6.8}{The Directory Stack}{94}
-@numsubsecentry{Directory Stack Builtins}{6.8.1}{Directory Stack Builtins}{94}
-@numsecentry{Controlling the Prompt}{6.9}{Controlling the Prompt}{95}
-@numsecentry{The Restricted Shell}{6.10}{The Restricted Shell}{96}
-@numsecentry{Bash POSIX Mode}{6.11}{Bash POSIX Mode}{97}
-@numchapentry{Job Control}{7}{Job Control}{101}
-@numsecentry{Job Control Basics}{7.1}{Job Control Basics}{101}
-@numsecentry{Job Control Builtins}{7.2}{Job Control Builtins}{102}
-@numsecentry{Job Control Variables}{7.3}{Job Control Variables}{104}
-@numchapentry{Command Line Editing}{8}{Command Line Editing}{105}
-@numsecentry{Introduction to Line Editing}{8.1}{Introduction and Notation}{105}
-@numsecentry{Readline Interaction}{8.2}{Readline Interaction}{105}
-@numsubsecentry{Readline Bare Essentials}{8.2.1}{Readline Bare Essentials}{106}
-@numsubsecentry{Readline Movement Commands}{8.2.2}{Readline Movement Commands}{106}
-@numsubsecentry{Readline Killing Commands}{8.2.3}{Readline Killing Commands}{107}
-@numsubsecentry{Readline Arguments}{8.2.4}{Readline Arguments}{107}
-@numsubsecentry{Searching for Commands in the History}{8.2.5}{Searching}{107}
-@numsecentry{Readline Init File}{8.3}{Readline Init File}{108}
-@numsubsecentry{Readline Init File Syntax}{8.3.1}{Readline Init File Syntax}{108}
-@numsubsecentry{Conditional Init Constructs}{8.3.2}{Conditional Init Constructs}{116}
-@numsubsecentry{Sample Init File}{8.3.3}{Sample Init File}{117}
-@numsecentry{Bindable Readline Commands}{8.4}{Bindable Readline Commands}{120}
-@numsubsecentry{Commands For Moving}{8.4.1}{Commands For Moving}{120}
-@numsubsecentry{Commands For Manipulating The History}{8.4.2}{Commands For History}{121}
-@numsubsecentry{Commands For Changing Text}{8.4.3}{Commands For Text}{122}
-@numsubsecentry{Killing And Yanking}{8.4.4}{Commands For Killing}{124}
-@numsubsecentry{Specifying Numeric Arguments}{8.4.5}{Numeric Arguments}{125}
-@numsubsecentry{Letting Readline Type For You}{8.4.6}{Commands For Completion}{125}
-@numsubsecentry{Keyboard Macros}{8.4.7}{Keyboard Macros}{127}
-@numsubsecentry{Some Miscellaneous Commands}{8.4.8}{Miscellaneous Commands}{127}
-@numsecentry{Readline vi Mode}{8.5}{Readline vi Mode}{129}
-@numsecentry{Programmable Completion}{8.6}{Programmable Completion}{130}
-@numsecentry{Programmable Completion Builtins}{8.7}{Programmable Completion Builtins}{132}
-@numsecentry{A Programmable Completion Example}{8.8}{A Programmable Completion Example}{136}
-@numchapentry{Using History Interactively}{9}{Using History Interactively}{139}
-@numsecentry{Bash History Facilities}{9.1}{Bash History Facilities}{139}
-@numsecentry{Bash History Builtins}{9.2}{Bash History Builtins}{139}
-@numsecentry{History Expansion}{9.3}{History Interaction}{141}
-@numsubsecentry{Event Designators}{9.3.1}{Event Designators}{142}
-@numsubsecentry{Word Designators}{9.3.2}{Word Designators}{142}
-@numsubsecentry{Modifiers}{9.3.3}{Modifiers}{143}
-@numchapentry{Installing Bash}{10}{Installing Bash}{144}
-@numsecentry{Basic Installation}{10.1}{Basic Installation}{144}
-@numsecentry{Compilers and Options}{10.2}{Compilers and Options}{145}
-@numsecentry{Compiling For Multiple Architectures}{10.3}{Compiling For Multiple Architectures}{145}
-@numsecentry{Installation Names}{10.4}{Installation Names}{145}
-@numsecentry{Specifying the System Type}{10.5}{Specifying the System Type}{145}
-@numsecentry{Sharing Defaults}{10.6}{Sharing Defaults}{146}
-@numsecentry{Operation Controls}{10.7}{Operation Controls}{146}
-@numsecentry{Optional Features}{10.8}{Optional Features}{146}
-@appentry{Reporting Bugs}{A}{Reporting Bugs}{152}
-@appentry{Major Differences From The Bourne Shell}{B}{Major Differences From The Bourne Shell}{153}
-@appsecentry{Implementation Differences From The SVR4.2 Shell}{B.1}{}{157}
-@appentry{GNU Free Documentation License}{C}{GNU Free Documentation License}{159}
-@appentry{Indexes}{D}{Indexes}{167}
-@appsecentry{Index of Shell Builtin Commands}{D.1}{Builtin Index}{167}
-@appsecentry{Index of Shell Reserved Words}{D.2}{Reserved Word Index}{168}
-@appsecentry{Parameter and Variable Index}{D.3}{Variable Index}{169}
-@appsecentry{Function Index}{D.4}{Function Index}{171}
-@appsecentry{Concept Index}{D.5}{Concept Index}{173}
+@numchapentry{Shell Builtin Commands}{4}{Shell Builtin Commands}{43}
+@numsecentry{Bourne Shell Builtins}{4.1}{Bourne Shell Builtins}{43}
+@numsecentry{Bash Builtin Commands}{4.2}{Bash Builtins}{50}
+@numsecentry{Modifying Shell Behavior}{4.3}{Modifying Shell Behavior}{61}
+@numsubsecentry{The Set Builtin}{4.3.1}{The Set Builtin}{61}
+@numsubsecentry{The Shopt Builtin}{4.3.2}{The Shopt Builtin}{65}
+@numsecentry{Special Builtins}{4.4}{Special Builtins}{71}
+@numchapentry{Shell Variables}{5}{Shell Variables}{72}
+@numsecentry{Bourne Shell Variables}{5.1}{Bourne Shell Variables}{72}
+@numsecentry{Bash Variables}{5.2}{Bash Variables}{72}
+@numchapentry{Bash Features}{6}{Bash Features}{84}
+@numsecentry{Invoking Bash}{6.1}{Invoking Bash}{84}
+@numsecentry{Bash Startup Files}{6.2}{Bash Startup Files}{86}
+@numsecentry{Interactive Shells}{6.3}{Interactive Shells}{87}
+@numsubsecentry{What is an Interactive Shell?}{6.3.1}{What is an Interactive Shell?}{88}
+@numsubsecentry{Is this Shell Interactive?}{6.3.2}{Is this Shell Interactive?}{88}
+@numsubsecentry{Interactive Shell Behavior}{6.3.3}{Interactive Shell Behavior}{88}
+@numsecentry{Bash Conditional Expressions}{6.4}{Bash Conditional Expressions}{89}
+@numsecentry{Shell Arithmetic}{6.5}{Shell Arithmetic}{91}
+@numsecentry{Aliases}{6.6}{Aliases}{92}
+@numsecentry{Arrays}{6.7}{Arrays}{93}
+@numsecentry{The Directory Stack}{6.8}{The Directory Stack}{95}
+@numsubsecentry{Directory Stack Builtins}{6.8.1}{Directory Stack Builtins}{95}
+@numsecentry{Controlling the Prompt}{6.9}{Controlling the Prompt}{96}
+@numsecentry{The Restricted Shell}{6.10}{The Restricted Shell}{97}
+@numsecentry{Bash POSIX Mode}{6.11}{Bash POSIX Mode}{98}
+@numchapentry{Job Control}{7}{Job Control}{102}
+@numsecentry{Job Control Basics}{7.1}{Job Control Basics}{102}
+@numsecentry{Job Control Builtins}{7.2}{Job Control Builtins}{103}
+@numsecentry{Job Control Variables}{7.3}{Job Control Variables}{105}
+@numchapentry{Command Line Editing}{8}{Command Line Editing}{106}
+@numsecentry{Introduction to Line Editing}{8.1}{Introduction and Notation}{106}
+@numsecentry{Readline Interaction}{8.2}{Readline Interaction}{106}
+@numsubsecentry{Readline Bare Essentials}{8.2.1}{Readline Bare Essentials}{107}
+@numsubsecentry{Readline Movement Commands}{8.2.2}{Readline Movement Commands}{107}
+@numsubsecentry{Readline Killing Commands}{8.2.3}{Readline Killing Commands}{108}
+@numsubsecentry{Readline Arguments}{8.2.4}{Readline Arguments}{108}
+@numsubsecentry{Searching for Commands in the History}{8.2.5}{Searching}{108}
+@numsecentry{Readline Init File}{8.3}{Readline Init File}{109}
+@numsubsecentry{Readline Init File Syntax}{8.3.1}{Readline Init File Syntax}{109}
+@numsubsecentry{Conditional Init Constructs}{8.3.2}{Conditional Init Constructs}{117}
+@numsubsecentry{Sample Init File}{8.3.3}{Sample Init File}{118}
+@numsecentry{Bindable Readline Commands}{8.4}{Bindable Readline Commands}{121}
+@numsubsecentry{Commands For Moving}{8.4.1}{Commands For Moving}{121}
+@numsubsecentry{Commands For Manipulating The History}{8.4.2}{Commands For History}{122}
+@numsubsecentry{Commands For Changing Text}{8.4.3}{Commands For Text}{123}
+@numsubsecentry{Killing And Yanking}{8.4.4}{Commands For Killing}{125}
+@numsubsecentry{Specifying Numeric Arguments}{8.4.5}{Numeric Arguments}{126}
+@numsubsecentry{Letting Readline Type For You}{8.4.6}{Commands For Completion}{126}
+@numsubsecentry{Keyboard Macros}{8.4.7}{Keyboard Macros}{128}
+@numsubsecentry{Some Miscellaneous Commands}{8.4.8}{Miscellaneous Commands}{128}
+@numsecentry{Readline vi Mode}{8.5}{Readline vi Mode}{130}
+@numsecentry{Programmable Completion}{8.6}{Programmable Completion}{131}
+@numsecentry{Programmable Completion Builtins}{8.7}{Programmable Completion Builtins}{133}
+@numsecentry{A Programmable Completion Example}{8.8}{A Programmable Completion Example}{137}
+@numchapentry{Using History Interactively}{9}{Using History Interactively}{140}
+@numsecentry{Bash History Facilities}{9.1}{Bash History Facilities}{140}
+@numsecentry{Bash History Builtins}{9.2}{Bash History Builtins}{140}
+@numsecentry{History Expansion}{9.3}{History Interaction}{142}
+@numsubsecentry{Event Designators}{9.3.1}{Event Designators}{143}
+@numsubsecentry{Word Designators}{9.3.2}{Word Designators}{143}
+@numsubsecentry{Modifiers}{9.3.3}{Modifiers}{144}
+@numchapentry{Installing Bash}{10}{Installing Bash}{145}
+@numsecentry{Basic Installation}{10.1}{Basic Installation}{145}
+@numsecentry{Compilers and Options}{10.2}{Compilers and Options}{146}
+@numsecentry{Compiling For Multiple Architectures}{10.3}{Compiling For Multiple Architectures}{146}
+@numsecentry{Installation Names}{10.4}{Installation Names}{146}
+@numsecentry{Specifying the System Type}{10.5}{Specifying the System Type}{146}
+@numsecentry{Sharing Defaults}{10.6}{Sharing Defaults}{147}
+@numsecentry{Operation Controls}{10.7}{Operation Controls}{147}
+@numsecentry{Optional Features}{10.8}{Optional Features}{147}
+@appentry{Reporting Bugs}{A}{Reporting Bugs}{153}
+@appentry{Major Differences From The Bourne Shell}{B}{Major Differences From The Bourne Shell}{154}
+@appsecentry{Implementation Differences From The SVR4.2 Shell}{B.1}{}{158}
+@appentry{GNU Free Documentation License}{C}{GNU Free Documentation License}{160}
+@appentry{Indexes}{D}{Indexes}{168}
+@appsecentry{Index of Shell Builtin Commands}{D.1}{Builtin Index}{168}
+@appsecentry{Index of Shell Reserved Words}{D.2}{Reserved Word Index}{169}
+@appsecentry{Parameter and Variable Index}{D.3}{Variable Index}{170}
+@appsecentry{Function Index}{D.4}{Function Index}{172}
+@appsecentry{Concept Index}{D.5}{Concept Index}{174}
diff --git a/doc/bashref.vr b/doc/bashref.vr
index 4270dee..ce2a5f8 100644
--- a/doc/bashref.vr
+++ b/doc/bashref.vr
@@ -1,8 +1,8 @@
\entry{LC_MESSAGES}{7}{\code {LC_MESSAGES}}
\entry{TEXTDOMAIN}{7}{\code {TEXTDOMAIN}}
\entry{TEXTDOMAINDIR}{7}{\code {TEXTDOMAINDIR}}
-\entry{*}{20}{\code {*}}
-\entry{$*}{20}{\code {$*}}
+\entry{*}{21}{\code {*}}
+\entry{$*}{21}{\code {$*}}
\entry{@}{21}{\code {@}}
\entry{$@}{21}{\code {$@}}
\entry{#}{21}{\code {#}}
@@ -19,147 +19,147 @@
\entry{$0}{21}{\code {$0}}
\entry{_}{21}{\code {_}}
\entry{$_}{21}{\code {$_}}
-\entry{CDPATH}{71}{\code {CDPATH}}
-\entry{HOME}{71}{\code {HOME}}
-\entry{IFS}{71}{\code {IFS}}
-\entry{MAIL}{71}{\code {MAIL}}
-\entry{MAILPATH}{71}{\code {MAILPATH}}
-\entry{OPTARG}{71}{\code {OPTARG}}
-\entry{OPTIND}{71}{\code {OPTIND}}
-\entry{PATH}{71}{\code {PATH}}
-\entry{PS1}{71}{\code {PS1}}
-\entry{PS2}{71}{\code {PS2}}
-\entry{BASH}{71}{\code {BASH}}
-\entry{BASHOPTS}{72}{\code {BASHOPTS}}
-\entry{BASHPID}{72}{\code {BASHPID}}
-\entry{BASH_ALIASES}{72}{\code {BASH_ALIASES}}
-\entry{BASH_ARGC}{72}{\code {BASH_ARGC}}
-\entry{BASH_ARGV}{72}{\code {BASH_ARGV}}
-\entry{BASH_ARGV0}{72}{\code {BASH_ARGV0}}
-\entry{BASH_CMDS}{72}{\code {BASH_CMDS}}
-\entry{BASH_COMMAND}{73}{\code {BASH_COMMAND}}
-\entry{BASH_COMPAT}{73}{\code {BASH_COMPAT}}
-\entry{BASH_ENV}{73}{\code {BASH_ENV}}
-\entry{BASH_EXECUTION_STRING}{73}{\code {BASH_EXECUTION_STRING}}
-\entry{BASH_LINENO}{73}{\code {BASH_LINENO}}
-\entry{BASH_LOADABLES_PATH}{73}{\code {BASH_LOADABLES_PATH}}
-\entry{BASH_REMATCH}{73}{\code {BASH_REMATCH}}
-\entry{BASH_SOURCE}{73}{\code {BASH_SOURCE}}
-\entry{BASH_SUBSHELL}{74}{\code {BASH_SUBSHELL}}
-\entry{BASH_VERSINFO}{74}{\code {BASH_VERSINFO}}
-\entry{BASH_VERSION}{74}{\code {BASH_VERSION}}
-\entry{BASH_XTRACEFD}{74}{\code {BASH_XTRACEFD}}
-\entry{CHILD_MAX}{74}{\code {CHILD_MAX}}
-\entry{COLUMNS}{74}{\code {COLUMNS}}
-\entry{COMP_CWORD}{74}{\code {COMP_CWORD}}
-\entry{COMP_LINE}{75}{\code {COMP_LINE}}
-\entry{COMP_POINT}{75}{\code {COMP_POINT}}
-\entry{COMP_TYPE}{75}{\code {COMP_TYPE}}
-\entry{COMP_KEY}{75}{\code {COMP_KEY}}
-\entry{COMP_WORDBREAKS}{75}{\code {COMP_WORDBREAKS}}
-\entry{COMP_WORDS}{75}{\code {COMP_WORDS}}
-\entry{COMPREPLY}{75}{\code {COMPREPLY}}
-\entry{COPROC}{75}{\code {COPROC}}
-\entry{DIRSTACK}{75}{\code {DIRSTACK}}
-\entry{EMACS}{76}{\code {EMACS}}
-\entry{ENV}{76}{\code {ENV}}
-\entry{EPOCHREALTIME}{76}{\code {EPOCHREALTIME}}
-\entry{EPOCHSECONDS}{76}{\code {EPOCHSECONDS}}
-\entry{EUID}{76}{\code {EUID}}
-\entry{EXECIGNORE}{76}{\code {EXECIGNORE}}
-\entry{FCEDIT}{76}{\code {FCEDIT}}
-\entry{FIGNORE}{76}{\code {FIGNORE}}
-\entry{FUNCNAME}{76}{\code {FUNCNAME}}
-\entry{FUNCNEST}{77}{\code {FUNCNEST}}
-\entry{GLOBIGNORE}{77}{\code {GLOBIGNORE}}
-\entry{GROUPS}{77}{\code {GROUPS}}
-\entry{histchars}{77}{\code {histchars}}
-\entry{HISTCMD}{77}{\code {HISTCMD}}
-\entry{HISTCONTROL}{77}{\code {HISTCONTROL}}
-\entry{HISTFILE}{77}{\code {HISTFILE}}
-\entry{HISTFILESIZE}{78}{\code {HISTFILESIZE}}
-\entry{HISTIGNORE}{78}{\code {HISTIGNORE}}
-\entry{HISTSIZE}{78}{\code {HISTSIZE}}
-\entry{HISTTIMEFORMAT}{78}{\code {HISTTIMEFORMAT}}
-\entry{HOSTFILE}{78}{\code {HOSTFILE}}
-\entry{HOSTNAME}{78}{\code {HOSTNAME}}
-\entry{HOSTTYPE}{78}{\code {HOSTTYPE}}
-\entry{IGNOREEOF}{79}{\code {IGNOREEOF}}
-\entry{INPUTRC}{79}{\code {INPUTRC}}
-\entry{LANG}{79}{\code {LANG}}
-\entry{LC_ALL}{79}{\code {LC_ALL}}
-\entry{LC_COLLATE}{79}{\code {LC_COLLATE}}
-\entry{LC_CTYPE}{79}{\code {LC_CTYPE}}
-\entry{LC_MESSAGES}{79}{\code {LC_MESSAGES}}
-\entry{LC_NUMERIC}{79}{\code {LC_NUMERIC}}
-\entry{LC_TIME}{79}{\code {LC_TIME}}
-\entry{LINENO}{79}{\code {LINENO}}
-\entry{LINES}{79}{\code {LINES}}
-\entry{MACHTYPE}{79}{\code {MACHTYPE}}
-\entry{MAILCHECK}{79}{\code {MAILCHECK}}
-\entry{MAPFILE}{79}{\code {MAPFILE}}
-\entry{OLDPWD}{80}{\code {OLDPWD}}
-\entry{OPTERR}{80}{\code {OPTERR}}
-\entry{OSTYPE}{80}{\code {OSTYPE}}
-\entry{PIPESTATUS}{80}{\code {PIPESTATUS}}
-\entry{POSIXLY_CORRECT}{80}{\code {POSIXLY_CORRECT}}
-\entry{PPID}{80}{\code {PPID}}
-\entry{PROMPT_COMMAND}{80}{\code {PROMPT_COMMAND}}
-\entry{PROMPT_DIRTRIM}{80}{\code {PROMPT_DIRTRIM}}
-\entry{PS0}{80}{\code {PS0}}
-\entry{PS3}{80}{\code {PS3}}
-\entry{PS4}{80}{\code {PS4}}
-\entry{PWD}{80}{\code {PWD}}
-\entry{RANDOM}{80}{\code {RANDOM}}
-\entry{READLINE_LINE}{80}{\code {READLINE_LINE}}
-\entry{READLINE_POINT}{81}{\code {READLINE_POINT}}
-\entry{REPLY}{81}{\code {REPLY}}
-\entry{SECONDS}{81}{\code {SECONDS}}
-\entry{SHELL}{81}{\code {SHELL}}
-\entry{SHELLOPTS}{81}{\code {SHELLOPTS}}
-\entry{SHLVL}{81}{\code {SHLVL}}
-\entry{TIMEFORMAT}{81}{\code {TIMEFORMAT}}
-\entry{TMOUT}{82}{\code {TMOUT}}
-\entry{TMPDIR}{82}{\code {TMPDIR}}
-\entry{UID}{82}{\code {UID}}
-\entry{auto_resume}{104}{\code {auto_resume}}
-\entry{bell-style}{109}{\code {bell-style}}
-\entry{bind-tty-special-chars}{109}{\code {bind-tty-special-chars}}
-\entry{blink-matching-paren}{109}{\code {blink-matching-paren}}
-\entry{colored-completion-prefix}{109}{\code {colored-completion-prefix}}
-\entry{colored-stats}{109}{\code {colored-stats}}
-\entry{comment-begin}{109}{\code {comment-begin}}
-\entry{completion-display-width}{109}{\code {completion-display-width}}
-\entry{completion-ignore-case}{110}{\code {completion-ignore-case}}
-\entry{completion-map-case}{110}{\code {completion-map-case}}
-\entry{completion-prefix-display-length}{110}{\code {completion-prefix-display-length}}
-\entry{completion-query-items}{110}{\code {completion-query-items}}
-\entry{convert-meta}{110}{\code {convert-meta}}
-\entry{disable-completion}{110}{\code {disable-completion}}
-\entry{echo-control-characters}{110}{\code {echo-control-characters}}
-\entry{editing-mode}{110}{\code {editing-mode}}
-\entry{emacs-mode-string}{110}{\code {emacs-mode-string}}
-\entry{enable-bracketed-paste}{111}{\code {enable-bracketed-paste}}
-\entry{enable-keypad}{111}{\code {enable-keypad}}
-\entry{expand-tilde}{111}{\code {expand-tilde}}
-\entry{history-preserve-point}{111}{\code {history-preserve-point}}
-\entry{history-size}{111}{\code {history-size}}
-\entry{horizontal-scroll-mode}{111}{\code {horizontal-scroll-mode}}
-\entry{input-meta}{111}{\code {input-meta}}
-\entry{meta-flag}{111}{\code {meta-flag}}
-\entry{isearch-terminators}{112}{\code {isearch-terminators}}
-\entry{keymap}{112}{\code {keymap}}
-\entry{mark-modified-lines}{112}{\code {mark-modified-lines}}
-\entry{mark-symlinked-directories}{112}{\code {mark-symlinked-directories}}
-\entry{match-hidden-files}{112}{\code {match-hidden-files}}
-\entry{menu-complete-display-prefix}{113}{\code {menu-complete-display-prefix}}
-\entry{output-meta}{113}{\code {output-meta}}
-\entry{page-completions}{113}{\code {page-completions}}
-\entry{revert-all-at-newline}{113}{\code {revert-all-at-newline}}
-\entry{show-all-if-ambiguous}{113}{\code {show-all-if-ambiguous}}
-\entry{show-all-if-unmodified}{113}{\code {show-all-if-unmodified}}
-\entry{show-mode-in-prompt}{113}{\code {show-mode-in-prompt}}
-\entry{skip-completed-text}{113}{\code {skip-completed-text}}
-\entry{vi-cmd-mode-string}{114}{\code {vi-cmd-mode-string}}
-\entry{vi-ins-mode-string}{114}{\code {vi-ins-mode-string}}
-\entry{visible-stats}{114}{\code {visible-stats}}
+\entry{CDPATH}{72}{\code {CDPATH}}
+\entry{HOME}{72}{\code {HOME}}
+\entry{IFS}{72}{\code {IFS}}
+\entry{MAIL}{72}{\code {MAIL}}
+\entry{MAILPATH}{72}{\code {MAILPATH}}
+\entry{OPTARG}{72}{\code {OPTARG}}
+\entry{OPTIND}{72}{\code {OPTIND}}
+\entry{PATH}{72}{\code {PATH}}
+\entry{PS1}{72}{\code {PS1}}
+\entry{PS2}{72}{\code {PS2}}
+\entry{BASH}{72}{\code {BASH}}
+\entry{BASHOPTS}{73}{\code {BASHOPTS}}
+\entry{BASHPID}{73}{\code {BASHPID}}
+\entry{BASH_ALIASES}{73}{\code {BASH_ALIASES}}
+\entry{BASH_ARGC}{73}{\code {BASH_ARGC}}
+\entry{BASH_ARGV}{73}{\code {BASH_ARGV}}
+\entry{BASH_ARGV0}{73}{\code {BASH_ARGV0}}
+\entry{BASH_CMDS}{73}{\code {BASH_CMDS}}
+\entry{BASH_COMMAND}{74}{\code {BASH_COMMAND}}
+\entry{BASH_COMPAT}{74}{\code {BASH_COMPAT}}
+\entry{BASH_ENV}{74}{\code {BASH_ENV}}
+\entry{BASH_EXECUTION_STRING}{74}{\code {BASH_EXECUTION_STRING}}
+\entry{BASH_LINENO}{74}{\code {BASH_LINENO}}
+\entry{BASH_LOADABLES_PATH}{74}{\code {BASH_LOADABLES_PATH}}
+\entry{BASH_REMATCH}{74}{\code {BASH_REMATCH}}
+\entry{BASH_SOURCE}{74}{\code {BASH_SOURCE}}
+\entry{BASH_SUBSHELL}{75}{\code {BASH_SUBSHELL}}
+\entry{BASH_VERSINFO}{75}{\code {BASH_VERSINFO}}
+\entry{BASH_VERSION}{75}{\code {BASH_VERSION}}
+\entry{BASH_XTRACEFD}{75}{\code {BASH_XTRACEFD}}
+\entry{CHILD_MAX}{75}{\code {CHILD_MAX}}
+\entry{COLUMNS}{75}{\code {COLUMNS}}
+\entry{COMP_CWORD}{75}{\code {COMP_CWORD}}
+\entry{COMP_LINE}{76}{\code {COMP_LINE}}
+\entry{COMP_POINT}{76}{\code {COMP_POINT}}
+\entry{COMP_TYPE}{76}{\code {COMP_TYPE}}
+\entry{COMP_KEY}{76}{\code {COMP_KEY}}
+\entry{COMP_WORDBREAKS}{76}{\code {COMP_WORDBREAKS}}
+\entry{COMP_WORDS}{76}{\code {COMP_WORDS}}
+\entry{COMPREPLY}{76}{\code {COMPREPLY}}
+\entry{COPROC}{76}{\code {COPROC}}
+\entry{DIRSTACK}{76}{\code {DIRSTACK}}
+\entry{EMACS}{77}{\code {EMACS}}
+\entry{ENV}{77}{\code {ENV}}
+\entry{EPOCHREALTIME}{77}{\code {EPOCHREALTIME}}
+\entry{EPOCHSECONDS}{77}{\code {EPOCHSECONDS}}
+\entry{EUID}{77}{\code {EUID}}
+\entry{EXECIGNORE}{77}{\code {EXECIGNORE}}
+\entry{FCEDIT}{77}{\code {FCEDIT}}
+\entry{FIGNORE}{77}{\code {FIGNORE}}
+\entry{FUNCNAME}{77}{\code {FUNCNAME}}
+\entry{FUNCNEST}{78}{\code {FUNCNEST}}
+\entry{GLOBIGNORE}{78}{\code {GLOBIGNORE}}
+\entry{GROUPS}{78}{\code {GROUPS}}
+\entry{histchars}{78}{\code {histchars}}
+\entry{HISTCMD}{78}{\code {HISTCMD}}
+\entry{HISTCONTROL}{78}{\code {HISTCONTROL}}
+\entry{HISTFILE}{78}{\code {HISTFILE}}
+\entry{HISTFILESIZE}{79}{\code {HISTFILESIZE}}
+\entry{HISTIGNORE}{79}{\code {HISTIGNORE}}
+\entry{HISTSIZE}{79}{\code {HISTSIZE}}
+\entry{HISTTIMEFORMAT}{79}{\code {HISTTIMEFORMAT}}
+\entry{HOSTFILE}{79}{\code {HOSTFILE}}
+\entry{HOSTNAME}{79}{\code {HOSTNAME}}
+\entry{HOSTTYPE}{79}{\code {HOSTTYPE}}
+\entry{IGNOREEOF}{80}{\code {IGNOREEOF}}
+\entry{INPUTRC}{80}{\code {INPUTRC}}
+\entry{LANG}{80}{\code {LANG}}
+\entry{LC_ALL}{80}{\code {LC_ALL}}
+\entry{LC_COLLATE}{80}{\code {LC_COLLATE}}
+\entry{LC_CTYPE}{80}{\code {LC_CTYPE}}
+\entry{LC_MESSAGES}{80}{\code {LC_MESSAGES}}
+\entry{LC_NUMERIC}{80}{\code {LC_NUMERIC}}
+\entry{LC_TIME}{80}{\code {LC_TIME}}
+\entry{LINENO}{80}{\code {LINENO}}
+\entry{LINES}{80}{\code {LINES}}
+\entry{MACHTYPE}{80}{\code {MACHTYPE}}
+\entry{MAILCHECK}{80}{\code {MAILCHECK}}
+\entry{MAPFILE}{80}{\code {MAPFILE}}
+\entry{OLDPWD}{81}{\code {OLDPWD}}
+\entry{OPTERR}{81}{\code {OPTERR}}
+\entry{OSTYPE}{81}{\code {OSTYPE}}
+\entry{PIPESTATUS}{81}{\code {PIPESTATUS}}
+\entry{POSIXLY_CORRECT}{81}{\code {POSIXLY_CORRECT}}
+\entry{PPID}{81}{\code {PPID}}
+\entry{PROMPT_COMMAND}{81}{\code {PROMPT_COMMAND}}
+\entry{PROMPT_DIRTRIM}{81}{\code {PROMPT_DIRTRIM}}
+\entry{PS0}{81}{\code {PS0}}
+\entry{PS3}{81}{\code {PS3}}
+\entry{PS4}{81}{\code {PS4}}
+\entry{PWD}{81}{\code {PWD}}
+\entry{RANDOM}{81}{\code {RANDOM}}
+\entry{READLINE_LINE}{81}{\code {READLINE_LINE}}
+\entry{READLINE_POINT}{82}{\code {READLINE_POINT}}
+\entry{REPLY}{82}{\code {REPLY}}
+\entry{SECONDS}{82}{\code {SECONDS}}
+\entry{SHELL}{82}{\code {SHELL}}
+\entry{SHELLOPTS}{82}{\code {SHELLOPTS}}
+\entry{SHLVL}{82}{\code {SHLVL}}
+\entry{TIMEFORMAT}{82}{\code {TIMEFORMAT}}
+\entry{TMOUT}{83}{\code {TMOUT}}
+\entry{TMPDIR}{83}{\code {TMPDIR}}
+\entry{UID}{83}{\code {UID}}
+\entry{auto_resume}{105}{\code {auto_resume}}
+\entry{bell-style}{110}{\code {bell-style}}
+\entry{bind-tty-special-chars}{110}{\code {bind-tty-special-chars}}
+\entry{blink-matching-paren}{110}{\code {blink-matching-paren}}
+\entry{colored-completion-prefix}{110}{\code {colored-completion-prefix}}
+\entry{colored-stats}{110}{\code {colored-stats}}
+\entry{comment-begin}{110}{\code {comment-begin}}
+\entry{completion-display-width}{110}{\code {completion-display-width}}
+\entry{completion-ignore-case}{111}{\code {completion-ignore-case}}
+\entry{completion-map-case}{111}{\code {completion-map-case}}
+\entry{completion-prefix-display-length}{111}{\code {completion-prefix-display-length}}
+\entry{completion-query-items}{111}{\code {completion-query-items}}
+\entry{convert-meta}{111}{\code {convert-meta}}
+\entry{disable-completion}{111}{\code {disable-completion}}
+\entry{echo-control-characters}{111}{\code {echo-control-characters}}
+\entry{editing-mode}{111}{\code {editing-mode}}
+\entry{emacs-mode-string}{111}{\code {emacs-mode-string}}
+\entry{enable-bracketed-paste}{112}{\code {enable-bracketed-paste}}
+\entry{enable-keypad}{112}{\code {enable-keypad}}
+\entry{expand-tilde}{112}{\code {expand-tilde}}
+\entry{history-preserve-point}{112}{\code {history-preserve-point}}
+\entry{history-size}{112}{\code {history-size}}
+\entry{horizontal-scroll-mode}{112}{\code {horizontal-scroll-mode}}
+\entry{input-meta}{112}{\code {input-meta}}
+\entry{meta-flag}{112}{\code {meta-flag}}
+\entry{isearch-terminators}{113}{\code {isearch-terminators}}
+\entry{keymap}{113}{\code {keymap}}
+\entry{mark-modified-lines}{113}{\code {mark-modified-lines}}
+\entry{mark-symlinked-directories}{113}{\code {mark-symlinked-directories}}
+\entry{match-hidden-files}{113}{\code {match-hidden-files}}
+\entry{menu-complete-display-prefix}{114}{\code {menu-complete-display-prefix}}
+\entry{output-meta}{114}{\code {output-meta}}
+\entry{page-completions}{114}{\code {page-completions}}
+\entry{revert-all-at-newline}{114}{\code {revert-all-at-newline}}
+\entry{show-all-if-ambiguous}{114}{\code {show-all-if-ambiguous}}
+\entry{show-all-if-unmodified}{114}{\code {show-all-if-unmodified}}
+\entry{show-mode-in-prompt}{114}{\code {show-mode-in-prompt}}
+\entry{skip-completed-text}{114}{\code {skip-completed-text}}
+\entry{vi-cmd-mode-string}{115}{\code {vi-cmd-mode-string}}
+\entry{vi-ins-mode-string}{115}{\code {vi-ins-mode-string}}
+\entry{visible-stats}{115}{\code {visible-stats}}
diff --git a/doc/bashref.vrs b/doc/bashref.vrs
index c56f253..44a931a 100644
--- a/doc/bashref.vrs
+++ b/doc/bashref.vrs
@@ -7,14 +7,14 @@
\entry {\code {$!}}{21}
\entry {\code {$#}}{21}
\entry {\code {$$}}{21}
-\entry {\code {$*}}{20}
+\entry {\code {$*}}{21}
\entry {\code {$-}}{21}
\entry {\code {$?}}{21}
\entry {\code {$@}}{21}
\entry {\code {$_}}{21}
\entry {\code {$0}}{21}
\initial {*}
-\entry {\code {*}}{20}
+\entry {\code {*}}{21}
\initial {-}
\entry {\code {-}}{21}
\initial {?}
@@ -26,167 +26,167 @@
\initial {0}
\entry {\code {0}}{21}
\initial {A}
-\entry {\code {auto_resume}}{104}
+\entry {\code {auto_resume}}{105}
\initial {B}
-\entry {\code {BASH}}{71}
-\entry {\code {BASH_ALIASES}}{72}
-\entry {\code {BASH_ARGC}}{72}
-\entry {\code {BASH_ARGV}}{72}
-\entry {\code {BASH_ARGV0}}{72}
-\entry {\code {BASH_CMDS}}{72}
-\entry {\code {BASH_COMMAND}}{73}
-\entry {\code {BASH_COMPAT}}{73}
-\entry {\code {BASH_ENV}}{73}
-\entry {\code {BASH_EXECUTION_STRING}}{73}
-\entry {\code {BASH_LINENO}}{73}
-\entry {\code {BASH_LOADABLES_PATH}}{73}
-\entry {\code {BASH_REMATCH}}{73}
-\entry {\code {BASH_SOURCE}}{73}
-\entry {\code {BASH_SUBSHELL}}{74}
-\entry {\code {BASH_VERSINFO}}{74}
-\entry {\code {BASH_VERSION}}{74}
-\entry {\code {BASH_XTRACEFD}}{74}
-\entry {\code {BASHOPTS}}{72}
-\entry {\code {BASHPID}}{72}
-\entry {\code {bell-style}}{109}
-\entry {\code {bind-tty-special-chars}}{109}
-\entry {\code {blink-matching-paren}}{109}
+\entry {\code {BASH}}{72}
+\entry {\code {BASH_ALIASES}}{73}
+\entry {\code {BASH_ARGC}}{73}
+\entry {\code {BASH_ARGV}}{73}
+\entry {\code {BASH_ARGV0}}{73}
+\entry {\code {BASH_CMDS}}{73}
+\entry {\code {BASH_COMMAND}}{74}
+\entry {\code {BASH_COMPAT}}{74}
+\entry {\code {BASH_ENV}}{74}
+\entry {\code {BASH_EXECUTION_STRING}}{74}
+\entry {\code {BASH_LINENO}}{74}
+\entry {\code {BASH_LOADABLES_PATH}}{74}
+\entry {\code {BASH_REMATCH}}{74}
+\entry {\code {BASH_SOURCE}}{74}
+\entry {\code {BASH_SUBSHELL}}{75}
+\entry {\code {BASH_VERSINFO}}{75}
+\entry {\code {BASH_VERSION}}{75}
+\entry {\code {BASH_XTRACEFD}}{75}
+\entry {\code {BASHOPTS}}{73}
+\entry {\code {BASHPID}}{73}
+\entry {\code {bell-style}}{110}
+\entry {\code {bind-tty-special-chars}}{110}
+\entry {\code {blink-matching-paren}}{110}
\initial {C}
-\entry {\code {CDPATH}}{71}
-\entry {\code {CHILD_MAX}}{74}
-\entry {\code {colored-completion-prefix}}{109}
-\entry {\code {colored-stats}}{109}
-\entry {\code {COLUMNS}}{74}
-\entry {\code {comment-begin}}{109}
-\entry {\code {COMP_CWORD}}{74}
-\entry {\code {COMP_KEY}}{75}
-\entry {\code {COMP_LINE}}{75}
-\entry {\code {COMP_POINT}}{75}
-\entry {\code {COMP_TYPE}}{75}
-\entry {\code {COMP_WORDBREAKS}}{75}
-\entry {\code {COMP_WORDS}}{75}
-\entry {\code {completion-display-width}}{109}
-\entry {\code {completion-ignore-case}}{110}
-\entry {\code {completion-map-case}}{110}
-\entry {\code {completion-prefix-display-length}}{110}
-\entry {\code {completion-query-items}}{110}
-\entry {\code {COMPREPLY}}{75}
-\entry {\code {convert-meta}}{110}
-\entry {\code {COPROC}}{75}
+\entry {\code {CDPATH}}{72}
+\entry {\code {CHILD_MAX}}{75}
+\entry {\code {colored-completion-prefix}}{110}
+\entry {\code {colored-stats}}{110}
+\entry {\code {COLUMNS}}{75}
+\entry {\code {comment-begin}}{110}
+\entry {\code {COMP_CWORD}}{75}
+\entry {\code {COMP_KEY}}{76}
+\entry {\code {COMP_LINE}}{76}
+\entry {\code {COMP_POINT}}{76}
+\entry {\code {COMP_TYPE}}{76}
+\entry {\code {COMP_WORDBREAKS}}{76}
+\entry {\code {COMP_WORDS}}{76}
+\entry {\code {completion-display-width}}{110}
+\entry {\code {completion-ignore-case}}{111}
+\entry {\code {completion-map-case}}{111}
+\entry {\code {completion-prefix-display-length}}{111}
+\entry {\code {completion-query-items}}{111}
+\entry {\code {COMPREPLY}}{76}
+\entry {\code {convert-meta}}{111}
+\entry {\code {COPROC}}{76}
\initial {D}
-\entry {\code {DIRSTACK}}{75}
-\entry {\code {disable-completion}}{110}
+\entry {\code {DIRSTACK}}{76}
+\entry {\code {disable-completion}}{111}
\initial {E}
-\entry {\code {echo-control-characters}}{110}
-\entry {\code {editing-mode}}{110}
-\entry {\code {emacs-mode-string}}{110}
-\entry {\code {EMACS}}{76}
-\entry {\code {enable-bracketed-paste}}{111}
-\entry {\code {enable-keypad}}{111}
-\entry {\code {ENV}}{76}
-\entry {\code {EPOCHREALTIME}}{76}
-\entry {\code {EPOCHSECONDS}}{76}
-\entry {\code {EUID}}{76}
-\entry {\code {EXECIGNORE}}{76}
-\entry {\code {expand-tilde}}{111}
+\entry {\code {echo-control-characters}}{111}
+\entry {\code {editing-mode}}{111}
+\entry {\code {emacs-mode-string}}{111}
+\entry {\code {EMACS}}{77}
+\entry {\code {enable-bracketed-paste}}{112}
+\entry {\code {enable-keypad}}{112}
+\entry {\code {ENV}}{77}
+\entry {\code {EPOCHREALTIME}}{77}
+\entry {\code {EPOCHSECONDS}}{77}
+\entry {\code {EUID}}{77}
+\entry {\code {EXECIGNORE}}{77}
+\entry {\code {expand-tilde}}{112}
\initial {F}
-\entry {\code {FCEDIT}}{76}
-\entry {\code {FIGNORE}}{76}
-\entry {\code {FUNCNAME}}{76}
-\entry {\code {FUNCNEST}}{77}
+\entry {\code {FCEDIT}}{77}
+\entry {\code {FIGNORE}}{77}
+\entry {\code {FUNCNAME}}{77}
+\entry {\code {FUNCNEST}}{78}
\initial {G}
-\entry {\code {GLOBIGNORE}}{77}
-\entry {\code {GROUPS}}{77}
+\entry {\code {GLOBIGNORE}}{78}
+\entry {\code {GROUPS}}{78}
\initial {H}
-\entry {\code {histchars}}{77}
-\entry {\code {HISTCMD}}{77}
-\entry {\code {HISTCONTROL}}{77}
-\entry {\code {HISTFILE}}{77}
-\entry {\code {HISTFILESIZE}}{78}
-\entry {\code {HISTIGNORE}}{78}
-\entry {\code {history-preserve-point}}{111}
-\entry {\code {history-size}}{111}
-\entry {\code {HISTSIZE}}{78}
-\entry {\code {HISTTIMEFORMAT}}{78}
-\entry {\code {HOME}}{71}
-\entry {\code {horizontal-scroll-mode}}{111}
-\entry {\code {HOSTFILE}}{78}
-\entry {\code {HOSTNAME}}{78}
-\entry {\code {HOSTTYPE}}{78}
+\entry {\code {histchars}}{78}
+\entry {\code {HISTCMD}}{78}
+\entry {\code {HISTCONTROL}}{78}
+\entry {\code {HISTFILE}}{78}
+\entry {\code {HISTFILESIZE}}{79}
+\entry {\code {HISTIGNORE}}{79}
+\entry {\code {history-preserve-point}}{112}
+\entry {\code {history-size}}{112}
+\entry {\code {HISTSIZE}}{79}
+\entry {\code {HISTTIMEFORMAT}}{79}
+\entry {\code {HOME}}{72}
+\entry {\code {horizontal-scroll-mode}}{112}
+\entry {\code {HOSTFILE}}{79}
+\entry {\code {HOSTNAME}}{79}
+\entry {\code {HOSTTYPE}}{79}
\initial {I}
-\entry {\code {IFS}}{71}
-\entry {\code {IGNOREEOF}}{79}
-\entry {\code {input-meta}}{111}
-\entry {\code {INPUTRC}}{79}
-\entry {\code {isearch-terminators}}{112}
+\entry {\code {IFS}}{72}
+\entry {\code {IGNOREEOF}}{80}
+\entry {\code {input-meta}}{112}
+\entry {\code {INPUTRC}}{80}
+\entry {\code {isearch-terminators}}{113}
\initial {K}
-\entry {\code {keymap}}{112}
+\entry {\code {keymap}}{113}
\initial {L}
-\entry {\code {LANG}}{79}
-\entry {\code {LC_ALL}}{79}
-\entry {\code {LC_COLLATE}}{79}
-\entry {\code {LC_CTYPE}}{79}
-\entry {\code {LC_MESSAGES}}{7, 79}
-\entry {\code {LC_NUMERIC}}{79}
-\entry {\code {LC_TIME}}{79}
-\entry {\code {LINENO}}{79}
-\entry {\code {LINES}}{79}
+\entry {\code {LANG}}{80}
+\entry {\code {LC_ALL}}{80}
+\entry {\code {LC_COLLATE}}{80}
+\entry {\code {LC_CTYPE}}{80}
+\entry {\code {LC_MESSAGES}}{7, 80}
+\entry {\code {LC_NUMERIC}}{80}
+\entry {\code {LC_TIME}}{80}
+\entry {\code {LINENO}}{80}
+\entry {\code {LINES}}{80}
\initial {M}
-\entry {\code {MACHTYPE}}{79}
-\entry {\code {MAIL}}{71}
-\entry {\code {MAILCHECK}}{79}
-\entry {\code {MAILPATH}}{71}
-\entry {\code {MAPFILE}}{79}
-\entry {\code {mark-modified-lines}}{112}
-\entry {\code {mark-symlinked-directories}}{112}
-\entry {\code {match-hidden-files}}{112}
-\entry {\code {menu-complete-display-prefix}}{113}
-\entry {\code {meta-flag}}{111}
+\entry {\code {MACHTYPE}}{80}
+\entry {\code {MAIL}}{72}
+\entry {\code {MAILCHECK}}{80}
+\entry {\code {MAILPATH}}{72}
+\entry {\code {MAPFILE}}{80}
+\entry {\code {mark-modified-lines}}{113}
+\entry {\code {mark-symlinked-directories}}{113}
+\entry {\code {match-hidden-files}}{113}
+\entry {\code {menu-complete-display-prefix}}{114}
+\entry {\code {meta-flag}}{112}
\initial {O}
-\entry {\code {OLDPWD}}{80}
-\entry {\code {OPTARG}}{71}
-\entry {\code {OPTERR}}{80}
-\entry {\code {OPTIND}}{71}
-\entry {\code {OSTYPE}}{80}
-\entry {\code {output-meta}}{113}
+\entry {\code {OLDPWD}}{81}
+\entry {\code {OPTARG}}{72}
+\entry {\code {OPTERR}}{81}
+\entry {\code {OPTIND}}{72}
+\entry {\code {OSTYPE}}{81}
+\entry {\code {output-meta}}{114}
\initial {P}
-\entry {\code {page-completions}}{113}
-\entry {\code {PATH}}{71}
-\entry {\code {PIPESTATUS}}{80}
-\entry {\code {POSIXLY_CORRECT}}{80}
-\entry {\code {PPID}}{80}
-\entry {\code {PROMPT_COMMAND}}{80}
-\entry {\code {PROMPT_DIRTRIM}}{80}
-\entry {\code {PS0}}{80}
-\entry {\code {PS1}}{71}
-\entry {\code {PS2}}{71}
-\entry {\code {PS3}}{80}
-\entry {\code {PS4}}{80}
-\entry {\code {PWD}}{80}
+\entry {\code {page-completions}}{114}
+\entry {\code {PATH}}{72}
+\entry {\code {PIPESTATUS}}{81}
+\entry {\code {POSIXLY_CORRECT}}{81}
+\entry {\code {PPID}}{81}
+\entry {\code {PROMPT_COMMAND}}{81}
+\entry {\code {PROMPT_DIRTRIM}}{81}
+\entry {\code {PS0}}{81}
+\entry {\code {PS1}}{72}
+\entry {\code {PS2}}{72}
+\entry {\code {PS3}}{81}
+\entry {\code {PS4}}{81}
+\entry {\code {PWD}}{81}
\initial {R}
-\entry {\code {RANDOM}}{80}
-\entry {\code {READLINE_LINE}}{80}
-\entry {\code {READLINE_POINT}}{81}
-\entry {\code {REPLY}}{81}
-\entry {\code {revert-all-at-newline}}{113}
+\entry {\code {RANDOM}}{81}
+\entry {\code {READLINE_LINE}}{81}
+\entry {\code {READLINE_POINT}}{82}
+\entry {\code {REPLY}}{82}
+\entry {\code {revert-all-at-newline}}{114}
\initial {S}
-\entry {\code {SECONDS}}{81}
-\entry {\code {SHELL}}{81}
-\entry {\code {SHELLOPTS}}{81}
-\entry {\code {SHLVL}}{81}
-\entry {\code {show-all-if-ambiguous}}{113}
-\entry {\code {show-all-if-unmodified}}{113}
-\entry {\code {show-mode-in-prompt}}{113}
-\entry {\code {skip-completed-text}}{113}
+\entry {\code {SECONDS}}{82}
+\entry {\code {SHELL}}{82}
+\entry {\code {SHELLOPTS}}{82}
+\entry {\code {SHLVL}}{82}
+\entry {\code {show-all-if-ambiguous}}{114}
+\entry {\code {show-all-if-unmodified}}{114}
+\entry {\code {show-mode-in-prompt}}{114}
+\entry {\code {skip-completed-text}}{114}
\initial {T}
\entry {\code {TEXTDOMAIN}}{7}
\entry {\code {TEXTDOMAINDIR}}{7}
-\entry {\code {TIMEFORMAT}}{81}
-\entry {\code {TMOUT}}{82}
-\entry {\code {TMPDIR}}{82}
+\entry {\code {TIMEFORMAT}}{82}
+\entry {\code {TMOUT}}{83}
+\entry {\code {TMPDIR}}{83}
\initial {U}
-\entry {\code {UID}}{82}
+\entry {\code {UID}}{83}
\initial {V}
-\entry {\code {vi-cmd-mode-string}}{114}
-\entry {\code {vi-ins-mode-string}}{114}
-\entry {\code {visible-stats}}{114}
+\entry {\code {vi-cmd-mode-string}}{115}
+\entry {\code {vi-ins-mode-string}}{115}
+\entry {\code {visible-stats}}{115}
diff --git a/subst.c b/subst.c
index a574db4..a6c7876 100644
--- a/subst.c
+++ b/subst.c
@@ -210,6 +210,7 @@ static int glob_argv_flags_size;
static WORD_LIST *cached_quoted_dollar_at = 0;
+/* Distinguished error values to return from expansion functions */
static WORD_LIST expand_word_error, expand_word_fatal;
static WORD_DESC expand_wdesc_error, expand_wdesc_fatal;
static char expand_param_error, expand_param_fatal, expand_param_unset;
@@ -298,7 +299,7 @@ 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 *parameter_brace_transform __P((char *, char *, int, char *, int, int, int, int));
static char *process_substitute __P((char *, int));
@@ -325,7 +326,7 @@ static char *skiparith __P((char *, int));
static int verify_substring_values __P((SHELL_VAR *, char *, char *, int, intmax_t *, intmax_t *));
static int get_var_and_type __P((char *, char *, arrayind_t, int, int, SHELL_VAR **, char **));
static char *mb_substring __P((char *, int, int));
-static char *parameter_brace_substring __P((char *, char *, int, char *, int, int));
+static char *parameter_brace_substring __P((char *, char *, int, char *, int, int, int));
static int shouldexp_replacement __P((char *));
@@ -334,7 +335,7 @@ static char *pos_params_pat_subst __P((char *, char *, char *, int));
static char *parameter_brace_patsub __P((char *, char *, int, char *, int, int, int));
static char *pos_params_casemod __P((char *, char *, int, int));
-static char *parameter_brace_casemod __P((char *, char *, int, int, char *, int, int));
+static char *parameter_brace_casemod __P((char *, char *, int, int, char *, int, int, int));
static WORD_DESC *parameter_brace_expand __P((char *, int *, int, int, int *, int *));
static WORD_DESC *param_expand __P((char *, int *, int, int *, int *, int *, int *, int));
@@ -796,12 +797,12 @@ string_extract (string, sindex, charlist, flags)
break;
}
#if defined (ARRAY_VARS)
- else if ((flags & SX_VARNAME) && c == '[')
+ else if ((flags & SX_VARNAME) && c == LBRACK)
{
int ni;
/* If this is an array subscript, skip over it and continue. */
ni = skipsubscript (string, i, 0);
- if (string[ni] == ']')
+ if (string[ni] == RBRACK)
i = ni;
}
#endif
@@ -878,16 +879,16 @@ string_extract_double_quoted (string, sindex, flags)
and want to strip these backslashes only if DQUOTE is non-zero,
indicating that we are inside an embedded double-quoted string. */
- /* If we are in an embedded quoted string, then don't strip
- backslashes before characters for which the backslash
- retains its special meaning, but remove backslashes in
- front of other characters. If we are not in an
- embedded quoted string, don't strip backslashes at all.
- This mess is necessary because the string was already
- surrounded by double quotes (and sh has some really weird
- quoting rules).
- The returned string will be run through expansion as if
- it were double-quoted. */
+ /* If we are in an embedded quoted string, then don't strip
+ backslashes before characters for which the backslash
+ retains its special meaning, but remove backslashes in
+ front of other characters. If we are not in an
+ embedded quoted string, don't strip backslashes at all.
+ This mess is necessary because the string was already
+ surrounded by double quotes (and sh has some really weird
+ quoting rules).
+ The returned string will be run through expansion as if
+ it were double-quoted. */
if ((stripdq == 0 && c != '"') ||
(stripdq && ((dquote && (sh_syntaxtab[c] & CBSDQUOTE)) || dquote == 0)))
temp[j++] = '\\';
@@ -916,7 +917,7 @@ add_one_character:
{
if (c == '`')
backquote = 0;
- temp[j++] = c;
+ temp[j++] = c; /* COPY_CHAR_I? */
i++;
continue;
}
@@ -952,6 +953,7 @@ add_one_character:
ret = string + i + 2;
}
+ /* XXX - CHECK_STRING_OVERRUN here? */
for (t = 0; ret[t]; t++, j++)
temp[j] = ret[t];
temp[j] = string[si];
@@ -1147,11 +1149,6 @@ string_extract_verbatim (string, slen, sindex, charlist, flags)
}
i = *sindex;
-#if 0
- /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need
- this only if MB_CUR_MAX > 1. */
- slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 1;
-#endif
#if defined (HANDLE_MULTIBYTE)
clen = strlen (charlist);
wcharlist = 0;
@@ -1267,6 +1264,7 @@ extract_process_subst (string, starter, sindex, xflags)
int xflags;
{
#if 0
+ /* XXX - check xflags&SX_COMPLETE here? */
return (extract_delimited_string (string, sindex, starter, "(", ")", SX_COMMAND));
#else
xflags |= (no_longjmp_on_fatal_error ? SX_NOLONGJMP : 0);
@@ -1287,8 +1285,8 @@ extract_array_assignment_list (string, sindex)
int slen;
char *ret;
- slen = strlen (string); /* ( */
- if (string[slen - 1] == ')')
+ slen = strlen (string);
+ if (string[slen - 1] == RPAREN)
{
ret = substring (string, *sindex, slen - 1);
*sindex = slen - 1;
@@ -1477,8 +1475,6 @@ extract_delimited_string (string, sindex, opener, alt_opener, closer, flags)
it should point to just after the first `{' found. On exit, SINDEX
gets the position of the matching `}'. QUOTED is non-zero if this
occurs inside double quotes. */
-/* XXX -- should this use skipsubscript to handle ${word[sub]}? (only do it
- if dolbrace_state == DOLBRACE_PARAM) */
/* XXX -- this is very similar to extract_delimited_string -- XXX */
static char *
extract_dollar_brace_string (string, sindex, quoted, flags)
@@ -1602,11 +1598,11 @@ extract_dollar_brace_string (string, sindex, quoted, flags)
#if defined (ARRAY_VARS)
/* XXX - bash-5.0 */
- if (c == '[' && dolbrace_state == DOLBRACE_PARAM)
+ if (c == LBRACK && dolbrace_state == DOLBRACE_PARAM)
{
si = skipsubscript (string, i, 0);
CHECK_STRING_OVERRUN (i, si, slen, c);
- if (string[si] == ']')
+ if (string[si] == RBRACK)
c = string[i = si];
}
#endif
@@ -1792,6 +1788,7 @@ skip_matched_pair (string, start, open, close, flags)
if (string[si] == '\0')
CQ_RETURN(si);
+ /* XXX - extract_command_subst here? */
if (string[i+1] == LPAREN)
temp = extract_delimited_string (ss, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
else
@@ -1952,12 +1949,8 @@ skip_to_delim (string, start, delims, flags)
si = i + 2;
if (string[si] == '\0')
CQ_RETURN(si);
-#if 1
+
temp = extract_delimited_string (string, &si, (c == '<') ? "<(" : ">(", "(", ")", SX_COMMAND|SX_NOALLOC); /* )) */
-#else
- temp = extract_process_subst (string, (c == '<') ? "<(" : ">(", &si, 0);
- free (temp); /* XXX - not using SX_NOALLOC here yet */
-#endif
CHECK_STRING_OVERRUN (i, si, slen, c);
i = si;
if (string[i] == '\0')
@@ -2247,7 +2240,7 @@ unclosed_pair (string, eindex, openstr)
rules. SENTINEL is an index to look for. NWP, if non-NULL,
gets the number of words in the returned list. CWP, if non-NULL, gets
the index of the word containing SENTINEL. Non-whitespace chars in
- DELIMS delimit separate fields. */
+ DELIMS delimit separate fields. This is used by programmable completion. */
WORD_LIST *
split_at_delims (string, slen, delims, sentinel, flags, nwp, cwp)
char *string;
@@ -2646,11 +2639,11 @@ string_list_dollar_at (list, quoted, flags)
sep[0] = ' ';
sep[1] = '\0';
}
-#else
+#else /* !HANDLE_MULTIBYTE */
/* XXX - bash-4.4/bash-5.0 test PF_ASSIGNRHS */
sep[0] = ((flags & PF_ASSIGNRHS) || ifs == 0 || *ifs == 0) ? ' ' : *ifs;
sep[1] = '\0';
-#endif
+#endif /* !HANDLE_MULTIBYTE */
/* XXX -- why call quote_list if ifs == 0? we can get away without doing
it now that quote_escapes quotes spaces */
@@ -2691,9 +2684,7 @@ string_list_pos_params (pchar, list, quoted)
ret = string_list (tlist);
}
else if (pchar == '*' && quoted == 0 && ifs_is_null) /* XXX */
- {
- ret = string_list_dollar_at (list, quoted, 0); /* Posix interp 888 */
- }
+ ret = string_list_dollar_at (list, quoted, 0); /* Posix interp 888 */
else if (pchar == '*')
{
/* Even when unquoted, string_list_dollar_star does the right thing
@@ -2711,9 +2702,7 @@ string_list_pos_params (pchar, list, quoted)
later splitting. */
ret = string_list_dollar_at (list, quoted, 0);
else if (pchar == '@' && quoted == 0 && ifs_is_null) /* XXX */
- {
- ret = string_list_dollar_at (list, quoted, 0); /* Posix interp 888 */
- }
+ ret = string_list_dollar_at (list, quoted, 0); /* Posix interp 888 */
else if (pchar == '@')
ret = string_list_dollar_star (list);
else
@@ -3203,7 +3192,7 @@ do_assignment_internal (word, expand)
aflags |= ASS_APPEND;
#if defined (ARRAY_VARS)
- if (t = mbschr (name, '[')) /*]*/
+ if (t = mbschr (name, LBRACK))
{
if (assign_list)
{
@@ -3396,7 +3385,6 @@ pos_params (string, start, end, quoted)
t = params;
params = params->next;
}
-
t->next = (WORD_LIST *)NULL;
ret = string_list_pos_params (string[0], h, quoted);
@@ -3869,6 +3857,8 @@ expand_string_for_rhs (string, quoted, op, dollar_at_p, expanded_p)
/* This was further clarified on the austin-group list in March, 2017 and
in Posix bug 1129 */
expand_no_split_dollar_star = (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || op == '=' || ifs_is_null == 0; /* XXX - was 1 */
+ /* You'd think Posix specifies W_ASSIGNRHS, but it results in tilde expansion
+ after `=' and `:' the rhs of ${param=word} */
td.flags = W_NOSPLIT2; /* no splitting, remove "" and '' */
td.word = string;
tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, expanded_p);
@@ -3918,6 +3908,77 @@ expand_string (string, quoted)
return (result ? dequote_list (result) : result);
}
+/*******************************************
+ * *
+ * Functions to expand WORD_DESCs *
+ * *
+ *******************************************/
+
+/* Expand WORD, performing word splitting on the result. This does
+ parameter expansion, command substitution, arithmetic expansion,
+ word splitting, and quote removal. */
+
+WORD_LIST *
+expand_word (word, quoted)
+ WORD_DESC *word;
+ int quoted;
+{
+ WORD_LIST *result, *tresult;
+
+ tresult = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
+ result = word_list_split (tresult);
+ dispose_words (tresult);
+ return (result ? dequote_list (result) : result);
+}
+
+/* Expand WORD, but do not perform word splitting on the result. This
+ does parameter expansion, command substitution, arithmetic expansion,
+ and quote removal. */
+WORD_LIST *
+expand_word_unsplit (word, quoted)
+ WORD_DESC *word;
+ int quoted;
+{
+ WORD_LIST *result;
+
+ expand_no_split_dollar_star = 1;
+#if defined (HANDLE_MULTIBYTE)
+ if (ifs_firstc[0] == 0)
+#else
+ if (ifs_firstc == 0)
+#endif
+ word->flags |= W_NOSPLIT;
+ word->flags |= W_NOSPLIT2;
+ result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
+ expand_no_split_dollar_star = 0;
+
+ return (result ? dequote_list (result) : result);
+}
+
+/* Perform shell expansions on WORD, but do not perform word splitting or
+ quote removal on the result. Virtually identical to expand_word_unsplit;
+ could be combined if implementations don't diverge. */
+WORD_LIST *
+expand_word_leave_quoted (word, quoted)
+ WORD_DESC *word;
+ int quoted;
+{
+ WORD_LIST *result;
+
+ expand_no_split_dollar_star = 1;
+#if defined (HANDLE_MULTIBYTE)
+ if (ifs_firstc[0] == 0)
+#else
+ if (ifs_firstc == 0)
+#endif
+ word->flags |= W_NOSPLIT;
+ word->flags |= W_NOSPLIT2;
+ result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
+ expand_no_split_dollar_star = 0;
+
+ return result;
+}
+
/***************************************************
* *
* Functions to handle quoting chars *
@@ -4128,7 +4189,7 @@ dequote_string (string)
internal_inform ("dequote_string: string with bare CTLESC");
#endif
- slen = strlen (string);
+ slen = STRLEN (string);
t = result = (char *)xmalloc (slen + 1);
@@ -4284,7 +4345,8 @@ remove_quoted_nulls (string)
point -- what if a CTLNUL has already been removed from the
string? We don't want to drop the CTLESC or recopy characters
that we've already copied down. */
- i++; string[j++] = CTLESC;
+ i++;
+ string[j++] = CTLESC;
if (i == slen)
break;
}
@@ -4295,7 +4357,7 @@ remove_quoted_nulls (string)
}
prev_i = i;
- ADVANCE_CHAR (string, slen, i);
+ ADVANCE_CHAR (string, slen, i); /* COPY_CHAR_I? */
if (j < prev_i)
{
do string[j++] = string[prev_i++]; while (prev_i < i);
@@ -4330,7 +4392,7 @@ word_list_remove_quoted_nulls (list)
/* **************************************************************** */
#if defined (HANDLE_MULTIBYTE)
-#if 0 /* Currently unused */
+# ifdef INCLUDE_UNUSED
static unsigned char *
mb_getcharlens (string, len)
char *string;
@@ -4353,7 +4415,7 @@ mb_getcharlens (string, len)
}
return ret;
}
-#endif
+# endif
#endif
/* Remove the portion of PARAM matched by PATTERN according to OP, where OP
@@ -5169,357 +5231,6 @@ 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 + MAX_ATTRIBUTES);
- 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;
- }
- else
- {
- ret = (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) ? quote_string (val) : quote_escapes (val);
- free (val);
- val = ret;
- }
- 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, 0, &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, *oname;
- SHELL_VAR *v;
-
- xc = xform[0];
- if (value == 0 && xc != 'A' && xc != 'a')
- return ((char *)NULL);
-
- oname = this_command_name;
- this_command_name = varname;
-
- vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
- if (vtype == -1)
- {
- this_command_name = oname;
- 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:
- this_command_name = oname;
- 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 == 0 && ifs_is_null)
- {
- /* Posix interp 888 */
- }
- else if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
- {
- val = quote_escapes (temp1);
- free (temp1);
- temp1 = val;
- }
- break;
- }
-
- this_command_name = oname;
- return temp1;
-}
-
-/*******************************************
- * *
- * Functions to expand WORD_DESCs *
- * *
- *******************************************/
-
-/* Expand WORD, performing word splitting on the result. This does
- parameter expansion, command substitution, arithmetic expansion,
- word splitting, and quote removal. */
-
-WORD_LIST *
-expand_word (word, quoted)
- WORD_DESC *word;
- int quoted;
-{
- WORD_LIST *result, *tresult;
-
- tresult = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
- result = word_list_split (tresult);
- dispose_words (tresult);
- return (result ? dequote_list (result) : result);
-}
-
-/* Expand WORD, but do not perform word splitting on the result. This
- does parameter expansion, command substitution, arithmetic expansion,
- and quote removal. */
-WORD_LIST *
-expand_word_unsplit (word, quoted)
- WORD_DESC *word;
- int quoted;
-{
- WORD_LIST *result;
-
- expand_no_split_dollar_star = 1;
-#if defined (HANDLE_MULTIBYTE)
- if (ifs_firstc[0] == 0)
-#else
- if (ifs_firstc == 0)
-#endif
- word->flags |= W_NOSPLIT;
- word->flags |= W_NOSPLIT2;
- result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
- expand_no_split_dollar_star = 0;
-
- return (result ? dequote_list (result) : result);
-}
-
-/* Perform shell expansions on WORD, but do not perform word splitting or
- quote removal on the result. Virtually identical to expand_word_unsplit;
- could be combined if implementations don't diverge. */
-WORD_LIST *
-expand_word_leave_quoted (word, quoted)
- WORD_DESC *word;
- int quoted;
-{
- WORD_LIST *result;
-
- expand_no_split_dollar_star = 1;
-#if defined (HANDLE_MULTIBYTE)
- if (ifs_firstc[0] == 0)
-#else
- if (ifs_firstc == 0)
-#endif
- word->flags |= W_NOSPLIT;
- word->flags |= W_NOSPLIT2;
- result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
- expand_no_split_dollar_star = 0;
-
- return result;
-}
-
#if defined (PROCESS_SUBSTITUTION)
/*****************************************************************/
@@ -5929,6 +5640,10 @@ process_substitute (string, open_for_read_in_child)
setup_async_signals ();
subshell_environment |= SUBSHELL_COMSUB|SUBSHELL_PROCSUB;
+ /* We don't inherit the verbose option for command substitutions now, so
+ let's try it for process substitutions. */
+ change_flag ('v', FLAG_OFF);
+
/* if we're expanding a redirection, we shouldn't have access to the
temporary environment, but commands in the subshell should have
access to their own temporary environment. */
@@ -6498,7 +6213,7 @@ array_length_reference (s)
array = array_p (var) ? array_cell (var) : (ARRAY *)NULL;
h = assoc_p (var) ? assoc_cell (var) : (HASH_TABLE *)NULL;
- if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
+ if (ALL_ELEMENT_SUB (t[0]) && t[1] == RBRACK)
{
if (assoc_p (var))
return (h ? assoc_num_elements (h) : 0);
@@ -6512,7 +6227,7 @@ array_length_reference (s)
{
t[len - 1] = '\0';
akey = expand_assignment_string_to_string (t, 0); /* [ */
- t[len - 1] = ']';
+ t[len - 1] = RBRACK;
if (akey == 0 || *akey == 0)
{
err_badarraysub (t);
@@ -6600,18 +6315,18 @@ chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at)
#if defined (ARRAY_VARS)
else if (valid_array_reference (name, 0))
{
- temp1 = mbschr (name, '[');
- if (temp1 && temp1[1] == '@' && temp1[2] == ']')
+ temp1 = mbschr (name, LBRACK);
+ if (temp1 && temp1[1] == '@' && temp1[2] == RBRACK)
{
if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
*quoted_dollar_atp = 1;
if (contains_dollar_at)
*contains_dollar_at = 1;
return 1;
- } /* [ */
+ }
/* ${array[*]}, when unquoted, should be treated like ${array[@]},
which should result in separate words even when IFS is unset. */
- if (temp1 && temp1[1] == '*' && temp1[2] == ']' && quoted == 0)
+ if (temp1 && temp1[1] == '*' && temp1[2] == RBRACK && quoted == 0)
{
if (contains_dollar_at)
*contains_dollar_at = 1;
@@ -6623,7 +6338,7 @@ chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at)
}
/* Parameter expand NAME, and return a new string which is the expansion,
- or NULL if there was no expansion.
+ or NULL if there was no expansion. NAME is as given in ${NAMEcWORD}.
VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
NAME was found inside of a double-quoted expression. */
@@ -6676,8 +6391,8 @@ parameter_brace_expand_word (name, var_is_special, quoted, pflags, indp)
expand_arrayref:
var = array_variable_part (name, 0, &tt, (int *)0);
if (pflags & PF_ASSIGNRHS)
- { /* [ */
- if (ALL_ELEMENT_SUB (tt[0]) && tt[1] == ']')
+ {
+ if (ALL_ELEMENT_SUB (tt[0]) && tt[1] == RBRACK)
{
/* Only treat as double quoted if array variable */
if (var && (array_p (var) || assoc_p (var)))
@@ -6688,8 +6403,8 @@ expand_arrayref:
}
else
temp = array_value (name, quoted, 0, &atype, &ind);
- } /* [ */
- else if (tt[0] == '*' && tt[1] == ']' && expand_no_split_dollar_star && ifs_is_null)
+ }
+ else if (tt[0] == '*' && tt[1] == RBRACK && expand_no_split_dollar_star && ifs_is_null)
temp = array_value (name, Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT, 0, &atype, &ind);
else
temp = array_value (name, quoted, 0, &atype, &ind);
@@ -6905,7 +6620,6 @@ parameter_brace_expand_rhs (name, value, op, quoted, pflags, qdollaratp, hasdoll
w = alloc_word_desc ();
l_hasdollat = 0;
- /* XXX was 0 not quoted */
l = *temp ? expand_string_for_rhs (temp, quoted, op, &l_hasdollat, (int *)NULL)
: (WORD_LIST *)0;
if (hasdollarat)
@@ -7216,7 +6930,7 @@ verify_substring_values (v, value, substr, vtype, e1p, e2p)
t = (char *)0;
temp1 = expand_arith_string (substr, Q_DOUBLE_QUOTES);
- *e1p = evalexp (temp1, 0, &expok);
+ *e1p = evalexp (temp1, 0, &expok); /* XXX - EXP_EXPANDED? */
free (temp1);
if (expok == 0)
return (0);
@@ -7274,15 +6988,17 @@ verify_substring_values (v, value, substr, vtype, e1p, e2p)
temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES);
free (temp2);
t[-1] = ':';
- *e2p = evalexp (temp1, 0, &expok);
+ *e2p = evalexp (temp1, 0, &expok); /* XXX - EXP_EXPANDED? */
free (temp1);
if (expok == 0)
return (0);
+
+ /* Should we allow positional parameter length < 0 to count backwards
+ from end of positional parameters? */
#if 1
if ((vtype == VT_ARRAYVAR || vtype == VT_POSPARMS) && *e2p < 0)
#else
- /* bash-4.3: allow positional parameter length < 0 to count backwards
- from end of positional parameters */
+ /* XXX - bash-5.0 */
if (vtype == VT_ARRAYVAR && *e2p < 0)
#endif
{
@@ -7378,8 +7094,8 @@ get_var_and_type (varname, value, ind, quoted, flags, varp, valp)
*valp = (char *)NULL;
}
if (v && (array_p (v) || assoc_p (v)))
- { /* [ */
- if (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']')
+ {
+ if (ALL_ELEMENT_SUB (temp[0]) && temp[1] == RBRACK)
{
/* Callers have to differentiate between indexed and associative */
vtype = VT_ARRAYVAR;
@@ -7394,7 +7110,7 @@ get_var_and_type (varname, value, ind, quoted, flags, varp, valp)
}
*varp = v;
}
- else if (v && (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']'))
+ else if (v && (ALL_ELEMENT_SUB (temp[0]) && temp[1] == RBRACK))
{
vtype = VT_VARIABLE;
*varp = v;
@@ -7437,6 +7153,292 @@ get_var_and_type (varname, value, ind, quoted, flags, varp, valp)
return vtype;
}
+/***********************************************************/
+/* */
+/* Functions to perform transformations on variable values */
+/* */
+/***********************************************************/
+
+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 + MAX_ATTRIBUTES);
+ 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] = LPAREN;
+ val[1] = RPAREN;
+ val[2] = 0;
+ }
+ else
+ {
+ ret = (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) ? quote_string (val) : quote_escapes (val);
+ free (val);
+ val = ret;
+ }
+ 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, 0, &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, pflags, flags)
+ char *varname, *value;
+ int ind;
+ char *xform;
+ int rtype, quoted, pflags, flags;
+{
+ int vtype, xc;
+ char *temp1, *val, *oname;
+ SHELL_VAR *v;
+
+ xc = xform[0];
+ if (value == 0 && xc != 'A' && xc != 'a')
+ return ((char *)NULL);
+
+ oname = this_command_name;
+ this_command_name = varname;
+
+ vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
+ if (vtype == -1)
+ {
+ this_command_name = oname;
+ 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:
+ this_command_name = oname;
+ 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 == 0 && ifs_is_null)
+ {
+ /* Posix interp 888 */
+ }
+ else if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
+ {
+ val = quote_escapes (temp1);
+ free (temp1);
+ temp1 = val;
+ }
+ break;
+ }
+
+ this_command_name = oname;
+ return temp1;
+}
+
/******************************************************/
/* */
/* Functions to extract substrings of variable values */
@@ -7479,14 +7481,14 @@ mb_substring (string, s, e)
VARNAME. If VARNAME is an array variable, use the array elements. */
static char *
-parameter_brace_substring (varname, value, ind, substr, quoted, flags)
+parameter_brace_substring (varname, value, ind, substr, quoted, pflags, flags)
char *varname, *value;
int ind;
char *substr;
- int quoted, flags;
+ int quoted, pflags, flags;
{
intmax_t e1, e2;
- int vtype, r, starsub;
+ int vtype, r, starsub, qflags;
char *temp, *val, *tt, *oname;
SHELL_VAR *v;
@@ -7535,7 +7537,12 @@ parameter_brace_substring (varname, value, ind, substr, quoted, flags)
FREE (tt);
break;
case VT_POSPARMS:
- tt = pos_params (varname, e1, e2, quoted);
+ qflags = quoted;
+ if (expand_no_split_dollar_star && starsub && (pflags & PF_NOSPLIT2))
+ qflags |= Q_DOUBLE_QUOTES; /* Posix interp 888 */
+ if (starsub && (pflags & PF_ASSIGNRHS) && quoted == 0 && ifs_is_null)
+ qflags |= Q_DOUBLE_QUOTES; /* Posix interp 888 */
+ tt = pos_params (varname, e1, e2, qflags);
if (tt && quoted == 0 && ifs_is_null)
{
temp = tt; /* Posix interp 888 */
@@ -7753,6 +7760,11 @@ pos_params_pat_subst (string, pat, rep, mflags)
pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
+ /* If we are expanding in a context where word splitting will not be
+ performed, treat as quoted. This changes how $* will be expanded. */
+ if (pchar == '*' && (mflags & MATCH_ASSIGNRHS) && ifs_is_null)
+ qflags |= Q_DOUBLE_QUOTES; /* Posix interp 888 */
+
ret = string_list_pos_params (pchar, save, qflags);
dispose_words (save);
@@ -7890,6 +7902,12 @@ parameter_brace_patsub (varname, value, ind, patsub, quoted, pflags, flags)
}
break;
case VT_POSPARMS:
+ /* This does the right thing for the case where we are not performing
+ word splitting. MATCH_STARSUB restricts it to ${* /foo/bar}, and
+ pos_params_pat_subst/string_list_pos_params will do the right thing
+ in turn for the case where ifs_is_null. Posix interp 888 */
+ if ((pflags & PF_NOSPLIT2) && (mflags & MATCH_STARSUB))
+ mflags |= MATCH_ASSIGNRHS;
temp = pos_params_pat_subst (val, p, rep, mflags);
if (temp && quoted == 0 && ifs_is_null)
{
@@ -7904,6 +7922,12 @@ parameter_brace_patsub (varname, value, ind, patsub, quoted, pflags, flags)
break;
#if defined (ARRAY_VARS)
case VT_ARRAYVAR:
+ /* If we are expanding in a context where word splitting will not be
+ performed, treat as quoted. This changes how ${A[*]} will be
+ expanded to make it identical to $*. */
+ if ((mflags & MATCH_STARSUB) && (mflags & MATCH_ASSIGNRHS) && ifs_is_null)
+ mflags |= MATCH_QUOTED; /* Posix interp 888 */
+
temp = assoc_p (v) ? assoc_patsub (assoc_cell (v), p, rep, mflags)
: array_patsub (array_cell (v), p, rep, mflags);
/* Don't call quote_escapes anymore; array_patsub calls
@@ -7957,6 +7981,11 @@ pos_params_modcase (string, pat, modop, mflags)
pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
+ /* If we are expanding in a context where word splitting will not be
+ performed, treat as quoted. This changes how $* will be expanded. */
+ if (pchar == '*' && (mflags & MATCH_ASSIGNRHS) && ifs_is_null)
+ qflags |= Q_DOUBLE_QUOTES; /* Posix interp 888 */
+
ret = string_list_pos_params (pchar, save, qflags);
dispose_words (save);
@@ -7968,11 +7997,11 @@ pos_params_modcase (string, pat, modop, mflags)
to perform. QUOTED is a flags word containing the type of quoting
currently in effect. */
static char *
-parameter_brace_casemod (varname, value, ind, modspec, patspec, quoted, flags)
+parameter_brace_casemod (varname, value, ind, modspec, patspec, quoted, pflags, flags)
char *varname, *value;
int ind, modspec;
char *patspec;
- int quoted, flags;
+ int quoted, pflags, flags;
{
int vtype, starsub, modop, mflags, x;
char *val, *temp, *pat, *p, *lpat, *tt, *oname;
@@ -8000,6 +8029,8 @@ parameter_brace_casemod (varname, value, ind, modspec, patspec, quoted, flags)
mflags |= MATCH_QUOTED;
if (starsub)
mflags |= MATCH_STARSUB;
+ if (pflags & PF_ASSIGNRHS)
+ mflags |= MATCH_ASSIGNRHS;
p = patspec;
if (modspec == '^')
@@ -8023,7 +8054,7 @@ parameter_brace_casemod (varname, value, ind, modspec, patspec, quoted, flags)
lpat = p ? savestring (p) : 0;
/* Perform the same expansions on the pattern as performed by the
- pattern removal expansions. FOR LATER */
+ pattern removal expansions. */
pat = lpat ? getpattern (lpat, quoted, 1) : 0;
/* OK, now we do the case modification. */
@@ -8058,6 +8089,12 @@ parameter_brace_casemod (varname, value, ind, modspec, patspec, quoted, flags)
#if defined (ARRAY_VARS)
case VT_ARRAYVAR:
+ /* If we are expanding in a context where word splitting will not be
+ performed, treat as quoted. This changes how ${A[*]} will be
+ expanded to make it identical to $*. */
+ if ((mflags & MATCH_STARSUB) && (mflags & MATCH_ASSIGNRHS) && ifs_is_null)
+ mflags |= MATCH_QUOTED; /* Posix interp 888 */
+
temp = assoc_p (v) ? assoc_modcase (assoc_cell (v), pat, modop, mflags)
: array_modcase (array_cell (v), pat, modop, mflags);
/* Don't call quote_escapes; array_modcase calls array_quote_escapes
@@ -8179,7 +8216,7 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta
name[1] = '\0';
t_index++;
}
- else if (*name == '!' && t_index > sindex && string[t_index] == '@' && string[t_index+1] == '}')
+ else if (*name == '!' && t_index > sindex && string[t_index] == '@' && string[t_index+1] == RBRACE)
{
name = (char *)xrealloc (name, t_index - sindex + 2);
name[t_index - sindex] = '@';
@@ -8272,7 +8309,7 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta
(legal_variable_starter ((unsigned char)name[1]) || DIGIT (name[1])
|| VALID_INDIR_PARAM (name[1]));
- /* Determine the value of this variable. */
+ /* Determine the value of this variable whose name is NAME. */
/* Check for special variables, directly referenced. */
if (SPECIAL_VAR (name, want_indir))
@@ -8364,16 +8401,16 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta
}
#if defined (ARRAY_VARS)
- /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
+ /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */
if (want_indir && string[sindex - 1] == RBRACE &&
- string[sindex - 2] == ']' && valid_array_reference (name+1, 0))
+ string[sindex - 2] == RBRACK && valid_array_reference (name+1, 0))
{
char *x, *x1;
temp1 = savestring (name + 1);
- x = array_variable_name (temp1, 0, &x1, (int *)0); /* [ */
+ x = array_variable_name (temp1, 0, &x1, (int *)0);
FREE (x);
- if (ALL_ELEMENT_SUB (x1[0]) && x1[1] == ']')
+ if (ALL_ELEMENT_SUB (x1[0]) && x1[1] == RBRACK)
{
temp = array_keys (temp1, quoted); /* handles assoc vars too */
if (x1[0] == '@')
@@ -8454,8 +8491,8 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta
if (pflags & PF_ASSIGNRHS)
qflags |= Q_DOUBLE_QUOTES;
/* We duplicate a little code here */
- t = mbschr (name, '[');
- if (t && ALL_ELEMENT_SUB (t[1]) && t[2] == ']')
+ t = mbschr (name, LBRACK);
+ if (t && ALL_ELEMENT_SUB (t[1]) && t[2] == RBRACK)
{
all_element_arrayref = 1;
if (expand_no_split_dollar_star && t[1] == '*') /* XXX */
@@ -8505,7 +8542,7 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta
/* If this is a substring spec, process it and add the result. */
if (want_substring)
{
- temp1 = parameter_brace_substring (name, temp, ind, value, quoted, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
+ temp1 = parameter_brace_substring (name, temp, ind, value, quoted, pflags, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
FREE (value);
FREE (temp);
@@ -8560,7 +8597,7 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta
#if defined (CASEMOD_EXPANSIONS)
else if (want_casemod)
{
- temp1 = parameter_brace_casemod (name, temp, ind, modspec, value, quoted, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
+ temp1 = parameter_brace_casemod (name, temp, ind, modspec, value, quoted, pflags, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
FREE (value);
FREE (temp);
@@ -8605,7 +8642,7 @@ bad_substitution:
break;
case '@':
- temp1 = parameter_brace_transform (name, temp, ind, value, c, quoted, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
+ temp1 = parameter_brace_transform (name, temp, ind, value, c, quoted, pflags, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
free (temp);
free (value);
@@ -8913,6 +8950,12 @@ param_expand (string, sindex, quoted, expanded_something,
if (expand_no_split_dollar_star && ifs_firstc == 0)
# endif
temp = string_list_dollar_star (list);
+ else if (expand_no_split_dollar_star && quoted == 0 && (ifs_is_set == 0 || ifs_is_null) && (pflags & PF_ASSIGNRHS))
+ {
+ /* Posix interp 888 */
+ temp = string_list_dollar_at (list, Q_DOUBLE_QUOTES, pflags);
+ tflag |= W_SPLITSPACE;
+ }
else
{
temp = string_list_dollar_at (list, quoted, 0);
@@ -9101,7 +9144,7 @@ comsub:
/* Do POSIX.2d9-style arithmetic substitution. This will probably go
away in a future bash release. */
- case '[':
+ case '[': /*]*/
/* Extract the contents of this arithmetic substitution. */
t_index = zindex + 1;
temp = extract_arithmetic_subst (string, &t_index);
@@ -9579,7 +9622,7 @@ add_string:
*contains_dollar_at = 1;
if (tword && (tword->flags & W_HASQUOTEDNULL))
- had_quoted_null = 1;
+ had_quoted_null = 1; /* note for later */
temp = tword ? tword->word : (char *)NULL;
dispose_word_desc (tword);
@@ -9735,7 +9778,7 @@ add_twochars:
temp = (char *)NULL;
- temp_has_dollar_at = 0; /* XXX */
+ temp_has_dollar_at = 0; /* does this quoted (sub)string include $@? */
/* Need to get W_HASQUOTEDNULL flag through this function. */
list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &temp_has_dollar_at, (int *)NULL);
has_dollar_at += temp_has_dollar_at;
@@ -9755,13 +9798,32 @@ add_twochars:
/* "$@" (a double-quoted dollar-at) expands into nothing,
not even a NULL word, when there are no positional
- parameters. */
+ parameters. Posix interp 888 says that other parts of the
+ word that expand to quoted nulls result in quoted nulls, so
+ we can't just throw the entire word away if we have "$@"
+ anywhere in it. We use had_quoted_null to keep track */
if (list == 0 && temp_has_dollar_at) /* XXX - was has_dollar_at */
{
quoted_dollar_at++;
break;
}
+ /* If this list comes back with a quoted null from expansion,
+ we have either "$x" or "$@" with $1 == ''. In either case,
+ we need to make sure we add a quoted null argument and
+ disable the special handling that "$@" gets. */
+ if (list && list->word && list->next == 0 && (list->word->flags & W_HASQUOTEDNULL))
+ {
+ /* If we already saw a quoted null, we don't need to add
+ another one */
+ if (had_quoted_null && temp_has_dollar_at)
+ {
+ quoted_dollar_at++;
+ break;
+ }
+ had_quoted_null = 1; /* XXX */
+ }
+
/* If we get "$@", we know we have expanded something, so we
need to remember it for the final split on $IFS. This is
a special case; it's the only case where a quoted string
@@ -9773,9 +9835,6 @@ add_twochars:
if (list)
dequote_list (list);
- if (list && list->word && (list->word->flags & W_HASQUOTEDNULL))
- had_quoted_null = 1; /* XXX */
-
if (temp_has_dollar_at) /* XXX - was has_dollar_at */
{
quoted_dollar_at++;
@@ -9791,6 +9850,7 @@ add_twochars:
/* What we have is "". This is a minor optimization. */
FREE (temp);
list = (WORD_LIST *)NULL;
+ had_quoted_null = 1; /* note for later */
}
/* The code above *might* return a list (consider the case of "$@",
@@ -9861,6 +9921,7 @@ add_twochars:
/* Add NULL arg. */
c = CTLNUL;
sindex--; /* add_character: label increments sindex */
+ had_quoted_null = 1; /* note for later */
goto add_character;
}
@@ -9888,9 +9949,13 @@ add_twochars:
else
remove_quoted_escapes (temp); /* ??? */
+ if (temp == 0 && quoted_state == PARTIALLY_QUOTED)
+ had_quoted_null = 1; /* note for later */
+
/* We do not want to add quoted nulls to strings that are only
partially quoted; such nulls are discarded. See above for the
- exception, which is when the string is going to be split. */
+ exception, which is when the string is going to be split.
+ Posix interp 888 */
if (temp == 0 && (quoted_state == PARTIALLY_QUOTED) && (word->flags & (W_NOSPLIT|W_NOSPLIT2)))
continue;
diff --git a/subst.h b/subst.h
index 6751dce..d5cb007 100644
--- a/subst.h
+++ b/subst.h
@@ -316,6 +316,7 @@ extern WORD_LIST *split_at_delims __P((char *, int, char *, int, int, int *, int
extern SHELL_VAR *ifs_var;
extern char *ifs_value;
extern unsigned char ifs_cmap[];
+extern int ifs_is_set, ifs_is_null;
#if defined (HANDLE_MULTIBYTE)
extern unsigned char ifs_firstc[];
diff --git a/tests/dollar-at-star b/tests/dollar-at-star
index e04c24b..2008290 100755
--- a/tests/dollar-at-star
+++ b/tests/dollar-at-star
@@ -276,4 +276,13 @@ ${THIS_SH} ./dollar-star7.sub
# problem through bash-4.4 in some parameter expansion contexts
${THIS_SH} ./dollar-star8.sub
+# tests for expansions of "$@" when there are no positional parameter or when
+# $1 == '' and the expansion is preceded by something that results in a quoted
+# null string
+${THIS_SH} ./dollar-at7.sub
+
+# tests for expansions of $* when in an assignment context (no splitting) and
+# IFS is null
+${THIS_SH} ./dollar-star9.sub
+
exit 0
diff --git a/tests/dollar-at7.sub b/tests/dollar-at7.sub
new file mode 100644
index 0000000..311a6fe
--- /dev/null
+++ b/tests/dollar-at7.sub
@@ -0,0 +1,46 @@
+set -- ''
+
+recho 1 ''"$@"
+recho 2 """$@"
+
+recho 3 "$@""$@"
+recho 4 "$x""$@"
+
+set --
+
+echo -----
+recho 1 ''"$@"
+recho 2 """$@"
+
+recho 3 "$@""$@"
+recho 4 "$x""$@"
+
+set -- X
+
+echo ------
+recho 1 ''"${@/*}"
+recho 2 """${@/*}"
+
+recho 3 "$x""${@/*}"
+
+recho 4 ''"${@#X}"
+recho 5 """${@#X}"
+
+recho 6 "$x""${@#X}"
+
+set --
+
+echo -----
+recho 1 ''"${@/*}"
+recho 2 """${@/*}"
+
+recho 3 "$x""${@/*}"
+
+recho 4 ''"${@#X}"
+recho 5 """${@#X}"
+
+recho 6 "$x""${@#X}"
+
+echo -----
+recho 1 "$novar${*}$(echo)"
+recho 2 ''"$novar${@}$(echo)"
diff --git a/tests/dollar-star9.sub b/tests/dollar-star9.sub
new file mode 100644
index 0000000..ecc5fbc
--- /dev/null
+++ b/tests/dollar-star9.sub
@@ -0,0 +1,16 @@
+set -- 1 2
+
+IFS=
+
+a=$* b=${*}
+c=${*/} d=${*#} e=${*%} f=${*:1}
+printf '<%s>' "$a" "$b" "$c" "$d" "$e" "$f"; echo
+
+unset a b c d e f
+: ${a=$*} ${b=${*}} ${c=${*/}}
+: ${d=${*#}} ${e=${*%}} ${f=${*:1}}
+printf '<%s>' "$a" "$b" "$c" "$d" "$e" "$f" ; echo
+
+unset f g
+f=${*,,} g=${*@Q}
+printf '<%s>' "$f" "$g" ; echo
diff --git a/tests/dollar.right b/tests/dollar.right
index 26e58ab..13c7c38 100644
--- a/tests/dollar.right
+++ b/tests/dollar.right
@@ -510,3 +510,53 @@ argv[1] = <a b c d>
<def>
<ghi>
<jkl>
+argv[1] = <1>
+argv[2] = <>
+argv[1] = <2>
+argv[2] = <>
+argv[1] = <3>
+argv[2] = <>
+argv[1] = <4>
+argv[2] = <>
+-----
+argv[1] = <1>
+argv[2] = <>
+argv[1] = <2>
+argv[2] = <>
+argv[1] = <3>
+argv[1] = <4>
+argv[2] = <>
+------
+argv[1] = <1>
+argv[2] = <>
+argv[1] = <2>
+argv[2] = <>
+argv[1] = <3>
+argv[2] = <>
+argv[1] = <4>
+argv[2] = <>
+argv[1] = <5>
+argv[2] = <>
+argv[1] = <6>
+argv[2] = <>
+-----
+argv[1] = <1>
+argv[2] = <>
+argv[1] = <2>
+argv[2] = <>
+argv[1] = <3>
+argv[2] = <>
+argv[1] = <4>
+argv[2] = <>
+argv[1] = <5>
+argv[2] = <>
+argv[1] = <6>
+argv[2] = <>
+-----
+argv[1] = <1>
+argv[2] = <>
+argv[1] = <2>
+argv[2] = <>
+<12><12><12><12><12><12>
+<12><12><12><12><12><12>
+<12><'1' '2'>
diff --git a/tests/exp.right b/tests/exp.right
index 18a4769..ec3fed3 100644
--- a/tests/exp.right
+++ b/tests/exp.right
@@ -334,3 +334,14 @@ jkl
[]
[foo]
[]
+< A >< B >< A >< B >
+< A >< B >< A >< B >
+< A >< B >< a >< b >
+< A >< B >< A >< B >
+< A >< B ><' A '><' B '>
+-----
+< A >< B >< A >< B >
+< A >< B >< A >< B >
+< A >< B >< a >< b >
+< A >< B >< A >< B >
+< A >< B ><' A '><' B '>
diff --git a/tests/exp.tests b/tests/exp.tests
index b446d63..d81d54f 100644
--- a/tests/exp.tests
+++ b/tests/exp.tests
@@ -405,3 +405,4 @@ ${THIS_SH} ./exp6.sub
${THIS_SH} ./exp7.sub
${THIS_SH} ./exp8.sub
${THIS_SH} ./exp9.sub
+${THIS_SH} ./exp10.sub
diff --git a/tests/exp10.sub b/tests/exp10.sub
new file mode 100644
index 0000000..6592bab
--- /dev/null
+++ b/tests/exp10.sub
@@ -0,0 +1,26 @@
+set -- ' A ' ' B '
+IFS=
+
+printf '<%s>' ${*} ${*##}
+echo
+printf '<%s>' ${*} ${*/}
+echo
+printf '<%s>' ${*} ${*,,}
+echo
+printf '<%s>' ${*} ${*:1:2}
+echo
+printf '<%s>' ${*} ${*@Q}
+echo
+
+echo -----
+
+printf '<%s>' ${@} ${@##}
+echo
+printf '<%s>' ${@} ${@/}
+echo
+printf '<%s>' ${@} ${@,,}
+echo
+printf '<%s>' ${@} ${@:1:2}
+echo
+printf '<%s>' ${@} ${@@Q}
+echo