]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
commit bash-20141205 snapshot
authorChet Ramey <chet.ramey@case.edu>
Mon, 12 Jan 2015 15:50:34 +0000 (10:50 -0500)
committerChet Ramey <chet.ramey@case.edu>
Mon, 12 Jan 2015 15:50:34 +0000 (10:50 -0500)
25 files changed:
CWRU/CWRU.chlog
CWRU/CWRU.chlog~ [new file with mode: 0644]
CWRU/POSIX.NOTES.old [new file with mode: 0644]
CWRU/old/set.def.save [new file with mode: 0644]
CWRU/save/unwind_prot.h.save [new file with mode: 0644]
builtins/declare.def
builtins/printf.def
cross-build/cygwin32.cache.old [new file with mode: 0644]
doc/FAQ.orig [new file with mode: 0644]
doc/aosa-bash.pdf.old [new file with mode: 0644]
doc/bash.0
examples/loadables/Makefile.in.save [new file with mode: 0644]
execute_cmd.c
jobs.c
jobs.c~ [new file with mode: 0644]
lib/readline/doc/Makefile.old [new file with mode: 0644]
po/._fr.po
subst.c
subst.c~ [new file with mode: 0644]
tests/RUN-ONE-TEST
tests/globstar2.sub
tests/misc/regress/log.orig [new file with mode: 0644]
tests/misc/regress/shx.orig [new file with mode: 0644]
variables.c
variables.h

index b1e1af46de831b19aad8faa4381503323463bb38..71d4ffe92031794061e3db8b0cbe8848e983a7c3 100644 (file)
@@ -7521,3 +7521,54 @@ lib/readline/input.c
          and returns -1/EINTR on a signal even if the signal was installed
          with SA_RESTART.  From a suggestion from Egmont Koblinger
          <egmont@gmail.com>
+
+                                  12/3
+                                  ----
+variables.c
+       - flush_temporary_env: new function, disposes all temp variables in
+         temporary_env hash table
+       - bind_variable: only try to update a temporary variable's value in the
+         temporary env if the value argument is not null.  Fixes bug reported
+         by <tangqinghao@360.cn>
+
+variables.h
+       - flush_temporary_env: new extern declaration
+
+subst.c
+       - command_substitute: if running command substitution as part of
+         expanding a redirection (expanding_redir == 1), flush any temporary
+         environment we've inherited as part of this command, since we are not
+         supposed to have access to the temporary environment.  Since
+         expanding_redir only controls access to the temporary environment for
+         variable lookup and binding, we can turn it off in the subshell
+
+                                  12/4
+                                  ----
+builtins/printf.def
+       - printstr: make sure a missing precision specifier after a `.' is
+         treated as 0, as printf(3) specifies.  Fixes ubuntu bash bug
+         1399087 (https://bugs.launchpad.net/ubuntu/+source/bash/+bug/1399087)
+
+                                  12/5
+                                  ----
+subst.c
+       - skip_to_delim: if scanning past process substitution (skipcmd == 1,
+         noprocsub == 0), use extract_delimited_string instead of
+         extract_process_subst, which was changed a while back (bash-4.3.23)
+         to use xparse_dolparen.  xparse_dolparen complains if the command
+         or process substitution is unterminated, since it runs the parser,
+         which is not what we want here.  Command substitution does the same
+         thing.  Fixes bug reported by  Daniel Kahn Gillmor
+         <dkg@fifthhorseman.net> as Debian bash bug 771968
+         (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=771968)
+
+                                  12/6
+                                  ----
+subst.c
+       - command_substitute: short-circuit without forking on a command string
+         that consists entirely of <blank>s and newlines
+
+jobs.c
+       - make_child: changes to allow interrupts through if fork fails and
+         we are sleeping for `forksleep' seconds
+       - waitchld: make things a little more resilient if CHILD ends up NULL
diff --git a/CWRU/CWRU.chlog~ b/CWRU/CWRU.chlog~
new file mode 100644 (file)
index 0000000..4c99403
--- /dev/null
@@ -0,0 +1,7569 @@
+                                2/14/2011
+                                ---------
+[bash-4.2 released]
+
+                                  2/15
+                                  ----
+lib/glob/gmisc.c
+       - fix wmatchlen and umatchlen to avoid going past the end of the
+         string on an incomplete bracket expression that ends with a
+         NUL.  Partial fix for bug reported by Clark Wang <dearvoid@gmail.com>
+
+                                  2/16
+                                  ----
+subst.h
+       - new string extract flag value: SX_WORD.  Used when calling
+         extract_dollar_brace_string to skip over the word in
+         ${param op word} from parameter_brace_expand
+
+subst.c
+       - change parameter_brace_expand to add SX_WORD to flags passed to
+         extract_dollar_brace_string
+       - change parameter_brace_expand to use SX_POSIXEXP for all non-posix
+         word expansion operators that treat single quotes as special, not
+         just % and #
+       - change extract_dollar_brace_string to initialize dolbrace_state to
+         DOLBRACE_WORD if SX_WORD flag supplied and we shouldn't use
+         DOLBRACE_QUOTE.  Fixes bug reported by Juergen Daubert <jue@jue.li>
+
+doc/{bash.1,bashref.texi}
+       - document the exact expansions here strings undergo
+
+                                  2/17
+                                  ----
+lib/readline/vi_mode.c
+       - make sure that `dd', `cc', and `yy' call vidomove_dispatch from
+         rl_domove_read_callback.  Fixes bug reported by Clark Wang
+         <dearvoid@gmail.com>
+
+lib/readline/callback.c
+       - make sure _rl_internal_char_cleanup is called after the
+         vi-motion callbacks (rl_vi_domove_callback) in rl_callback_read_char.
+         Companion to above fix
+
+doc/{bash.1,bashref.texi}
+       - make sure that the text describing the rhs of the == and =~
+         operators to [[ states that only the quoted portion of the pattern
+         is matched as a string
+
+                                  2/18
+                                  ----
+lib/glob/gmisc.c
+       - better fix for umatchlen/wmatchlen: keep track of the number of
+         characters in a bracket expression as the value to increase
+         matchlen by if the bracket expression is not well-formed.  Fixes
+         bug reported by Clark Wang <dearvoid@gmail.com>
+
+subst.c
+       - change expand_string_for_rhs so that it sets the W_NOSPLIT2 flag
+         in the word flags.  We will not perform word splitting or quote
+         removal on the result, so we do not want to add quoted nulls if
+         we see "" or ''.  Fixes bug reported by Mike Frysinger
+         <vapier@gentoo.org>
+
+                                  2/19
+                                  ----
+variables.c
+       - new function, int chkexport(name), checks whether variable NAME is
+         exported and remakes the export environment if necessary.  Returns
+         1 if NAME is exported and 0 if not
+       - call chkexport(name) to get tzset to look at the right variable in
+         the environment when modifying TZ in sv_tz.  Don't call tzset if
+         chkexport doesn't indicate that the variable is exported
+
+variables.h
+       - new extern declaration for chkexport
+
+
+{parse.y,builtins/printf.def}
+       - call sv_tz before calling localtime() when formatting time strings
+         in prompt strings or using printf.  Fixes bug reported by
+         Dennis Williamson <dennistwilliamson@gmail.com>
+
+execute_cmd.c
+       - modify fix of 2/9 to add casts when those variables are passed to
+         functions; some compilers throw errors instead of warnings.  Report
+         and fix from Joachim Schmitz <jojo@schmitz-digital.de>
+
+support/shobj-conf
+       - add a stanza for nsk on the Tandem from Joachim Schmitz
+         <jojo@schmitz-digital.de>
+
+{shell,lib/readline/shell}.c
+       - Tandem systems should use getpwnam (getlogin()); for some reason
+         they don't do well with using getuid().  Fix from Joachim Schmitz
+         <jojo@schmitz-digital.de>
+
+                                   3/1
+                                   ---
+variables.c
+       - make sure that the return value from find_variable is non-null
+         before trying to use it in chkexport.  Fixes bug reported by
+         Evangelos Foutras <foutrelis@gmail.com>
+
+                                   3/3
+                                   ---
+parse.y
+       - when adding $$ to the current token buffer in read_token_word(),
+         don't xmalloc a buffer for two characters and then strcpy it, just
+         copy the characters directly into the token buffer.  Fix from
+         Michael Whitten <mfwitten@gmail.com>
+
+execute_cmd.c
+       - fix expand_word_unsplit to add the W_NOSPLIT2 flag to the word to
+         be expanded, so "" doesn't add CTLNUL.  Similar to fix of 2/18 to
+         expand_string_for_rhs.  Fixes bug reported by Nathanael D. Noblet
+         <nathanael@gnat.ca> and Matthias Klose <doko@debian.org>
+
+parse.y
+       - fix extended_glob case of read_token_word to allocate an extra
+         space in the buffer for the next character read after the extended
+         glob specification if it's a CTLESC or CTLNUL.  Report and fix from
+         Michael Witten <mfwitten@gmail.com>
+       - fix shell expansions case of read_token_word to allocate an extra
+         space in the buffer for the next character read after the shell
+         expansion if it's a CTLESC or CTLNUL.  Report and fix from
+         Michael Witten <mfwitten@gmail.com>
+       - TENTATIVE: fix read_token_word to reduce the amount of buffer space
+         required to hold the translated and double-quoted value of $"..."
+         strings.  Report and fix from Michael Witten <mfwitten@gmail.com>
+       - change code around got_character and got_escaped_character labels to
+         make sure that we call RESIZE_MALLOCED_BUFFER before adding the
+         CTLESC before a CTLESC or CTLNUL, and before adding the character if
+         we're not adding a CTLESC.  Report and fix from
+         Michael Witten <mfwitten@gmail.com>
+
+subst.c
+       - new param flags value, PF_ASSIGNRHS, mirrors W_ASSIGNRHS, noting that
+         parameter expansion is on rhs of assignment statement.  That inhibits
+         word splitting
+       - change param_expand to call string_list_dollar_at with quoted == 1
+         if PF_ASSIGNRHS is set, so it will quote IFS characters in the
+         positional parameter before separating them with the first char of
+         $IFS.  This keeps the rhs from being split inappropriately.  Fixes
+         bug reported by Andres Perera <andres.p@zoho.com>
+
+                                   3/4
+                                   ---
+lib/readline/bind.c
+       - add a missing free of `names' in rl_function_dumper.  Bug report
+         and fix from Michael Snyder <msnyder@vmware.com>
+
+                                   3/5
+                                   ---
+lib/readline/rltty.c
+       - change rl_deprep_terminal so it uses fileno (stdin) for the tty fd
+         if rl_instream is not set, like rl_prep_terminal
+
+                                   3/6
+                                   ---
+lib/readline/display.c
+       - fix rl_message to use a dynamically-allocated buffer instead of a
+         fixed-size buffer of 128 chars for the `local message prompt'.  Bug
+         report and fix from Micah Cowan <micah@cowan.name>
+
+                                   3/7
+                                   ---
+jobs.c
+       - add sentinel to wait_sigint_handler so it only sets wait_sigint_received
+         if waiting_for_child is non-zero; otherwise, it restores the old
+         SIGINT handler and sends itself the SIGINT
+       - set waiting_for_child around the calls to waitchld that use it to
+         synchronously wait for a process
+       - change logic that decides whether or not the child process blocked
+         or handled SIGINT based on whether or not waitpid returns -1/EINTR
+         and the shell receives a SIGINT and the child does not exit.  If
+         the child later exits due to SIGINT, cancel the assumoption that it
+         was handled
+       - instead of testing whether or not the child exited due to SIGINT
+         when deciding whether the shell should act on a SIGINT it received
+         while waiting, test whether or not we think the child caught
+         SIGINT.  If it did, we let it go (unless the shell has it trapped);
+         if it did not catch it, the shell acts on the SIGINT.  Fix from
+         Linus Torvalds <torvalds@linux-foundation.org>, bug report originally
+         from Oleg Nesterov <oleg@redhat.com>
+
+                                   3/8
+                                   ---
+shell.c
+       - initialize no_line_editing to 1 if READLINE is not defined -- we
+         can't have line editing without readline
+
+                                  3/12
+                                  ----
+lib/readline/signals.c
+       - add SIGHUP to the set of signals readline handles
+
+lib/readline/doc/rltech.texi
+       - document that SIGHUP is now part of the set of signals readline
+         handles
+
+lib/readline/input.c
+       - if _rl_caught_signal indicates that read() was interrupted by a
+         SIGHUP or SIGTERM, return READERR or EOF as appropriate
+       - call rl_event_hook, if it's set, if call to read in rl_getc
+         returns -1/EINTR.  If rl_event_hook doesn't do anything, this
+         continues the loop as before.  This handles the other fatal
+         signals
+
+execute_cmd.c
+       - add a couple of QUIT; calls to execute_disk_command and
+         execute_simple_command to improve responsiveness to interrupts
+         and fatal signals
+
+input.c
+       - rearrange getc_with_restart so that the return values from read()
+         are handled right
+
+parse.y
+       - don't need to set terminate_immediately in yy_stream_get, since
+         getc_with_restart checks for terminating signals itself
+       - since readline returns READERR on SIGHUP or SIGTERM, don't need
+         to set terminate_immediately.  Still doesn't handle other
+         signals well -- will have to check that some more
+
+bashline.c
+       - new function, bash_event_hook, for rl_event_hook.  Just checks for
+         terminating signals and acts on them using CHECK_TERMSIG.
+       - set rl_event_hook to bash_event_hook
+
+builtins/read.def
+       - take out setting terminate_immediately; add calls to CHECK_TERMSIG
+         after read calls
+
+doc/{bash.1,bashref.texi}
+       - move the text describing the effect of negative subscripts used to
+         reference indexed array elements to the paragraphs describing
+         ${parameter[subscript]}, since that's where they are implemented.
+         Pointed out by Christopher F. A. Johnson <cfajohnson@gmail.com>
+
+arrayfunc.[ch],subst.c
+       - array_expand_index now takes a new first argument: a SHELL_VAR *
+         of the array variable being subscripted.  Can be used later to fully
+         implement negative subscripts
+
+                                  3/14
+                                  ----
+lib/glob/glob.c
+       - fix mbskipname to not turn the directory entry name into a wide char
+         string if the conversion of the pattern to a wide char string fails
+       - fix mbskipname to call skipname if either the pattern or the filename
+         can't be converted into a wide-char string
+
+lib/glob/xmbsrtowcs.c
+       - fix xdupmbstowcs2 to handle return value of 0 from mbsnrtowcs and
+         short-circuit with failure in that case.  Fixes bug reported by
+         Roman Rakus <rrakus@redhat.com>
+
+                                  3/15
+                                  ----
+bashline.c
+       - new variable, bash_filename_quote_characters to store the value
+         assigned to rl_filename_quote_characters so it can be restored
+         if changed.
+       - change bashline_reset and attempt_shell_completion to restore
+         rl_filename_quote_characters if not set to default
+
+                                  3/22
+                                  ----
+lib/glob/glob.c
+       - wdequote_pathname falls back to udequote_pathname if xdupmbstowcs
+         fails to convert the pathname to a wide-character string
+
+lib/glob/xmbsrtowcs.c
+       - xdupmbstowcs2: change to fix problem with leading '\\' (results in
+         nms == 0, which causes it to short-circuit with failure right
+         away).  Fixes bug pointed out by Werner Fink <werner@suse.de>
+       - xdupmbstowcs2: compensate for mbsnrtowcs returning 0 by taking the
+         next single-byte character and going on
+       - xdupmbstowcs2: change memory allocation to increase by WSBUF_INC
+         bytes; try to avoid calls to realloc (even if they don't actually
+         result in more memory being allocated)
+
+                                  3/24
+                                  ----
+doc/{bash.1,bashref.texi}
+       - slightly modify BASH_SUBSHELL description based on complaint from
+         Sam Liddicott <sam@liddicott.com>
+
+                                  3/25
+                                  ----
+trap.c
+       - change free_trap_strings to not call free_trap_string for signals
+         that are being ignored, like reset_or_restore_signal_handlers.
+         Fixes bug reported by Satoshi Takahashi <blue3waters@gmail.com>
+
+                                  3/26
+                                  ----
+lib/readline/rltypedefs.h
+       - remove old Function/VFunction/CPFunction/CPPFunction typedefs as
+         suggested by Tom Tromey <tromey@redhat.com>
+
+lib/readline/rlstdc.h
+       - move defines for USE_VARARGS/PREFER_STDARG/PREFER_VARARGS from
+         config.h.in to here because declaration of rl_message in
+         readline.h uses the defines.  This makes it hard for another packages
+         to use after the header files are installed, since config.h is not
+         one of the installed files.  Suggested by Tom Tromey
+         <tromey@redhat.com>
+
+                                  3/27
+                                  ----
+print_cmd.c
+       - change indirection_string from a static buffer to a dynamic one
+         managed by indirection_level_string(), so we don't end up truncating
+         PS4.  Suggested by Dennis Williamson <dennistwilliamson@gmail.com>
+
+lib/readline/shell.c
+       - change sh_set_lines_and_columns to use static buffers instead of
+         allocating the buffers to pass to setenv/putenv
+
+lib/readline/terminal.c
+       - change _rl_get_screen_size to not call sh_set_lines_and_columns if
+         ignore_env == 0
+       - _rl_sigwinch_resize_terminal: new function to just retrieve terminal
+         size, ignoring environment
+
+lib/readline/rlprivate.h
+       - new external declaration for _rl_sigwinch_resize_terminal() (currently
+         unused)
+
+lib/readline/signals.c
+       - rl_sigwinch_handler: set _rl_caught_signal to SIGWINCH
+       - rl_sigwinch_handler: don't immediately call rl_resize_terminal; just
+         leave _rl_caught_signal set for RL_CHECK_SIGNALS to handle
+       - _rl_signal_handler: call rl_resize_terminal if sig == SIGWINCH.
+         Should fix hang when sending multiple repeated SIGWINCH reported by
+         Henning Bekel <h.bekel@googlemail.com>
+
+                                  3/29
+                                  ----
+lib/sh/snprintf.c
+       - include math.h for any defines for isinf/isnan
+       - use code from gnulib documentation to implement isinf/isnan if they
+         are not defined
+
+configure.in
+       - don't check for isinf or isnan; c99 says they're macros anyway
+
+config.h.in
+       - remove defines for ISINF_IN_LIBC and ISNAN_IN_LIBC, no longer used
+         by snprintf.c
+
+                                   4/2
+                                   ---
+braces.c
+       - brace_gobbler: fix to understand double-quoted command substitution,
+         since the shell understands unquoted comsubs.  Fixes bug reported
+         by Michael Whitten <mfwitten@gmail.com>
+
+lib/readline/display.c
+       - include <pc.h> on MDOS
+       - get and set screen size using DJGPP-specific calls on MSDOS
+       - move cursor up clear screen using DJGPP-specific calls
+       - don't call tputs on DJGPP; there is no good terminfo support
+
+lib/readline/terminal.c
+       - include <pc.h> on MDOS
+       - get and set screen size using DJGPP-specific calls on MSDOS
+       - use DJGPP-specific initialization on MSDOS, zeroing all the
+         _rl_term_* variables
+       - don't call tputs on DJGPP; there is no good terminfo support
+         DJGPP support from Eli Zaretskii  <eliz@gnu.org>
+
+                                   4/6
+                                   ---
+
+config-top.h
+       - change DEFAULT_PATH_VALUE to something more useful and modern
+
+                                   4/8
+                                   ---
+tests/printf2.sub
+       - make sure LC_ALL and LC_CTYPE are set so LANG assignment takes effect.
+         Reported by Cedric Arbogast <arbogast.cedric@gmail.com>
+
+                                  4/11
+                                  ----
+include/chartypes.h
+       - fix a couple of dicey defines (though ones that don't cause any
+         compiler warnings) in IN_CTYPE_DOMAIN
+
+doc/{bashref.texi,bash.1}
+       - add note referring to duplicating file descriptors in sections
+         describing redirecting stdout and stderr and appending to stdout
+         and stderr.  Suggested by Matthew Dinger <mdinger.bugzilla@gmail.com>
+
+pcomplete.c
+       - it_init_helptopics: new function to support completing on help topics,
+         not just builtins
+       - it_helptopics: new programmable completion list of help topics
+       - build list of helptopic completions in gen_action_completions on
+         demand
+
+pcomplete.h
+       - new extern declaration for it_helptopics
+
+builtins/complete.def
+       - the `helptopic' action now maps to CA_HELPTOPIC intead of CA_BUILTIN,
+         since there are more help topics than just builtins.  Suggested by
+         Clark Wang <dearvoid@gmail.com>
+
+                                  4/12
+                                  ----
+print_cmd.c
+       - fix print_arith_for_command to add a call to PRINT_DEFERRED_HEREDOCS
+         before ending the body of the command, so heredocs get attached to
+         the right command instead of to the loop.  From gentoo bug 363371
+         http://bugs.gentoo.org/show_bug.cgi?id=363371
+
+execute_cmd.c
+       - change coproc_pidchk to unset the appropriate shell variables when
+         the (currently single) known coproc pid terminates
+       - cleanup and new functions to fully support multiple coprocesses when
+         and if I decide to go there
+
+                                  4/13
+                                  ----
+print_cmd.c
+       - fix print_group_command to add a call to PRINT_DEFERRED_HEREDOCS
+         after call to make_command_string_internal before printing closing
+         `}'
+       - fix make_command_string_internal to add a call to
+         PRINT_DEFERRED_HEREDOCS after recursive call to
+         make_command_string_internal in case cm_subshell before printing
+         closing `)'
+
+                                  4/14
+                                  ----
+print_cmd.c
+       - change overlapping strcpy in named_function_string to memmove
+
+sig.h
+       - UNBLOCK_SIGNAL: convenience define, same as UNBLOCK_CHILD, just
+         restores an old signal mask
+
+trap.c
+       - set_signal: instead of setting the signal handler to SIG_IGN while
+         installing the new trap handler, block the signal and unblock it
+         after the new handler is installed.  Fixes bug reported by Roman
+         Rakus <rrakus@redhat.com>
+
+                                  4/15
+                                  ----
+doc/{bash.1,bashref.texi}
+       - make it clear that enabling monitor mode means that all jobs run in
+         separate process groups
+
+                                  4/18
+                                  ----
+builtins/fc.def
+       - update fix of 4/15/2010 to not take saved_command_line_count into
+         account when stepping down the history list to make sure that
+         last_hist indexes something that is valid.  Fixes bug reported by
+         <piuma@piumalab.org>
+
+                                  4/19
+                                  ----
+builtins/fc.def
+       - fc_gethnum: make sure the calculation to decide the last history
+         entry is exactly the same as fc_builtin.  Fixes bug uncovered by
+         fix of 4/18 to stop seg fault
+
+                                  4/22
+                                  ----
+lib/readline/terminal.c
+       - change _rl_enable_meta_key to set a flag indicating that it sent the
+         enable-meta sequence
+       - _rl_disable_meta_key: new function to turn off meta mode after we
+         turned it on with _rl_enable_meta_key
+
+lib/readline/rlprivate.h
+       - extern declaration for _rl_disable_meta_key
+
+configure.in
+       - if not cross-compiling, set CFLAGS_FOR_BUILD from any CFLAGS inherited
+         from the environment.  Fixes HP/UX build problem reported by
+         "Daniel Richard G." <skunk@iSKUNK.ORG>
+
+                                  4/26
+                                  ----
+config-top.h
+       - define MULTIPLE_COPROCS to 0 so the code is still disabled but easy
+         to enable via configure option or editing this file
+
+                                  4/29
+                                  ----
+lib/sh/eaccess.c
+       - freebsd provides faccessat, with the same misfeature as their eaccess
+         and access implementations (X_OK returns true for uid==0 regardless
+         of the actual file permissions), so reorganize code to check the
+         file permissions as with eaccess.  Report and fix from Johan Hattne
+         <johan.hattne@utsouthwestern.edu>
+
+                                   5/2
+                                   ---
+doc/{bash.1,bashref.texi}
+       - add forward reference to `Pattern Matching' from `Pathname
+         Expansion', suggested by Greg Wooledge <wooledg@eeg.ccf.org>
+
+                                   5/5
+                                   ---
+pcomplib.c
+       - the bash_completion project now distributes over 200 completions
+         for various programs, with no end in sight, so increase the value
+         of COMPLETE_HASH_BUCKETS from 32 to 128
+
+pathexp.c
+       - quote_string_for_globbing: make sure CTLESC quoting CTLESC is
+         translated into \<CTLESC> even if the flags include QGLOB_REGEXP.
+         We don't want to process the second CTLESC as a quote character.
+         Fixes bug reported by Shawn Bohrer <sbohrer@rgmadvisors.com>
+
+                                   5/6
+                                   ---
+builtins/printf.def
+       - change PRETURN to not call fflush if ferror(stdout) is true
+       - if a call to one of the stdio functions or printstr leaves
+         ferror(stdout) true, and PRETURN is going to be called, let PRETURN
+         print the error message rather than doubling up the messages.  Fixes
+         problem reported by Roman Rakus <rrakus@redhat.com>
+
+                                   5/9
+                                   ---
+doc/{bash.1,bashref.texi}
+       - add note to the effect that lists inside compound command can be
+         terminated by newlines as well as semicolons.  Suggested by
+         Roman Byshko <rbyshko@gmail.com>
+
+                                  5/10
+                                  ----
+subst.c
+       - remove_quoted_nulls: fix problem that caused it to skip over the
+         character after a CTLNUL, which had the effect of skipping every
+         other of a series of CTLNULs.  Fixes bug reported by
+         Marten Wikstrom <marten.wikstrom@keystream.se>
+
+                                  5/11
+                                  ----
+subst.c
+       - extract_process_subst: add SX_COMMAND flag to call to
+         extract_delimited_string, since we're expanding the same sort of
+         command as command substitution.  Fixes bug reported in Ubuntu
+         bug 779848
+
+                                  5/12
+                                  ----
+configure.in
+       - set the prefer_shared and prefer_static variables appropriately
+         depending on the value of $opt_static_link
+
+aclocal.m4
+       - AC_LIB_LINKFLAGS_BODY: change to not prefer shared versions of the
+         libraries it's searching for if the prefer_shared variable is "no".
+         Fixes problem reported by Cedric Arbogast <arbogast.cedric@gmail.com>
+
+                                  5/13
+                                  ----
+lib/readline/readline.c
+       - _rl_internal_teardown: add call to _rl_disable_meta_key to make the
+         meta key active only for the duration of the call to readline()
+       - _rl_internal_setup: move call to _rl_enable_meta_key here from
+         readline_initialize_everything so the meta key is active only for
+         the duration of the call to readline().  Suggestion from Miroslav
+         Lichvar <mlichvar@redhat.com>
+
+builtins/help.def
+       - help_builtin: change strncmp to strcmp so that `help read' no longer
+         matches `readonly'.  Suggested by Clark Wang <dearvoid@gmail.com>
+
+config.h.in
+       - add define for GLIBC21, checked using jm_GLIBC21 as part of the tests
+         for libintl
+
+lib/malloc/malloc.c
+       - internal_free: don't use the cached value of memtop when deciding
+         whether or not to adjust the break and give memory back to the kernel
+         when using the GNU C library, since glibc uses sbrk for its own
+         internal purposes.  From Debian bug 614815, reported by Samuel
+         Thibault <samuel.thibault@gnu.org>
+
+aclocal.m4
+       - BASH_STRUCT_WEXITSTATUS_OFFSET: change AC_RUN_IFELSE to AC_TRY_RUN
+         to avoid warning about not using AC_LANG_SOURCE
+
+                                  5/14
+                                  ----
+bashline.[ch]
+       - two new functions, bashline_set_event_hook and bashline_reset_event_hook,
+         to set rl_event_hook to bash_event_hook and back to NULL, respectively
+       - don't set rl_event_hook unconditionally
+
+sig.c
+       - termsig_sighandler: if the shell is currently interactive and
+         readline is active, call bashline_set_event_hook to cause
+         termsig_handler to be called via bash_event_hook when the shell
+         returns from the signal handler
+
+                                  5/15
+                                  ----
+lib/readline/display.c
+       - _rl_col_width: Mac OS X has a bug in wcwidth: it does not return 0
+         for UTF-8 combining characters.  Added workaround dependent on
+         MACOSX.  Fixes problem pointed out by Thomas De Contes
+         <d.l.tDecontes@free.fr>
+
+                                  5/16
+                                  ----
+lib/readline/rlmbutil.h
+       - WCWIDTH: wrapper for wcwidth that returns 0 for Unicode combining
+         characters on systems where wcwidth is broken (e.g., Mac OS X).
+
+lib/readline/{complete,display,mbutil}.c
+       - use WCWIDTH instead of wcwidth
+
+                                  5/17
+                                  ----
+lib/readline/display.c
+       - update_line: after computing ofd and nfd, see whether the next
+         character in ofd is a zero-width combining character.  If it is,
+         back ofd and nfd up one, so the base characters no longer compare
+         as equivalent.  Fixes problem reported by Keith Winstein
+         <keithw@mit.edu>
+
+lib/readline/nls.c
+       - _rl_utf8locale: new flag variable, set to non-zero if the current
+         locale is UTF-8
+       - utf8locale(): new function, returns 1 if the passed lspec (or the
+         current locale) indicates that the locale is UTF-8.  Called from
+         _rl_init_eightbit
+
+lib/readline/rlprivate.h
+       - extern declaration for _rl_utf8locale
+
+locale.c
+       - locale_utf8locale: new flag variable, set to non-zero if the current
+         locale is UTF-8 (currently unused)
+       - locale_isutf8(): new function, returns 1 if the passed lspec (or the
+         current locale) indicates that the locale is UTF-8.  Should be called
+         whenever the locale or LC_CTYPE value is modified
+
+aclocal.m4
+       - BASH_WCWIDTH_BROKEN: new test for whether or not wcwidth returns
+         zero-width characters like unicode combining characters as having
+         display length 1; define WCWIDTH_BROKEN in this case
+
+config.h.in
+       - WCWIDTH_BROKEN: new define
+
+lib/readline/rlmbutil.h
+       - change WCWIDTH macro to use _rl_utf8locale and the full range of
+         Unicode combining characters (U+0300-U+036F)
+
+                                  5/19
+                                  ----
+lib/readline/rlprivate.h
+       - _rl_search_context: new member, prevc, will hold character read
+         prior to lastc
+
+lib/readline/isearch.c
+       - _rl_isearch_dispatch: if the character causes us to index into
+         another keymap, save that character in cxt->prevc
+       - _rl_isearch_dispatch: if we index into another keymap, but don't
+         find a function that's special to i-search, and the character that
+         caused us to index into that keymap would have terminated the
+         search, push back cxt->prevc and cxt->lastc to make it appear as
+         if `prevc' terminated the search, and execute lastc as a command.
+         We have to push prevc back so we index into the same keymap before
+         we read lastc.  Fixes bug report from Davor Cubranic
+         <cubranic@stat.ubc.ca>
+
+                                  5/20
+                                  ----
+expr.c
+       - expr_bind_variable: pay attention to the return value from
+         bind_variable and check whether or not we should error out due to
+         a readonly or noassign variable.  Fixes bug reported by Eric
+         Blake <eblake@redhat.com>
+
+                                  5/26
+                                  ----
+
+lib/readline/search.c
+       - include histlib.h for ANCHORED_SEARCH defines
+       - rl_history_search_flags: new variable, holds ANCHORED_SEARCH flag for
+         the duration of a history search
+       - rl_history_search_reinit: takes a new flags variable, defines whether
+         or not the search is anchored; assigned to rl_history_search_flags
+       - rl_history_serarch_reinit: if ANCHORED_SEARCH flag passed, add ^ to
+         beginning of search string; otherwise search string is unmodified
+       - rl_history_search_internal: set rl_point appropriately based on
+         whether or not rl_history_search_flags includes ANCHORED_SEARCH
+       - rl_history_substr_search_forward: new function, for non-anchored
+         substring search forward through history for string of characters
+         preceding rl_point
+       - rl_history_substr_search_backward: new function, for non-anchored
+         substring search backward through history for string of characters
+         preceding rl_point.  Original code from Niraj Kulkarni
+         <kulkarniniraj14@gmail.com>
+
+lib/readline/readline.h
+       - extern declarations for rl_history_substr_search_{for,back}ward
+
+lib/readline/funmap.c
+       - history-substring-search-forward: new bindable command, invokes
+         rl_history_substr_search_forward
+       - history-substring-search-backward: new bindable command, invokes
+         rl_history_substr_search_backward
+
+lib/readline/doc/{rluser.texi,readline.3}
+       - document history-substring-search-forward and
+         history-substring-search-backward
+
+                                  5/27
+                                  ----
+{nojobs,jobs}.c
+       - add support for DONT_REPORT_SIGTERM so that the shell doesn't print
+         a message when a job exits due to SIGTERM since that's the default
+         signal sent by the kill builtin.  Suggested by Marc Herbert
+         <mark.herbert@gmail.com>
+
+config-top.h
+       - DONT_REPORT_SIGTERM: new user-modifiable setting.  Commented out
+         by default
+
+                                  5/28
+                                  ----
+lib/readline/bind.c
+       - _rl_skip_to_delim: skip to a closing double quote or other delimiter,
+         allowing backslash to quote any character, including the delimiter
+       - rl_parse_and_bind: call _rl_skip_to_delim instead of using inline
+         code
+       - rl_parse_and_bind: allow quoted strings as the values of string
+         variables.  Variable values without double quotes have trailing
+         whitespace removed (which still allows embedded whitespace, for
+         better or worse).  Fixes problem with string variables not matching
+         in `set' command if values happen to have trailing spaces or tabs
+         (debian bash bug #602762), but introduces slight incompatibility.
+
+                                  5/29
+                                  ----
+doc/{bash.1,bashref.texi}
+       - clarify unset description to specify that without options, a
+         variable, then a shell function if there is no variable by that
+         name, is unset.  Fixes discrepancy reported by Mu Qiao
+         <qiaomuf@gentoo.org>
+
+                                  6/4
+                                  ----
+doc/{bash.1,bashref.texi}
+       - clarify description of LINES and COLUMNS (and checkwinsize shopt
+         option) to make it clear that only interactive shells set a
+         handler for SIGWINCH and update LINES and COLUMNS.  Original
+         report submitted by Jonathan Nieder <jrnieder@gmail.com>
+
+arrayfunc.c
+       - expand_compound_array_assignment: defer expansion of words between
+         parens when performing compound assignmnt to an associative array
+         variable
+       - assign_compound_array_list: perform the same expansions when doing
+         a compound array assignment to an associative array variable as
+         when doing a straight array index assignment.  The idea is that
+               foo=( [ind1]=bar [ind2]=quux)
+         is the same as
+               foo[ind1]=bar ; foo[ind2]=quux
+
+         This fixes problems with double-expansion and quote removal being
+         performed on the array indices
+
+                                  6/13
+                                  ----
+doc/{bash.1,bashref.texi}
+       - Add a little text to make it clear that the locale determines how
+         range expressions in glob patterns are handled.
+
+
+                                  6/21
+                                  ----
+builtins/read.def
+       - display a message and return error status if -a is used with an
+         existing associative array.  Fixes bug reported by Curtis Doty
+         <curtis@greenkey.net>
+
+                                  6/24
+                                  ----
+{jobs,nojobs}.c
+       - non-interactive shells now react to the setting of checkwinsize
+         and set LINES and COLUMNS after a foreground job exits.  From a
+         suggestion by Leslie Rhorer <lrhorer@satx.rr.com>
+
+doc/{bash.1,bashref.texi}
+       - checkwinsize: remove language saying that only interactive shells
+         check the window size after each command
+
+lib/readline/histfile.c
+       - history_backupfile: new file, creates a backup history file name
+         given a filename (appending `-')
+       - history_do_write: when overwriting the history file, back it up
+         before writing.  Restore backup file on a write error.  Suggested
+         by chkno@chkno.net
+
+bashline.c
+       - find_cmd_name: two new arguments, return the start and end of the
+         actual text string used to find the command name, without taking
+         whitespace into account
+       - attempt_shell_completion: small changes to make sure that completion
+         attempted at the beginning of a non-empty line does not find a
+         programmable completion, even if the command name starts at point
+       - attempt_shell_completion: small change to make sure that completion
+         does not find a progcomp when in whitespace before the command
+         name
+       - attempt_shell_completion: small change to make sure that completion
+         does not find a progcomp when point is at the first character of a
+         command name, even when there is leading whitespace (similar to
+         above).  Fixes problems noted by Ville Skytta <ville.skytta@iki.fi>
+
+subst.c
+       - brace_expand_word_list: since the individual strings in the strvec
+         returned by brace_expand are already allocated, don't copy them to
+         newly-allocated memory when building the WORD_LIST, just use them
+         intact
+
+locale.c
+       - locale_mb_cur_max: cache value of MB_CUR_MAX when we set or change
+         the locale to avoid a function call every time we need to read it
+
+shell.h
+       - new struct to save shell_input_line and associated variables:
+         shell_input_line_state_t
+       - add members of sh_parser_state_t to save and restore token and the
+         size of the token buffer
+
+parse.y
+       - {save,restore}_input_line_state: new functions to save and restore
+         shell_input_line and associated variables
+       - {save,restore}_parser_state: add code to save and restore the token
+         and token buffer size
+       - xparse_dolparen: call save_ and restore_input_line_state to avoid
+         problems with overwriting shell_input_line when we recursively
+         call the parser to parse a command substitution.  Fixes bug
+         reported by Rui Santos <rsantos@grupopie.com>
+
+include/shmbutil.h
+       - use locale_mb_cur_max instead of MB_CUR_MAX in ADVANCE_CHAR and
+         similar macros
+
+lib/glob/smatch.c
+       - rangecmp,rangecmp_wc: change to take an additional argument, which
+         forces the use of strcoll/wscoll when non-zero.  If it's 0, a new
+         variable `glob_asciirange' controls whether or not we use strcoll/
+         wscoll.  If glob_asciirange is non-zero, we use straight
+         C-locale-like ordering. Suggested by  Aharon Robbins
+         <arnold@skeeve.com>
+
+                                  6/30
+                                  ----
+execute_cmd.c
+       - execute_pipeline: make sure the lastpipe code is protected by
+         #ifdef JOB_CONTROL.  Fixes problem reported by Thomas Cort
+         <tcort@minix3.org>
+
+                                   7/2
+                                   ---
+lib/readline/complete.c
+       - EXPERIMENTAL: remove setting of _rl_interrupt_immediately around
+         completion functions that touch the file system.  Idea from Jan
+         Kratochvil <jan.ktratochvil@redhat.com> and the GDB development
+         team
+
+lib/readline/signals.c
+       - rl_signal_handler: if we're in callback mode, don't interrupt
+         immediately on a SIGWINCH
+
+                                   7/3
+                                   ---
+bashline.c
+       - set_directory_hook: and its siblings are a new set of functions to
+         set, save, and restore the appropriate directory completion hook
+       - change callers to use {set,save,restore}_directory_hook instead of
+         manipulating rl_directory_rewrite_hook directly
+       - dircomplete_expand: new variable, defaults to 0, if non-zero causes
+         directory names to be word-expanded during word and filename
+         completion
+       - change {set,save,restore}_directory_hook to look at dircomplete_expand
+         and change rl_directory_completion_hook or rl_directory_rewrite_hook
+         appropriately
+
+bashline.h
+       - extern declaration for set_directory_hook so shopt code can use it
+
+                                   7/6
+                                   ---
+builtins/shopt.def
+       - globasciiranges: new settable shopt option, makes glob ranges act
+         as if in the C locale (so b no longer comes between A and B).
+         Suggested by Aharon Robbins <arnold@skeeve.com>
+
+                                   7/7
+                                   ---
+doc/{bash.1,bashref.texi}
+       - document new `globasciiranges' shopt option
+
+                                   7/8
+                                   ---
+builtins/shopt.def
+       - direxpand: new settable option, makes filename completion expand
+         variables in directory names like bash-4.1 did.
+       - shopt_set_complete_direxpand: new function, does the work for the
+         above by calling set_directory_hook
+
+doc/{bash.1,bashref.texi}
+       - document new `direxpand' shopt option
+
+                                  7/15
+                                  ----
+lib/readline/isearch.c
+       - _rl_isearch_dispatch: when adding character to search string, use
+         cxt->lastc (which we use in the switch statement) instead of c,
+         since lastc can be modified earlier in the function
+
+                                  7/18
+                                  ----
+lib/readline/rlprivate.h
+       - _rl_search_context: add another member to save previous value of
+         (multibyte) lastc: pmb is to mb as prevc is to lastc
+
+lib/readline/isearch.c:
+       - _rl_isearch_dispatch: if a key sequence indexes into a new keymap,
+         but doesn't find any bound function (k[ind].function == 0) or is
+         bound to self-insert (k[ind].function == rl_insert), back up and
+         insert the previous character (the one that caused the index into a
+         new keymap) and arrange things so the current character is the next
+         one read, so both of them end up in the search string.  Fixes bug
+         reported by Clark Wang <dearvoid@gmail.com>
+       - _rl_isearch_dispatch: a couple of efficiency improvements when adding
+         characters to the isearch string
+
+                                  7/24
+                                  ----
+lib/readline/isearch.c
+       - _rl_isearch_dispatch: save and restore cxt->mb and cxt->pmb
+         appropriately when in a multibyte locale
+
+doc/{bash.1,bashref.texi}
+       - correct description of {x}>file (and other redirection operators
+         that allocate a file descriptor) to note the the fd range is
+         greater than or equal to 10.  Fixes problem reported by
+         Christian Ullrich 
+
+lib/readline/signals.c
+       - rl_signal_handler: don't interrupt immediately if in callback mode
+
+lib/readline/callback.c
+       - rl_callback_read_char: install signal handlers only when readline
+         has control in callback mode, so readline's signal handlers aren't
+         called when the application is active (e.g., between the calls to
+         rl_callback_handler_install and rl_callback_read_char).  If the
+         readline signal handlers only set a flag, which the application
+         doesn't know about, the signals will effectively be ignored until
+         the next time the application calls into the readline callback
+         interface.  Fixes problem of calling unsafe functions from signal
+         handlers when in callback mode reported by Jan Kratochvil
+         <jan.kratochvil@redhat.com>
+
+execute_cmd.c
+       - fix_assignment_words: when in Posix mode, the `command' builtin
+         doesn't change whether or not the command name it protects is an
+         assignment builtin.  One or more instances of `command'
+         preceding `export', for instance, doesn't make `export' treat its
+         assignment statement arguments differently.  Posix interpretation
+         #351
+
+doc/{bash.1,bashref.texi}
+       - document new Posix-mode behavior of `command' when preceding builtins
+         that take assignment statements as arguments
+
+builtins/printf.def
+       - printstr: if fieldwidth or precision are < 0 or > INT_MAX when
+         supplied explicitly (since we take care of the `-' separately),
+         clamp at INT_MAX like when using getint().  Fixes issue reported
+         by Ralph Coredroy <ralph@inputplus.co.uk>
+
+                                  7/25
+                                  ----
+lib/readline/chardefs.h
+       - isxdigit: don't define if compiling with c++; declared as a c++
+         template function.  Fixes bug reported by Miroslav Lichvar
+         <mlichvar@redhat.com>
+
+builtins/printf.def
+       - getint: if garglist == 0, return whatever getintmax returns (0).
+         Fixes bug reported  by Ralph Coredroy <ralph@inputplus.co.uk>
+
+                                  7/28
+                                  ----
+doc/{bash.1,bashref.texi}
+       - minor changes to the descriptions of the cd and pushd builtins
+
+lib/sh/zread.c
+       - zsyncfd: change variable holding return value from lseek to
+         off_t.  Bug report and fix from Gregory Margo <gmargo@pacbell.net>
+
+                                   8/1
+                                   ---
+expr.c
+       - don't check for division by 0 when in a context where no evaluation
+         is taking place.  Fixes bug reported by dnade.ext@orange-ftgroup.com
+
+                                   8/6
+                                   ---
+execute_cmd.c
+       - execute_command_internal: the parent branch of the subshell code
+         (where the child calls execute_in_subshell) should not close all
+         open FIFOs with unlink_fifo_list if it's part of a shell function
+         that's still executing.  Fixes bug reported by Maarten Billemont
+         <lhunath@lyndir.com>
+
+                                   8/9
+                                   ---
+builtins/common.c
+       - get_exitstat: return EX_BADUSAGE (2) on a non-numeric argument
+
+builtins/return.def
+       - return_builtin: just call get_exitstat to get the return status,
+         let it handle proper parsing and handling of arguments.  Fixes
+         issue most recently raised by Linda Walsh <bash@tlinx.org>.
+         Reverses change from 9/11/2008 (see above)
+
+                                  8/16
+                                  ----
+doc/{bash.1,bashref.texi}
+       - clean up `set -e' language to make it clearer that any failure of
+         a compound command will cause the shell to exit, not just subshells
+         and brace commands
+
+                                  8/17
+                                  ----
+configure.in
+       - make the various XXX_FOR_BUILD variables `precious' to autoconf to
+         avoid stale data
+       - change how CC_FOR_BUILD is initialized when cross-compiling and not,
+         but do not change behavior
+       - initialize CFLAGS_FOR_BUILD to -g when cross-compiling
+       - initialize LIBS_FOR_BUILD to $(LIBS) when not cross-compiling, empty
+         when cross-compiling
+       - create AUTO_CFLAGS variable to hold basic CFLAGS defaults; used when
+         CFLAGS not inherited from environment (like effect of old
+         auto_cflags variable)
+       - substitute LIBS_FOR_BUILD into output Makefiles
+         [changes inspired by bug report from Nathan Phillip Brink
+         <ohnobinki@ohnopublishing.net> -- gentoo bug 378941]
+
+builtins/Makefile.in   
+       - substitute LIBS_FOR_BUILD from configure, not strictly initialized
+         to $(LIBS)
+
+                                  8/27
+                                  ----
+doc/{bash.1,bashref.texi}
+       - minor changes to the here string description to clarify the
+         expansions performed on the word
+
+support/shobj-conf
+       - handle compilation on Lion (Mac OS X 10.7/darwin11) with changes
+         to darwin stanzas.  Fixes readline bug reported by Vincent
+         Sheffer <vince.sheffer@apisphere.com>
+
+lib/sh/strtrans.c
+       - ansic_wshouldquote: check a string with multi-byte characters for
+         characters that needs to be backslash-octal escaped for $'...'
+       - ansic_shouldquote: if is_basic fails for one character, let
+         ansic_wshouldquote examine the rest of the string and return what
+         it returns.  From a patch sent by Roman Rakus <rrakus@redhat.com>
+
+                                  8/30
+                                  ----
+lib/sh/strtrans.c
+       - ansic_quote: changes to quote (or not) multibyte characters.  New
+         code converts them to wide characters and uses iswprint to check
+         valid wide chars.  From a patch sent by Roman Rakus
+         <rrakus@redhat.com>
+
+                                   9/7
+                                   ---
+lib/sh/shquote.c
+       - sh_backslash_quote: change to be table-driven so we can use a
+         different table if we want to
+       - sh_backslash_quote: takes a second char table[256] argument;
+
+externs.h
+       - sh_backslash_quote: add second argument to function prototype
+
+bashline.c,braces.c,parse.y,builtins/printf.def
+       - change callers of sh_backslash_quote to add second argument
+
+bashline.c
+       - filename_bstab: table of characters to pass to sh_backslash_quote;
+         characters with value 1 will be backslash-quoted
+       - set_filename_bstab: turn on characters in filename backslash-quote
+         table according to passed string argument
+       - call set_filename_bstab every time rl_filename_quote_characters is
+         assigned a value
+       - bash_quote_filename: call sh_backslash_quote with filename_bstab
+         as second argument.  This allows other characters in filenames to
+         be quoted without quoting, for instance, a dollar sign in a shell
+         variable reference
+
+                                   9/8
+                                   ---
+bashline.c
+       - complete_fullquote: new variable, controls table passed to
+         sh_backslash_quote.  If non-zero (the default), the standard set
+         of shell metacharacters -- as in bash versions up to and including
+         bash-4.2 -- gets backslash-quoted by the completion code.  If zero,
+         sh_backslash_quote gets the table with the characters in the
+         variable reference removed, which means they are removed from the
+         set of characters to be quoted in filenames
+
+                                  9/10
+                                  ----
+bashline.c
+       - bash_filename_stat_hook: new function, designed to expand variable
+         references in filenames before readline passes them to stat(2)
+         to determine whether or not they are a directory
+
+                                  9/15
+                                  ----
+builtins/declare.def
+       - if assign_array_element fails due to a bad (or empty) subscript, mark
+         it as an assignment error and don't attempt any further processing
+         of that declaration.  Fixes segfault bug reported by Diego Augusto
+         Molina <diegoaugustomolina@gmail.com>
+
+                                  9/19
+                                  ----
+expr.c
+       - exppower: replace the simple exponentiation algorithm with an
+         implementation of exponentiation by squaring.  Inspired by report
+         from Nicolas ARGYROU <nargy@yahoo.com>
+
+bashline.c
+       - bash_quote_filename: check for rtext being non-null before
+         dereferencing it
+       - set_saved_history: operate_and_get_next assumes that the previous
+         line was added to the history, even when the history is stifled and
+         at the max number of entries.  If it wasn't, make sure the history
+         number is incremented properly.  Partial fix for bug reported by
+         gregrwm <backuppc-users@whitleymott.net>
+
+doc/{bash.1,bashref.texi},lib/readline/doc/{hsuser,rluser}.texi
+       - minor editorial changes inspired by suggestions from
+         Roger Zauner <rogerx.oss@gmail.com>
+
+                                  9/20
+                                  ----
+lib/intl/localealias.c
+       - read_alias_file: close resource leak (fp) when returning on error
+
+                                  9/22
+                                  ----
+execute_command.c
+       - execute_intern_function: implement Posix interpretation 383 by making
+         it an error to define a function with the same name as a special
+         builtin when in Posix mode.
+         http://austingroupbugs.net/view.php?id=383#c692
+
+                                  9/25
+                                  ----
+doc/{bash.1,bashref.texi}
+       - formatting and some content changes from Benno Schulenberg
+         <bensberg@justemail.net>
+       - document new posix-mode behavior from interp 383 change of 9/22
+
+                                  9/30
+                                  ----
+execute_cmd.c
+       - shell_execve: add strerror to error message about executable file
+         that shell can't execute as a shell script.  From suggestion by
+         daysleeper <daysleeper@centrum.cz>
+
+                                  10/1
+                                  ----
+bashhist.c
+       - maybe_add_history: act as if literal_history is set when parser_state
+         includes PST_HEREDOC, so we save the bodies of here-documents just
+         as they were entered.  Fixes bug reported by Jonathan Wakely
+         <bugs@kayari.org>
+       - bash_add_history: make sure that the second and subsequent lines of
+         a here document don't have extra newlines or other delimiting
+         chars added, since they have the trailing newline preserved, when
+         `lithist' is set and history_delimiting_chars isn't called
+
+execute_cmd.c
+       - execute_command_internal: avoid fd exhaustion caused by using
+         process substitution in loops inside shell functions by using
+         copy_fifo_list and close_new_fifos ().  Fixes debian bash bug
+         642504
+
+lib/readline/complete.c
+       - new variable, rl_filename_stat_hook, used by append_to_match.  If
+         filename completion is desired, and rl_filename_stat_hook points
+         to a function, call that function to expand the filename in an
+         application-specific way before calling stat.
+
+bashline.c
+       - bash_default_completion: if variable completion returns a single
+         match, use bash_filename_stat_hook and file_isdir to determine
+         whether or not the variable name expands to a directory.  If it
+         does, set the filename_append_character to `/'.  This is not
+         perfect, so we will see how it works out.  Adds functionality
+         requested by Peter Toft <pto@linuxbog.dk> and Patrick Pfeifer
+         <patrick@pfeifer.de>
+       - rl_filename_stat_hook: assigned bash_filename_stat_hook, so things
+         like $HOME/Downloads (after completion) have a slash appended.
+         In general, this causes the stat hook to be called whenever
+         filename completion is appended.  Adds functionality requested by
+         Patrick Pfeifer <patrick@pfeifer.de>
+
+lib/readline/readline.h
+       - new extern declaration for rl_filename_stat_hook
+
+lib/readline/doc/rltech.texi
+       - rl_directory_rewrite_hook: now documented
+       - rl_filename_stat_hook: document
+
+pcomplete.c
+       - gen_action_completions: in the CA_DIRECTORY case, turn off
+         rl_filename_completion_desired if it was off before we called
+         rl_filename_completion_function and we didn't get any matches.
+         Having it on causes readline to quote the matches as if they
+         were filenames.  Adds functionality requested by many,
+         including Clark Wang <dearvoid@gmail.com>
+
+assoc.[ch]
+       - assoc_replace: new function, takes the same arguments as
+         assoc_insert, but returns the old data instead of freeing it
+       - assoc_insert: if the object returned by hash_insert doesn't have
+         the same value for its key as the key passed as an argument, we
+         are overwriting an existing value.  In this case, we can free the
+         key.  Fixes bug reported by David Parks <davidparks21@yahoo.com>
+
+                                  10/5
+                                  ----
+print_cmd.c
+       - indirection_level_string: small change to only re-enable `x'
+         option after calling decode_prompt_string if it was on before.  In
+         normal mode, it will be, but John Reiser <jreiser@bitwagon.com>
+         has a novel use for that code in conjunction with a pre-loaded
+         shared library that traces system call usage in shell scripts
+
+                                  10/10
+                                  -----
+Makefile.in
+       - Fix from Mike Frysinger <vapier@gentoo.org> to avoid trying to
+         build y.tab.c and y.tab.h with two separate runs of yacc if
+         parse.y changes.  Problem with parallel makes
+       - Fix from Mike Frysinger <vapier@gentoo.org> to avoid subdirectory
+         builds each trying to make version.h (and all its dependencies)
+
+lib/sh/Makefile.in
+       - remove some dependencies on version.h where it doesn't make sense
+
+variables.c
+       - initialize_shell_variables: while reading the environment, a shell
+         running in posix mode now checks for SHELLOPTS being readonly (it
+         gets set early on in main()) before trying to assign to it.  It
+         saves an error message and the variable gets parsed as it should.
+         Fixes bug reported by Len Giambrone <Len.Giambrone@intersystems.com>
+
+                                  10/14
+                                  -----
+doc/{bash.1,bashref.texi}
+       - add to the "duplicating file descriptors" description that >&word
+         doesn't redirect stdout and stderr if word expands to `-'
+       - add to the "appending standard output and standard error"
+         description a note that >&word, where word is a number or `-',
+         causes other redirection operators to apply for sh and Posix
+         compatibility reasons.  Suggested by Greg Wooledge
+         <wooledg@eeg.ccf.org>
+
+                                  10/15
+                                  -----
+pcomplete.c
+       - change pcomp_filename_completion_function to only run the filename
+         dequoting function in the cases (as best as it can figure) where
+         readline won't do it via rl_filename_completion_function.  Based
+         on reports from <lolilolicon@gmail.com>
+
+                                  10/19
+                                  -----
+bashline.c
+       - attempt_shell_completion: add call to set_directory_hook() to make
+         sure the rewrite functions are correct.  It's cheap and doesn't
+         hurt
+       - command_word_completion_function: if completing a command name that
+         starts with `.' or `..', temporarily suppress the effects of the
+         `direxpand' option and restore the correct value after calling
+         rl_filename_completion_function.  If it's enabled, the directory
+         name will be rewritten and no longer match `./' or `../'.  Fixes
+         problem reported by Michael Kalisz <michael@kalisz.homelinux.net>
+
+                                  10/22
+                                  -----
+builtins/history.def
+       - push_history: make sure remember_on_history is enabled before we
+         try to delete the last history entry -- the `history -s' command
+         might not have been saved.  Fixes bug reported by
+         lester@vmw-les.eng.vmware.com
+
+lib/readline/complete.c
+       - rl_callback_read_char: add calls to a macro CALLBACK_READ_RETURN
+         instead of straight return; add same call at end of function.
+         Placeholder for future work in deinstalling signal handlers when
+         readline is not active
+
+                                  10/25
+                                  -----
+expr.c
+       - exp2: catch arithmetic overflow when val1 == INTMAX_MIN and val2 == -1
+         for DIV and MOD and avoid SIGFPE.  Bug report and pointer to fix
+         from Jaak Ristioja <jaak.ristioja@cyber.ee>
+       - expassign: same changes for arithmetic overflow for DIV and MOD
+
+                                  10/28
+                                  -----
+subst.c
+       - parameter_brace_expand: allow pattern substitution when there is an
+         expansion of the form ${var/} as a no-op: replacing nothing with
+         nothing
+       - parameter_brace_patsub: don't need to check for PATSUB being NULL;
+         it never is
+
+flags.c
+       - if STRICT_POSIX is defined, initialize history_expansion to 0, since
+         history expansion (and its treatment of ! within double quotes) is
+         not a conforming posix environment.  From austin-group issue 500
+
+lib/readline/histexpand.c
+       - history_expand: when processing a string within double quotes
+         (DQUOTE == 1), make the closing double quote inhibit history
+         expansion, as if the word were outside double quotes.  In effect,
+         we assume that the double quote is followed by a character in
+         history_no_expand_chars.  tcsh and csh seem to do this.  This
+         answers a persistent complaint about history expansion
+
+                                  10/29
+                                  -----
+make_cmd.c
+       - make_arith_for_command: use skip_to_delim to find the next `;'
+         when breaking the string between the double parens into three
+         separate components instead of a simple character loop.  Fixes
+         bug reported by Dan Douglas <ormaaj@gmail.com>
+
+                                  11/2
+                                  ----
+Makefile.in
+       - make libbuiltins.a depend on builtext.h to serialize its creation
+         and avoid conflict between multiple invocations of mkbuiltins.
+         Fix from Mike Frysinger <vapier@gentoo.org>
+
+                                  11/5
+                                  ----
+findcmd.c
+       - user_command_matches: if stat(".", ...) returns -1, set st_dev
+         and st_ino fields in dotinfo to 0 to avoid same_file matches
+       - find_user_command_in_path: check stat(2) return the same way
+
+lib/glob/glob.c
+       - glob_vector: don't call strlen(pat) without checking pat == 0
+       - glob_dir_to_array: make sure to free `result' and all allocated
+         members before returning error due to malloc failure
+       - glob_vector: make sure to free `nextname' and `npat' on errors
+         (mostly when setting lose = 1)
+       - glob_vector: if flags & GX_MATCHDIRS but not GX_ALLDIRS, make
+         sure we free `subdir'
+       - glob_filename: when expanding ** (GX_ALLDIRS), make sure we
+         free temp_results (return value from glob_vector)
+
+lib/glob/xmbsrtowcs.c
+       - xdupmbstowcs: fix call to realloc to use sizeof (char *) instead
+         of sizeof (char **) when assigning idxtmp
+
+execute_cmd.c
+       - print_index_and_element: return 0 right away if L == 0
+       - is_dirname: fix memory leak by freeing `temp'
+       - time_command: don't try to deref NULL `command' when assigning
+         to `posix_time'
+       - shell_execve: null-terminate `sample' after READ_SAMPLE_BUF so it's
+         terminated for functions that expect that
+
+builtins/read.def
+       - read_builtin: don't call bind_read_variable with a potentially-null
+         string
+
+pcomplete.c
+       - gen_command_matches: don't call dispose_word_desc with a NULL arg
+       - gen_compspec_completions: fix memory leak by freeing `ret' before
+         calling gen_action_completions (tcs, ...).  happens when
+         performing directory completion as default and no completions
+         have been generated
+       - gen_progcomp_completions: make sure to set foundp to 0 whenever
+         returning NULL
+       - it_init_aliases: fix memory leak by freeing alias_list before
+         returning
+
+bashline.c
+       - command_word_completion_function: don't call restore_tilde with a
+         NULL directory_part argument
+       - bash_directory_expansion: bugfix: don't throw away results of
+         rl_directory_rewrite_hook if it's set and returns non-zero
+       - bind_keyseq_to_unix_command: free `kseq' before returning error
+
+arrayfunc.c
+       - assign_array_element_internal: make sure `akey' is freed if non-null
+         before returning error
+       - assign_compound_array_list: free `akey' before returning error
+       - array_value_internal: free `akey' before returning error
+       - unbind_array_element: free `akey' before returning error
+
+subst.c
+       - array_length_reference: free `akey' before returning error in case
+         of expand_assignment_string_to_string error
+       - array_length_reference: free `akey' after call to assoc_reference
+       - skip_to_delim: if skipping process and command substitution, free
+         return value from extract_process_subst
+       - parameter_brace_substring: free `val' (vtype == VT_VARIABLE) before
+         returning if verify_substring_values fails
+       - parameter_brace_expand: remove two duplicate lines that allocate
+         ret in parameter_brace_substring case
+       - parameter_brace_expand: convert `free (name); name = xmalloc (...)'
+         to use `xrealloc (name, ...)'
+       - parameter_brace_expand: free `name' before returning when handling
+         ${!PREFIX*} expansion
+       - split_at_delims: fix memory leak by freeing `d2' before returning
+
+redir.c
+       - redirection_error: free `filename' if the redirection operator is
+         REDIR_VARASSIGN by assigning allocname
+
+eval.c
+       - send_pwd_to_eterm: fix memory leak by freeing value returned by
+         get_working_directory()
+
+builtins/cd.def
+       - change_to_directory: fix memory leak by freeing return value from
+         resetpwd()
+       - cd_builtin: fix memory leak by freeing value returned by dirspell()
+       - cd_builtin: fix memory leak by freeing `directory' if appropriate
+         before overwriting with return value from resetpwd()
+
+builtins/type.def
+       - describe_command: free `full_path' before overwriting it with return
+         value from sh_makepath
+
+builtins/complete.def
+       - compgen_builtin: fix memory leak by calling strlist_dispose (sl)
+         before overwriting sl with return value from completions_to_stringlist
+
+builtins/hash.def
+       - list_hashed_filename_targets: fix memory leak by freeing `target'
+
+make_cmd.c
+       - make_arith_for_command: free `init', `test', and `step' before
+         returning error on parse error
+
+jobs.c
+       - initialize_job_control: don't call move_to_high_fd if shell_tty == -1
+
+general.c
+       - check_dev_tty: don't call close with an fd < 0
+       - legal_number: deal with NULL `string' argument, return invalid
+
+lib/sh/fmtulong.c
+       - fmtulong: if the `base' argument is invalid, make sure we index
+         buf by `len-1' at maximum
+
+print_cmd.c
+       - print_deferred_heredocs: don't try to dereference a NULL `cstring'
+       - cprintf: make sure to call va_end (args)
+
+variables.c
+       - push_dollar_vars: fix call to xrealloc to use sizeof (WORD_LIST *)
+         instead of sizeof (WORD_LIST **)
+
+lib/sh/zmapfd.c
+       - zmapfd: if read returns error, free result and return -1 immediately
+         instead of trying to reallocate it
+
+                                  11/6
+                                  ----
+execute_cmd.c
+       - cpl_reap: rewrote to avoid using pointer after freeing it; now builds
+         new coproc list on the fly while traversing the old one and sets the
+         right values for coproc_list when done
+
+                                  11/12
+                                  -----
+builtins/set.def
+       - if neither -f nor -v supplied, don't allow a readonly function to
+         be implicitly unset.  Fixes bug reported by Jens Schmidt
+         <jens.schmidt35@arcor.de>
+
+lib/readline/callback.c
+       - change CALLBACK_READ_RETURN to clear signal handlers before returning
+         from rl_callback_read_char so readline's signal handlers aren't
+         installed when readline doesn't have control.  Idea from Jan
+         Kratochvil <jan.ktratochvil@redhat.com> and the GDB development
+         team
+
+pcomplete.h
+       - COPT_NOQUOTE: new complete/compgen option value
+
+builtins/complete.def
+       - noquote: new complete/compgen option; will be used to disable
+         filename completion quoting
+
+pcomplete.c
+       - pcomp_set_readline_variables: pay attention to COPT_NOQUOTE; turns
+         of rl_filename_quoting_desired if set; turns it on if unset (value
+         is inverted, since default is on)
+
+doc/bash.1,lib/readline/doc/rluser.texi
+       - document new -o noquote option to complete/compgen/compopt
+
+pathexp.c
+       - quote_string_for_globbing: if QGLOB_REGEXP, make sure characters
+         between brackets in an ERE bracket expression are not inappropriately
+         quoted with backslashes.  This is a pretty substantial change,
+         should be stressed when opening bash up for alpha and beta tests.
+         Fixes bug pointed out by Stephane Chazleas
+         <stephane_chazelas@yahoo.fr>
+
+doc/{bash.1,bashref.texi}
+       - document that regexp matches can be inconsistent when quoting
+         characters in bracket expressions, since usual quoting characters
+         lose their meaning within brackets
+       - note that regular expression matching when the pattern is stored
+         in a shell variable which is quoted for expansion causes string
+         matching
+
+redir.h
+       - RX_SAVEFD: new flag value; notes that a redirection denotes an
+         fd used to save another even if it's not >= SHELL_FD_BASE
+
+redir.c
+       - do_redirection_internal: when deciding whether or not to reset the
+         close-on-exec flag on a restored file descriptor, trust the value
+         of redirect->flags & RX_SAVCLEXEC even if the fd is < SHELL_FD_BASE
+         if the RX_SAVEFD flag is set
+       - add_undo_redirect: set the RX_SAVEFD flag if the file descriptor
+         limit is such that the shell can't duplicate to a file descriptor
+         >= 10.  Fixes a limitation that tripped a coreutils test reported
+         by Paul Eggert <eggert@cs.ucla.edu>
+
+                                  11/19
+                                  -----
+doc/{bash.1,bashref.texi},lib/readline/doc/hsuser.texi
+       - make it clear that bash runs HISTFILESIZE=$HISTSIZE after reading
+         the startup files
+       - make it clear that bash runs HISTSIZE=500 after reading the
+         startup files
+       - make it clear that setting HISTSIZE=0 causes commands to not be
+         saved in the history list
+       - make it clear that setting HISTFILESIZE=0 causes the history file
+         to be truncated to zero size
+
+variables.c
+       - sv_histsize: change so setting HISTSIZE to a value less than 0
+         causes the history to be `unstifled'
+       - sv_histsize: change so setting HISTFILESIZE to a value less than 0
+         results in no file truncation
+       - make it clear that numeric values less than 0 for HISTFILESIZE or
+         HISTSIZE inhibit the usual functions
+
+                                  11/23
+                                  -----
+parse.y
+       - save_input_line_state: add missing `return ls' at the end, since the
+         function is supposed to return its argument.  Pointed out by
+         Andreas Schwab <schwab@linux-m68k.org>
+
+builtins/read.def
+       - skip over NUL bytes in input, as most modern shells seem to.  Bug
+         report by Matthew Story <matt@tablethotels.com>
+
+lib/readline/vi_mode.c
+       - rl_vi_replace: set _rl_vi_last_key_before_insert to invoking key
+
+                                  11/25
+                                  -----
+builtins/read.def
+       - read_builtin: if xrealloc returns same pointer as first argument,
+         don't bother with the remove_unwind_protect/add_unwind_protect pair
+       - read_builtin: set a flag (`reading') around calls to zread/zreadc
+         and readline()
+       - sigalrm: change to set flag (`sigalrm_seen') and only longjmp if
+         currently in read(2) (reading != 0)
+       - CHECK_ALRM: new macro, checks sigalrm_seen and longjmps if non-zero,
+         behavior of old SIGALRM catching function
+       - read_builtin: call CHECK_ALRM in appropriate places while reading
+         line of input.  Fixes bug reported by Pierre Gaston
+         <pierre.gaston@gmail.com>
+
+lib/readline/vi_mode.c
+       - rl_vi_replace: initialize characters before printing characters in
+         vi_replace_keymap to their default values in vi_insertion_keymap,
+         since we're supposed to be in insert mode replacing characters
+       - rl_vi_replace: call rl_vi_start_inserting to set last command to
+         `R' for undo
+       - rl_vi_replace: set _rl_vi_last_key_before_insert to `R' for future
+         use by _rl_vi_done_inserting
+       - vi_save_insert_buffer: new function, broke out code that copies text
+         into vi_insert_buffer from _rl_vi_save_insert
+       - _rl_vi_save_replace: new function, saves text modified by
+         rl_vi_replace (using current point and vi_replace_count to figure
+         it out) to vi_replace_buffer
+       - _rl_vi_save_insert: call vi_save_insert_buffer
+       - _rl_vi_done_inserting: if _rl_vi_last_key_before_insert == 'R', call
+         _rl_vi_save_replace to save text modified in replace mode (uses
+         vi_save_insert_buffer)
+       - _rl_vi_replace_insert: new function, replaces the number of chars
+         in vi_insert_buffer after rl_point with contents ov vi_insert_buffer
+       - rl_vi_redo: call _rl_vi_replace_insert if last command == 'R' and
+         there's something in vi_insert_buffer.  Fixes bug with `.' not
+         redoing the most recent `R' command, reported by Geoff Clare
+         <g.clare@opengroup.org> in readline area on savannah
+
+                                  11/26
+                                  -----
+lib/readline/rlprivate.h
+       - RL_SIG_RECEIVED(): evaluate to non-zero if there is a pending signal
+         to be handled
+       - RL_SIGINT_RECEIVED(): evaluate to non-zero if there is a pending
+         SIGINT to be handled
+
+lib/readline/complete.c
+       - remove all mention of _rl_interrupt_immediately
+       - rl_completion_matches: check RL_SIG_RECEIVED after each call to
+         the entry function, call RL_CHECK_SIGNALS if true to handle the
+         signal
+       - rl_completion_matches: if RL_SIG_RECEIVED evaluates to true, free
+         and zero out the match_list this function allocated
+       - rl_completion_matches: if the completion entry function is
+         rl_filename_completion_function, free the contents of match_list,
+         because that function does not keep state and will not free the
+         entries; avoids possible memory leak pointed out by
+         Garrett Cooper <yanegomi@gmail.com>
+       - gen_completion_matches: if RL_SIG_RECEIVED evalutes to true after
+         calling rl_attempted_completion_function, free the returned match
+         list and handle the signal with RL_CHECK_SIGNALS; avoids
+         possible memory leak pointed out by Garrett Cooper
+         <yanegomi@gmail.com>
+       - gen_completion_matches: if RL_SIG_RECEIVED evaluates to true after
+         calling rl_completion_matches, free the returned match list and
+         handle the signal with RL_CHECK_SIGNALS
+
+lib/readline/util.c
+       - rl_settracefp: new utility function to set the tracing FILE *
+
+lib/readline/signals.c
+       - _rl_sigcleanup: pointer to a function that will be called with the
+         signal and a void * argument from _rl_handle_signal
+       - _rl_sigcleanarg: void * that the rest of the code can set to have
+         passed to the signal cleanup function
+       - _rl_handle_signal: if _rl_sigcleanup set, call as
+               (*_rl_sigcleanup) (sig, _rl_sigcleanarg)
+
+lib/readline/rlprivate.h
+       - extern declarations for _rl_sigcleanup and _rl_sigcleanarg
+
+lib/readline/complete.c
+       - _rl_complete_sigcleanup: signal cleanup function for completion code;
+         calls _rl_free_match_list on _rl_sigcleanarg if signal == SIGINT
+       - rl_complete_internal: before calling display_matches if what_to_do
+         == `?', set _rl_sigcleanup to _rl_complete_sigcleanup so the match
+         list gets freed on SIGINT; avoids possible memory leak pointed out
+         by Garrett Cooper <yanegomi@gmail.com>
+       - rl_complete_internal: in default switch case, call _rl_free_match_list
+         before returning to avoid memory leak
+
+doc/bashref.texi
+       - start at a set of examples for the =~ regular expression matching
+         operator, touching on keeping the pattern in a shell variable and
+         quoting portions of the pattern to remove their special meaning
+
+                                  12/1
+                                  ----
+lib/glob/gmisc.c
+       - extglob_pattern: new function, returns 1 if pattern passed as an
+         argument looks like an extended globbing pattern
+
+lib/glob/glob.c
+       - skipname: return 0 immediately if extglob_pattern returns non-zero,
+         let the extended globbing code do the right thing with skipping
+         names beginning with a `.'
+       - mbskipname: return 0 immediately if extglob_pattern returns non-zero,
+         let the extended globbing code do the right thing with skipping
+         names beginning with a `.'.  Fixes bug reported by Yongzhi Pan
+         <panyongzhi@gmail.com>
+
+                                  12/2
+                                  ----
+lib/glob/smatch.c
+       - patscan, patscan_wc: no longer static so other parts of the glob
+         library can use them, renamed to glob_patscan, glob_patscan_wc
+
+lib/glob/glob.c
+       - extern declarations for glob_patscan, glob_patscan_wc
+       - wchkname: new function, does skipname on wchar_t pattern and dname,
+         old body of mbskipname after converting to wide chars
+       - extglob_skipname: new function, checks all subpatterns in an extglob
+         pattern to determine whether or not a filename should be skipped.
+         Calls skipname for each subpattern.  Dname is only skipped if all
+         subpatterns indicate it should be.  Better fix for bug reported by
+         Yongzhi Pan <panyongzhi@gmail.com>
+       - wextglob_skipname: wide-char version of extglob_skipname, calls
+         wchkname instead of calling back into mbskipname for each
+         subpattern to avoid problems with char/wchar_t mismatch
+       - skipname: call extglob_skipname if extglob_pattern returns non-zero
+       - mbskipname: call wextglob_skipname if extglob_pattern returns non-zero
+       - mbskipname: short-circuit immediately if no multibyte chars in
+         pattern or filename
+
+execute_cmd.c
+       - execute_cond_node: added parens to patmatch assignment statement to
+         make intent clearer
+
+                                  12/3
+                                  ----
+configure.in,config.h.in
+       - check for imaxdiv, define HAVE_IMAXDIV if present
+
+expr.c
+       - expassign, exp2: use imaxdiv if available.  Doesn't help with checks
+         for overflow from 10/25
+
+                                  12/6
+                                  ----
+lib/readline/complete.c
+       - compute_lcd_of_matches: if we're ignoring case in the matches, only
+         use what the user typed as the lcd if it matches the first match
+         (after sorting) up to the length of what was typed (if what the
+         user typed is longer than the shortest of the possible matches, use
+         the shortest common length of the matches instead).  If it doesn't
+         match, use the first of the list of matches, as if case were not
+         being ignored.  Fixes bug reported by Clark Wang
+         <dearvoid@gmail.com>
+
+                                  12/7
+                                  ----
+builtins/cd.def
+       - cd_builtin: add code to return error in case cd has more than one
+         non-option argument, conditional on CD_COMPLAINS define (which is
+         not defined anywhere)
+
+doc/{bash.1,bashref.texi}
+       - note that additional arguments to cd following the directory name
+         are ignored.  Suggested by Vaclav Hanzl <hanzl@noel.feld.cvut.cz>
+
+                                  12/10
+                                  -----
+lib/readline/input.c
+       - rl_read_key: don't need to increment key sequence length here; doing
+         it leads to an off-by-one error
+
+lib/readline/macro.c
+       - rl_end_kbd_macro: after off-by-one error with rl_key_sequence_length
+         fixed, can decrement current_macro_index by rl_key_sequence_length
+         (length of key sequence that closes keyboard macro)
+
+lib/readline/readline.c
+       - _rl_dispatch_subseq: fix extra increment of rl_key_sequence_length
+         when ESC maps to a new keymap and we're converting meta characters
+         to ESC+key
+       - _rl_dispatch_subseq: better increment of rl_key_sequence_length
+         before we dispatch to a function in the ISFUNC case (where the
+         second increment above should have happened)
+       - rl_executing_keyseq: the full key sequence that ended up executing
+         a readline command.  Available to the calling application, maintained
+         by _rl_dispatch_subseq, indexed by rl_key_sequence_length
+       - rl_executing_key: the key that was bound to the currently-executing
+         readline command.  Same as the `key' argument to the function
+
+lib/readline/readline.h
+       - rl_executing_keyseq: extern declaration
+       - rl_executing_key: extern declaration
+       - rl_key_sequence_length: declaration moved here from rlprivate.h,
+         now part of public interface
+
+lib/readline/rlprivate.h
+       - new extern declaration for _rl_executing_keyseq_size, buffer size
+         for rl_executing_keyseq
+
+lib/readline/doc/rltech.texi
+       - documented new variables: rl_executing_key, rl_executing_keyseq,
+         rl_key_sequence_length
+
+                                  12/13
+                                  -----
+bashline.c
+       - bash_execute_unix_command: replace ad-hoc code that searches
+         cmd_xmap for correct command with call to rl_function_of_keyseq
+         using rl_executing_keyseq; now supports key sequences longer
+         than two characters.  Fixes bug reported by Michael Kazior
+         <kazikcz@gmail.com>
+
+                                  12/15
+                                  -----
+make_cmd.c
+       - make_function_def: don't null out source_file before calling
+         make_command so it can be used later on when the function definition
+         is executed
+
+execute_cmd.c
+       - execute_intern_function: second argument is now FUNCTION_DEF *
+         instead of COMMAND *
+       - execute_command_internal: call execute_intern_function with the
+         new second argument (the entire FUNCTION_DEF instead of just the
+         command member)
+       - execute_intern_function: if DEBUGGER is defined, call
+         bind_function_def before calling bind_function, just like
+         make_function_def does (might be able to take out the call in
+         make_function_def depending on what the debugger does with it).
+         Fixes bug reported by <dethrophes@motd005>
+
+expr.c
+       - more minor changes to cases of INTMAX_MIN % -1 and INTMAX_MIN / 1;
+         fix typos and logic errors
+
+                                  12/16
+                                  -----
+bashline.c
+       - find_cmd_start: change flags to remove SD_NOSKIPCMD so it skips over
+         command substitutions and doesn't treat them as command separators
+       - attempt_shell_completion: instead of taking first return from
+         find_cmd_name as command name to use for programmable completion,
+         use loop to skip over assignment statements.  Fixes problem reported
+         by Raphael Droz <raphael.droz+floss@gmail.com>
+       - attempt_shell_completion: if we don't find a command name but the
+         command line is non-empty, assume the other words are all assignment
+         statements and flag that point is in a command position so we can
+         do command name completion
+       - attempt_shell_completion: if the word being completed is the first
+         word following a series of assignment statements, and the
+         command line is non-empty, flag that point is in a command position
+         so we can do command name completion
+
+lib/readline/history.c
+       - history_get_time: atol -> strtol
+
+                                  12/18
+                                  -----
+parse.y
+       - parser_in_command_position: external interface to the
+         command_token_position macro for use by other parts of the shell,
+         like the completion mechanism
+
+externs.h
+       - extern declaration for parser_in_command_position
+
+                                  12/19
+                                  -----
+
+builtins/read.def
+       - read_builtin: make sure all calls to bind_read_variable are passed
+         a non-null string.  Fixes bug reported by Dan Douglas
+         <ormaaj@gmail.com>
+
+bashline.c
+       - attempt_shell_completion: mark that we're in a command position if
+         we're at the start of the line and the parser is ready to accept
+         a reserved word or command name.  Feature most recently suggested
+         by Peng Yu <pengyu.ut@gmail.com>
+
+                                  12/21
+                                  -----
+lib/readline/bind.c
+       - _rl_escchar: return the character that would be backslash-escaped
+         to denote the control character passed as an argument ('\n' -> 'n')
+       - _rl_isescape: return 1 if character passed is one that has a
+         backslash escape
+       - _rl_untranslate_macro_value: new second argument: use_escapes, if
+         non-zero translate to backslash escapes where possible instead of
+         using straight \C-x for control character `x'.  Change callers
+       - _rl_untranslate_macro_value: now global
+
+lib/readline/rlprivate.h
+       - _rl_untranslate_macro_value: extern declaration
+
+lib/readline/{macro.c,readline.h}
+       - rl_print_last_kbd_macro: new bindable function, inspired by patch
+         from Mitchel Humpherys
+
+lib/readline/funmap.c
+       - print-last-kbd-macro: new bindable command, bound to
+         rl_print_last_kbd_macro
+
+lib/readline/doc/{rluser.texi,readline.3},doc/bash.1
+       - print-last-kbd-macro: document.
+
+lib/readline/text.c
+       - _rl_insert_next: if we're defining a macro, make sure the key gets
+         added to the macro text (should really audit calls to rl_read_key()
+         and make sure the right thing is happening for all of them)
+
+bashline.[ch]
+       - print_unix_command_map: new function, prints all bound commands in
+         cmd_xmap using rl_macro_dumper in a reusable format
+
+builtins/bind.def
+       - new -X option: print all keysequences bound to Unix commands using
+         print_unix_command_map.  Feature suggested by Dennis Williamson
+         (2/2011)
+
+doc/{bash.1,bashref.texi}
+       - document new `bind -X' option
+
+                                  12/24
+                                  -----
+
+doc/{bash.1,bashref.texi}
+       - add a couple of sentences to the description of the case modification
+         operators making it clearer that each character of parameter is
+         tested against the pattern, and that the pattern should only attempt
+         to match a single character.  Suggested by Bill Gradwohl
+         <bill@ycc.com>
+
+                                  12/28
+                                  -----
+shell.c
+       - init_noninteractive: instead of calling set_job_control(0) to
+         unconditionally turn off job control, turn on job control if
+         forced_interactive or jobs_m_flag is set
+       - shell_initialize: call initialize_job_control with jobs_m_flag as
+         argument so `bash -m script' enables job control while running the
+         script
+
+jobs.c
+       - initialize_job_control: if the `force' argument is non-zero, turn on
+         job control even if the shell is not currently interactive
+         (interactive == 0)
+
+                                  12/29
+                                  -----
+
+flags.h
+       - new extern declaration for jobs_m_flag
+
+builtins/{cd,set}.def,doc/{bash.1,bashref.texi}
+       - added text clarifying the descriptions of cd -L and -P, suggested by
+         Padraig Brady <p@draigbrady.com>
+       - slight change to the description of `set -P' about resolving symbolic
+         links
+
+lib/readline/doc/rluser.texi
+       - Added an example to the programmable completion section: _comp_cd,
+         a completion function for cd, with additional verbiage.  Text
+         includes a reference to the bash_completion project
+
+                                1/1/2012
+                                --------
+jobs.c
+       - set_job_status_and_cleanup: note that a job is stopped due to
+         SIGTSTP (any_tstped) if job_control is set; there's no need to
+         test interactive
+
+                                   1/5
+                                   ---
+quit.h
+       - LASTSIG(): new macro, expands to signal number of last terminating
+         signal received (terminating_signal or SIGINT)
+
+trap.c
+       - first_pending_trap: returns lowest signal number with a trap pending
+       - trapped_signal_received: set to the last trapped signal the shell
+         received in trap_handler(); reset to 0 in run_pending_traps
+
+builtins/read.def
+       - read_builtin: changes to posix-mode (posixly_correct != 0) to make
+         `read' interruptible by a trapped signal.  After the trap runs,
+         read returns 128+sig and does not assign the partially-read line
+         to the named variable(s).  From an austin-group discussion started
+         by David Korn
+
+                                  1/11
+                                  ----
+doc/{bash.1,bashref.texi}
+       - slight changes to the descriptions of the compat32 and compat40 shell
+         options to clarify their meaning
+
+                                  1/12
+                                  ----
+lib/readline/{colors.[ch],parse-colors.[ch]}
+       - new files, part of color infrastructure support
+
+Makefile.in,lib/readline/Makefile.in
+       - arrange to have colors.o and parse-colors.o added to readline
+         library
+
+{configure,config.h}.in
+       - check for stdbool.h, define HAVE_STDBOOL_H if found
+
+                                  1/14
+                                  ----
+lib/readline/bind.c
+       - colored_stats: new bindable variable, enables using colors to
+         indicate file type when listing completions
+
+lib/readline/complete.c
+       - _rl_colored_stats: new variable, controlled by colored-stats bindable
+         variable
+       - colored_stat_start, colored_stat_end: new functions to set and reset
+         the terminal color appropriately depending on the type of the
+         filename to be printed
+       - print_filename: changes to print colors if `colored-stats' variable
+         set.  Changes contributed by Raphael Droz
+         <raphael.droz+floss@gmail.com>
+
+lib/readline/readline.c
+       - rl_initialize_everything: add call to _rl_parse_colors to parse
+         color values out of $LS_COLORS.  May have to add to rl_initialize
+         to make more dynamic if LS_COLORS changes (which doesn't happen
+         very often, if at all)
+
+lib/readline/rlprivate.h
+       - _rl_colored_stats: new extern declaration
+
+lib/readline/doc/{readline.3,rluser.texi},doc/bash.1
+       - colored-stats: document new bindable readline variable
+
+lib/readline/colors.c
+       - _rl_print_color_indicator: call rl_filename_stat_hook before calling
+         lstat/stat so we can get color indicators for stuff like
+         $HOME/Applications
+
+lib/readline/complete.c
+       - stat_char: call rl_filename_stat_hook before calling lstat/stat
+
+findcmd.[ch],execute_cmd.c
+       - search_for_command: now takes a second `flags' argument; changed
+         header function prototype and callers
+       - search_for_command: if (flags & 1), put the command found in $PATH
+         into the command hash table (previous default behavior)
+
+execute_cmd.c
+       - is_dirname: call search_for_command with flags argument of 0 so it
+         doesn't try to put something in the command hash table
+
+bashline.c
+       - bash_command_name_stat_hook: a hook function for readline's
+         filename_stat_hook that does $PATH searching the same way that
+         execute_cmd.c:execute_disk_command() does it, and rewrites the
+         passed filename if found.  Does not put names into command hash
+         table.  This allows command name completion to take advantage
+         of `visible-stats' and `colored-stats' settings.
+       - executable_completion: new function, calls the directory completion
+         hook to expand the filename before calling executable_file or
+         executable_or_directory; change command_word_completion_function to
+         call executable_completion.  This allows $HOME/bin/[TAB] to do
+         command completion and display alternatives
+
+                                  1/17
+                                  ----
+pcomplete.c
+       - gen_command_matches: now takes a new second argument: the command
+         name as deciphered by the programmable completion code and used
+         to look up the compspec; changed callers (gen_compspec_completions)
+       - gen_shell_function_matches: now takes a new second argument: the
+         command that originally caused the completion function to be
+         invoked; changed callers (gen_compspec_completions))
+       - build_arg_list: now takes a new second argument: the command name
+         corresponding to the current compspec; changed callers
+         (gen_command_matches, gen_shell_function_matches)
+       - build_arg_list: now uses `cmd' argument to create $1 passed to
+         invoked command or shell function
+       - gen_compspec_completions: if we skipped a null command at the
+         beginning of the line (e.g., for completing `>'), add a new word for
+         it at the beginning of the word list and increment nw and cw
+         appropriately.  This is all a partial fix for the shortcoming
+         pointed out by Sung Pae <sungpae@gmail.com>
+
+                                  1/18
+                                  ----
+
+{configure,config.h}.in
+       - new check: check for AUDIT_USER_TTY defined in <linux/audit.h>,
+         define HAVE_DECL_AUDIT_USER_TTY if both are found
+
+lib/readline/rlconf.h
+       - ENABLE_TTY_AUDIT_SUPPORT: new define, allows use of the Linux kernel
+         tty auditing system if it's available and enabled
+
+lib/readline/util.c
+       - _rl_audit_tty: new function, send a string to the kernel tty audit
+         system
+
+lib/readline/rlprivate.h
+       - _rl_audit_tty: new extern declaration
+
+lib/readline/readline.c
+       - readline: call _rl_audit_tty with line to be returned before returning
+         it if the Linux tty audit system is available and it's been enabled
+         in rlconf.h  Original patch from Miroslav Trmac; recent request
+         from Miroslav Lichvar <mlichvar@redhat.com>
+
+                                  1/21
+                                  ----
+
+lib/readline/readline.c:
+       - _rl_dispatch_subseq: add an inter-character timeout for multi-char
+         key sequences.  Suggested by <rogerx.oss@gmail.com>.  Still needs
+         work to make a user-settable variable
+
+parse.y
+       - shell_getc: make code that uses the pop_alias dependent on ALIAS
+         define
+
+variables.h
+       - sv_tz: extern define should only depend on HAVE_TZSET
+
+expr.c
+       - expr_streval: if ARRAY_VARS is not defined, set lvalue->ind to -1;
+         move assignment to `ind' inside define
+       - expr_bind_array_element: declaration and uses need to be #ifdef
+         ARRAY_VARS
+
+arrayfunc.h
+       - AV_ALLOWALL, AV_QUOTED, AV_USEIND: define to 0 if ARRAY_VARS not
+         defined; used in subst.c unconditionally
+
+sig.h
+       - make the signal blocking functions not dependent on JOB_CONTROL
+
+sig.c
+       - sigprocmask: make the replacement definition not dependent on
+         JOB_CONTROL
+
+trap.c
+       - use BLOCK_SIGNAL/UNBLOCK_SIGNAL instead of code dependent on
+         HAVE_POSIX_SIGNALS and BSD signals
+
+                                  1/24
+                                  ----
+
+print_cmd.c
+       - print_redirection_list: change the conditions under which
+         r_duplicating_output_word is mapped to r_err_and_out to more or
+         less match those used in redir.c.  Fixes bug pointed out by
+         Dan Douglas <ormaaj@gmail.com>
+
+
+                                  1/29
+                                  ----
+lib/readline/signals.c
+       - _rl_block_sigwinch,_rl_release_sigwinch: don't compile in bodies
+         unless SIGWINCH is defined.  Fixes bug reported by Pierre Muller
+         <pierre.muller@ics-cnrs.unistra.fr>
+
+doc/{bash.1,bashref.texi}
+       - small modifications to the introduction to the REDIRECTION section
+         to describe how redirections can modify file handles
+       - small modification to the section describing base#n to make it
+         clearer that n can be denoted using non-numerics.  From a posting
+         by Linda Walsh <bash@tlinx.org>
+
+                                   2/2
+                                   ---
+builtins/printf.def
+       - printf_builtin: make sure vbuf is intialized and non-null when -v
+         is supplied, since other parts of the code assume that it's not
+         null (e.g., bind_printf_variable()).  Fixes bug reported by Jim
+         Avera <james_avera@yahoo.com>
+
+                                   2/4
+                                   ---
+lib/readline/undo.c
+       - _rl_free_undo_list: new function, old body of rl_free_undo_list,
+         frees undo entries in UNDO_LIST * passed as argument
+       - rl_free_undo_list: call _rl_free_undo_list
+
+lib/readline/rlprivate.h
+       - _rl_free_undo_list: new extern declaration
+       - _rl_keyseq_timeout: new extern declaration (see below)
+
+lib/readline/misc.c
+       - rl_clear_history: new function.  Clears the history list and frees
+         all associated data similar to history.c:clear_history(), but
+         takes rl_undo_list into account and frees and UNDO_LISTs saved as
+         `data' members of a history list entry
+
+lib/readline/doc/rltech.texi
+       - rl_clear_history: documented
+
+lib/readline/readline.c
+       - _rl_keyseq_timeout: new variable to hold intra-key timeout value
+         from 1/21 fix; specified in milliseconds.  Default value is 500
+       - _rl_dispatch_subseq: change to use _rl_keyseq_timeout as intra-key
+         timeout if it's greater than 0; no timeout if <= 0
+       - _rl_dispatch_subseq: don't check for queued keyboard input if we have
+         pushed or pending input, or if we're reading input from a macro
+
+lib/readline/bind.c
+       - keyseq-timeout: new bindable variable, shadows _rl_keyseq_timeout
+       - string_varlist: add keyseq-timeout
+       - sv_seqtimeout: new function to modify value of _rl_keyseq_timeout;
+         clamps negative values at 0 for now
+       - _rl_get_string_variable_value: return value for keyseq-timeout
+
+doc/bash.1,lib/readline/doc/{rluser.texi,readline.3}
+       - keyseq-timeout: documented
+
+lib/readline/isearch.c
+       - _rl_isearch_dispatch: modification to fix from 7/18 to not use
+         cxt->keymap and cxt->okeymap, since by the time this code is
+         executed, they are equal.  Use `f' to check for rl_insert or
+         unbound func
+       - _rl_isearch_dispatch: if we're switching keymaps, not in
+         callback mode, and don't have pending or pushed input, use
+         _rl_input_queued to resolve a potentially ambiguous key sequence.
+         Suggested by Roger Zauner <rogerx.oss@gmail.com>
+       - _rl_isearch_dispatch: if we have changed keymaps and resolved to
+         an editing function (not self-insert), make sure we stuff the
+         right characters back onto the input after changing the keymap
+         back so the right editing function is executed after the search
+         is terminated.  Rest of fix for bug reported by Roger Zauner
+         <rogerx.oss@gmail.com>
+
+                                   2/5
+                                   ---
+builtins/gen-helpfiles.c
+       - new file: reads struct builtin and writes the long docs to files
+         in the `helpdirs' subdirectory.  The filename is given in the
+         previously-unused `handle' member of the struct builtin.  Links
+         with `tmpbuiltins.o', which is created by Makefile to have the
+         right long documentation.  When not cross-compiling, gets the
+         right #defines based on configuration options from config.h instead
+         of trying to parse conditional parts of def files.  Fixes
+         shortcoming pointed out by Andreas Schwab <schwab@linux-m68k.org>
+
+builtins/Makefile.in
+       - tmpbuiltins.c: new generated file, created to enable creation of
+         separate helpfiles based on correct #defines instead of trying to
+         parse conditional parts of def files
+       - gen-helpfiles: new program to generate helpfiles, links with
+         tmpbuiltins.o
+       - HELPFILES_TARGET: new target, substituted by configure to `helpdoc'
+         if separate helpfiles requested
+       - targets: new target, libbuiltins.a and $(HELPFILES_TARGET)
+       - CREATED_OBJECTS: new variable, holds created object files for
+         make clean; changed make clean to remove created objects
+       - helpdoc: changed to call gen-helpfiles instead of mkbuiltins
+
+Makefile.in
+       - when building libbuiltins.a, recursively call make with `targets'
+         argument to make sure separate helpfiles get built
+
+configure.in
+       - substitute `helpdoc' as value of HELPFILES_TARGET if
+         --enable-separate-helpfiles supplied as configure argument
+
+builtins/mkbuiltins.c
+       - `-nofunctions': new argument, causes mkbuiltins to not write value
+         for function implementing a particular builtin to struct builtin
+         and to write document file name to `handle' member of struct builtin
+       - no longer writes separate helpfiles; that is left to gen-helpfiles
+
+                                   2/8
+                                   ---
+subst.c
+       - make sure last_command_exit_value is set to a non-zero value before
+         any calls to report_error, since `-e' set will short-circuit
+         report_error.  Fixes bug reported by Ewan Mellor
+         <Ewan.Mellor@eu.citrix.com>
+
+variables.c
+       - make_local_array_variable: added second argument; if non-zero,
+         function will return an existing local associative array variable
+         instead of insisting on an indexed array
+
+variable.h,subst.c
+       - make_local_array_variable: changed prototype and caller
+
+builtins/declare.def
+       - declare_internal: add second arg to call to make_local_array_variable;
+         making_array_special, which indicates we're processing an
+         assignment like declare a[b]=c.  Fixes seg fault resulting from
+         a being an already-declared local associative array variable in a
+         function.  Ubuntu bash bug 928900.
+
+                                  2/14
+                                  ----
+
+execute_cmd.c
+       - execute_command_internal: if redirections into or out of a loop fail,
+         don't try to free ofifo_list unless saved_fifo is non-zero.  It's
+         only valid if saved_fifo is set
+
+                                  2/15
+                                  ----
+{arrayfunc,braces,variables}.c
+       - last_command_exit_value: make sure it's set before any calls to
+         report_error, since -e will cause that to exit the shell
+
+builtins/common.c
+       - get_job_by_name: call internal_error instead of report_error so this
+         doesn't exit the shell
+
+                                  2/18
+                                  ----
+builtins/evalstring.c
+       - parse_and_execute: make sure the file descriptor to be redirected to
+         is 1 before calling cat_file.  One fix for bug reported by Dan Douglas
+         <ormaaj@gmail.com>
+
+parse.y
+       - read_token_word: don't return NUMBER if a string of all digits
+         resolves to a number that overflows the bounds of an intmax_t.
+         Other fix for bug reported by Dan Douglas <ormaaj@gmail.com>
+
+                                  2/19
+                                  ----
+lib/sh/strtrans.c
+       - ansicstr: use 0x7f as the boundary for characters that translate
+         directly from ASCII to unicode (\u and \U escapes) instead of
+         UCHAR_MAX, since everything >= 0x80 requires more than one byte.
+         Bug and fix from John Kearney <dethrophes@web.de>
+
+builtins/printf.def
+       - tescape: ditto for printf \u and \U escape sequences
+
+                                  2/20
+                                  ----
+lib/sh/unicode.c
+       - u32toutf8: fix to handle encodings up to six bytes long correctly
+         (though technically UTF-8 only has characters up to 4 bytes long).
+         Report and fix from John Kearney <dethrophes@web.de>
+       - u32toutf8: first argument is now an unsigned 32-bit quantity,
+         changed callers (u32cconv) to pass c instead of wc
+       - u32reset: new function, resets local static state to uninitialized
+         (locale information, currently)
+
+locale.c
+       - call u32reset whenever LC_CTYPE/LC_ALL/LANG is changed to reset the
+         cached locale information used by u32cconv.  From a report from
+         John Kearney <dethrophes@web.de>
+
+                                  2/21
+                                  ----
+doc/{bash,builtins}.1
+       - minor changes from Bjarni Ingi Gislason <bjarniig@rhi.hi.is>
+
+lib/sh/unicode.c
+       - u32cconv: only assume you can directly call wctomb on the passed
+         value if __STDC_ISO_10646__ is defined and the value is <=
+         0x7fffffff
+       - stub_charset: return locale as default instead of "ASCII", let
+         rest of code decide what to do with it
+
+lib/readline/parens.c
+       - _rl_enable_paren_matching: make paren matching work in vi insert
+         mode.  Bug report from <derflob@derflob.de>
+
+                                  2/22
+                                  ----
+lib/sh/shquote.c
+       - sh_backslash_quote: quote tilde in places where it would be
+         expanded.  From a report from John Kearney <dethrophes@web.de>
+
+                                  2/23
+                                  ----
+execute_cmd.c
+       - execute_pipeline: wrap the discard_unwind_frame call in #ifdef
+         JOB_CONTROL, since the frame is only created if JOB_CONTROL is
+         defined.  Bug and fix from Doug Kehn <rdkehn@yahoo.com>
+
+                                  2/25
+                                  ----
+error.c
+       - report_error: make sure last_command_exit_value is non-zero before
+         we call exit_shell, since the exit trap may reference it.  Call
+         exit_shell with last_command_exit_value to allow exit statuses
+         other than 1
+
+unicode.c
+       - stub_charset: use local static buffer to hold charset, don't change
+         value returned by get_locale_var.  Based on idea and code from
+         John Kearney <dethrophes@web.de>
+       - u32toutf16: function to convert unsigned 32-bit value (unicode) to
+         UTF-16.  From John Kearney <dethrophes@web.de>
+       - u32cconv: call u32toutf16 if __STDC_ISO_10646__ defined and wchar_t
+         is two bytes, send result to wcstombs, return if not encoding error.
+         From John Kearney <dethrophes@web.de>
+       - u32cconv: return UTF-8 conversion if iconv conversion to local
+         charset is unsupported
+
+                                   3/2
+                                   ---
+lib/readline/complete.c
+       - print_filename: if there is no directory hook, but there is a stat
+         hook, and we want to append a slash to directories, call the stat
+         hook before calling path_isdir on the expanded directory name.
+         Report and pointer to fix from Steve Rago <sar@nec-labs.com>
+
+                                   3/3
+                                   ---
+builtins/evalstring.c
+       - parse_and_execute: fix to change of 2/18: make sure the file
+         descriptor being redirected to is 0 before calling cat_file when
+         we see something like $(< file).  Real fix for bug reported by
+         Dan Douglas <ormaaj@gmail.com>
+
+subst.c
+       - parameter_brace_patsub: run the replacement string through quote
+         removal even if the expansion is within double quotes, because
+         the parser and string extract functions treat the quotes and
+         backslashes as special.  If they're treated as special, quote
+         removal should remove them (this is the Posix position and
+         compatible with ksh93).  THIS IS NOT BACKWARDS COMPATIBLE.
+
+                                   3/4
+                                   ---
+lib/readline/complete.c
+       - rl_menu_complete: fix to make show-all-if-ambiguous and
+         menu-complete-display-prefix work together if both are set.  Fix
+         from Sami Pietila <sami.pietila@gmail.com>
+
+                                   3/5
+                                   ---
+bashline.c
+       - dircomplete_expand_relpath: new variable, if non-zero, means that
+         `shopt -s direxpand' should expand relative pathnames.  Zero by
+         default, not user-settable yet
+       - bash_directory_completion_hook: if we have a relative pathname that
+         isn't changed by canonicalization or spell checking after being
+         appended to $PWD, then don't change what the user typed.  Controlled
+         by dircomplete_expand_relpath
+
+                                   3/7
+                                   ---
+m4/timespec.m4
+       - new macros, cribbed from gnulib and coreutils: find out whether we
+         have `struct timespec' and what file includes it
+
+m4/stat-time.m4
+       - new macros, cribbed from gnulib and coreutils: find out whether the
+         mtime/atime/ctime/etctime fields of struct stat are of type
+         struct timespec, and what the name is
+
+include/stat-time.h
+       - new file, cribbed from gnulib, with additions from coreutils: include
+         the right file to get the struct timespec define, or provide our own
+         replacement.  Provides a bunch of inline functions to turn the
+         appropriate members of struct stat into `struct timespec' values,
+         zeroing out the tv_nsec field if necessary
+
+test.c
+       - include "stat-time.h" for the nanosecond timestamp resolution stuff
+       - stat_mtime: new function, returns struct stat and the mod time
+         normalized into a `struct timespec' for the filename passed as the
+         first argument
+       - filecomp: call stat_mtime instead of sh_stat for each filename
+         argument to get the mtime as a struct timespec
+       - filecomp: call timespec_cmp instead of using a straight arithmetic
+         comparison for the -nt and -ot operators, using timespec returned by
+         stat_mtime.  Added functionality requested by by Werner Fink
+         <werner@suse.de> for systems that can support it
+
+                                  3/10
+                                  ----
+include/posixdir.h
+       - REAL_DIR_ENTRY: remove dependency on _POSIX_SOURCE, only use feature
+         test macros to decide whether dirent.d_ino is present and usable;
+         define D_INO_AVAILABLE.  Report and fix from Fabrizion Gennari
+         <fabrizio.ge@tiscali.it>
+       - D_FILENO_AVAILABLE: define if we can use dirent.d_fileno
+
+lib/sh/getcwd.c
+       - use D_FILENO_AVAILABLE to decide whether or not to compile in
+         _path_checkino and whether or not to call it.  Report and initial
+         fix from Fabrizion Gennari <fabrizio.ge@tiscali.it>
+
+lib/readline/signals.c
+       - make sure all occurrences of SIGWINCH are protected by #ifdef
+
+sig.c
+       - make sure all occurrences of SIGCHLD are protected by #ifdef
+
+nojobs.c
+       - make sure SA_RESTART is defined to 0 if the OS doesn't define it
+
+version.c
+       - show_shell_version: don't use string literals in printf, use %s.
+         Has added benefit of removing newline from string to be translated
+
+trap.c
+       - queue_sigchld_trap: new function, increments the number of pending
+         SIGCHLD signals by the argument, which is by convention the number
+         of children reaped in a call to waitchld()
+
+trap.h
+       - queue_sigchld_trap: new extern declaration
+
+jobs.c
+       - waitchld: if called from the SIGCHLD signal handler (sigchld > 0),
+         then call queue_sigchld_trap to avoid running the trap in a signal
+         handler context.  Report and original fix from Siddhesh Poyarekar
+         <siddhesh@redhat.com>
+
+lib/sh/unicode.c
+       - u32tocesc: take an unsigned 32-bit quantity and encode it using
+         ISO C99 string notation (\u/\U)
+       - u32cconv: call u32tocesc as a fallback instead of u32cchar
+       - u32cconv: call u32tocesc if iconv cannot convert the character.
+         Maybe do the same thing if iconv_open fails
+       - u32reset: call iconv_close on localconv if u32init == 1
+
+                                  3/11
+                                  ----
+config-top.h
+       - CHECKWINSIZE_DEFAULT: new define, set to initial value of
+         check_window_size (shopt checkwinsize): 0 for off, 1 for on.
+         Default is 0
+
+{jobs,nojobs}.c
+       - check_window_size: default initial value to CHECKWINSIZE_DEFAULT
+
+                                  3/13
+                                  ----
+doc/bashref.texi
+       - change text referring to the copying restrictions to that
+         recommended by the FSF (no Front-Cover Texts and no Back-Cover
+         Texts)
+
+lib/readline/doc/{history,rlman,rluserman}.texi
+       - change text referring to the copying restrictions to that
+         recommended by the FSF (no Front-Cover Texts and no Back-Cover
+         Texts)
+
+                                  3/15
+                                  ----
+array.c
+       - LASTREF_START: new macro to set the starting position for an array
+         traversal to `lastref' if that's valid, and to the start of the array
+         if not.  Used in array_reference, array_insert, array_remove
+       - array_remove: try to be a little smarter with lastref instead of
+         unconditionally invalidating it
+
+                                  3/16
+                                  ----
+array.c
+       - array_insert: fix memory leak by deleting element to be added in the
+         case of an error
+
+                                  3/18
+                                  ----
+lib/sh/mbschr.c
+       - mbschr: don't call mbrlen unless is_basic is false; devolves to a
+         straight character-by-character run through the string
+
+                                  3/19
+                                  ----
+stringlib.c
+       - substring: use memcpy instead of strncpy, since we know the length
+         and are going to add our own NUL terminator
+
+                                  3/20
+                                  ----
+subst.c
+       - parameter_brace_expand_rhs: if expand_string_for_rhs returns a quoted
+         null string (a list with one element for which
+         QUOTED_NULL(list->word->word) returns true), return the quoted null
+         and set the flags in the returned word to indicate it.  Fixes bug
+         reported by Mark Edgar <medgar123@gmail.com>
+
+lib/sh/tmpfile.c
+       - use random(3) instead of get_random_number to avoid perturbing the
+         random sequence you get using $RANDOM.  Bug report and fix from
+         Jurij Mihelic <jurij.mihelic@fri.uni-lj.si>
+
+                                  3/21
+                                  ----
+config-top.h
+       - OPTIMIZE_SEQUENTIAL_ARRAY_ASSIGNMENT: define to 1 to optimize
+         sequential indexed array assignment patterns.  Defined to 1 by
+         default
+
+array.c
+       - array_insert: if OPTIMIZE_SEQUENTIAL_ARRAY_ASSIGNMENT is defined,
+         start the search at lastref (see change from 3/15)
+
+                                  3/27
+                                  ----
+print_cmd.c
+       - debug_print_word_list: new debugging function, prints a word list
+         preceded by an optional string and using a caller-specified
+         separator
+
+                                   4/1
+                                   ---
+command.h
+       - W_ASSNGLOBAL: new flag, set to indicate declare -g
+
+execute_cmd.c
+       - fix_assignment_words: note that we have a -g argument to an assignment
+         builtin and set the W_ASSNGLOBAL flag in the variable word
+
+subst.c
+       - dump_word_flags: print out W_ASSNGLOBAL if present
+       - do_assignment_internal: only set ASS_MKLOCAL if W_ASSIGNARG is set
+         and W_ASSNGLOBAL is not.  Don't want to create a local variable even
+         if variable_context is non-zero if ASSNGLOBAL is set.  Fixes bug
+         reported by Bill Gradwohl <bill@ycc.com>
+
+                                   4/7
+                                   ---
+lib/readline/readline.c
+       - _rl_dispatch_subseq: make the `keyseq-timeout' variable apply to
+         ESC processing when in vi mode.  After hitting ESC, readline will
+         wait up to _rl_keyseq_timeout*1000 microseconds (if set) for
+         additional input before dispatching on the ESC and switching to
+         command/movement mode.  Completes timeout work suggested by
+         <rogerx.oss@gmail.com>; this prompted by report from Barry Downes
+         <barry.downes@gmail.com>
+
+lib/sh/shmbchar.c
+       - sh_mbsnlen: new function, returns the number of (possibly multibyte)
+         characters in a passed string with a passed length, examining at most
+         maxlen (third argument) bytes
+
+externs.h
+       - sh_mbsnlen: extern declaration for new function
+
+shell.c
+       - exit_shell: call maybe_save_shell_history if remember_on_history is
+         set, not just in interactive shells.  That means the history is
+         saved if history is enabled, regardless of whether or not the shell
+         is interactive
+
+doc/{bash.1,bashref.texi}
+       - TMOUT: fix description to make it explicit that TMOUT is the timeout
+         period for a complete line of input, not just any input.  Fixes
+         problem reported in Ubuntu bug 957303:
+         https://bugs.launchpad.net/ubuntu/+source/bash/+bug/957303
+       - HISTFILE: document change to write history list to history file in
+         any shell with history enabled, not just interactive shells.  This
+         seems to be more logical behavior.  Suggested by Greg Wooledge
+         <wooledg@eeg.ccf.org>
+
+                                  4/12
+                                  ----
+lib/readline/colors.h
+       - only include stdbool.h if HAVE_STDBOOL_H is defined
+       - if HAVE_STDBOOL_H is not defined, provide enough definition for the
+         library to use `bool', `true', and `false'
+
+lib/readline/parse-colors.[ch]
+       - don't try to include <stdbool.h> at all; rely on colors.h to do it
+
+lib/sh/snprintf.c
+       - vsnprintf_internal: only treat '0' as a flag to indicate zero padding
+         if `.' hasn't been encountered ((flags&PF_DOT) == 0); otherwise treat
+         it as the first digit of a precision specifier.  Fixes bug reported
+         by Petr Sumbera <petr.sumbera@sun.com>
+
+                                  4/15
+                                  ----
+lib/sh/snprintf.c
+       - vsnprintf_internal: if the '0' and '-' flags both occur, the '0'
+         flag is ignored -- Posix.  Start of a series of fixes based on
+         tests and patches from Petr Sumbera <petr.sumbera@sun.com>
+       - PUT_PLUS: make sure PF_PLUS flag is specified before putting the `+'
+       - vsnprintf_internal: when '+' is read as a flag, don't set right-
+         justify flag if the LADJUST (`-') flag has already been supplied
+       - floating: make sure to output space padding before the `+', zero
+         padding after
+       - exponent: make sure to output space padding before the `+', zero
+         padding after
+       - exponent: only subtract one from the width for the decimal point
+         if we're really going to print one
+       - floating: use presence of PF_PLUS flag to decide whether to account
+         for the `+' in the padded field width.  Ditto for exponent()
+
+                                  4/16
+                                  ----
+lib/sh/snprintf.c
+       - vsnprint_internal: only reduce precision by 1 when processing the `g'
+         format if it's > 0.  A precision of 0 should stay 0; otherwise it
+         gets set to -1 (NOT_FOUND) and converted to the default
+       - number, lnumber: if an explicit precision is supplied, turn off the
+         zero-padding flag and set the pad character back to space
+       - number, lnumber: only account for a `+' when performing the field
+         width calculation if the coversion is base 10; we don't add a `+'
+         for other bases
+
+                                  4/18
+                                  ----
+tests/printf3.sub
+       - try using "perl -e 'print time'" to get the current time in seconds
+         since the epoch if "date +%s" is not available (solaris 8-10)
+
+                                  4/19
+                                  ----
+tests/run-printf
+       - use cat -v instead of relying on diff -a being available to convert
+         control characters to ascii and avoid the dreaded "Binary files
+         /tmp/xx and printf.right differ"
+
+                                  4/20
+                                  ----
+lib/sh/strftime.c
+       - incoporated new version from Aharon Robbins <arnold@skeeve.com>
+
+                                  4/22
+                                  ----
+doc/{bash.1,bashref.texi}
+       - slight change to the description of /dev/tcp and /dev/udp
+
+subst.c
+       - match_wpattern: logic fix to the calculation of `simple' (was |=,
+         needs to be &=).  Bug report from Mike Frysinger <vapier@gentoo.org>,
+         fix from Andreas Schwab <schwab@linux-m68k.org>
+
+bashline.c
+       - bash_filename_stat_hook: add code from bash_directory_completion_hook
+         that performs pathname canonicalization in the same way that cd and
+         other builtins will do
+
+                                  4/25
+                                  ----
+execute_cmd.c
+       - execute_pipeline: change the call to move_to_high_fd to make it use
+         getdtablesize() and to not stomp on existing open file descriptors,
+         like the fd the shell is using to read a script.  Bug report from
+         Greg Wooledge <wooledg@eeg.ccf.org>
+
+                                   5/6
+                                   ---
+subst.c
+       - expand_word_internal: case '$': after calling param_expand and
+         setting had_quoted_null, set TEMP to null.  The code that builds the
+         returned string at the end of the function will take care of making
+         and returning a quoted null string if there's nothing else in
+         ISTRING.  If there is, the quoted null should just go away.  Part of
+         fix for bug reported by Ruediger Kuhlmann <RKuhlmann@orga-systems.com>
+       - expand_word_internal: when processing ISTRING to build return value,
+         only set W_HASQUOTEDNULL in the returned word flags if the word is
+         a quoted null string AND had_quoted_null is set.  Rest of fix
+
+                                   5/9
+                                   ---
+variables.c
+       - bind_variable_internal: if we get an array variable here (implicit
+         assignment to index 0), call make_array_variable_value, which
+         dummies up a fake SHELL_VAR * from array[0].  This matters when
+         we're appending and have to use the current value
+       - bind_variable_internal: after computing the new value, treat assoc
+         variables with higher precedence than simple array variables; it
+         might be that a variable has both attributes set
+
+arrayfunc.c
+       - bind_array_var_internal: break code out that handles creating the
+         new value to be assigned to an array variable index into a new
+         function, make_array_variable_value.  This handles creating a
+         dummy SHELL_VAR * for implicit array[0] assignment.  Fixes bug
+         reported by Dan Douglas <ormaaj@gmail.com>
+
+arrayfunc.h
+       - make_array_variable_value: new extern declaration
+
+                                  5/19
+                                  ----
+variables.c
+       - bind_int_variable: if an assignment statement like x=y comes in
+         from the expression evaluator, and x is an array, handle it like
+         x[0]=y.  Fixes bug reported by Dan Douglas <ormaaj@gmail.com>
+
+                                  5/24
+                                  ----
+
+braces.c
+       - mkseq: handle possible overflow and break the sequence generating
+         loop if it occurs.  Fixes OpenSUSE bug 763591:
+         https://bugzilla.novell.com/show_bug.cgi?id=763591
+
+                                  5/25
+                                  ----
+Makefile.in
+       - LDFLAGS_FOR_BUILD: add to compilation recipes for build tools
+         buildversion, mksignames, mksyntax
+       - LDFLAGS_FOR_BUILD: add to compilation recipes for test tools
+         recho, zecho, printenv, xcase
+
+builtins/Makefile.in
+       - LDFLAGS_FOR_BUILD: add to compilation recipes for build tools
+         gen-helpfiles, psize.aux
+
+variables.c
+       - bind_int_variable: if LHS is a simple variable name without an array
+         reference, but resolves to an array variable, call
+         bind_array_variable with index 0 to make x=1 equivalent to x[0]=1.
+         Fixes bug reported by Dan Douglas <ormaaj@gmail.com>
+
+                                  5/27
+                                  ----
+subst.c
+       - expand_word_internal: make sure has_dollar_at doesn't get reset before
+         recursive calls to param_expand or expand_word_internal, since it has
+         to save state of what came before.  Use temp variable and make sure
+         has_dollar_at is incremented if recursive call processes "$@".
+         Fixes bug reported by gregrwm <backuppc-users@whitleymott.net> and
+         supplemented by Dan Douglas <ormaaj@gmail.com>
+
+doc/{bash.1,bashref.texi}
+       - changes to the description of substring expansion inspired by
+         suggestions from Bill Gradwohl <bill@ycc.com>
+
+doc/bashref.texi
+       - added substring expansion examples inspired by suggestions from
+         Bill Gradwohl <bill@ycc.com>
+
+variables.c
+       - find_shell_variable: search for a variable in the list of shell
+         contexts, ignore the temporary environment
+       - find_variable_tempenv: search for a variable in the list of shell
+         contexts, force search of the temporary environment
+       - find_variable_notempenv: search for a variable in the list of shell
+         contexts, don't force search of the temporary environment
+
+variables.h
+       - find_shell_variable: extern declaration
+       - find_variable_tempenv: extern declaration
+       - find_variable_notempenv: extern declaration
+
+arrayfunc.c
+       - bind_array_variable: call find_shell_variable instead of calling
+         var_lookup directly
+
+findcmd.c
+       - search_for_command: call find_variable_tempenv instead of
+         find_variable_internal directly
+       - _find_user_command_internal: call find_variable_tempenv instead of
+         find_variable_internal directly
+
+builtins/setattr.def
+       - set_var_attribute: call find_variable_notempenv instead of
+         find_variable_internal directly
+       - show_name_attributes:  call find_variable_tempenv instead of
+         find_variable_internal directly
+
+                                   6/1
+                                   ---
+sig.c
+       - termsig_handler: don't try to save the shell history on a terminating
+         signal any more, since it just causes too many problems on Linux
+         systems using glibc and glibc malloc
+
+lib/readline/vi_mode.c
+       - rl_vi_change_to: change to correctly redo `cc', since `c' is not a vi
+         motion character.  From Red Hat bug 813289
+       - rl_vi_delete_to: change to correctly redo `dd', since `d' is not a vi
+         motion character
+       - rl_vi_yank_to: change to correctly redo `yy', since `y' is not a vi
+         motion character
+
+                                   6/4
+                                   ---
+lib/sh/mktime.c
+       - current versions of VMS do not need to include <stddef.h>.  Fix from
+         John E. Malmberg <wb8tyw@qsl.net>
+
+                                   6/5
+                                   ---
+lib/sh/eaccess.c
+       - sh_stat: instead of using a static buffer to do the DEV_FD_PREFIX
+         translation, use a dynamically-allocated buffer that we keep
+         resizing.  Fixes potential security hole reported by David Leverton
+         <levertond@googlemail.com>
+
+                                   6/5
+                                   ---
+braces.c
+       - expand_seqterm: check errno == ERANGE after calling strtoimax for
+         rhs and incr.  Part of a set of fixes from Scott McMillan
+         <scotty.mcmillan@gmail.com>
+       - expand_seqterm: incr now of type `intmax_t', which changes
+         arguments to mkseq
+       - mkseq: a better fix for detecting overflow and underflow since it's
+         undefined in C and compilers `optimize' out overflow checks.  Uses
+         ADDOVERFLOW and SUBOVERFLOW macros
+       - mkseq: use sh_imaxabs (new macro) instead of abs() for intmax_t
+         variables
+       - mkseq: don't allow incr to be converted to -INTMAX_MIN
+       - mkseq: make sure that strvec_create isn't called with a size argument
+         greater than INT_MAX, since it only takes an int
+
+                                   6/6
+                                   ---
+braces.c
+       - mkseq: try and be smarter about not overallocating elements in
+         the return array if the increment is not 1 or -1
+
+                                   6/7
+                                   ---
+parse.y
+       - history_delimiting_chars: if the parser says we're in the middle of
+         a compound assignment (PST_COMPASSIGN), just return a space to avoid
+         adding a stray semicolon to the history entry.  Fixes bug reported
+         by "Davide Brini" <dave_br@gmx.com>
+
+                                   6/8
+                                   ---
+bashline.c
+       - bash_directory_completion_hook: don't attempt spelling correction
+         on the directory name unless the direxpand option is set and we are
+         going to replace the directory name with the corrected one in the
+         readline line.  Suggested by Linda Walsh <bash@tlinx.org>
+
+lib/sh/shquote.c
+       - sh_backslash_quote: now takes a third argument: flags.  If non-zero,
+         tildes are not backslash-escaped.  Have to handle both printf %q,
+         where they should be escaped, and filename completion, where they
+         should not when used as usernames
+
+externs.h
+       - sh_backslash_quote: declaration now takes a third argument
+
+builtins/printf.def
+       - printf_builtin: call sh_backslash_quote with 1 as third argument
+         so tildes get escaped
+
+{bashline,bracecomp}.c
+       - call sh_backslash_quote with 0 as third argument so tildes are not
+         escaped in completed words
+
+doc/bash.1
+       - add `coproc' to the list of reserved words.  From a report by
+         Jens Schweikhardt <schweikh@schweikhardt.net>
+
+                                  6/10
+                                  ----
+execute_cmd.c
+       - line_number_for_err_trap: now global, so parse_and_execute can save
+         and restore it with unwind-protect
+
+builtins/evalstring.c
+       - parse_prologue: save and restore line_number_for_err_trap along
+         with line_number
+       - restore_lastcom: new function, unwind-protect to restore
+         the_printed_command_except_trap
+       - parse_prologue: use restore_lastcom to save and restore the value
+         of the_printed_command_except_trap around calls to parse_and_execute
+         (eval/source/.)
+
+                                  6/15
+                                  ----
+lib/readline/complete.c
+       - complete_fncmp: change filename comparison code to understand
+         multibyte characters, even when doing case-sensitive or case-mapping
+         comparisons.  Fixes problem reported by Nikolay Shirokovskiy
+         <nshyrokovskiy@gmail.com>
+
+                                  6/20
+                                  ----
+builtins/mapfile.def
+       - mapfile: move the line count increment and check for having read
+         the specified number of lines to the end of the loop to avoid
+         reading an additional line with zgetline.  Fixes bug reported by
+         Dan Douglas <ormaaj@gmail.com>
+
+                                  6/21
+                                  ----
+
+execute_cmd.c
+       - execute_pipeline: make sure `lastpipe_flag' is initialized to 0 on
+         all systems, since it's tested later in the function.  Fixes bug
+         reported by John E. Malmberg <wb8tyw@qsl.net>
+
+                                  6/22
+                                  ----
+mailcheck.c
+       - file_mod_date_changed: return 0 right away if mailstat() does not
+         return success.  Fixes bug with using uninitialized values reported
+         by szymon.kalasz@uj.edu.pl
+
+builtins/set.def
+       - the `monitor' option is not available when the shell is compiled
+         without job control, since the underlying `m' flag is not available
+
+nojobs.c
+       - job_control: now declared as int variable, initialized to 0, never
+         modified
+
+jobs.h
+       - job_control: extern declaration no longer dependent on JOB_CONTROL
+
+execute_cmd.c
+       - execute_pipeline: made necessary changes so `lastpipe' shell option
+         is now available in all shells, even those compiled without
+         JOB_CONTROL defined
+
+                                  6/23
+                                  ----
+lib/glob/glob.c
+       - glob_filename: check for interrupts before returning if glob_vector
+         returns NULL or an error.  Bug reported by Serge van den Boom
+         <svdb@stack.nl>, fix from Andreas Schwab <schwab@linux-m68k.org>
+       - call run_pending_traps after each call to QUIT or test of
+         interrupt_state, like we do in mainline shell code
+       - glob_vector: don't call QUIT; in `if (lose)' code block; just free
+         memory, return NULL, and let callers deal with interrupt_state or
+         other signals and traps
+
+                                  6/25
+                                  ----
+lib/readline/input.c
+       - rl_read_key: restructure the loop that calls the event hook a little,
+         so that the hook is called only after rl_gather_tyi returns no input,
+         and any pending input is returned first.  This results in better
+         efficiency for processing pending input without calling the hook
+         on every input character as bash-4.1 did.  From a report from
+         Max Horn <max@quendi.de>
+
+                                  6/26
+                                  ----
+trap.c
+       - signal_is_pending: return TRUE if SIG argument has been received and
+         a trap is waiting to execute
+
+trap.h
+       - signal_is_pending: extern declaration
+
+lib/glob/glob.c
+       - glob_vector: check for pending SIGINT trap each time through the loop,
+         just like we check for interrupt_state or terminating_signal, and
+         set `lose = 1' so we clean up after ourselves and interrupt the
+         operation before running the trap.  This may require a change later,
+         maybe call run_pending_traps and do that if run_pending_traps returns?
+
+variables.c
+       - sv_histtimefmt: set history_comment_character to default (`#') if
+         it's 0 when we're turning on history timestamps.  The history code
+         uses the history comment character to prefix timestamps, and
+         leaving it at 0 effectively removes them from the history.  From a
+         report to help-bash by Dennis Williamson <dennistwilliamson@gmail.com>
+
+                                  6/27
+                                  ----
+lib/readline/signals.c
+       - rl_maybe_restore_sighandler: new function, sets handler for SIG to
+         HANDLER->sa_handler only if it's not SIG_IGN.  Needs to be called
+         on same signals set using rl_maybe_set_sighandler, which does not
+         override an existing SIG_IGN handler (SIGALRM is ok since it does
+         the check inline; doesn't mess with SIGWINCH)
+
+                                  6/30
+                                  ----
+variables.h
+       - additional defines for the new `nameref' variable attribute
+         (att_nameref): nameref_p, nameref_cell, var_setref
+
+variables.c
+       - find_variable_nameref: resolve SHELL_VAR V through chain of namerefs
+       - find_variable_last_nameref: resolve variable NAME until last in a
+         chain of possibly more than one nameref starting at shell_variables
+       - find_global_variable_last_nameref: resolve variable NAME until last
+         in a chain of possibly more than one nameref starting at
+         global_variables
+       - find_nameref_at_context: resolve SHELL_VAR V through chain of namerefs        
+         in a specific variable context (usually a local variable hash table)
+       - find_variable_nameref_context: resolve SHELL_VAR V through chain of
+         namerefs following a chain of varible contexts
+       - find_variable_last_nameref_context: resolve SHELL_VAR V as in
+         find_variable_last_context, but return the final nameref instead of
+         what the final nameref resolves to
+       - find_variable_tempenv, find_variable_notempenv, find_global_variable,
+         find_shell_variable, find_variable: modified to follow namerefs
+       - find_global_variable_noref: look up a global variable without following
+         any namerefs
+       - find_variable_noref: look up a shell variable without following any
+         namerefs
+       - bind_variable_internal: modify to follow a chain of namerefs in the
+         global variables table; change to handle assignments to a nameref by
+         following nameref chain
+       - bind_variable: modify to follow chain of namerefs when binding to a
+         local variable
+       - unbind_variable: changes to unset nameref variables (unsets both
+         nameref and variable it resolves to)
+
+subst.c
+       - parameter_brace_expand_word: change to handle expanding nameref whose
+         value is x[n]
+       - parameter_brace_expand_indir: change to expand in ksh93-compatible
+         way if variable to be indirected is nameref and a simple (non-array)
+         expansion
+       - param_expand: change to expand $foo where foo is a nameref whose value
+         is x[n]
+
+execute_cmd.c
+       - execute_for_command: changes to implement ksh93 semantics when index
+         variable is a nameref
+
+builtins/setattr.def
+       - show_var_attributes: change to add `n' to flags list if att_nameref
+         is set
+
+builtins/set.def
+       - unset_builtin: changes to error messages to follow nameref variables
+
+builtins/declare.def
+       - document new -n option
+       - declare_internal: new `-n' and `+n' options
+       - declare_internal: handle declare -n var[=value] and
+         declare +n var[=value] for existing and non-existant variables.
+         Enforce restriction that nameref variables cannot be arrays.
+         Implement semi-peculiar ksh93 semantics for typeset +n ref=value
+
+                                   7/5
+                                   ---
+variables.c
+       - unbind_variable: unset whatever a nameref resolves to, leaving the
+         nameref variable itself alone
+       - unbind_nameref: new function, unsets a nameref variable, not the
+         variable it references
+
+variables.h
+       - unbind_nameref: extern declaration
+
+builtins/set.def
+       - unset_builtin: modify to add -n option, which calls unbind_nameref
+         leaving unbind_variable for the usual case.  This required slight
+         changes and additions to the test suite
+
+doc/{bash.1,bashref.texi}
+       - document namerefs and typeset/declare/local/unset -n
+
+                                  7/13
+                                  ----
+lib/sh/casemod.c
+       - include shmbchar.h for is_basic and supporting pieces
+       - sh_casemod: use _to_wupper and _to_wlower to convert wide character
+         case instead of TOUPPER and TOLOWER.  Fixes bug reported by
+         Dennis Williamson <dennistwilliamson@gmail.com>, fix from
+         Andreas Schwab <schwab@linux-m68k.org>
+       - cval: short-circuit and return ascii value if is_basic tests true
+       - sh_casemod: short-circuit and use non-multibyte case modification
+         and toggling code if is_basic tests true
+
+lib/readline/signals.c
+       - _rl_{block,release}_sigint: remove the code that actually blocks and
+         releases the signals, since we defer signal handling until calls to
+         RL_CHECK_SIGNALS()
+
+lib/readline/{callback,readline,util}.c
+       - if HAVE_POSIX_SIGSETJMP is defined, use sigsetjmp/siglongjmp without
+         saving and restoring the signal mask instead of setjmp/longjmp
+
+lib/readline/rltty.c
+       - prepare_terminal_settings: don't mess with IXOFF setting if
+         USE_XON_XOFF defined
+
+doc/{bash.1,bashref.texi}
+       - add some text to the description of set -e clarifying its effect
+         on shell functions and shell function execution.  Suggested by
+         Rainer Blome <rainer.blome@gmx.de>
+
+bashline.c
+       - edit_and_execute_command: increment current_command_line_count before
+         adding partial line to command history (for command-oriented-history
+         because of rl_newline at beginning of function), then reset it to 0
+         before adding the dummy history entry to make sure the dummy entry
+         doesn't get added to previous incomplete command.  Partial fix for
+         problem reported by Peng Yu <pengyu.ut@gmail.com>
+
+                                  7/24
+                                  ----
+configure.in
+       - interix: define RECYCLES_PIDS.  Based on a report from Michael
+         Haubenwallner <michael.haubenwallner@salomon.at>
+
+                                  7/26
+                                  ----
+jobs.c
+       - make_child: call bgp_delete on the newly-created pid unconditionally.
+         Some systems reuse pids before cycling through an entire set of
+         CHILD_MAX/_SC_CHILD_MAX unique pids.  This is no longer dependent
+         on RECYCLES_PIDS.  Based on a report from Michael Haubenwallner
+         <michael.haubenwallner@salomon.at>
+
+support/shobj-conf
+       - Mac OS X: drop MACOSX_DEPLOYMENT_TARGET=10.3 from the LDFLAGS. We
+         can finally kill Panther
+
+                                  7/28
+                                  ----
+subst.c
+       - command_substitute: make sure last_made_pid gets reset if make_child
+         fails
+
+execute_cmd.c
+       - execute_command_internal: case cm_simple: decide whether or not to
+         wait_for a child if already_making_children is non-zero, indicates
+         that there is an unwaited-for child.  More of fix for bug report
+         from Michael Haubenwallner <michael.haubenwallner@salomon.at>
+
+jobs.c
+       - make_child: call delete_old_job (new_pid) unconditionally, don't
+         bother to check whether or not pid wrap occurred.  Rest of fix for
+         bug report from Michael Haubenwallner
+         <michael.haubenwallner@salomon.at>
+
+                                  7/29
+                                  ----
+shell.c
+       - subshell_exit: new function, exits the shell (via call to sh_exit())
+         after calling any defined exit trap
+
+externs.h
+       - subshell_exit: new extern declaration
+
+execute_cmd.c
+       - execute_command_internal: make sure to call subshell_exit for
+         {} group commands executed asynchronously (&).  Part of fix for
+         EXIT trap bug reported by Maarten Billemont <lhunath@lyndir.com>
+
+sig.c
+       - reset_terminating_signals: make sure to set termsigs_initialized back
+         to 0, so a subsequent call to initialize_terminating_signals works
+         right.  Rest of fix for bug reported by Maarten Billemont
+         <lhunath@lyndir.com>
+
+{execute_cmd,general,jobs,mailcheck,mksyntax,test}.c
+builtins/{cd,fc,pushd,ulimit}.def
+lib/malloc/getpagesize.h
+lib/sh/{clktck,fpurge,inet_aton,mailstat,oslib,pathcanon,pathphys,spell,strerror}.c
+       - make inclusion of <sys/param.h> dependent on HAVE_SYS_PARAM_H
+         consistently
+
+                                   8/6
+                                   ---
+lib/readline/histexpand.c
+       - history_expand_internal: now takes an additional argument saying
+         whether the history expansion occurs within a quoted string, set to
+         the open quote character
+       - history_expand_internal: use new argument instead of checking prev
+         char and initializing quoted_search_delimiter, pass qc directly to
+         get_history_event, where it allows a matching quote to terminate a
+         string defining an event
+       - history_expand: change single-quote handling code so that if
+         history_quotes_inhibit_expansion is 0, single quotes are treated
+         like double quotes
+       - history_expand: change call to history_expand_internal to pass new
+         argument of `"' if double-quoted string, `'' if single-quoted string;
+         this lets history_expand decide what is a quoted string and what
+         is not
+
+                                   8/7
+                                   ---
+configure.in
+       - AC_CANONICAL_BUILD: invoke for later use
+
+lib/readline/macro.c
+       - _rl_prev_macro_key: new function, inverse of _rl_next_macro_key:
+         backs up the index into the current macro by 1
+
+lib/readline/rlprivate.h
+       - _rl_prev_macro_key: extern declaration
+
+
+lib/readline/readline.c
+       - _rl_dispatch_subseq, _rl_subseq_result: don't call _rl_unget_char
+         if we're currently reading from a macro; call _rl_prev_macro_key
+         instead.  Fixes bug reported by Clark Wang <clark.wang@oracle.com>
+
+                                  8/13
+                                  ----
+builtins/evalstring.c
+       - evalstring(): new function, wrapper around parse_and_execute.
+         make sure we handle cases where parse_and_execute can call `return'
+         and short-circuit without cleaning up properly.  We call
+         parse_and_execute_cleanup() then jump to the previous-saved return
+         location
+
+builtins/common.h
+       - extern declaration for evalstring()
+
+builtins/eval.def
+       - eval_builtin: make sure we handle `eval " ... return"' in contexts
+         where `return' is valid by calling evalstring().  Fixes bug with
+         `eval return' in sourced files reported by Clark Wang
+         <dearvoid@gmail.com>
+
+trap.c
+       - run_pending_traps: call evalstring instead of parse_and_execute.
+         XXX - still needs to handle saving and restoring token state in the
+         presence of `return'; could use unwind_protects for that
+
+builtins/mapfile.def
+       - run_callback: call evalstring instead of parse_and_execute
+
+                                  8/15
+                                  ----
+bashline.c
+       - bash_filename_stat_hook: make sure we don't free local_dirname
+         before using it to canonicalize any expanded filename.  Make sure
+         it always points to *dirname and only free it if we're replacing
+         it.
+
+lib/readline/complete.c
+       - append_to_match: make sure we call rl_filename_stat_hook with
+         newly-allocated memory to avoid problems with freeing it twice
+
+                                  8/17
+                                  ----
+variables.c,config-top.h
+       - if ARRAY_EXPORT is defined to 1 when variables.c is compiled, the
+         code that allows indexed arrays to be exported is enabled and
+         included
+
+                                  8/19
+                                  ----
+shell.c
+       - call start_debugger from main() only if dollar_vars[1] != 0 (close
+         enough to a non-interactive shell, since we can be interactive with
+         -i while running a shell script).  Fixes oddity reported by
+         Techlive Zheng <techlivezheng@gmail.com>
+
+                                  8/20
+                                  ----
+arrayfunc.c
+       - quote_array_assignment_chars: don't bother quoting if the word has
+         not been marked as an assignment (W_ASSIGNMENT)
+       - quote_array_assignment_chars: turn on W_NOGLOB in the word flags
+         so assignment statements don't undergo globbing.  Partial fix for
+         problems reported by Dan Douglas <ormaaj@gmail.com>
+
+                                  8/21
+                                  ----
+command.h
+       - W_NOBRACE: new word flag that means to inhibit brace expansion
+
+subst.c
+       - brace_expand_word_list: suppress brace expansion for words with
+         W_NOBRACE flag
+
+                                  8/22
+                                  ----
+builtins/read.def
+       - read_builtin: don't call dequote_string on what we've read, even if
+         we saw an escape character, unless (input_string && *input_string).
+         We may have escaped an IFS whitespace character.  Fixes seg fault
+         reported by <armandsl@gmail.com>
+
+execute_cmd.c
+       - execute_command_internal: set the_printed_command_except trap when
+         about to execute a ( ... ) user subshell.  For now, set it only if
+         ERR is trapped; can relax that later.  Fixes bug reported by
+         Mike Frysinger <vapier@gentoo.org>
+
+                                  8/23
+                                  ----
+jobs.c
+       - remove references to first_pid and pid_wrap, since we're not using
+         them for anything anymore
+
+                                  8/24
+                                  ----
+subst.c
+       - changes for W_NOBRACE everywhere appropriate: so it can be displayed
+         for debugging, and passed out of expand_word_internal
+
+doc/{bash.1,bashref.texi}
+       - small changes to make it clearer that the = and == operators are
+         equivalent, and will cause pattern matching when used with [[.
+         From a question from Michal Soltys <soltys@ziu.info>
+
+doc/bashref.texi
+       - some small formatting changes from Karl Berry <karl@freefriends.org>
+
+                                  8/27
+                                  ----
+lib/readline/doc/{history,rlman,rluserman}.texi
+       - some small formatting changes from Karl Berry <karl@freefriends.org>
+
+arrayfunc.c
+       - assign_array_element_internal, assign_compound_array_list,
+         unbind_array_element, array_value_internal: changes to make
+         assignment statements to negative indices (a[-1]=2) and unsetting
+         array elements using negative indices (unset 'a[-1]') work.
+         From suggestions by Dennis Williamson <dennistwilliamson@gmail.com>
+         and Chris F. A. Johnson <chris@cfajohnson.com>
+
+subst.c
+       - array_length_reference: changes to make length references to array
+         elements using negative indices (${#a[-1]}) work
+
+                                  8/28
+                                  ----
+doc/{bash.1,bashref.texi}
+       - document new treatment of negative indices to indexed arrays when
+         assigning, referencing, calculating length, and unsetting
+
+                                  8/29
+                                  ----
+shell.c
+       - show_shell_usage: add -l to list of shell invocation options (short
+         for --login).  From Red Hat bug 852469
+
+configure.ac
+       - renamed from configure.in, as latest autoconf versions want.  Patches
+         Stefano Lattarini <stefano.lattarini@gmail.com>
+
+MANIFEST,Makefile.in,doc/bashref.texi,support/mkconffiles
+       - configure.in -> configure.ac
+
+                                   9/1
+                                   ---
+
+parse.y
+       - read_token_word: allow words like {array[ind]} to be valid redirection
+         words for constructs like {x}<file
+
+redir.c
+       - redir_varassign: bind_var_to_int already handles array assignments,
+         so don't need to do anything more for things like {a[i]}<file
+       - redir_varvalue: changes to allow references to {a[i]} when
+         performing redirections using valid_array_reference and
+         get_array_value.  Adds functionality requested most recently by
+         <unknown@vmw-les.eng.vmware.com>
+
+lib/readline/display.c
+       - update_line: if the first difference between the old and new lines
+         is completely before any invisible characters in the prompt, we
+         should not adjust _rl_last_c_pos, since it's before any invisible
+         characters.  Fixed in two places
+       - prompt_modechar: return a character indicating the editing mode:
+         emacs (@), vi command (:), or vi insert (+)
+       - _rl_reset_prompt: new function, just calls rl_expand_prompt.  Will be
+         inlined, placeholder for more changes
+       - expand_prompt: if show-mode-in-prompt is enabled, add a character to
+         the front of the prompt indicating the editing mode, adjusting the
+         various variables as appropriate to keep track of the number of
+         visible characters and number of screen positions
+
+lib/readline/bind.c
+       - show-mode-in-prompt: new bindable boolean variable, shadowed by
+         _rl_show_mode_in_prompt variable
+       - hack_special_boolean_var: call _rl_reset_prompt when toggling or
+         setting show-mode-in-prompt
+
+lib/readline/readline.c
+       - readline_internal_setup: make sure the correct vi mode keymap is set
+         before expanding the prompt string for the first time
+
+lib/readline/misc.c
+       - rl_emacs_editing_mode: make sure to call _rl_reset_prompt if we're
+         showing the editing mode in the prompt
+
+lib/readline/rlprivate.h
+       - _rl_reset_prompt, _rl_show_mode_in_prompt: extern declarations
+
+lib/readline/vi_mode.c
+       - rl_vi_insertion_mode: call _rl_reset_prompt
+       - rl_vi_movement_mode: call _rl_reset_prompt.  Finishes changes for
+         showing mode in prompt string, originally requested by Miroslav
+         Koskar <mkoskar@gmail.com> and most recently by Jordan Michael
+         Ziegler <jziegler@bnl.gov>
+
+doc/bash.1,lib/readline/doc/{readline.3,rluser.texi}
+       - document new show-mode-in-prompt variable, off by default
+
+                                   9/3
+                                   ---
+
+jobs.c
+       - set_childmax: new function, external mechanism for other parts of
+         the shell to set js.c_childmax, the number of saved exited child
+         statuses to remember
+jobs.h
+       - set_childmax: extern declaration
+
+variables.c
+       - CHILD_MAX: new special variable, with sv_childmax function to
+         run when it changes.  Setting CHILD_MAX to a value greater than
+         zero but less than some maximum (currently 8192) sets the number of
+         exited child statuses to remember.  set_childmax (jobs.c) ensures
+         that the number does not drop below the posix-mandated minimum
+         (CHILD_MAX)
+
+doc/{bash.1,bashref.texi}
+       - CHILD_MAX: document new meaning and action when variable is set
+
+                                   9/5
+                                   ---
+redir.c
+       - redir_varassign: call stupidly_hack_special_variables after
+         assigning fd number to specified variable, so we can use constructs
+         like {BASH_XTRACEFD}>foo.  Suggested by Pierre Gaston
+         <pierre.gaston@gmail.com>
+
+                                   9/8
+                                   ---
+expr.c
+       - readtok: invalidate previous contents of `curlval' before freeing
+         and reallocating tokstr (which, chances are, will get the same
+         pointer as before and render curlval inconsistent).  Fixes other
+         bug reported by Dan Douglas <ormaaj@gmail.com>
+
+                                   9/9
+                                   ---
+lib/readline/complete.c
+       - rl_username_completion_function: protect call to setpwent() with
+         #ifdef (HAVE_GETPWENT)/#endif.  Fixes bug reported by
+         Gerd Hofmann <gerd.hofmann.nbg@googlemail.com>
+
+lib/readline/display.c
+       - rl_message: second and subsequent calls to rl_message can result in
+         local_prompt being overwritten with new values (e.g., from the
+         successive calls displaying the incremental search string).  Need
+         to free before overwriting if it's not the same as the value saved
+         in saved_local_prompt.  Fixes memory leak reported by
+         Wouter Vermaelen <vermaelen.wouter@gmail.com>
+
+lib/readline/{terminal.c,rlprivate.h}
+       - move CUSTOM_REDISPLAY_FUNC and CUSTOM_INPUT_FUNC defines from
+         terminal.c to rlprivate.h so other files can use them
+
+expr.c
+       - expr_streval: if noeval is non-zero, just return 0 right away,
+         short-circuiting evaluation completely.  readtok will leave curtok
+         set correctly without re-entering the evaluator at all.  Rest of
+         fix for bug reported by Dan Douglas <ormaaj@gmail.com>
+
+                                  9/11
+                                  ----
+
+parse.y
+       - parse_comsub: make sure the `reserved word ok in this context' flag
+         is preserved after we read `do' followed by whitespace.  Fixes bug
+         reported by Benoit Vaugon <benoit.vaugon@gmail.com>
+
+                                  9/13
+                                  ----
+configure.ac,config.h.in
+       - enable-direxpand-default: new configure option, turns the `direxpand'
+         shell option on by default
+
+bashline.c
+       - dircomplete_expand, dircomplete_expand_relpath: initialize to 1 if
+         DIRCOMPLETE_EXPAND_DEFAULT is defined and non-zero
+
+doc/bashref.texi
+       - enable-direxpand-default: document new configure option
+
+                                  9/14
+                                  ----
+shell.c
+       - --protected: make option valid only when wordexp is compiled into
+         the shell.  Fix from Roman Rakus <rrakus@redhat.com>
+
+configure.ac
+       - HP NonStop (*-nsk*): compile --without-bash-malloc. Change from
+         Joachim Schmitz <jojo@schmitz-digital.de>
+
+                                  9/16
+                                  ----
+subst.c,execute_cmd.c,lib/glob/sm_loop.c,lib/sh/shquote.c
+       - minor code cleanups from Joachim Schmitz <jojo@schmitz-digital.de>
+
+lib/readline/colors.h
+       - workaround for HP NonStop compiler issue with <stdbool.h> from
+         Joachim Schmitz <jojo@schmitz-digital.de>
+
+                                  9/17
+                                  ----
+builtins/printf.def
+       - printf_builtin: handle localtime returning NULL, as can happen when
+         encountering overflow.  Bug report and initial fix from
+         Eduardo A. Bustamante López <dualbus@gmail.com>
+
+doc/{bash.1,bashref.texi}
+       - emphasize that brace expansion using character ranges ({a..c}) acts
+         as if the C locale were in use.  Prompted by message from
+         Marcel Giannelia <info@skeena.net>
+
+                                  9/20
+                                  ----
+lib/sh/wcsnwidth.c
+       - wcsnwidth: new function, variant of wcwidth, returns the number of
+         wide characters from a string that will be displayed to not exceed
+         a specified max column position
+
+                                  9/21
+                                  ----
+builtins/help.def
+       - show_builtin_command_help: break code that displays the short-doc
+         for each builtin in two columns into a new function: dispcolumn
+       - wdispcolumn: multibyte-char version of dispcolumn; uses wide
+         chars and printf "%ls" format.  Fixes problem reported by
+         Nguyá»n Thái Ngá»c Duy <pclouds@gmail.com>
+
+                                  9/22
+                                  ----
+execute_cmd.c
+       - execute_disk_command: before running the command-not-found hook,
+         call kill_current_pipeline() to make sure we don't add processes
+         to an existing pipeline or wait for processes erroneously
+
+                                  9/23
+                                  ----
+lib/readline/input.c
+       - rl_input_available_hook: new hook function, called from
+         _rl_input_available (or _rl_input_queued) to return whether or not
+         input is available wherever the input source is
+
+lib/readline/doc/rltech.texi
+       - rl_input_available_hook: document
+
+                                  9/27
+                                  ----
+lib/glob/sm_loop.c:
+       - GMATCH: after one or more `*', an instance of ?(x) can match zero or
+         1 times (unlike ?, which has to match one character).  The old code
+         failed if it didn't match at least once.  Fixes `a*?(x)' bug.
+       - GMATCH: if we hit the end of the search string, but not the end of
+         the pattern, and the rest of the pattern is something that can
+         match the NUL at the end of the search string, we should successfully
+         match.  Fixes `a*!(x)' bug reported by <hans1worst@gmail.com>
+
+                                  10/2
+                                  ----
+command.h
+       - add c_lock member to coproc structure for future use to tell who is
+         manipulating it
+
+execute_cmd.c
+       - execute_coproc: block SIGCHLD while parent is forking coproc
+         process and adding pid to sh_coproc struct to avoid race condition
+         where child is reaped before the pid is assigned and the coproc is
+         never marked as having died.  Fixes race condition identified by
+         Davide Baldini <baldiniebaldini@gmail.com>
+       - add assignments to c_lock member of struct coproc in various
+         functions that manipulate it; was used to identify race condition
+       - coproc_pidchk: don't call coproc_dispose to avoid using malloc and
+         other functions in a signal handler context
+       - coproc_dispose: call BLOCK_SIGNAL/UNBLOCK_SIGNAL for SIGCHLD while
+         manipulating the sh_coproc struct
+
+                                  10/6
+                                  ----
+lib/readline/complete.c
+       - rl_display_match_list: if printing completions horizontally, don't
+         bother with spacing calculations if limit == 1, which means we are
+         printing one completion per line no matter what.  Fixes bug
+         reported by David Kaasen <kaasen@nvg.ntnu.no>
+
+                                  10/7
+                                  ----
+builtins/declare.def
+       - declare_internal: add error checking for nameref attribute and
+         variable assignments: self-references, attempts to make an array
+         variable a nameref
+
+subst.c
+       - parameter_brace_expand: handle parameter_brace_expand_word returning
+         &expand_param_fatal or &expand_param_error and return the appropriate
+         error value
+       - parameter_brace_expand_word: if a nameref variable's value is not a
+         valid identifier, return an error
+       - param_expand: if a nameref variable's value is not a valid identifier,
+         return an error
+
+test.c
+       - unary_operator: add new -R variable, returns true if variable is set
+         and has the nameref attribute. From ksh93
+
+builtins/test.def
+       - add -R to description of conditional commands for help test
+
+doc/{bash.1,bashref.texi}
+       - document new -R unary conditional operator
+
+                                  10/13
+                                  -----
+trap.c
+       - check_signals_and_traps: new function, convenience function for the
+         rest of the shell to check for pending terminating and interrupt
+         signals, and to check for and process any pending traps
+       - any_signals_trapped: new function, returns non-zero if any signals
+         are trapped and -1 if not
+
+trap.h
+       - extern declaration for check_signals_and_traps
+
+bashline.c
+       - bashline_reset: make sure we reset the event hook
+       - bash_event_hook: call check_signals_and_traps instead of just
+         checking for terminating signals so we can run pending traps and
+         react to interrupts, and reset the event hook when we're done
+
+
+                                  10/14
+                                  -----
+trap.c
+       - trap_handler: if executing in a readline signal handler context,
+         call bashline_set_event_hook to install bash_event_hook to process
+         the signal (if bash cares about it)
+
+sig.c
+       - sigint_sighandler: call bashline_set_event_hook to set the event
+         hook if we're executing in a readline signal handler context
+
+lib/readline/input.c
+       - rl_getc: call RL_CHECK_SIGNALS if read returns -1/EINTR and the caught
+         signal is SIGINT or SIGQUIT rather than waiting until the next time
+         around the loop
+       - rl_getc: call rl_event_hook after calling RL_CHECK_SIGNALS to allow
+         an application signal handler to set the event hook in its own
+         signal handler (e.g., like bash trap_handler or sigint_sighandler)
+
+
+parse.y
+       - yy_readline_get: don't set interrupt_immediately before we call
+         readline().  Inspired by report from lanshun zhou
+         <zls.sogou@gmail.com>
+
+input.c
+       - getc_with_restart: add call to run_pending_traps after call to
+         CHECK_TERMSIG
+
+lib/sh/zread.c
+       - zread: call check_signals_and_traps if read() returns -1/EINTR
+         instead of just ignoring the EINTR and deferring handling any
+         signal that generated it
+
+builtins/mapfile.def
+       - mapfile: don't set interrupt_immediately before calling zgetline()
+         (which uses zread internally)
+
+builtins/read.def
+       - read_builtin: don't set interrupt_immediately before calling zread
+         (moved code around so that it was only being set right around calls
+         to zread to avoid signal handler conflicts).  Inspired by report
+         from lanshun zhou <zls.sogou@gmail.com>
+       - edit_line: don't set interrupt_immediately around call to readline()
+       - include shmbutil.h
+       - read_builtin: don't call read_mbchar unless is_basic(c) returns
+         false for the character we just read
+
+                                  10/15
+                                  -----
+sig.c
+       - throw_to_top_level: if interrupt_state is non-zero, make sure that
+         last_command_exit_value reflects 128+SIGINT if it's not already
+         greater than 128
+
+                                  10/20
+                                  -----
+builtins/wait.def
+       - WAIT_RETURN: set wait_signal_received back to 0 for the potential
+         next call to wait
+
+quit.h
+       - CHECK_WAIT_INTR: macro to check whether trap_handler handled a
+         signal and set wait_signal_received; longjmp to wait_intr_buf in
+         that case
+
+jobs.c
+       - wait_for, waitchld: call CHECK_WAIT_INTR at the same places we call
+         CHECK_TERMSIG to check for terminating signals
+       - wait_sigint_handler: don't longjmp out of the wait builtin unless
+         interrupt_immediately is set; otherwise just SIGRETURN from the
+         handler
+       - wait_sigint_handler: if interrupt_immediately not set, but we are
+         executing in the wait builtin and SIGINT is not trapped, treat it
+         as a `normally received' SIGINT: restore the signal handler and
+         send SIGINT to ourselves
+       - waitchld: when in posix mode and running SIGCHLD traps, don't longjmp
+         to wait_intr_buf (and let wait be interrupted) if we're running from
+         a signal handler.  Wait for CHECK_WAIT_INTR to do the longjmp.
+         run_pending_traps will run the SIGCHLD trap later
+
+nojobs.c
+       - reap_zombie_children, wait_for_single_pid, wait_for: call
+         CHECK_WAIT_INTR where we call CHECK_TERMSIG
+       - wait_sigint_handler: don't longjmp out of the wait builtin unless
+         interrupt_immediately is set; otherwise just SIGRETURN from the
+         handler
+
+trap.c
+       - trap_handler: make sure wait_signal_received is set if the wait
+         builtin is executing, and only longjmp if interrupt_immediately is
+         set.  This whole set of fixes was prompted by report from
+         lanshun zhou <zls.sogou@gmail.com>
+
+                                  10/24
+                                  -----
+lib/glob/glob.c
+       - glob_filename: only check directory_name for globbing chars if
+         it's of non-zero length
+
+lib/sh/strchrnul.c
+       - new simpler implementation
+
+subst.c
+       - command_substitute: call set_shellopts after turning off errexit
+         in subshells so it's reflected in $SHELLOPTS
+
+                                  11/7
+                                  ----
+builtins/evalstring.c
+       - parse_and_execute: treat ERREXIT case like reader_loop does: set
+         variable_context to 0 before longjmping back to top_level. Don't
+         run the unwind-protect context to avoid side effects from popping
+         function contexts.  Part of fix for problem reported by Nikolai
+         Kondrashov <nikolai.kondrashov@redhat.com>
+
+execute_cmd.c
+       - execute_simple_command: call unlink_fifo_list only if this is the
+         last element of a pipeline (or not in a pipeline), rather than for
+         every child.  Fixes difference in behavior between /dev/fd and
+         FIFOs reported by Zev Weiss <zev@bewilderbeest.net>
+       - execute_null_command: do the same thing in the parent branch after
+         make_child
+
+                                  11/14
+                                  -----
+subst.c
+       - parameter_brace_expand: a variable is null if it's special ($@, $*),
+         the expansion occurs within double quotes, and the expansion turns
+         into a quoted null.  Fixes debian bug 692447 reported by
+         Matrosov Dmitriy <sgf.dma@gmail.com>
+
+jobs.c
+       - run_sigchld_trap: make sure `running_trap' sentinel is set
+         appropriately
+       - waitchld: only run the sigchld trap if we're not in a signal
+         handler, not running a trap, and executing the wait builtin.
+         Otherwise, queue for later handling.  We still run one instance
+         of the trap handler per exited child.  Bulk of fix for bug
+         reported by Elliott Forney <idfah@cs.colostate.edu>
+
+trap.c
+       - queue_sigchld_trap: set catch_flag so run_pending_traps notices,
+         and set trapped_signal_received for completeness.  Rest of fix
+         for bug reported by Elliott Forney <idfah@cs.colostate.edu>
+
+lib/malloc/malloc.c
+       - block_signals: renamed to _malloc_block_signals, made public
+       - unblock_signals: renamed to _malloc_unblock_signals, made public
+
+lib/malloc/imalloc.h
+       - extern declarations for _malloc_{un,}block_signals
+
+lib/malloc/table.c
+       - mregister_alloc, mregister_free: block signals around table
+         manipulation
+
+                                  11/15
+                                  -----
+trap.c
+       - run_pending_traps: set SIG_INPROGRESS flag around calls to
+         run_sigchld_handler so other parts of the shell know that the
+         SIGCHLD trap handler is executing
+       - run_pending_traps: if we get a situation where we are looking at
+         running a SIGCHLD trap but the trap string is IMPOSSIBLE_TRAP_HANDLER
+         and the SIG_INPROGRESS flag is set, just skip it.  This is possible
+         if run_pending_traps is called from a SIGCHLD trap handler run by
+         run_sigchld_trap
+
+doc/bash.1,lib/readline/doc/{rluser.texi,readline.3}
+       - corrected description of the effect of `set history-size 0'.  Report
+         from Vesa-Matti J Kari <vmkari@cc.helsinki.fi>
+
+include/stdc.h
+       - CPP_STRING: new define, replaces __STRING
+
+lib/malloc/{malloc.c,imalloc.h}
+       - replace __STRING with CPP_STRING
+
+                                  11/16
+                                  -----
+lib/readline/bind.c
+       - sv_histsize: if argument evaluates to a value < 0, unstifle the
+         history
+
+                                  11/22
+                                  -----
+redir.c
+       - do_redirection_internal: if we have REDIR_VARASSIGN set in the
+         redirection flags and we set up `redirector' using fcntl or dup2,
+         don't add a redirect to make sure it stays open.  Let the
+         script programmer manage the file handle.  Fixes bug reported by
+         Sam Liddicott <sam@liddicott.com>
+
+                                  11/24
+                                  -----
+jobs.c
+       - wait_for_any_job: new function, waits for an unspecified background
+         job to exit and returns its exit status.  Returns -1 on no background
+         jobs or no children or other errors.  Calls wait_for with new
+         sentinel value ANY_PID
+       - wait_for: changes to handle argument of ANY_PID: don't look up or
+         try to modify the child struct, only go through the wait loop once.
+         Return -1 if waitpid returns no children
+
+jobs.h
+       - ANY_PID: new define
+
+builtins/wait.def
+       - new option: -n. Means to wait for the next job and return its exit
+         status.  Returns 127 if there are no background jobs (or no
+         children).  Feature most recently requested by Elliott Forney
+         <idfah@cs.colostate.edu>
+
+doc/{bash.1,bashref.texi}
+       - document new `wait -n' option
+
+execute_cmd.c
+       - execute_command_internal: save make_command_string () result in a
+         temp variable before calling savestring() on it; avoids evaluating
+         make_command_string() result twice.  Fix from John E. Malmberg
+         <wb8tyw@qsl.net>
+
+                                  11/28
+                                  -----
+
+builtins/declare.def
+       - declare_internal: if an array variable is declared using `declare -a'
+         or `declare -A', but not assigned a value, set the `invisible'
+         attribute so the variable does not show up as set.  Fix for bug
+         about variable initialization reported by Tim Friske <me@timfriske.com>
+
+builtins/{mapfile,read}.def
+       - after calling find_or_make_array_variable, make sure the invisible
+         flag is turned off, in case the variable was declared previously
+         using `declare -a' or `declare -A'.  Side effect of above change to
+         declare_internal
+
+subst.c
+       - shell_expand_word_list: handle the W_ASSNGLOBAL flag and put -g into
+         the list of options passed to make_internal_declare as appropriate.
+         Fix for bug reported by Tim Friske <me@timfriske.com>
+
+                                  11/30
+                                  -----
+test.c
+       - unary_op: make sure -v and -n check that the variable is not marked
+         as invisible before calling var_isset.  Fix for bug reported by Tim
+         Friske <me@timfriske.com>
+
+                                  12/2
+                                  ----
+subst.c
+       - process_substitute: turn off the `expanding_redir' flag, which
+         controls whether or not variables.c:find_variable_internal uses the
+         temporary environment to find variables.  We want to use the
+         temp environment, since we don't have to worry about order of
+         evaluation in a subshell.  Fixes bug reported by Andrey Borzenkov
+         <arvidjaar@gmail.com>
+
+                                  12/4
+                                  ----
+lib/glob/glob.c
+       - glob_filename: changes to avoid null filenames and multiple entries
+         returned for patterns like **/** (globstar enabled).  Fixes bug
+         reported by Ulf Magnusson <ulfalizer@gmail.com>
+
+                                  12/10
+                                  -----
+lib/glob/glob.c
+       - glob_filename: finish up a series of changes to make globstar-style   
+         globbing more efficient, avoid more duplicate filenames, and be more
+         compatible with other shells that implement it
+               o collapse a sequence of **/**/** to one **
+               o note when the directory name is all ** or ends in ** so we
+                 can treat it specially when the filename is **
+         All inspired by report from Andrey Borzenkov <arvidjaar@gmail.com>
+
+lib/sh/zread.c
+       - zreadn: new function, like zread, but takes an additional argument
+         saying how many bytes to read into the local buffer.  Can be used to
+         implement `read -N' without so many one-byte calls to zreadc.  Code
+         from Mike Frysinger <vapier@gentoo.org>
+
+                                  12/12
+                                  -----
+lib/glob/sm_loop.c
+       - PATSCAN (glob_patscan): if passed string already points to end of
+         pattern, return NULL immediately.  Fixes problem with
+         extglob_skipname reported by Raphaël Droz <raphael.droz@gmail.com>
+
+                                  12/13
+                                  -----
+execute_cmd.c
+       - execute_coproc: handle the command's exit status being inverted
+         (an oversight).  Fixes bug reported by DJ Mills
+         <danielmills1@gmail.com> and Andreas Schwab <schwab@linux-m68k.org>
+
+                                  12/14
+                                  -----
+lib/readline/readline.c
+       - bind_arrow_keys_internal: add MINGW key bindings for Home, End,
+         Delete, and Insert keys.  Fix from Pierre Muller
+         <pierre.muller@ics-cnrs.unistra.fr>
+
+builtins/printf.def
+       - printf_builtin: '%()T' conversion: if there is no argument supplied,
+         behave as if -1 had been supplied (current time).  ksh93-like feature
+         suggested by Clark Wang <dearvoid@gmail.com>
+
+doc/{bash.1,bashref.texi}
+       - document new printf %()T default argument behavior
+
+                                  12/15
+                                  -----
+lib/readline/display.c
+       - displaying_prompt_first_line: new variable, indicates whether or
+         not the first line of output is displaying the prompt.  Always true
+         in normal mode, sometimes false in horizontal scrolling mode
+       - rl_redisplay: set displaying_prompt_first_line to true unless we
+         are in horizontal mode; set to false in horizontal mode if the left
+         margin of the displayed line is greater than the end of the prompt
+         string
+       - rl_redisplay: when in horizontal scroll mode, don't adjust
+         _rl_last_c_pos by the wrap offset unless the line is displaying
+         a prompt containing invisible chars
+       - update line: don't adjust _rl_last_c_pos by the wrap offset unless
+         the line is displaying a prompt containing invisible chars
+       - update_line: if shrinking the line by reducing the number of
+         displayed characters, but we have already moved the cursor to the
+         beginning of the line where the first difference starts, don't
+         try to delete characters
+
+builtins/read.def
+       - unbuffered_read: set to 2 if invoked as `read -N'
+       - if unbuffered_read is set to 2, compute the number of chars we
+         need to read and read that many with zreadn.  Posix mode still
+         uses zreadintr.  Code from Mike Frysinger <vapier@gentoo.org>
+
+doc/{bash.1,bashref.texi}
+       - read: make it clear that if read times out, it saves any input
+         read to that point into the variable arguments.  Report from
+         Fiedler Roman <Roman.Fiedler@ait.ac.at>
+
+subst.c
+       - command_substitute: change direct assignment of exit_immediately_on_error
+         to use change_flag ('e', FLAG_OFF) instead
+
+flags.c
+       - use errexit_flag as the variable modified by changes to the -e
+         option, reflect those changes to exit_immediately_on_error
+
+execute_cmd.c
+       - execute_builtin: new global variable, builtin_ignoring_errexit, set
+         to 0 by default and set to 1 if eval/source/command executing in a
+         context where -e should be ignored
+       - execute_builtin: set exit_immediately_on_error to errextit_flag
+         after executing eval/source/command in a context where -e should
+         be ignored
+
+flags.c
+       - if builtin_ignoring_errexit is set, changes to errexit_flag are
+         not reflected in the setting of exit_immediately_on_error.  Fixes
+         bug reported by Robert Schiele <rschiele@gmail.com>
+
+                                  12/23
+                                  -----
+include/posixjmp.h
+       - setjmp_nosigs: new define, call setjmp in such a way that it will
+         not manipulate the signal mask
+
+{expr,test,trap}.c
+       - setjmp_nosigs: call instead of setjmp; don't need to manipulate
+         signal mask
+
+builtins/read.def
+       - read_builtin: setjmp_nosigs: call instead of setjmp; don't need
+         to manipulate signal mask
+
+builtins/evalstring.c:
+       - parse_and_execute: setjmp_nosigs: call instead of setjmp; don't need
+         to manipulate signal mask
+       - parse_string: setjmp_nosigs: call instead of setjmp; don't need
+         to manipulate signal mask
+       - parse_and_execute: save and restore the signal mask if we get a
+         longjmp that doesn't cause us to return or exit (case DISCARD)
+
+                                  12/24
+                                  -----
+general.c
+       - bash_tilde_expand: only set interrupt_immediately if there are no
+         signals trapped; we want to jump to top level if interrupted but
+         not run any trap commands
+
+                                  12/25
+                                  -----
+jobs.c
+       - run_sigchld_trap: no longer set interrupt_immediately before calling
+         parse_and_execute, even if this is no longer run in a signal handler
+         context
+
+input.c
+       - getc_with_restart: add call to QUIT instead of CHECK_TERMSIG
+
+parse.y
+       - yy_stream_get: now that getc_with_restart calls QUIT, don't need to
+         set interrupt_immediately (already had call to run_pending_traps)
+
+execute_cmd.c
+       - execute_subshell_builtin_or_function,execute_function,execute_in_subshell:
+         setjmp_nosigs: call instead of setjmp when saving return_catch; don't
+         need to manipulate signal mask
+       - execute_subshell_builtin_or_function,execute_in_subshell:
+         setjmp_nosigs: call instead of setjmp where appropriate when saving
+         top_level; don't need to manipulate signal mask if we're going to
+         exit right away
+
+subst.c
+       - command_substitute: setjmp_nosigs: call instead of setjmp when saving
+         return_catch; don't need to manipulate signal mask
+       - command_substitute: setjmp_nosigs: call instead of setjmp where
+         appropriate when saving top_level; don't need to manipulate signal
+         mask if we're going to exit right away
+
+trap.c
+       - run_exit_trap: setjmp_nosigs: call instead of setjmp when saving
+         return_catch; don't need to manipulate signal mask
+       - run_exit_trap: setjmp_nosigs: call instead of setjmp where
+         appropriate when saving top_level; don't need to manipulate signal
+         mask if we're going to exit right away
+       - _run_trap_internal: setjmp_nosigs: call instead of setjmp when saving
+         return_catch; don't need to manipulate signal mask
+
+builtins/evalfile.c
+       - _evalfile: setjmp_nosigs: call instead of setjmp when saving
+         return_catch; don't need to manipulate signal mask
+
+builtins/evalstring.c
+       - evalstring: setjmp_nosigs: call instead of setjmp when saving
+         return_catch; don't need to manipulate signal mask
+
+shell.c
+       - main: setjmp_nosigs: call instead of setjmp where appropriate when
+         saving top_level; don't need to manipulate signal mask if we're
+         going to exit right away
+       - run_one_command: setjmp_nosigs: call instead of setjmp where
+         appropriate when saving top_level; don't need to manipulate signal
+         mask if we're going to exit right away
+       - run_wordexp: setjmp_nosigs: call instead of setjmp where
+         appropriate when saving top_level; don't need to manipulate signal
+         mask if we're going to exit right away
+
+eval.c
+       - reader_loop: save and restore the signal mask if we get a longjmp
+         that doesn't cause us to return or exit (case DISCARD)
+
+                                  12/26
+                                  -----
+parse.y
+       - shell_input_line_{index,size,len}: now of type size_t; in some cases
+         the unsigned property makes a difference
+       - STRING_SAVER: saved_line_{size,index} now of type size_t
+       - shell_getc: don't allow shell_input_line to grow larger than SIZE_MAX;
+         lines longer than that are truncated until read sees a newline;
+         addresses theoretical buffer overflow described by Paul Eggert
+         <eggert@cs.ucla.edu>
+       - set_line_mbstate: size_t changes like shell_getc
+       - shell_getc: if shell_input_line is larger than 32K, free it and
+         start over to avoid large memory allocations sticking around
+
+variables.c
+       - bind_global_variable: new function, binds value to a variable in
+         the global shell_variables table
+
+variables.h
+       - bind_global_variable: new extern declaration
+
+builtins/declare.def
+       - declare_internal: if -g given with name=value, but variable is not
+         found in the global variable table, make sure to call
+         bind_global_variable so the variable is created and modified at
+         global scope.  Fixes a bug where declare -g x=y could modify `x'
+         at a previous function scope
+
+command.h
+       - W_ASSIGNARRAY: new word flag, compound indexed array assignment
+
+subst.h
+       - ASS_MKGLOBAL: new assignment flag, forcing global assignment even in
+         a function context, used by declare -g
+
+execute_cmd.c
+       - fix_assignment_words: set W_ASSIGNARRAY flag if -a option given to
+         declaration builtin
+
+subst.c
+       - do_assignment_internal: explicitly handle case where we are
+         executing in a function and we want to create a global array or
+         assoc variable
+       - shell_expand_word_list: call make_internal_declare if -a option
+         given to declaration builtin (W_ASSIGNARRAY); handle -g option with
+         it (W_ASSNGLOBAL).  Fixes inconsistency noticed by Vicente Couce
+         Diaz <vituko@gmail.com>, where declare -ag foo=(bar) could modify
+         array variable foo at previous function scope, not global scope
+
+                                  12/27
+                                  -----
+bashline.c
+       - Minix needs the third argument to tputs to be a void funtion taking
+         an int argument, not an int-returning function.  Fix from
+         John E. Malmberg <wb8tyw@qsl.net> as part of VMS bash port
+
+                                  12/29
+                                  -----
+configure.ac,version.c,patchlevel.h
+       - bash-4.3-devel: new version, new shell compatibility level (43)
+
+subst.c
+       - parameter_brace_patsub: put the bash-4.2 code back in from the
+         change of 3/3 that runs the replacement string through quote
+         removal, make it dependent on shell_compatibility_level <= 42
+
+builtins/shopt.def
+       - compat42: new shopt option
+       - set_compatibility_level: change logic to set and unset various
+         compat variables and shell_compatibility_level
+
+COMPAT
+       - new documentation for bash-4.3 compatibility changes
+
+doc/{bash.1,bashref.texi}
+       - compat42: document new shopt option
+
+builtins/shopt.def
+       - set_compatibility_opts: new function, sets the various shopt
+         compat variables based on the value of shell_compatibility_level
+
+builtins/common.h
+       - set_compatibility_opts: new extern declaration
+
+variables.c
+       - BASH_COMPAT: new special variable; sets the shell compatibility
+         level.  Accepts values in decimal (4.2) or integer (42) form;
+         Unsetting variable, setting it to empty string, or setting it to
+         out-of-range value sets the shell's compatibility level to the
+         default for the current version.  Valid values are 3.1/31 through
+         the current version
+       - sv_shcompat: new function implementing logic for BASH_COMPAT
+
+variables.h
+       - sv_shcompat: new extern declaration
+
+doc/{bash.1,bashref.texi}
+       - BASH_COMPAT: description of new variable
+
+lib/readline/complete.c
+       - _rl_colored_stats: default back to 0 for 4.3 release branch
+
+                                1/5/2013
+                                --------
+quit.h
+       - remove spurious call to itrace in CHECK_WAIT_INTR
+
+bashline.c
+       - bash_event_hook: if we're going to jump to top_level, make sure we
+         clean up after readline() by calling rl_cleanup_after_signal().
+         Fixes bug reported against devel branch by Raphaël Droz
+         <raphael.droz@gmail.com>
+       - bash_event_hook: reset the event hook before checking for signals
+         or traps in case we longjmp
+
+doc/{bash.1,bashref.texi}
+       - small additions to the set -e section to make it more clear that
+         contexts where -e is ignored extend to compound commands as well
+         as shell functions
+
+lib/readline/readline.h
+       - rl_signal_event_hook: new extern declaration
+
+lib/readline/input.c
+       - rl_signal_event_hook: new variable, hook function to call when a
+         function (currently just read(2)) is interrupted by a signal and
+         not restarted
+       - rl_getc: call rl_signal_event_hook instead of rl_event_hook
+
+lib/readline/doc/rltech.texi
+       - rl_signal_event_hook: document new function
+
+bashline.c
+       - changes to set rl_signal_event_hook instead of rl_event_hook
+
+lib/readline/readline.h
+       - change readline version numbers to 6.3
+
+                                   1/6
+                                   ---
+doc/{bash.1,bashref.texi}
+       - a couple of changes to the descriptions of the ERR trap and its
+         effects based on a message from Rob Nagler <nagler@bivio.biz>
+
+                                   1/9
+                                   ---
+expr.c
+       - expassign: invalidate curlval before freeing and NULLing tokstr to
+         avoid aliasing issues.  Fixes bug reported by Eduardo A. Bustamante
+         López<dualbus@gmail.com>  and Dan Douglas <ormaaj@gmail.com>
+
+braces.c
+       - array_concat: don't be so aggressive in trying to short-circuit. We
+         can only short-circuit if we have a single-element array where the
+         element is an empty string (array[0] == "" array[1] = 0x0).  Existing
+         practice requires us to replicate arrays and prefix or append empty
+         strings.  Fixes bug reported by Eduardo A. Bustamante López
+         <dualbus@gmail.com>
+
+                                  1/11
+                                  ----
+execute_cmd.c
+       - execute_builtin: since mapfile uses evalstring() to run its callbacks
+         internally, just like eval, so it needs to handle the case where the
+         temp environment given to mapfile persists throughout the entire
+         set of callback commands.  This might be a problem with trap also, but
+         trap isn't run in the same way.  Fixes bug reported by Dan Douglas
+         <ormaaj@gmail.com>
+
+                                  1/13
+                                  ----
+redir.c
+       - redirection_error: before expanding the redirection word (if
+         expandable_redirection_filename returns true), disable command
+         substitution during expansion.  Fixes bug reported by Dan Douglas
+         <ormaaj@gmail.com>
+
+subst.c
+       - expand_word_internal: case '\\': if the next character is an IFS
+         character, and the expansion occurs within double quotes, and the
+         character is not one for which backslash retains its meaning, add
+         the (escaped) '\' and the (escaped) character.  Fixes bug reported
+         by Dan Douglas <ormaaj@gmail.com>
+
+                                  1/15
+                                  ----
+builtins/cd.def
+       - cd_builtin: make sure call to internal_getopt handles -e option.
+         Fixes bug reported by <mashimiao.fnst@cn.fujitsu.com>
+
+                                  1/17
+                                  ----
+subst.c
+       - expand_word_list_internal: make sure tempenv_assign_error is
+         initialized to 0
+
+execute_cmd.c
+       - execute_simple_command: make sure tempenv_assign_error is reset to 0
+         after it's tested to see if an error should force the shell to exit.
+         Fixes problem where a the failure of a tempenv assignment preceding
+         a non-special builtin `sticks' and causes the next special builtin
+         to exit the shell.  From a discussion on bug-bash started by
+         douxin <wq-doux@cn.fujitsu.com>
+
+                                  1/20
+                                  ----
+subst.c
+       - parameter_brace_expand_rhs: call stupidly_hack_special_variables
+         after assigning with ${param[:]=word} even if IFS is changing.
+         Suggested by Dan Douglas <ormaaj@gmail.com> [TENTATIVE, needs work
+         on IFS side effects]
+
+command.h
+       - W_GLOBEXP (which was unused) is now W_SPLITSPACE (which isn't used
+         yet)
+
+{execute_cmd,subst,variables}.c
+       - removed all code that mentioned W_GLOBEXP
+       - removed mention of gnu_argv_flags and code that set it
+
+                                  1/22
+                                  ----
+subst.c
+       - param_expand: set W_SPLITSPACE if we expand (unquoted) $* and
+         IFS is unset or null so we can be sure to split this on spaces
+         no matter what happens with IFS later
+       - expand_word_internal: note that param_expand returns W_SPLITSPACE
+         in the returned word flags and keep track of that state with
+         `split_on_spaces'
+
+                                  1/23
+                                  ----
+subst.c
+       - expand_word_internal: if split_on_spaces is non-zero, make sure
+         we split `istring' on spaces and return the resultant word.  The
+         previous expansions should have quoted spaces in the positional
+         parameters where necessary.  Suggested by Dan Douglas
+         <ormaaj@gmail.com>
+
+execute_cmd.c
+       - execute_command_internal: make sure any subshell forked to run a
+         group command or user subshell at the end of a pipeline runs any
+         EXIT trap it sets.  Fixes debian bash bug 698411
+         http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=698411
+
+subst.c
+       - shell_expand_word_list: fix code that creates args for and calls
+         make_internal_declare to avoid calling it twice (missing `else'
+         in 12/26 change)
+       - do_assignment_internal: fix code from 12/26 change to fix problem
+         where an existing assoc variable could be converted to an array
+         without checking `mkassoc'
+
+                                  1/24
+                                  ----
+builtins/evalfile.c
+       - _evalfile: add missing `close (fd)' calls before returning to
+         avoid fd leaks.  Bug and fix from Roman Rakus <rrakus@redhat.com>
+
+                                  1/25
+                                  ----
+builtins/read.def
+       - read_builtin: don't try to play tricks with the top of the unwind-
+         protect stack after read gets a SIGALRM; save input_string to new
+         memory, run the stack, then restore input_string and assign the
+         variables.  Part of fix for bug reported by konsolebox
+         <konsolebox@gmail.com>; the rest of the fix is with the changes in
+         trap and signal handling and doing away with interrupt_immediately
+
+                                  1/26
+                                  ----
+redir.c
+       - redirection_expand, write_here_string, write_here_document: before
+         calling any of the word expansion functions, after setting
+         expanding_redir to 1 (which bypasses the temp environment in the
+         variable lookup functions), call sv_ifs to reset the cached IFS-
+         related variables set by subst.c:setifs().  This ensures that
+         redirections will not get any IFS values that are set in the
+         temporary environment, as Posix specifies.  Then, after the word
+         expansions, after resetting expanding_redir to 0, call sv_ifs
+         again to make sure the cached IFS values are set from any
+         assignments in the temporary environment.  We force executing_builtin
+         to 1 to `fool' the variable lookup functions into using any temp
+         environment, then reset it to its old value after sv_ifs returns.
+         This is what allows read() to use the (cached) IFS variables set
+         in the temp environment. Fixes inconsistency reported by Dan Douglas
+         <ormaaj@gmail.com>
+
+                                  1/29
+                                  ----
+lib/readline/display.c
+       - update_line: fix off-by-one error when updating vis_lbreaks array
+         in a multibyte locale that occurs when moving multibyte chars from
+         one line down to another.  Bug report and fix from Egmont
+         Koblinger <egmont@gmail.com>
+
+                                  1/30
+                                  ----
+configure.ac
+       - changed version to 4.3-alpha
+
+redir.c
+       - redir_open: handle open returning -1/EINTR, which seems to happen
+         a lot with FIFOs and SIGCHLD, and call QUIT to handle other
+         signals that can interrupt open(2).  Bug report and initial fix
+         from Mike Frysinger <vapier@gentoo.org>
+
+                                  1/31
+                                  ----
+subst.c
+       - parameter_brace_expand: make sure to propagate the PF_ASSIGNRHS flag
+         to parameter_brace_expand_word
+       - parameter_brace_expand_word: make sure that if the PF_ASSIGNRHS flag
+         is set and we are expanding ${a[@]} or ${a[*]} we set quoted to
+         include Q_DOUBLE_QUOTES before calling array_value_internal, mirroring
+         what we do for $@ and $*.  Fixes inconsistency reported by Dan
+         Douglas <ormaaj@gmail.com>
+
+configure.ac
+       - use AC_CHECK_TOOL instead of AC_CHECK_PROG to check for ar, since it
+         will find $host-prefixed versions of utilities.  Report and fix from
+         Mike Frysinger <vapier@gentoo.org>
+
+builtins/setattr.def
+       - set_var_attribute: check whether bind_variable (called when the
+         variable whose attributes are being modified is found in the temp
+         environment) just modified a read-only global variable, and don't
+         bother marking the temporary variable for propagation if so.  The
+         propagation is superfluous and will result in a strange error
+         message
+
+                                   2/2
+                                   ---
+variables.c
+       - initialize_shell_variables: don't try to import function definitions
+         with invalid names from the environment if already in posix mode,
+         but create them as (invisible) exported variables so they pass
+         through the environment.  Print an error message so user knows
+         what's wrong.  Fixes bug reported by Tomas Trnka <ttrnka@mail.muni.cz>
+
+                                   2/9
+                                   ---
+
+builtins/read.def
+       - sigalrm_seen, alrmbuf: now global so the rest of the shell (trap.c)
+         can use them
+       - sigalrm: just sets flag, no longer longjmps to alrmbuf; problem was
+         longjmp without manipulating signal mask, leaving SIGALRM blocked
+
+quit.h
+       - move CHECK_ALRM macro here from builtins/read.def so trap.c:
+         check_signals() can call it
+
+trap.c
+       - check_signals: add call to CHECK_ALRM before QUIT
+       - check_signals_and_traps: call check_signals() instead of including
+         CHECK_ALRM and QUIT inline.  Integrating check for read builtin's
+         SIGALRM (where zread call to check_signals_and_traps can see it)
+         fixes problem reported by Mike Frysinger <vapier@gentoo.org>
+
+                                  2/12
+                                  ----
+lib/glob/xmbsrtowcs.c
+       - xdupmbstowcs2: fixed but where end of string was not handled
+         correctly, causing loop to go past end of string in a bunch of cases.
+         Fixes bug reported by "Dashing" <dashing@hushmail.com>
+
+
+                                  2/13
+                                  ----
+builtins/pushd.def
+       - popd_builtin: treat any argument that isn't -n or of the form
+         [-+][[:digit:]]* as an error.  Fixes problem reported by Bruce
+         Korb <bruce.korb@gmail.com>
+
+                                  2/14
+                                  ----
+configure.ac
+       - add check for sig_atomic_t; already a placeholder for it in
+         config.h.in
+
+                                  2/15
+                                  ----
+subst.c
+       - do_compound_assignment: don't call assign_compound_array_list with
+         a NULL variable in case make_local_xxx_variable returns NULL
+         (it will if you try to shadow a readonly or noassign variable).
+         Fixes bug reported by Richard Tollerton <rich.tollerton@ni.com>
+
+                                  2/16
+                                  ----
+variables.c
+       - make_local_variable: print error messager if an attempt is made to
+         create a local variable shadowing a `noassign' variable.  Previously
+         we just silently refused to do it
+
+trap.[ch]
+       - get_original_signal: now global so rest of the shell can use it
+
+sig.c
+       - initialize_shell_signals: install a signal handler for SIGTERM
+         that does nothing except set a sigterm_received flag instead of
+         ignoring it with SIG_IGN, as long as SIGTERM is not ignored when
+         the shell is started.  Use get_original_signal early to get the
+         original handler, since we will do that later anyway
+       - set_signal_handler: if installing sigterm_sighandler as the SIGTERM
+         handler, make sure to add SA_RESTART flag to make it as close to
+         SIG_IGN as possible
+
+sig.h
+       - sigterm_sighandler: new extern declaration
+
+quit.h
+       - RESET_SIGTERM: set sigterm_receved to 0
+       - CHECK_SIGTERM: check sigterm_received; if it's non-zero, treat it
+         as a fatal signal and call termsig_handler to exit the shell
+
+jobs.c
+       - make_child: call RESET_SIGTERM just before fork() so we can detect
+         if the child process received a SIGTERM before it's able to change
+         the signal handler back to what it was when the shell started
+         (presumably SIG_DFL).  Only has effect if the shell installed
+         sigterm_sighandler for SIGTERM, interactive shells that were not
+         started with SIG_IGN as the SIGTERM handler
+       - make_child: call RESET_SIGTERM in the parent after fork() so the
+         rest of the shell won't react to it
+
+execute_cmd.c
+       - execute_simple_command: call CHECK_SIGTERM after make_child in child
+         to catch SIGTERM received after fork() and before restoring old
+         signal handlers
+       - execute_disk_command: call CHECK_SIGTERM after make_child in child
+         process after restoring old signal handlers and again just before
+         calling shell_execve.  Fixes race condition observed by
+         Padraig Brady <p@draigbrady.com> when testing with his `timeout'
+         program
+
+lib/readline/display.c
+       - open_some_spaces: new function, subset of insert_some_chars that just
+         opens up a specified number of spaces to be overwritten
+       - insert_some_spaces: now just calls to open_some_spaces followed by
+         _rl_output_some_chars
+       - update_line: use col_temp instead of recalculating it using
+         _rl_col_width in the case where we use more columns with fewer bytes
+       - update_line: use open_some_spaces and then output the right number
+         of chars instead of trying to print new characters then overwrite
+         existing characters in two separate calls.  This includes removing
+         some dodgy code and making things simpler.  Fix from Egmont
+         Koblinger <egmont@gmail.com>
+       - use new variable `bytes_to_insert' instead of overloading temp in
+         some code blocks (nls - nfd, bytes that comprise the characters
+         different in the new line from the old)
+
+                                  2/18
+                                  ----
+redir.c
+       - do_redirection_internal: add undoable redirection for the implicit
+         close performed by the <&n- and >&n- redirections.  Fixes bug
+         reported by Stephane Chazelas <stephane.chazelas@gmail.com>
+
+                                  2/19
+                                  ----
+sig.c
+       - termsig_handler: an interactive shell killed by SIGHUP and keeping
+         command history will try to save the shell history before exiting.
+         This is an attempt to preserve the save-history-when-the-terminal-
+         window-is-closed behavior
+
+                                  2/21
+                                  ----
+braces.c
+       - brace_expand: if a sequence expansion fails (e.g. because the
+         integers overflow), treat that expansion as a simple string, including
+         the braces, and try to process any remainder of the string.  The
+         remainder may include brace expansions.  Derived from SuSE bug
+         804551 example (https://bugzilla.novell.com/show_bug.cgi?id=804551)
+
+                                  2/23
+                                  ----
+{quit,sig}.h,sig.c
+       - sigterm_received declaration now in sig.h; type is sig_atomic_t
+       - sigwinch_received type now sig_atomic_t
+       - sig.h includes bashtypes.h and <signal.h> if SIG_DFL not defined
+         (same logic as trap.h) to pick up sig_atomic_t
+
+unwind_prot.c
+       - include sig.h before quit.h (reverse order)
+
+                                  2/27
+                                  ----
+builtins/shopt.def
+       - reset_shopt_options: make sure check_window_size is reset to the
+         default from config.h, not unconditionally to 0
+
+jobs.[ch]
+       - last_made_pid, last_asynchronous_pid: now volatile.  Change from SuSE
+
+jobs.c
+       - wait_for: if we're using sigaction to install a handler for SIGCHLD,
+         make sure we specify SA_RESTART
+
+lib/{tilde,readline}/shell.c
+       - get_home_dir: instead of looking in the password file every time,
+         look once and cache the result
+
+sig.[ch]
+       - sigwinch_received, sigterm_received: now `volatile' qualified
+
+sig.c,quit.h
+       - interrupt_state,terminating_signal: now sig_atomic_t
+
+                                   3/1
+                                   ---
+MANIFEST,examples/*
+       - removed around 120 files without FSF copyrights; requested by
+         Karl Berry in early January
+
+                                   3/2
+                                   ---
+lib/malloc/malloc.c
+       - morecore: only check whether SIGCHLD is trapped if SIGCHLD is defined
+
+doc/bashref.texi
+       - Fixed most of the examples in the GNU Parallel section to use better
+         shell idioms following complaints on bug-bash; added a couple of
+         examples and smoothed out the text
+
+quit.h
+       - include "sig.h" for sig_atomic_t
+
+lib/readline/display.c
+       - update_line: when inserting one or more characters at the end of
+         the display line in a non-multibyte environment, just write from the
+         first difference to the end of the line and return. We don't have
+         to adjust _rl_last_c_pos.  This is needed to adjust from the old
+         two-part copy to a single call to _rl_output_some_chars (change of
+         2/16)
+
+                                   3/4
+                                   ---
+Makefile.in,doc/Makefile.in
+       - PACKAGE_TARNAME, docdir: new variables substituted by autoconf
+       - OTHER_DOCS,OTHER_INSTALLED_DOCS: new variables with auxiliary
+         documentation files to be installed into $(docdir)
+       - install: add new rule to install $(OTHER_DOCS)
+       - uninstall: add new rule to uninstall $(docdir)/$(OTHER_INSTALLED_DOCS)
+
+doc/bash.1
+       - add URL to `POSIX' file in `SEE ALSO' section; put pointer to that
+         section in --posix and set -o posix descriptions
+
+examples/
+       - removed around 110 examples at the request of the FSF due to copyright
+         issues
+
+                                   3/5
+                                   ---
+builtins/setattr.def
+       - readonly: modified help text slightly to make it clearer that
+         functions aren't changed or displayed unless the -f option is given.
+         Report from <gotmynick@gmail.com>
+
+                                   3/9
+                                   ---
+include/typemax.h
+       - SIZE_MAX: define to 65535 (Posix minimum maximum) if not defined
+
+parse.y
+       - include "typemax.h" for possible SIZE_MAX definition, make sure we
+         include it after shell.h
+
+{braces,expr}.c
+       - include "typemax.h" for possible INTMAX_MIN and INTMAX_MAX definitions
+
+                                  3/10
+                                  ----
+bashline.c
+       - bash_default_completion: make sure completion type of `!' (same as
+         TAB but with show-all-if-ambiguous set) and glob-word-completion
+         sets rl_filename_completion_desired to 0 so extra backslashes don't
+         get inserted by `quoting' the completion.  We can't kill all the
+         matches because show-all-if-ambiguous needs them.   Bug report from
+         Marcel (Felix) Giannelia <info@skeena.net>
+
+[bash-4.3-alpha frozen]
+
+                                  3/14
+                                  ----
+general.c
+       - trim_pathname: use memmove instead of memcpy since the source and
+         destination pathnames may overlap.  Report and fix from Matthew
+         Riley <mattdr@google.com>
+
+                                  3/18
+                                  ----
+configure.ac
+       - socklen_t is defined as `unsigned int' if configure can't find it
+
+                                  3/20
+                                  ----
+lib/readline/complete.c
+       - S_ISVTX: since it's not defined on all platforms (Minix), make sure
+         its use is protected with #ifdef
+
+                                  3/21
+                                  ----
+doc/{bash.1,bashref.texi}
+       - Added mention of ${!name[@]} and ${!name[*]} expansions to get all
+         indices of an array.  Suggested by Jonathan Leffler
+         <jonathan.leffler@gmail.com>
+
+                                  3/24
+                                  ----
+subst.h
+       - SD_IGNOREQUOTE: new define for skip_to_delim; if set, means that
+         single quotes (for now) will be treated as ordinary characters
+
+subst.c
+       - skip_to_delim: handle SD_IGNOREQUOTE. no callers use it for now
+
+                                  3/25
+                                  ----
+support/config.{guess,sub}
+       - updated to versions from autoconf-2.69
+
+                                  3/31
+                                  ----
+lib/sh/shquote.c
+       - sh_single_quote: short-circuit quoting a single "'" instead of
+         creating a long string with empty single-quoted strings
+
+parser.h
+       - DOLBRACE_QUOTE2: new define, like DOLBRACE_QUOTE, but need to single-
+         quote results of $'...' expansion because quote removal will be
+         done later.  Right now this is only done for ${word/pat/rep}
+
+parse.y
+       - parse_matched_pair: set state to DOLBRACE_QUOTE2 for pattern
+         substitution word expansion so we don't treat single quote specially
+         in the pattern or replacement string
+       - parse_matched_pair: if we're parsing a dollar-brace word expansion
+         (${...}) and we're not treating single quote specially within
+         double quotes, single-quote the translation of $'...' ansi-c
+         escaped strings.  Original report and fix from Eduardo A.
+         Bustamante López <dualbus@gmail.com>
+
+subst.c
+       - extract_dollar_brace_string: ${word/pat/rep} scanning now sets the
+         DOLBRACE_QUOTE2 flag instead of DOLBRACE_QUOTE so we don't treat
+         single quotes specially within a double-quoted string
+
+execute_cmd.c
+       - fix_assignment_words: skip over assignment statements preceding a
+         command word before trying to figure out whether or not assignment
+         statements following a possible declaration command should be 
+         treated specially.  Fixes bug reported by Dan Douglas
+         <ormaaj@gmail.com>
+
+                                   4/4
+                                   ---
+lib/readline/readline.c
+       - _rl_dispatch_subseq: only call _rl_vi_set_last (and check whether
+         the key is a text modification command) if the key sequence length
+         is 1.  That keeps the arrow keys from setting the last command
+         when called in vi command mode.  Fixes bug reported by Ian A.
+         Watson <watson_ian_a@lilly.com>
+
+                                   4/6
+                                   ---
+lib/readline/bind.c
+       - rl_parse_and_bind: when parsing a double-quoted string as the value
+         of a variable, make sure we skip past the leading double quote.
+         Fix from Andreas Schwab <schwab@linux-m68k.org>
+
+variables.c
+       - hash_lookup: set new local variable last_table_searched to the table
+         a successful lookup appears in; tested in make_local_variable to
+         solve the problem below
+       - make_local_variable: if we find a variable with the tempenv flag
+         set at the same `level' as variable_context', but not found in the
+         temporary_env (temp environment preceding the builtin), return it.
+         The temp environment preceding the function call has already been
+         merged (in execute_function) into the list of variable contexts the
+         function sees as shell_variables by the time this is called.  Fixes
+         inconsistency pointed out by Dan Douglas <ormaaj@gmail.com>
+
+subst.c
+       - expand_arith_string: expanded out contents of expand_string,
+         expand_string_internal, expand_string_if_necessary to create a
+         WORD_DESC and call call_expand_word_internal() on it directly.
+         We don't want process substitution to be performed ( 1<(2) ) should
+         mean something different in an arithmetic expression context.
+         It doesn't work to just turn on the DQUOTE flag, since that means
+         that things like ${x["expression"]} are not expanded correctly.
+         Fixes problem pointed out by Dan Douglas <ormaaj@gmail.com>
+
+                                  4/13
+                                  ----
+subst.c
+       - process_substitute: run the EXIT trap before exiting, as other
+         shells seem to.  Fixes problem pointed out by Dan Douglas
+         <ormaaj@gmail.com>
+
+lib/readline/readline.c
+       - readline_internal_setup: call rl_vi_insertion_mode to enter vi
+         mode instead of rl_vi_insert_mode to avoid resetting the saved last
+         command information.  Posix says that `.' can repeat a command
+         that was entered on a previous line so we need to save the info.
+         Fixes bug reported by Ian A. Watson <watson_ian_a@lilly.com>
+
+                                  4/14
+                                  ----
+lib/readline/complete.c
+       - rl_completion_matches: make sure xrealloc returns something non-null
+         (can happen when interrupted by a signal) before trying to add
+         matches to match_list
+
+subst.c
+       - array_remove_pattern: return NULL right away if array_variable_part
+         returns an invisible variable
+       - array_length_reference: handle array_variable_part returning an
+         invisible variable
+       - get_var_and_type: handle array_variable_part returning an invisible
+         variable
+
+                                  4/15
+                                  ----
+execute_cmd.c
+       - execute_command_internal: make sure to run the EXIT trap for group
+         commands anywhere in pipelines, not just at the end.  From a point
+         raised by Andreas Schwab <schwab@linux-m68k.org>
+
+variables.c
+       - bind_int_variable: make sure invisible flag is unset.  Fixes problems
+         like "declare -ai a; : $(( a[4]=4 ));"
+
+arrayfunc.c
+       - array_variable_part: return variable even if invisible flag set,
+         callers must handle invisible vars
+
+                                  4/18
+                                  ----
+builtins/set.def
+       - unset_builtin: if -n flag given, call unset_nameref instead of
+         unset_variable
+
+variables.c
+       - find_variable_nameref: print warning message if nameref circular
+         reference detected, return NULL and let caller deal with it
+
+builtins/declare.def
+       - declare_builtin: only disallow global references at this point if
+         we are at the global scope
+
+                                  5/16
+                                  ----
+configure.ac
+       - update release status to beta
+
+                                  5/23
+                                  ----
+trap.c
+       - run_pending_traps: save and restore pipeline around calls to
+         evalstring() in case we get a trap while running a trap. Have to
+         figure out the recursive running traps issue elsewhere.  Fixes
+         bug reported by Roman Rakus <rrakus@redhat.com>
+       - run_pending_traps: make sure to set running_trap to the appropriate
+         signal value when running a trap command
+       - run_pending_traps: short-circuit immediately if running_trap set
+         when invoked.  Could change this later to only skip if it would
+         run the same trap as currently being run (running_trap == sig + 1)
+
+configure.ac
+       - add warning if bison not found
+
+lib/readline/doc/rltech.texi
+       - new section with an example program illustrating the callback
+         interface. Suggested by Peng Yu <pengyu.ut@gmail.com>
+
+examples/loadables/Makefile.in
+       - remove references to `cut' and `getconf', which were removed in
+         early March
+
+                                  5/28
+                                  ----
+lib/sh/pathphys.c
+       - sh_realpath: correct inverted two arguments to call to sh_makepath.
+         Report and fix from Julien Thomas <jthomas@exosec.fr>
+
+                                   6/7
+                                   ---
+execute_cmd.c
+       - executing_line_number: the else clauses that are conditional on
+         various options being defined can simply be if clauses -- they are
+         mutually exclusive and all have `return' in the body.  Fixes bug
+         reported by Flavio Medeiros <flaviomotamedeiros@gmail.com>
+
+                                  6/25
+                                  ----
+lib/readline/readline.c
+       - readline_internal_setup: only sent the meta-key enable string to the
+         terminal if we've been told to use one and the terminal has been
+         successfully initialized (RL_ISSTATE (RL_STATE_TERMPREPPED) != 0).
+         Suggested by Dan Mick <dan.mick@inktank.com>
+
+lib/readline/signals.c
+       - _rl_signal_handler: call any defined signal hook after calling
+         rl_resize_terminal when handling a SIGWINCH.  We already have called
+         the original SIGWINCH handler but will not be resending the signal
+         to ourselves
+
+                                  6/27
+                                  ----
+lib/readline/doc/history.3, doc/bash.1
+       - fix description of the `$' modifier to note that it expands to the
+         last *word*, which is not always the last argument.  Report from
+         ariyetz@gmail.com via gnu.org RT
+
+                                  6/29
+                                  ----
+lib/glob/smatch.c
+       - glob_asciiranges: initialize to value of GLOBASCII_DEFAULT instead
+         of 0 (0 if not defined)
+
+configure.ac,config.h.in
+       - --enable-glob-asciiranges-default: new option, controls the value of
+         GLOBASCII_DEFAULT; use it to turn globasciiranges shopt option on
+         by default
+
+doc/bashref.texi
+       - document new --enable-glob-asciiranges-default configure option
+
+variables.c
+       - assign_in_env: implement += value appending semantics for assignments
+         preceding command names
+
+                                   7/4
+                                   ---
+expr.c
+       - set lasttok = NUM in all of the functions that result in a number,
+         even if it's a boolean, to avoid errors with constructs like
+         1 * x = 1, which should be an asignment error.  Fixes problem
+         pointed out by Dan Douglas <ormaaj@gmail.com>
+
+parse.y
+       - decode_prompt_string: don't bother to call strcpy if
+         polite_directory_format returns its argument unchanged.  It's not
+         necessary and Mac OS X 10.9 aborts because of a supposed overlapping
+         string copy.  Bug and fix from simon@hitzemann.org
+
+subst.c
+       - parameter_brace_find_indir: new function, code from
+         parameter_brace_expand_indir that looks up the indirectly-referenced
+         variable, but does not expand it
+       - parameter_brace_expand_indir: call parameter_brace_find_indir to
+         look up indirected variable reference
+       - get_var_and_type: call parameter_brace_find_indir if it looks like we
+         are trying to manipulate an indirect variable reference like
+         ${!b%%foo}.  This makes a difference if !b references an array
+         variable.  Bug report from Dan Douglas <ormaaj@gmail.com>
+
+                                   7/6
+                                   ---
+lib/sh/casemod.c
+       - sh_modcase: make sure argument passed to is_basic is <= UCHAR_MAX,
+         since cval can convert something to a wchar_t greater than UCHAR_MAX.
+         Fixes bug reported by Tomasz Tomasik <scx.mail@gmail.com>
+
+                                   7/8
+                                   ---
+lib/readline/history.c
+       - add_history_time: if history_length == 0, referencing history_length
+         - 1 will result in an array bounds error, so make history_length be
+         at least 1 before going on.  Fixes bug reported by Geng Sheng Liu
+         <gsliu.tju@gmail.com>
+
+builtins/setattr.def
+       - show_func_attributes: display definition (if NODEFS argument is 0) and
+         attributes for a particular function; used by `declare -fp name'
+
+builtins/declare.def
+       - declare_internal: call show_func_attributes if -f supplied with -p.
+         Fixes inconsistency observed by Linda Walsh <bash@tlinx.org>
+
+builtins/common.h
+       - new extern declaration for show_func_attributes
+
+builtins/read.def
+       - read_builtin: check the first supplied variable name for validity
+         before attempting to read any input, since we know we will have to
+         at least use that one.  Don't check any other names yet.  Suggested
+         by jidanni@jidanni.org
+
+                                  7/10
+                                  ----
+redir.c
+       - do_redirection_internal: when closing a file descriptor with
+         r_close_this ([n]<&-) count close errors as redirection errors if
+         errno ends up as EIO or ENOSPC.  Originally reported back in April
+         2012 by Andrey Zaitsev <jstcdr@gmail.com>
+
+                                  7/11
+                                  ----
+redir.c
+       - do_redirection_internal: before calling check_bash_input, make sure
+         that we don't call check_bash_input for an asynchronous process that
+         is replacing stdin with something else. The seek backwards affects
+         the parent process as well, since parents and children share the
+         file pointer. Fixes problem originally reported in March 2013 by
+         Martin Jackson <mjackson220.list@gmail.com>
+
+                                  7/13
+                                  ----
+doc/{bash.1,bashref.texi}
+       - slight change to add a description of `shopt -o' suggested by Bruce
+         Korb <bruce.korb@gmail.com>
+
+                                  7/19
+                                  ----
+lib/readline/histfile.c
+       - history_do_write: if close returns < 0, make sure we restore the
+         backup history file and return a non-zero value
+       - history_truncate_file: if write or close return < 0, make sure we
+         return a non-zero value
+
+[bash-4.3-beta frozen]
+
+                                  7/21
+                                  ----
+lib/readline/isearch.c
+       - rl_display_search: now takes an entire search context flags word as
+         the second argument, instead of just reverse flag; changed callers
+       - rl_display_search: if the search has failed, add `failed ' to the
+         beginning of the search prompt
+       - _rl_isearch_dispatch: if the search has failed, display the entire
+         search string with an indication that the search failed but with the
+         last matching line.  Suggested by jidanni@jidanni.org
+
+command.h
+       - W_ASSIGNINT: new word flag; used internally for make_internal_declare
+         and set by fix_assignment_words
+
+execute_cmd.c
+       - fix_assignment_words: set W_ASSIGNINT if compound assignment and -i
+         given as option.  We don't do anything with the value yet
+
+subst.c
+       - shell_expand_word_list: rework the way the option list that is
+         passed to make_internal_declare is created
+
+                                   8/1
+                                   ---
+doc/{bash.1,bashref.texi}
+       - minor changes to description of $! based on a report from Chris
+         Down <chris@chrisdown.name>
+
+arrayfunc.c
+       - assign_array_element_internal: before trying to get an array's max
+         index to process a negative subscript, make sure the array exists.
+         Bug report from Geir Hauge <geir.hauge@gmail.com>
+
+                                   8/2
+                                   ---
+arrayfunc.c
+       - assign_array_element_internal: before using array_max_index() when
+         processing a negative subscript, make sure the variable is an array.
+         if it's not, use 0 as array_max_index assuming it's a string.
+         Fixes bug report from Geir Hauge <geir.hauge@gmail.com>
+
+                                   8/3
+                                   ---
+Makefile.in
+       - pcomplete.o: add dependency on $(DEFDIR)/builtext.h. Suggested by
+         Curtis Doty <curtis@greenkey.net>
+
+                                   8/5
+                                   ---
+lib/glob/sm_loop.c
+       - strcompare: short-circuit and return FNM_NOMATCH if the lengths of the
+         pattern and string (pe - p  and se - s, respectively) are not equal
+       - strcompare: don't bother trying to set *pe or *se to '\0' if that's
+         what they already are.  Fixes bug reported by Geir Hauge
+         <geir.hauge@gmail.com>
+
+                                   8/6
+                                   ---
+doc/{bash.1,bashref.texi},builtins/hash.def,lib/readline/doc/rluser.texi
+       - minor typo changes from Geir Hauge <geir.hauge@gmail.com>
+
+bultins/help.def
+       - show_longdoc: avoid trying to translate the empty string because it
+         often translates to some boilerplate about the project and
+         translation.  Report and fix from Geir Hauge <geir.hauge@gmail.com>
+
+                                   8/8
+                                   ---
+builtins/help.def
+       - help_builtin: try two passes through the list of help topics for each
+         argument: one doing exact string matching and one, if the first pass
+         fails to find a match, doing string prefix matching like previous
+         versions.  This prevents `help read' from matching both `read' and
+         `readonly', but allows `help r' to match everything beginning with
+         `r'.  Inspired by report from Geir Hauge <geir.hauge@gmail.com>
+
+                                  8/13
+                                  ----
+builtins/fc.def
+       - fc_builtin,fc_gethnum: calculate `real' end of the history list and
+         use it if -0 is specified as the beginning or end of the history
+         range to list.  Doesn't work for fc -e or fc -s by design.  Feature
+         requested by Mike Fied <micfied@gmail.com>
+
+                                  8/16
+                                  ----
+trap.c
+       - _run_trap_internal: use {save,restore}_parser_state instead of
+         {save,restore}_token_state. It's more comprehensive
+
+                                  8/23
+                                  ----
+doc/bash.1
+       - disown: remove repeated text.  Report and fix from Thomas Hood
+         <jdthood@gmail.com>
+
+                                  8/25
+                                  ----
+lib/readline/rltty.c
+       - set_special_char: fix prototype (last arg is rl_command_func_t *)
+
+sig.c
+       - set_signal_handler: return oact.sa_handler only if sigaction
+         succeeds; if it doesn't, return SIG_DFL (reasonable default).  From
+         https://bugzilla.redhat.com/show_bug.cgi?id=911404
+
+bashline.c
+       - attempt_shell_completion: fix to skip assignment statements preceding
+         command name even if there are no programmable completions defined.
+         From https://bugzilla.redhat.com/show_bug.cgi?id=994659
+       - attempt_shell_completion: if still completing command word following
+         assignment statements, do command completion even if programmable
+         completion defined for partial command name entered so far
+
+                                  8/26
+                                  ----
+pcomplete.c
+       - pcomp_filename_completion_function: make sure rl_filename_dequoting_function
+         is non-NULL before trying to call it.  Bug and fix from
+         Andreas Schwab <schwab@linux-m68k.org>
+
+bashline.c
+       - bash_command_name_stat_hook: if *name is not something we're going
+         to look up in $PATH (absolute_program(*name) != 0), just call the
+         usual bash_filename_stat_hook and return those results.  This makes
+         completions like $PWD/exam[TAB] add a trailing slash
+
+                                   9/2
+                                   ---
+builtins/read.def
+       - read_builtin: before comparing what we read to the delim, make sure
+         we are not supposed to be ignoring the delimiter (read -N).  We
+         set the delim to -1, but it's possible to read a character whose
+         int value ends up being between -1 and -128.  Fixes bug
+         reported by Stephane Chazelas <stephane.chazelas@gmail.com>
+
+doc/{bash.1,bashref.texi}
+       - word splitting: crib some language from Posix to make it clear that
+         characters in IFS are treated as field *terminators*, not field
+         *separators*.  Addresses issue raised by DJ Mills
+         <danielmills1@gmail.com>
+
+lib/readline/{util.c,rldefs.h}
+       - _rl_stricmp,_rl_strnicmp: now take const char * string arguments;
+         changed prototype declarations
+
+                                   9/5
+                                   ---
+doc/{bash.1,bashref.texi}
+       - [[: modify description of pattern matching to make it clear that the
+         match is performed as if the extglob option were enabled.  From Red
+         Hat bug https://bugzilla.redhat.com/show_bug.cgi?id=1002078
+
+                                  9/12
+                                  ----
+lib/readline/isearch.c
+       - _rl_isearch_dispatch: if we read an ESC and it's supposed to
+         terminate the search, make sure we check for typeahead with
+         _rl_pushed_input_available, since installing a hook function causes
+         typeahead to be collected in `ibuffer' (input.c).  If there is any,
+         make sure we still use the ESC as a prefix character.  Bug and fix
+         from Mike Miller <mtmiller@ieee.org>
+
+                                  9/16
+                                  ----
+builtins/{caller,cd,kill,pushd,wait}.def
+       - builtin_usage(): make sure call to this sets return status to
+         EX_USAGE
+
+                                  9/18
+                                  ----
+terminal.c
+       - rl_change_environment: new application-settable variable; if non-
+         zero (the default), readline will modify LINES and COLUMNS in the
+         environment when it handles SIGWINCH
+       - _rl_get_screen_size: if rl_change_environment is non-zero, use setenv
+         to modify LINES and COLUMNS environment variables
+
+readline.h
+       - rl_change_environment: new extern declaration for applications
+
+                                  9/22
+                                  ----
+configure.ac
+       - relstatus: bumped version to bash-4.3-beta2
+
+                                  9/24
+                                  ----
+
+lib/readline/readline.c
+       - bind_arrow_keys_internal: added more key bindings for the numeric key
+         pad arrow keys on mingw32.  Patch from Pierre Muller
+         <pierre.muller@ics-cnrs.unistra.fr>
+
+                                  10/19
+                                  -----
+
+bashline.c
+       - maybe_restore_tilde: version of restore_tilde that honors `direxpand';
+         calls restore_tilde after saving directory expansion hook if
+         necessary.  Report from Andreas Schwab <schwab@linux-m68k.org>
+
+builtins/cd.def
+       - -@: new option, allows cd to use `extended attributes' present in
+         NFSv4, ZFS; idea taken from ksh93.  Attributes associated with a
+         file are presented as a directory containing the attributes as
+         individual files.  Original patch contributed by Cedric Blancher
+         <cedric.blancher@gmail.com>
+
+                                  10/20
+                                  -----
+aclocal.m4
+       - BASH_CHECK_MULTIBYTE: check for wcwidth being broken with unicode
+         combining characters needs a value to use when cross-compiling.
+         Bug report from Bert Sutherland <bertsutherland@gmail.com>
+
+doc/{bash.1,bashref.texi}
+       - document new -@ option to cd builtin
+
+                                  10/28
+                                  -----
+lib/glob/{{gmisc,glob}.c,glob.h}
+       - extglob_pattern renamed to extglob_pattern_p, declared in glob.h
+
+subst.c
+       - expand_word_internal: typo fix: case to fix " $@\ " bug in bash-4.2
+         had a typo (& isexp instead of &&)
+
+                                  10/29
+                                  -----
+input.c
+       - getc_with_restart: make sure local_index and local_bufused are
+         reset to 0 before returning EOF, in case we are running an interactive
+         shell without line editing and ignoreeof is set.  Report and fix
+         from Yong Zhang <yong.zhang@windriver.com>
+
+lib/readline/search.c
+       - _rl_nsearch_init: take out extra third argument to rl_message; it
+         only matches prototype (and maybe format) in cases where
+         PREFER_STDARG and USE_VARARGS are both undefined, which is rare
+
+                                  10/31
+                                  -----
+subst.c
+       - process_substitute: when opening the named pipe in the child, open
+         without O_NONBLOCK to avoid race conditions.  Happens often on AIX.
+         Bug report and fix from Michael Haubenwallner
+         <michael.haubenwallner@salomon.at>
+
+builtins/ulimit.def
+       - RLIMIT_NTHR: if RLIMIT_PTHREAD is not defined, but RLIMIT_NTHR is,
+         use RLIMIT_NTHR (NetBSD)
+
+                                  11/5
+                                  ----
+locale.c
+       - set_default_locale_vars,set_locale_var: if TEXTDOMAINDIR has been
+         set, and default_dir has a non-null value, call bindtextdomain(3)
+         when TEXTDOMAIN is assigned a value.  Fixes problem reported by
+         Michael Arlt <qwertologe@googlemail.com>
+
+                                  11/6
+                                  ----
+builtins/cd.def
+       - cdxattr: only create synthetic pathname in `buf' if NDIRP argument
+         is non-null
+       - change_to_directory: if we have specified -@ and cdxattr returns
+         failure, fail immediately.  Fixes bug reported by Joshuah Hurst
+         <joshhurst@gmail.com>
+
+                                  11/12
+                                  -----
+redir.c
+       - print_redirection: change r_err_and_out (&>) and its append form,
+         r_append_err_and_out (&>>) cases to separate redirection operator
+         from filename by a space, in case we have a process substitution.
+         Fixes bug reported by admn ombres <admn.ombres@gmail.com>
+
+                                  11/15
+                                  -----
+execute_cmd.c
+       - execute_simple_command: don't close process substitution fds until
+         we are finished executing any current shell function.  Partial fix
+         for bug reported by John Dawson <john.dawson@gmail.com>
+
+support/shobj-conf
+       - add support for Darwin 13 (Mac OS X 10.9, Mavericks).  Based on a
+         report by Ludwig Schwardt <ludwig.schwardt@gmail.com>
+
+                                  11/20
+                                  -----
+[bash-4.3-rc1 frozen]
+
+                                  11/24
+                                  -----
+builtins/printf.def
+       - bind_printf_variable: make sure that the variable assigned to is
+         no longer marked as invisible. Fixes bug reported by NBaH
+         <nbah@sfr.fr>
+
+                                  11/28
+                                  -----
+jobs.c
+       - delete_old_job: fix off-by-one error in job index in call to
+         internal_warning. Bug report from Peter Cordes <peter@cordes.ca>
+
+                                  11/30
+                                  -----
+doc/bashref.texi
+       - add string to description of special parameters with name of
+         special parameter prefixed by a $, so you can search for $#,
+         for instance
+
+                                  12/2
+                                  ----
+lib/readline/{histexpand.c
+       - get_history_event: account for current_history() possibly returning
+         NULL. Report and fix from Pankaj Sharma <pankaj.s01@samsung.com>
+
+
+                                  12/11
+                                  -----
+
+lib/readline/parse-colors.c
+       - get_funky_string: don't call abort if we see something we can't
+         parse; just return an error
+       - _rl_parse_colors: if we encounter an error while parsing $LS_COLORS
+         we need to leave _rl_color_ext_list as NULL after freeing its
+         elements, then turn off _rl_colored_stats. Report and fix from Martin
+         Wesdorp <mwesdorp@casema.nl>
+
+                                  12/13
+                                  -----
+
+lib/readline/parse-colors.c
+       - _rl_parse_colors: if we encounter an unrecognized prefix, throw an
+         error but try to recover and go on to the next specification
+
+variables.c
+       - make_local_variable: for new variables this function creates, set
+         the att_invisible attribute.  All callers from declare_internal.
+         Indirectly, this is a fix for bug with `declare -n var; var=foo;'
+         reported by Pierre Gaston <pierre.gaston@gmail.com>
+       - bind_variable: if assigning to nameref variable that doesn't have
+         a value yet (e.g., with `declare -n var; var=foo'), don't try to
+         use the unset name. Fixes a segfault reported by Pierre Gaston
+         <pierre.gaston@gmail.com>
+
+execute_cmd.c
+       - execute_command_internal: make sure last_command_exit_value is set
+         to 0 after any command executed in the background.  Fixes bug
+         reported by Martin Kealey <martin@kurahaupo.gen.nz>
+
+                                  12/17
+                                  -----
+support/config.{guess,sub}
+       - updated to latest versions from git
+
+                                  12/19
+                                  -----
+parse.y
+       - struct STRING_SAVER: now has a new `flags' element, to identify the
+         caller: alias expansion, double-paren parsing, or parse_and_execute
+       - push_string: now sets flags to PSH_ALIAS if `ap' argument is non-NULL
+       - push_string: now doesn't attempt to call strlen on a NULL string to
+         set shell_input_line_size
+       - parser_expanding_alias, parser_save_alias, parser_restore_alias: new
+         functions to provide an external interface to push_string and
+         pop_string; parser_save_alias sets flags element to PSH_SOURCE (could
+         be renamed PSH_EXTERN someday)
+       - shell_getc: when yy_getc returns '\0', instead of just testing
+         whether the pushed_string_list is not-empty before popping it, don't
+         pop if if the saved string has flags PSH_SOURCE, indicating that
+         parse_and_execute set it before setting bash_input to the string.
+         We should continue reading to the end of that string before popping
+         back to a potential alias. Partial solution for the problem of aliases
+         with embedded newlines containing `.' commands being executed out of
+         order reported by Andrew Martin <andrew.martin@gmail.com>
+       - shell_getc: when yy_getc returns '\0' and there is a saved string of
+         type PSH_SOURCE, restart the read without popping the string stack
+         if we have not read to the end of bash_input.location.string.  Rest
+         of fix for out-of-order execution problem
+
+externs.h
+       - parser_expanding_alias, parser_save_alias, parser_restore_alias: new
+         extern function declarations
+
+builtins/evalstring.c
+       - pe_prologue: if the parser is expanding an alias, make sure to add
+         an unwind-protect to restore the alias; undoes the work that will be
+         performed by parse_and_execute/parse_string
+       - parse_and_execute,parse_string: after calling push_stream to save
+         bash_input, check whether or not the parser is currently expanding
+         an alias (parser_expanding_alias() != 0). If it is, we want to save
+         that string in the pushed_string_list, which we do with
+         parser_save_alias.
+
+                                  12/23
+                                  -----
+execute_cmd.c
+       - execute_for_command: make sure to set line_number before expanding
+         the word list, so expansion errors have the right line number.
+         From a report from Ben Okopnik <ben@okopnik.com>
+
+expr.c
+       - exp2: save token pointer before calling readtok(), arrange to use
+         saved token pointer when printing error token on a division by 0
+         error
+
+                                  12/27
+                                  -----
+lib/readline/display.c
+       - rl_redisplay: when calculating effects of invisible characters in a
+         prompt that is split across physical screen lines to set the indices
+         of linebreaks, don't bother testing local_prompt_prefix (line 751).
+         That prefix doesn't matter when calculating prompt visible and
+         invisible characters.  Fixes problem reported by Jinesh Choksi
+         <jinesh@onelittlehope.com>
+
+Makefile.in
+       - install: make sure to use $(DESTDIR) when installing OTHER_DOCS.
+         Report and fix from Matthias Klose <doko@debian.org>
+
+doc/texinfo.tex
+       - updated to version of 2013-09-11
+
+                                  12/28
+                                  -----
+lib/readline/undo.c
+       - rl_do_undo: if we are undoing from a history entry (rl_undo_list ==
+         current_history()->data), make sure the change to rl_line_buffer is
+         reflected in the history entry. We use the guts of
+         rl_maybe_replace_line to do the work.  Fixes problem reported by
+         gregrwm <backuppc-users@whitleymott.net>
+
+                                  12/30
+                                  -----
+sig.c
+       - sigint_sighandler: if we get a SIGINT (and this signal handler is
+         installed) while the wait builtin is running, note that we received
+         it in the same way as jobs.c:wait_sigint_handler and return.  The
+         various wait_for functions will look for that with CHECK_WAIT_INTR.
+         This fixes the wait builtin not being interruptible in an interactive
+         job control shell
+
+                                  12/31
+                                  -----
+trap.c
+       - set_signal_hard_ignored: rename set_signal_ignored to this, since it
+         both sets original_signals[sig] and sets the HARD_IGNORE flag
+       - set_signal_ignored: new function, now just sets original_signals[sig]
+
+trap.h
+       - set_signal_hard_ignored: new external declaration
+
+sig.c
+       - initialize_terminating_signals: call set_signal_hard_ignored instead
+         of set_signal_ignored for signals with disposition SIG_IGN when the
+         shell starts
+
+execute_cmd.c
+       - setup_async_signals: make sure we get the original dispositions for
+         SIGINT and SIGQUIT before starting the subshell, and don't call
+         set_signal_ignored  because that sets original_signals[sig].  If we
+         don't, subsequent attempts to reset handling using trap will fail
+         because it thinks the original dispositions were SIG_IGN. Posix
+         interpretation 751 (http://austingroupbugs.net/view.php?id=751)
+
+                                1/2/2014
+                                --------
+lib/sh/stringvec.c
+       - strvec_mcreate, strvec_mresize: versions of create and resize that
+         use malloc and realloc, respectively, instead of xmalloc/xrealloc
+
+braces.c
+       - expand_amble,mkseq: use strvec_mcreate/strvec_mresize so we can
+         catch and handle memory allocation failures instead of aborting
+         with the xmalloc/xrealloc interface
+
+lib/sh/strdup.c
+       - strdup replacement function for ancient systems that don't have it
+
+lib/sh/itos.c
+       - mitos: new function, itos that uses strdup instead of savestring
+
+externs.h
+       - strvec_mcreate/strvec_mresize: new extern declarations
+       - mitos: new extern declaration
+
+configure.ac
+       - bash version moved to 4.3-rc2
+
+                                   1/6
+                                   ---
+doc/bash.1,lib/readline/doc/{rluser.texi,readline.3}
+       - separate the description of what happens when readline reads the
+         tty EOF character from the description of delete-char, leaving a
+         note in the delete-char description about common binding for ^D.
+         From suggestion by Parke <parke.nexus@gmail.com>
+
+lib/readline/doc/{version.texi,history.3,*.texi}
+       - updated email addresses and copyright dates
+
+                                   1/7
+                                   ---
+variables.c
+       - delete_var: new function, just removes a variable from a hash table
+         and frees it, without doing anything else
+       - make_variable_value: if we are trying to assign to a nameref variable,
+         return NULL if the value is null or the empty string or not a valid
+         identifier
+
+variables.h
+       - delete_var: new extern declaration
+
+subst.h
+       - ASS_NAMEREF: new define for assignments, means assigning to a nameref
+         variable
+
+builtins/declare.def
+       - declare_internal: if we are creating and assigning to a nameref
+         variable, make sure the value is a valid variable name (checks done
+         by make_variable_value via bind_variable_value) and display an
+         error message, deleting the variable we just created, if it is not.
+         Fixes bug reported by Peggy Russell <prusselltechgroup@gmail.com>
+
+                                   1/9
+                                   ---
+builtins/declare.def
+       - declare_internal: turning on nameref attribute for an existing
+         variable turns off -i/-l/-u/-c attributes (essentially the ones
+         that cause evaluation at assignment time) for ksh93 compat
+
+builtins/setattr.def
+       - show_name_attributes: if asked to display attributes and values for
+         a nameref variable, don't follow the nameref chain to the end. More
+         ksh93 compat
+
+                                  1/10
+                                  ----
+trap.c
+       - _run_trap_internal: use {save,restore}_parser_state instead of
+         {save,restore}_token_state, like in run_pending_traps(); don't
+         need to save and restore last_command_exit_value as a result
+       - _run_trap_internal: call {save,restore}_pipeline like in
+         run_pending_traps()
+       - run_pending_traps: since we no longer run traps in a signal handler
+         context, do not block and unblock the trapped signal while the
+         trap is executing
+       - run_pending_traps: allow recursive invocations (basically, running
+         traps from a trap handler) with only a warning if the shell is
+         compiled in debug mode.  If a caller doesn't want this to happen,
+         it should test running_trap > 0. signal_in_progress (sig) only works
+         for the signals the shell handles specially
+
+bashline.c
+       - bash_event_hook: make sure we clean up readline if interrupt_state
+         is set, not only when SIGINT is not trapped.  check_signals_and_traps
+         will call check_signals, which calls QUIT, which will longjmp back
+         to top_level, running the interrupt trap along the way.  Fixes the
+         problem of signal handlers being reset out from under readline, and
+         not being set properly the next time readline is called, because
+         signals_set_flag is still set to 1.  XXX - might need to do this
+         for other signals too?
+
+                                  1/11
+                                  ----
+subst.h
+       - SD_GLOB: new define for skip_to_delim; means we are scanning a
+         glob pattern.
+
+subst.c
+       - skip_to_delim: if flags include SD_GLOB, assume we are scanning a
+         glob pattern.  Currently only used to skip bracket expressions
+         which may contain one of the delimiters
+
+                                  1/12
+                                  ----
+subst.c
+       - parameter_brace_expand: when expanding $@ as part of substring
+         expansion, pattern substitution, or case modification, don't turn
+         on the QUOTED_NULL flag.  The code that constructs the word to be
+         returned from expand_word_internal expects a different code path
+         when $@ is being expanded.  Fixes bug reported by Theodoros
+         V. Kalamatianos <thkala@gmail.com>
+
+                                  1/19
+                                  ----
+subst.c
+       - list_dequote_escapes: new function; analogue of list_quote_escapes
+
+pathexp.c
+       - quote_string_for_globbing: fix case where unescaped ^A is last char
+         in string; need to pass it through unaltered instead of turning it
+         into a bare backslash
+       - quote_string_for_globbing: when quoting for regexp matching in [[,
+         don't treat backslash as a quote character; quote the backslash as
+         any other character.  Part of investigation into reports from
+         Eduardo A. Bustamante López <dualbus@gmail.com>
+
+                                  1/25
+                                  ----
+builtins/gen-helpfiles.c
+       - write_helpfiles: add prototype
+       - make sure to #undef xmalloc/xfree/xrealloc/free if USING_BASH_MALLOC
+         is defined. the code does not use them, and we don't link against
+         xmalloc.o. Report from Linda Walsh <bash@tlinx.org>
+
+Makefile.in
+       - variables.o: add dependency on builtins/builtext.h; helps with
+         parallel builds.  Report from Linda Walsh <bash@tlinx.org>
+
+support/shobj-conf
+       - darwin: combine the stanzas into one that will not require them to
+         be updated on each Mac OS X release.  Report and fix from Max Horn
+         <max@quendi.de>
+
+                                  1/27
+                                  ----
+support/shobj-conf
+       - darwin: changed the install_name embedded into the shared library
+         to contain only the major version number, not the minor one. The
+         idea is that the minor versions should all be API/ABI compatible,
+         and it is better to link automatically with the latest one.  Idea
+         from Max Horn <max@quendi.de>
+
+                                  1/29
+                                  ----
+[bash-4.3-rc2 released]
+
+                                  1/30
+                                  ----
+lib/readline/readline.h
+       - rl_clear_history, rl_free_keymap: add extern declarations.  Report
+         from Hiroo Hayashi <hiroo.hayashi@computer.org>
+
+general.c
+       - include trap.h for any_signals_trapped() prototype
+
+lib/sh/unicode.c
+       - include <stdio.h> for sprintf prototype
+
+                                  1/31
+                                  ----
+execute_cmd.c
+       - execute_simple_command: only posix-mode shells should exit on an
+         assignment failure in the temporary environment preceding a special
+         builtin. This is what the documentation and code comments have
+         always said
+       - execute_simple_command: make sure redirection errors, word expansion
+         errors, and assignment errors to Posix special builtins cause a
+         non-interactive posix mode shell to exit.  Previously the shell
+         would not exit if the failed special builtin was on the LHS of ||
+         or &&
+
+pathexp.c
+       - quote_string_for_globbing: when quoting a regular expression
+         (QGLOB_REGEXP), allow an unquoted backslash to pass through
+         unaltered. Don't use it as a quote character or quote it.  More
+         investigation from 1/24 and report by Mike Frysinger
+         <vapier@gentoo.org>
+       - quote_string_for_globbing: when quoting a regular expression
+         (QGLOB_REGEXP), turn CTLESC CTLESC into CTLESC without adding a
+         backslash to quote it. We should not have to quote it because it is
+         not a character special to EREs. More investigation from 1/24
+
+lib/glob/glob.c
+       - glob_testdir: now takes a second flags argument (currently unused);
+         changed prototype and callers
+
+                                   2/1
+                                   ---
+lib/glob/glob.c
+       - glob_testdir: if flags argument includes GX_ALLDIRS (globstar), use
+         lstat so we skip symlinks when traversing the directory tree.
+         Originally reported by Chris Down <chris@chrisdown.name>
+
+                                   2/2
+                                   ---
+lib/readline/undo.c
+       - rl_do_undo: make sure CUR is non-zero before dereferencing it to
+         check cur->data against rl_undo_list.  Report and fix from
+         Andreas Schwab <schwab@linux-m68k.org>
+
+doc/{bash.1,bashref.texi}
+       - added slight clarifying language to the description of $*,
+         describing what happens when the expansion is not within double
+         quotes
+
+                                   2/4
+                                   ---
+test.c
+       - unary_test: add code to -v case so that it interprets `bare' array
+         references (foo[1]) and returns true if that index has a value
+
+                                   2/5
+                                   ---
+trap.c
+       - restore_default_signal: fix SIGCHLD special case for SIG_TRAPPED flag
+         off but SIG_INPROGRESS mode set and handler IMPOSSIBLE_TRAP_HANDLER;
+         continue with resetting handler in this case. maybe_set_sigchld_trap
+         will check these things before resetting sigchld trap from
+         run_sigchld_trap.  Fixes (apparently long-standing?) problem reported
+         by Alexandru Damian <alexandru.damian@intel.com>
+
+                                   2/6
+                                   ---
+lib/sh/strtrans.c
+       - ansic_quote: fixed a bug when copying a printable character that
+         consumes more than one byte; byte counter was not being incremented.
+         Bug report from jidanni@jidanni.org
+
+                                   2/7
+                                   ---
+input.c
+       - getc_with_restart: if read(2) returns -1/EINTR and interrupt_state or
+         terminating_signal is set (which means QUIT; will longjmp out of this
+         function), make sure the local buffer variables are zeroed out to
+         avoid reading past the end of the buffer on the next call.  Bug report
+         from Dan Jacobson <jidanni@jidanni.org>
+
+                                   2/9
+                                   ---
+bashline.c
+       - command_word_completion_function: if a directory in $PATH contains
+         quote characters, we need to quote them before passing the candidate
+         path to rl_filename_completion_function, which performs dequoting on
+         the pathname it's passed.  Fixes bug reported by Ilyushkin Nikita
+         <ilyushkeane@gmail.com>
+
+                                  2/11
+                                  ----
+parse.y
+       - xparse_dolparen: save and restore shell_eof_token around call to
+         parse_string, intead of just leaving it set to ')'
+       - shell_getc: when -v is set, only print the command line when
+         shell_eof_token is 0, so we don't print it multiple times when
+         recursively entering the parser to parse $(...) commands.  Fixes
+         bug reported by Greg Wooledge <wooledg@eeg.ccf.org>
+
+[changed release status to 4.3-release]
+
+                                  2/13
+                                  ----
+lib/sh/strtrans.c
+       - ansic_quote: handle case where mbrtowc reports that the multibyte
+         sequence is incomplete or invalid.  Fixes bug reported by
+         Eduardo A. Bustamante López <dualbus@gmail.com>
+
+                                  2/14
+                                  ----
+variables.c
+       - find_variable_nameref_context: fix a problem that caused the loop
+         to go one context too close to the global context.  In some cases,
+         simple variable assignment would set a variable in the global
+         context instead of a local context.  Bug report from
+         Geir Hauge <geir.hauge@gmail.com>
+
+                                  2/26
+                                  ----
+[bash-4.3 released]
+
+                                  2/27
+                                  ----
+aclocal.m4
+       - broken wcwidth check: fix typo reported by David Michael
+         <fedora.dm0@gmail.com>
+
+                                  2/28
+                                  ----
+support/bashbug.sh
+       - add ${BUGADDR} to error message printed if sending mail fails
+
+trap.c
+       - _run_trap_internal: don't call {save,restore}_pipeline if running
+         DEBUG trap; run_debug_trap calls them itself.  Fixes bug reported
+         by Moe Tunes <moetunes42@gmail.com>
+
+test.c
+       - unary_test: fix 'R' case by using find_variable_noref instead of
+         find_variable
+       - test_unop: add back missing 'R' case.  Fixes bug reported by
+         NBaH <nbah@sfr.fr>
+
+                                   3/2
+                                   ---
+jobs.c
+       - end_job_control: if job control is active, we changed the terminal's
+         process group, so make sure we restore it.  Fixes bug reported by
+         Eduardo A. Bustamante López <dualbus@gmail.com>
+
+                                   3/7
+                                   ---
+pcomplete.c
+       - pcomp_curtxt: new variable, holds the original text to be completed
+         as passed to the programmable completion code
+       - pcomp_filename_completion_function: if we are running compgen
+         (presumably in a shell function completion) and performing readline
+         completion, check the word being completed.  If it's not empty, but
+         the original word passed to the programmable completion code is an
+         empty string (""), call a dequoting function if one is available.
+         This compensates for an assumption in bash-completion.  Reported by
+         Albert Shih <Albert.Shih@obspm.fr>
+
+lib/readline/readline.c
+       - _rl_dispatch_subseq: when deciding whether or not to set vi mode's
+         idea of the last command, use whether or not the dispatching keymap
+         is vi_movement_keymap instead of the key sequence length.  The `c',
+         `d', and `y' commands all take motion commands as `arguments' and
+         will produce key sequences longer than 1 character.  The arrow keys
+         will end up dispatching out of a different keymap, so the test will
+         prevent arrow keys from setting the last command (the problem in
+         bash-4.2). Bug report from Daan van Rossum <daan@flash.uchicago.edu>
+
+lib/readline/vi_mode.c
+       - _rl_vi_motion_command: convenience function to test whether a key is
+         a vi-mode motion command
+
+lib/readline/rlprivate.h
+       - _rl_vi_motion_command: extern declaration
+
+parse.y
+       - parse_matched_pair: we should not skip processing single quotes in
+         posix mode if dolbrace_state == DOLBRACE_QUOTE2 (pattern
+         substitution).  Fixes bug reported by David Sines
+         <dave.gma@googlemail.com>
+
+                                  3/10
+                                  ----
+lib/readline/readline.c
+       - _rl_dispatch_callback: treat a return value of -1 as the end of
+         a command dispatch sequence if the current context doesn't
+         indicate that we're reading a multi-key sequence
+         ((cxt->flags & KSEQ_SUBSEQ) == 0).  Turn off the multikey flag
+         and free the context chain in this case.  Fixes one bug reported
+         by Felix Yan <felixonmars@gmail.com> to bug-readline list
+       - _rl_dispatch_callback: treat a return value of > 0 the same as 0
+         and return from the function, since only values < 0 cause us to
+         simulate recursion.  Rest of fix for bug tracked down by
+         Anatol Pomozov <anatol.pomozov@gmail.com>
+
+                                  3/11
+                                  ----
+
+execute_cmd.c
+       - execute_in_subshell: if a longjmp occurs, set result to
+         EXECUTION_FAILURE only if last_command_exit_value == EXECUTION_SUCCESS;
+         use value of last_command_exit_value otherwise.  Fixes cosmetic
+         issue reported by Dennis Lambe Jr. <malsyned@malsyned.net>
+
+doc/bash.1
+       - shell-kill-word and shell-backward-kill-word should be documented
+         as unbound by default.  Report from Oliver Hartley
+         <ohartley@talktalk.net>
+
+trap.c
+       - run_pending_traps: save value of $? before running trap commands in
+         trap_saved_exit_value, like run_exit_trap
+       - _run_trap_internal: save value of $? before running trap commands in
+         trap_saved_exit_value, like run_exit_trap
+
+builtins/common.c
+       - get_exitstat: when running `return' in a trap action, and it is not
+         supplied an argument, use the saved exit status in
+         trap_saved_exit_value.  Fixes Posix problem reported by
+         Eduardo A. Bustamante López <dualbus@gmail.com>
+
+                                  3/13
+                                  ----
+lib/sh/shquote.c
+       - sh_contains_quotes: new function, returns true if a given string
+         contains any of the shell quote characters (single quote, double
+         quote, or backslash)
+
+externs.h
+       - sh_contains_quotes: new extern declaration
+
+pcomplete.c
+       - pcomp_filename_completion_function: more changes for the benefit of
+         bash-completion: if the argument is not the same as the original
+         argument passed to the programmable completion code (pcomp_curtxt),
+         and we are being run by compgen as part of a completion, dequote the
+         argument as bash-completion expects.  Fix for the complete-word-
+         with-quoted-special-chars problem with bash-completion
+
+                                  3/17
+                                  ----
+execute_cmd.c
+       - execute_intern_function: when in posix mode, make defining a function
+         with the same name as a special builtin a fatal error only when the
+         shell is not interactive. Interactive shells display an error
+         message and go on.  From a discussion with Doug McIlroy
+         <doug@cs.dartmouth.edu>
+
+                                  3/18
+                                  ----
+arrayfunc.c
+       - assign_compound_array_list: when using expand_assignment_string_to_string
+         to expand the value in a ( [x]=y ) compound assignment, make sure
+         that we convert 0x0 to "" when expanding [x]= so it doesn't appear as
+         if the index is unset.  Fixes bug reported by Geir Hauge
+         <geir.hauge@gmail.com>
+
+builtins/common.c
+       - get_exitstat: update fix of 3/11 to allow the DEBUG trap to use the
+         current value of $? instead of the value it had before the trap
+         action was run.  This is one reason the DEBUG trap exists, and
+         extended debug mode uses it.  Might want to do this only in Posix
+         mode
+
+doc/{bash.1,bashref.texi}
+       - return: add language cribbed from Posix saying what happens when
+         return is run without an argument from a trap, including the DEBUG
+         trap exception
+
+                                  3/19
+                                  ----
+lib/glob/gmisc.c
+       - extglob_pattern_p: make sure ?(patlist) is flagged as an extglob
+         pattern
+
+lib/glob/glob.c
+       - extglob_skipname: rewrite to handle patterns that begin but do not
+         end with an extglob pattern; change test for easy case and loop
+         through patterns accordingly.  Fixes problem with matching filenames
+         with a leading dot reported by Stephane Chazelas
+         <stephane.chazelas@gmail.com>
+       - wextglob_skipname: make analogous changes
+
+                                  3/20
+                                  ----
+Makefile.in
+       - pass -DDEBUG down to builds in readline and history directories
+
+lib/readline/util.c
+       - _rl_trace and related functions are now only compiled in if DEBUG
+         is defined
+
+lib/readline/Makefile.in
+       - substitute @DEBUG@ and pass -DDEBUG, if necessary, to compilation
+         in LOCAL_CFLAGS
+
+                                  3/21
+                                  ----
+parse.y
+       - shell_getc: when checking whether or not to reallocate
+         shell_input_line to add trailing newline, don't try to subtract from
+         shell_input_line_size.  size_t is unsigned, so if its value is less
+         than 3 (like, say, 2), size-3 is a very large number and the string
+         will not be reallocated.  Use len+3 > size instead of len > size-3.
+         Fixes bug reported in
+         https://bugs.launchpad.net/ubuntu/+source/bash/+bug/1295467
+
+                                  3/27
+                                  ----
+lib/readline/display.c
+       - _rl_clean_up_for_exit: don't bother to call _rl_move_vert to whatever
+         readline thinks the last displayed line is if it's 0.  Two reasons: a
+         minor optimization, and it protects against unwanted moving if this
+         function is called twice, as it is when ^C is pressed.  Fixes bug
+         reported by Egmont Koblinger <egmont@gmail.com>
+
+                                  3/28
+                                  ----
+bashline.c
+       - invalid_completion: new function, used to identify attempts to
+         complete words that are syntax errors
+       - attempt_shell_completion: if invalid_completion returns true for a
+         word in a command position, punt on all completions.  Fixes cosmetic
+         issue reported by Uwe Storbeck <uwe@ibr.ch>
+       - attempt_shell_completion: add clause so that in_command_position
+         remains set to 1 for an empty word following a command separator like
+         (, &, or |
+
+lib/readline/kill.c
+       - rl_yank, rl_yank_nth_arg_internal: don't return -1 from bindable
+         functions, return 1 instead
+
+lib/readline/text.c
+       - rl_rubout, _rl_rubout_char, rl_delete, rl_change_case,
+         rl_transpose_chars, rl_transpose_words, _rl_set_mark_at_pos,
+         rl_exchange_point_and_mark, _rl_insert_next, _rl_char_search,
+         _rl_char_search_internal:
+         don't return -1 from bindable functions, return 1 instead
+
+lib/readline/vi_mode.c
+       - rl_vi_end_word, rl_vi_rubout, rl_vi_delete, rl_vi_char_search,
+         rl_vi_match, _rl_vi_set_mark, _rl_vi_goto_mark:
+         don't return -1 from bindable functions, return 1 instead
+
+lib/readline/macro.c
+       - rl_start_kbd_macro, rl_end_kbd_macro:
+         don't return -1 from bindable functions, return 1 instead
+
+builtins/setattr.def
+       - set_var_attribute: honor setting of no_invisible_vars when setting
+         att_invisible on a variable
+       - include "../flags.h" for no_invisible_vars
+
+builtins/declare.def
+       - declare_internal: honor setting of no_invisible_vars when setting
+         att_invisible on a variable
+       - include "../flags.h" for no_invisible_vars
+
+Makefile.in,builtins/Makefile.in
+       - make sure declare.o and setattr.o depend on flags.h
+
+execute_cmd.c
+       - decpoint: new function, returns locale's decimal point or `.' default
+       - mkfmt: use decpoint() to get decimal point instead of unconditionally
+         using `.'.  Fixes bug reported by Andrey Tataranovich
+         <tataranovich@gmail.com> in debian bug 741669
+
+                                  4/10
+                                  ----
+lib/readline/rltypedefs.h
+       - add back old Function/VFunction/etc typedefs, since other packages
+         (python, samba) use them. Mark as deprecated using gcc and clang
+         attributes.  Report and fix from Max Horn <max@quendi.de>
+
+                                  4/14
+                                  ----
+jobs.c
+       - run_sigchld_trap: unwind-protect value of this_shell_builtin, since
+         it matters in some cases whether or not we are running `wait' or
+         `eval'.  Fixes bug reported by Eduardo A. Bustamante López
+         <dualbus@gmail.com>
+
+                                  4/18
+                                  ----
+shell.h
+       - sh_parser_state_t: add `need_here_doc' flags member, since
+         xparse_dolparen (via parse_command) sets it to 0
+
+parse.y
+       - gather_here_documents: make sure need_here_doc is > 0, since we
+         don't want to just decrement it forever if it ends up < 0. Partial
+         fix for bug reported by Jared Yanovich <slovichon@gmail.com>
+       - {save,restore}_parser_state: save and restore need_here_doc flag.
+         Rest of fix for bug reported by Jared Yanovich <slovichon@gmail.com>
+
+                                  4/19
+                                  ----
+subst.c
+       - cond_expand_word: since we are not supposed to be performing word
+         splitting here, set expand_no_split_dollar_star to 1 in addition to
+         setting W_NOSPLIT2
+       - expand_word_internal: if we have a case where we have an unquoted
+         $@ but we are in a case where we don't want to split (W_NOSPLIT2),
+         make sure we return a list consisting of a single word with the
+         arguments separated by spaces and don't do word splitting.  Fixes
+         bug reported by Greg Wooledge <wooledg@eeg.ccf.org> from an IRC
+         discussion
+
+builtins/hash.def
+       - print_portable_hash_info: single-quote pathnames and hashed filenames
+         that contain shell metacharacters.  Fixes bug reported by
+         <g1pi@libero.it> in debian bash bug #739853
+
+                                  4/20
+                                  ----
+lib/readline/display.c
+       - When using horizontal scrolling, the redisplay code erases too much
+         of the line containing successful results, so make sure we only
+         erase to the end of the line after making sure we move the cursor
+         to the end.  Fixes bug reported by <Trond.Endrestol@ximalas.info>
+
+                                  4/23
+                                  ----
+{bashhist,bashline}.c
+builtins{bind,help,type}.def
+lib/glob/glob.c, lib/intl/{loadmsgcat,localealias}.c,lib/sh/mktime.c
+       - fixes to memory leaks uncovered by coverity scan
+
+                                  4/24
+                                  ----
+{bashhist,subst,redir,assoc,jobs,array,trap}.c
+lib/intl/l10flist.c
+builtins/complete.def
+       - fixes to memory leaks and other resource usage problems uncovered by
+         coverity scan
+
+redir.c
+       - do_redirection_internal: if dup2 fails (presumably because of a
+         resource limit), close the file descriptor we opened before returning
+         error
+
+                                  4/25
+                                  ----
+config-top.h
+       - DEFAULT_BASHRC: new define with the name of the default shell
+         startup file
+
+bashline.c
+       - bash_directory_completion_matches: don't dequote the directory name.
+         If rl_completion_found_quote is non-zero, readline will dequote the
+         filename itself.  Fixes bug reported by Clark Wang
+         <dearvoid@gmail.com>
+
+                                  4/27
+                                  ----
+subst.c
+       - parameter_brace_expand_rhs: if parameter_brace_find_indir returns
+         NULL or "", or if it returns something that is not a valid identifier,
+         report an error and return &expand_wdesc_error so the error can
+         propagate up.  Fixes bug reported by Andre Holzhey
+         <andre.holzhey@gmx.de>
+
+                                  4/29
+                                  ----
+subst.c
+       - parameter_brace_substring: don't short-circuit right away if the
+         value is NULL but we are looking at the positional parameters.  Part
+         of fix for bug reported by Pierre Gaston <pierre.gaston@gmail.com>
+       - pos_params: if there are no positional parameters, only short-circuit
+         if we are looking for $1 and above.  Rest of fix for bug reported
+         by Pierre Gaston <pierre.gaston@gmail.com>
+
+subst.h
+       - SD_NOPROCSUB: new flag for skip_to_delim, means to not allow any
+         process subsitutions (should not have overloaded SD_NOSKIPCMD)
+
+subst.c
+       - skip_to_delim: honor SD_NOPROCSUB flag
+
+make_cmd.c
+       - make_arith_for_expr: set W_NOPROCSUB flag in the created word
+       - make_arith_for_command: set SD_NOPROCSUB in the flags argument to
+         skip_to_delim so we don't treat <( or >( as a process substitution
+         (we won't evaluate them in eval_arith_for_expr anyway).  Fixes
+         bug reported by Pierre Gaston <pierre.gaston@gmail.com>
+
+                                   5/1
+                                   ---
+lib/glob/gmisc.c
+       - glob_dirscan: new function, takes a pattern and a directory separator
+         argument and advances the pattern to the last occurrence of the
+         separator. Like strrchr, but understands extended glob patterns and
+         uses glob_patscan to skip over them
+
+lib/glob/glob.c
+       - extglob_skipname: if the extended globbing pattern is invalid, don't
+         skip the name
+       - glob_filename: if there is a slash in the pattern to be matched, and
+         extglob is enabled, use glob_dirscan to find the real last occurrence
+         of `/' to avoid being confused by slashes in extglob patterns.  Fix
+         for bug reported by Pierre Gaston <pierre.gaston@gmail.com>
+
+                                   5/6
+                                   ---
+variables.c
+       - make_local_variable: only set the att_invisible attribute if
+         no_invisible_vars isn't set
+       - find_variable_for_assignment: new function, intended to be called by
+         code that eventually wants to assign a value to the variable; will not
+         skip invisible variables; currently identical to find_variable
+       - find_variable_no_invisible: new function, finds the first visible
+         instance of variable with a given name in the variable context chain;
+         eventually will be used to replace find_variable; separate right now
+         for testing
+
+variables.h
+       - find_variable_for_assignment: extern declaration
+       - find_variable_no_invisible: extern declaration
+
+                                   5/7
+                                   ---
+variables.c
+       - make_local_variable: don't clear `invisible' attribute if we are
+         returning an existing local variable at the right context.  Let the
+         upper layers do that. Fixes bug reported by Dan Douglas
+         <ormaaj@gmail.com>
+
+                                   5/8
+                                   ---
+lib/readline/input.c
+       - rl_getc: call RL_CHECK_SIGNALS if a read(2) is interrupted (-1/EINTR)
+         by SIGALRM or SIGVTALRM (placeholder for non-keyboard-generated
+         signals of interest)
+
+builtins/read.def
+       - edit_line: call bashline_set_event_hook and
+         bashline_reset_event_hook around call to readline(), so the right
+         signal handling happens
+       - read_builtin: make sure we add an unwind_protect call to
+         bashline_reset_event_hook.  These changes fix bug reported in
+         https://bugs.launchpad.net/ubuntu/+source/bash/+bug/1317476
+
+bashline.c
+       - bash_event_hook: make sure we clean up the readline state by calling
+         rl_cleanup_after_signal if sigalrm_seen is non-zero.  The read builtin
+         sets this when it times out
+
+                                  5/12
+                                  ----
+doc/{bash.1,bashref.texi}
+       - clarify language to make it clear that changing attributes of a
+         nameref variable (e.g., export), actually changes the attributes of
+         the referenced variable.  Fixes omission noted by Jeff Haemer
+         <jeffrey.haemer@gmail.com>
+
+arrayfunc.c
+       - bind_array_var_internal: make sure ENTRY no longer has invisible
+         attribute before returning.  Fixes bug reported by Geir Hauge
+         <geir.hauge@gmail.com>
+
+                                  5/22
+                                  ----
+execute_cmd.c
+       - shell_execve: if execve fails and we return 127 or 126, make sure to
+         set last_command_exit_value if a call to file_error or report_error
+         causes the shell to exit.  This ensures that the shell exits with
+         the right value.
+
+                                   6/6
+                                   ---
+shell.c
+       - drop_priv_mode: print an error message on setuid() failure, optionally
+         exit if errno == EAGAIN, as it can be on Linux when RLIMIT_NPROC for
+         the target user is exceeded.
+
+config-top.h
+       - EXIT_ON_SETUID_FAILURE: new settable define, will cause the shell to
+         exit if setuid fails with errno == EAGAIN
+
+                                  6/10
+                                  ----
+parse.y
+       - time_command_acceptable: fix so time is accepted everywhere the
+         grammar is looking for a `compound_list'.  Fixes bug reported by
+         Dale Worley <worley@alum.mit.edu>
+
+                                  6/12
+                                  ----
+subst.c
+       - clear_fifo_list: new function, clears FDs associated with open pipes
+         in current FIFO list without closing the file descriptors.  Can
+         possibly be used when shell_execve fails and the shell jumps back
+         to top_level and we don't want the shell to close the open FIFOs
+         each time through the read-execute loop.  Bug reported by Harald
+         Koenig <koenig@tat.physik.uni-tuebingen.de>
+
+
+                                  6/16
+                                  ----
+builtins/shopt.def
+       - compat42: make sure the `compat42' option sets the correct variable
+         for compatibility level.  Fixes bug reported by Ondrej Oprala
+         <ooprala@redhat.com>
+
+support/bashbug.sh
+       - fix typo when echoing $USAGE.  Report from Shantanu Kulkarni
+         <djbware@shantanukulkarni.org>
+
+execute_cmd.c
+       - shell_execve: before longjmp back to subshell_top_level, clear out the
+         FIFO fd list by calling clear_fifo_list so the FDs (which we inherited
+         from our parent) aren't closed every time through the read-eval loop.
+         Fix for bug reported by Harald Koenig <koenig@tat.physik.uni-tuebingen.de>
+
+                                  6/18
+                                  ----
+subst.c
+       - extract_process_subst: add additional argument: xflags, allow callers to
+         pass flags like extract_command_subst
+       - extract_process_subst: call xparse_dolparen like command substitution
+         to avoid problems when parsing commands constructs with embedded open
+         parens.  Fixes bug reported by Tim Friske <me@timfriske.com>
+
+subst.h
+       - extract_process_subst: modified prototype for extern declaration
+
+                                  6/19
+                                  ----
+execute_cmd.c
+       - execute_pipeline: if running with lastpipe enabled, make sure that we
+         check whether or not the job id is valid using INVALID_JOB before
+         calling job_exit_status. the jobs list can get frozen and unfrozen in
+         the presence of nested pipelines and loops and wait_for can clear a
+         job table entry.  Fixes bug reported by <scorp.dev.null@gmail.com>
+
+jobs.c
+       - freeze_jobs_list: now returns old value of jobs_list_frozen; unused at
+         current time
+
+jobs.h
+       - freeze_jobs_list: change return value
+
+                                  6/20
+                                  ----
+lib/glob/smatch.c
+       - MEMCHR: single-byte and wide character defines (memchr/wmemchr)
+
+lib/glob/sm_loop.c
+       - GMATCH: when the wildcards are the last element of the pattern, make
+         sure they do not match a string containing a `/' if FNM_PATHNAME is
+         set in FLAGS
+       - GMATCH: when recursively calling GMATCH after we see a `*', don't
+         try to consume the rest of the pattern with `*' if FNM_PATHNAME is
+         set in FLAGS, just consume up to the next slash and then see whether
+         or not the rest of the pattern matches.  Fixes bug reported by Ian
+         Kelling <ian@iankelling.org>
+       - GMATCH: when processing `*' in the pattern, after skipping consecutive
+         wildcards, if we hit a literal `/' in the pattern and we're looking
+         for a pathname, skip characters in the string until we find a `/'
+         (no slash means the match fails), and try to match the rest of the
+         pattern against the portion of the string after the next `/'.  Picked
+         up from gnulib/glibc
+
+pathexp.c
+       - split_ignorespec: since split_ignorespec gets globbing patterns,
+         make sure we call skip_to_delim with the SD_GLOB flag so delimiters
+         that occur within bracket expressions don't delimit the pattern.
+         Fixes problem with [[:digit:]] in GLOBIGNORE reported by Ian Kelling
+         <ian@iankelling.org>
+
+unwind_prot.c
+       - unwind_protect_tag_on_stack: new function, returns 1 if unwind-protect
+         frame corresponding to `tag' argument is on unwind-protect stack
+
+unwind_prot.h
+       - unwind_protect_tag_on_stack: extern declaration
+
+                                  6/30
+                                  ----
+lib/readline/misc.c
+       - _rl_revert_all_lines: set entry->data to 0 after assigning it to
+         rl_undo_list to avoid pointer aliasing problems that would result
+         in entry->line being freed by an undo.  The subsequent free would
+         be a double free.  Report and fix from Jared Yanovich
+         <slovichon@gmail.com>
+
+subst.c
+       - command_substitute: other shells do not appear to inherit the -v
+         option when reading and executing command substitutions.  Reported
+         by Ondrej Oprala <ooprala@redhat.com>
+
+                                   7/1
+                                   ---
+config-top.h
+       - CHECKHASH_DEFAULT: new define that supplies the default value for
+         check_hashed_filenames (`checkhash' shopt option); still 0 by default
+
+findcmd.c
+       - check_hashed_filenames: initialize using CHECKHASH_DEFAULT
+
+lib/readline/histexpand.c
+       - history_expand: double quotes can inhibit recognition of the history
+         comment character if history_quotes_inhibit_expansion is non-zero
+
+lib/readline/doc/{history.3,hstech.texi}
+       - history_quotes_inhibit_expansion: expand definition to note that it
+         inhibits scanning for the history comment character as well; correct
+         typo to make it clear that it only works on double-quoted strings
+
+lib/sh/zgetline.c
+       - add new fourth argument: DELIM, allows delimiter to be something
+         other than newline (if DELIM != '\n', UNBUFFERED_READ should be
+         non-zero)
+       - UNBUFFERED_READ is now fifth argument
+       - check character against DELIM rather than strictly newline
+
+externs.h
+       - zgetline: change function prototype for extern declaration
+
+builtins/mapfile.def
+       - mapfile: change calling sequence for zgetline calls
+       - mapfile_builtin: new -d option: DELIM, like in read builtin
+       - mapfile_builtin: pass `delim' to mapfile() as new argument; default
+         to '\n' unless -d option supplied
+       - mapfile: take new DELIM argument, pass to zgetline
+       - mapfile: if DELIM != '\n', set unbuffered_read to 1
+
+doc/{bash.1,bashref.texi}
+       - mapfile: document new `-d DELIM' option
+
+                                   7/5
+                                   ---
+lib/readline/histfile.c
+       - history_truncate_file: if there is an error writing the truncated
+         history list back to the history file, use the same strategy as
+         history_do_write: create a backup file, rename the history file to
+         the backup file, and restore the original history file from the
+         backup file name if the write or the close fails.  Suggestion from
+         Chen Gang <gang.chen.5i5j@gmail.com> to bug-readline
+
+execute_cmd.c
+       - evalnest, evalnest_max: new variables establishing maximum number of
+         recursive `eval' calls; current max is 4096
+       - execute_builtin: unwind-protect value of evalnest around calls to
+         eval builtin. Suggested by Oliver Morais <oliver.morais@gmail.com>
+       - {initialize_subshell,execute_subshell_builtin_or_function}: reset
+         evalnest to 0 in a subshell
+
+builtins/setattr.def
+       - show_name_attributes: show a variable's attributes even if it's
+         invisible (don't show any value since it has none). This means that
+         declare -p var will display VAR's attributes even when var marked
+         as invisible.  Feature request from Peggy Russell
+         <prusselltechgroup@gmail.com>
+       - show_var_attributes: don't print assignment if array or assoc
+         attribute is set but variable marked as invisible
+
+tests/array.right
+       - special note: changed all declare -a output tests because the shell
+         will no longer print out values for invisible array variables. This
+         is a change, but one for correctness:
+
+               declare -a foo='()'
+         and
+               declare -a foo
+         are not equivalent
+
+                                  7/22
+                                  ----
+subst.c
+       - parameter_brace_expand: after calling parameter_brace_expand_indir,
+         turn off the W_ARRAYIND flag in the word it returns, because there
+         is no way for it to return the index that should be used, and the
+         rest of the function assumes that IND is valid if W_ARRAYIND is set.
+         Fixes bug reported by Corentin Peuvrel <cpeuvrel@pom-monitoring.com>
+
+                                   8/2
+                                   ---
+parse.y
+       - read_token_word: if we read a character that will end a command
+         substitution, don't skip over quoted newlines when we read an
+         additional character to figure out whether it's a two-character
+         token. This lets the higher layers deal with quoted newlines after
+         the command substitution. Fixes bug reported by EmanueL Czirai
+         <amanual@riseup.net>
+
+                                  8/11
+                                  ----
+execute_cmd.c
+       - execute_pipeline: check whether lastpipe_jid corresponds to a valid
+         job before calling append_process, for the same reason as fix from
+         6/19.  Fixes bug reported by <lolilolicon@gmail.com>
+
+                                  8/12
+                                  ----
+lib/sh/unicode.c
+       - stub_charset: use strncpy instead of strcpy because we are copying
+         into a local fixed-length buffer.  Fixes vulnerability reported by
+         <romerox.adrian@gmail.com>
+
+execute_cmd.c
+       - execute_pipeline: if we don't call append_process, call
+         wait_for_single_pid to get the status of `lastpid', since that will
+         check the status of already-reaped processes.  Fixes spurious error
+         message about non-existent process from fix of 8/11
+
+                                  8/15
+                                  ----
+jobs.c
+       - running_in_background: new variable, keeps track of whether or not we
+         are running in the background (not perfect yet)
+       - initialize_job_control: even if we are not turning on job control,
+         get the terminal pgrp so we can use it later
+       - {set_job_control,initialize_job_control}: set running_in_background
+         to 1 if terminal pgrp != shell pgrp
+       - {stop_pipeline,make_child,wait_for}: if we are running in the
+         background, don't mess with the terminal's process group; assume that
+         the parent shell will do that.  Fixes bug reprted by Greg Wooledge
+         <wooledg@eeg.ccf.org>
+
+shell.c
+       - shell_reinitialize: reset running_in_background back to 0
+
+                                  8/24
+                                  ----
+execute_cmd.c
+       - {execute_connection,execute_command_internal}: make sure that
+         asynchronous commands always set $? to 0 and are not affected by the
+         command's exit status being inverted using `!'.  Fixes bug reported
+         by Vincent Lefevre <vincent@vinc17.net>
+
+lib/readline/display.c
+       - rl_message: call vsnprintf with full msg_bufsiz, since it counts 
+         one fewer than the buffer length passed as an argument.  Bug report
+         and fix from Dylan Cali <calid1984@gmail.com>
+
+                                  8/26
+                                  ----
+builtins/evalstring.c
+       - evalstring: if CURRENT_TOKEN == yacc_EOF, reset it to newline.  This
+         is instead of calling reset_parser(); that might still be needed.
+         Fixes bug with eval and a subsequent statement ending with EOF
+         reported by <jim.avera@gmail.org>
+
+pcomplete.c
+       - filter_stringlist: when extglob is on, a leading ! in the filter
+         pattern should be left alone when it introduces a !(pat) pattern;
+         otherwise it messes up the pattern.  Fixes bug reported by David
+         Korn <dgkorn@gmail.com>
+
+                                  8/27
+                                  ----
+doc/{bash.1,bashref.texi}
+       - clarify the behavior of bash when given the -c option, since $0 is
+         technically not a positional parameter.  Bug reported by Stephane
+         Chazelas <stephane.chazelas@gmail.com>
+
+                                  8/28
+                                  ----
+lib/readline/history.c
+       - add_history: use history_max_entries (if history is stifled) or
+         DEFAULT_HISTORY_INITIAL_SIZE if not (new define, defaults to 502)
+         to size the initial allocation of the history array.  Assumption
+         is that this will reduce the number of allocations
+
+                                  8/29
+                                  ----
+execute_command.c:
+       - sourcenest, sourcenest_max: new variables used to track level of
+         sourced files and (maybe) one day catch infinite source recursion
+       - execute_builtin: if current source level exceeds sourcenest_max,
+         trigger an error and jump back to the top level
+       - {initialize_subshell,execute_subshell_builtin_or_function}: reset
+         sourcenest to 0 in a subshell
+
+                                   9/2
+                                   ---
+variables.c
+       - bind_variable: if a nameref expands to an array reference, make
+         sure that assign_array_element gets called (maybe even
+         recursively) instead of bind_variable_internal, so invalid variable
+         names (like arr[0]) don't get created.  Fixes bug reported by
+         <lolilolicon@gmail.com>
+
+                                   9/3
+                                   ---
+execute_cmd.c
+       - evalnest_max,sourcenest_max: initialize from EVALNEST_MAX and
+         SOURCENEST_MAX, respectively.  Feature suggested by
+         <bogun.dmitriy@gmail.com>
+
+config-top.h
+       - define EVALNEST_MAX and SOURCENEST_MAX to 0
+
+                                   9/6
+                                   ---
+bashline.c
+       - find_cmd_start: fix to (crudely) deal with >| token; even though
+         skip_to_delim finds `|' as a delimiter, we call it again and use
+         what the second call finds.  Fixes bug reported by Dan Jacobson
+         <jidanni@jidanni.org>
+
+findcmd.c
+       - find_in_path_element: if in posix mode, do not expand a literal
+         tilde in a $PATH element
+
+doc/bashref.texi
+       - add change to tilde expansion in $PATH elements to posix mode
+         description
+
+builtins/common.h
+       - ISHELP: new define for builtins that do their own option parsing
+         and don't use internal_getopt(); checks whether argument is --help
+       - CHECK_HELPOPT: convenience define to help builtins that do their
+         own option parsing to check for --help with one line of code
+       - CASE_HELPOPT: convenience define to help builtins that use
+         internal_getopt() check for --help with one line of code
+
+builtins/help.def
+       - builtin_help: new function, prints out --help output for current
+         builtin
+
+builtins/{kill,let,pushd}.def
+       - add CHECK_HELPOPT to builtins that use ISOPTION; call builtin_help
+         and return EX_USAGE (kill/let/pushd/popd/dirs)
+
+builtins/{caller,fg_bg}.def
+       - use CHECK_HELPOPT to recognize --help, since these builtins perform
+         checks that can cause them to return before calling no_options
+         (caller/fg/bg)
+
+builtins/{exit,return}.def
+       - use CHECK_HELPOPT to recognize --help before calling get_exitstat()
+         (return/exit/logout)
+
+builtins/{break,shift}.def
+       - use CHECK_HELPOPT to recognize --help before any other checks
+         (break/continue/shift)
+
+builtins/bashgetopt.h
+       - GETOPT_EOF: convenience define
+       - GETOPT_HELP: new define, to indicate internal_getopt saw --help
+
+builtins/bashgetopt.c
+       - internal_getopt: return GETOPT_HELP for --help
+
+builtins/common.c
+       - no_options: recognize --help, call builtin_help and return 2
+         (builtin/eval/source/./times)
+
+builtins/command.def
+       - use CASE_HELPOPT() to handle --help after calling internal_getopt()
+         (command)
+
+builtins/{colon,echo,test}.def
+       - do not recognize --help (:/true/false/echo/test)
+
+                                   9/8
+                                   ---
+sig.c
+       - termsig_sighandler: if readline is active now, set the bashline event
+         hook. Old code just set it for interactive shells.  Part of fix for
+         bug reported by <mickael9@gmail.com>
+
+bashline.c
+       - bash_event_hook: call rl_cleanup_after_signal if terminating_signal
+         is non-zero, since check_signals_and_traps() will cause the shell to
+         exit if it is and we want to clean up the readline state first.  Rest
+         of fix for bug reported by <mickael9@gmail.com>
+
+                                   9/9
+                                   ---
+jobs.c
+       - waitchld: when running the wait builtin in posix mode, with a trap set
+         on SIGCHLD, use queue_sigchld_trap instead of trap_handler (SIGCHLD),
+         otherwise you will lose SIGCHLDs when children_exited > 1.  Fixes bug
+         reported by <crispusfairbairn@gmail.com>
+
+builtins/read.def
+       - read_builtin: if we are changing the tty settings, call
+         initialize_terminating_signals so we have a chance to catch all
+         terminating signals and potentially clean up the terminal before
+         exiting
+       - read_builtin: tty_modified: new variable, set to 1 if we change the
+         terminal attributes and have to call ttyrestore() to restore them
+       - if one of the `reads' returns -1/EINTR due to a terminating signal,
+         and we have modified the terminal, call ttyrestore before calling
+         CHECK_TERMSIG
+       - ttyrestore: set tty_modified to 0 when called
+
+                                  9/10
+                                  ----
+builtins/read.def
+       - termsave: now global to file so other functions can use it
+       - read_tty_cleanup: if tty_modified is non-zero, call ttycleanup to restore
+         old terminal settings and turn off tty_modified
+
+sig.c
+       - termsig_handler: call read_tty_cleanup if currently executing read
+         builtin; it does the right thing.  Final piece of fix for bug reported
+         by Jan Rome <jan.rome@gmail.com>
+
+                                  9/11
+                                  ----
+general.c
+       - printable_filename: general function to return a printable representation
+         of a string (presumed to be a filename)
+
+general.h
+       - extern declaration for printable_filename
+
+execute_cmd.c
+       - execute_disk_command: use printable_filename
+
+builtins/{bind,cd,enable,hash,source}.def
+       - use printable_filename as appropriate when printing error messages.
+         From a suggestion by Vincent Lefevre <vincent@vinc17.net>
+
+builtins/bind.def
+       - use CASE_HELPOPT() to handle --help after calling internal_getopt()
+         (bind)
+
+                                  9/12
+                                  ----
+builtins/common.h
+       - SEVAL_FUNCDEF: new flag for parse_and_execute; it means that we only
+         accept a single function definition command, as when we are importing
+         functions from the environment
+       - SEVAL_ONECMD: new flag for parse_and_execute; for future use
+
+builtins/evalstring.c
+       - parse_and_execute: if the SEVAL_FUNCDEF flag is set, disallow anything
+         but a function definition command
+
+variables.c
+       - initialize_shell_variables: don't allow functions with invalid names
+         to be imported from the environment, even though we still allow them
+         to be defined
+       - initialize_shell_variables: when importing function definitions from
+         the environment, call parse_and_execute with the SEVAL_FUNCDEF flag
+         to force the command to be just a function definition
+
+subst.c
+       - param_expand: when expanding a $name variable expansion, make sure that
+         the variable is visible and set before following the nameref chain
+       - param_expand: when expanding a $name variable expansion and following the
+         nameref chain, make sure the resulting variable is visible and set
+         before using it
+
+                                  9/13
+                                  ----
+variables.c
+       - initialize_shell_variables: when importing function definitions from
+         environment, use SEVAL_ONECMD flag for parse_and_execute.  Part of
+         CVE-2014-6271
+
+builtins/evalstring.c
+       - parse_and_execute: if SEVAL_ONECMD flag set, return immediately after
+         calling execute_command_internal.  Final piece for fix for bug
+         reported by Stephane Chazelas <stephane.chazelas@gmail.com>.  Part of
+         CVE-2014-6271
+
+                                  9/24
+                                  ----
+parse.y
+       - reset_parser: reset eol_ungetc_lookahead to 0 here, since we don't want
+         shell_getc returning it on the next call.  Fixes problem reported by
+         Tavis Ormandy <taviso@cmpxchg8b.com> and Michal Zalewski
+         <lcamtuf@coredump.cx>.  Potentially part of CVE-2014-6271; fix for
+         CVE-2014-7169
+
+                                  9/25
+                                  ----
+parse.y
+       - push_heredoc: new function, pushes a here-doc redirection onto
+         redir_stack handling overflow of redir_stack. Exits on overflow.
+         Original fix from Florian Weimer <fweimer@redhat.com>.  Fix for
+         CVE-2014-7186
+       - change straight assignments to redir_stack to call push_redir
+       - add one to size of word_lineno stack to avoid off-by-one error
+         below in read_token_word. Overflow just results in line numbers
+         being wrong.  Fix for CVE-2014-7187
+
+                                  9/27
+                                  ----
+{execute_cmd,trap}.c
+       - changes to make minimal-config builds work again, mostly missing
+         #ifdefs for optional features
+
+builtins/common.c
+       - builtin_help: dummy version to be included if HELP_BUILTIN not
+         defined, for minimal-config builds
+
+variables.c
+       - initialize_shell_variables: incorporated patches from Florian
+         Weimer <fweimer@redhat.com> to change the strings bash looks
+         for when importing shell functions from the environment.  It
+         adds a prefix (BASH_FUNC_) and a suffix (%%) to the name to
+         mark it as having been created by bash as an exported function.
+         Fix for remote attacks part of CVE-2014-6271 and CVE-2014-7169
+       - mk_env_string: takes new argument, indicating whether we are
+         constructing a function
+       - mk_env_string: encodes function names as described above, so
+         initialize_shell_variables can find them
+
+                                  9/28
+                                  ----
+copy_cmd.c
+       - copy_redirects: before calling savestring on here_doc_eof, make
+         sure it's not NULL (it could have been the result of a here
+         document delimited by EOF or EOS).  Fixes bug reported by
+         Michal Zalewski <lcamtuf@coredump.cx>.  Fix for CVE-2014-6277
+
+make_cmd.c
+       - make_redirection: initialize here_doc_eof member to NULL.  Rest of
+         fix for CVE-2014-6277
+
+                                  9/29
+                                  ----
+parse.y
+       - current_input_line_state: return a sh_input_line_state_t containing
+         the current shell_input_line and its index and size variables
+
+shell.h
+       - current_input_line_state: extern declaration
+
+builtins/evalstring.c
+       - parse_and_execute: call reset_parser() before returning if
+         SEVAL_ONECMD set.  Fixes bug reported by Michal Zalewski
+         <lcamtuf@coredump.cx> and designated CVE-2014-6278
+       - parse_and_execute: if we parse a function definition when
+         SEVAL_FUNCDEF is set, but don't consume the entire passed string,
+         throw an error, reset the parser, and return.  Part of fix for
+         CVE-2014-6278
+       - parse_and_execute: if parsing the shell function definition when
+         SEVAL_FUNCDEF is set transforms the function name (e.g., if it
+         begins with a newline or begins or ends with whitespace), throw
+         an error, reset the parser, and return.  Fixes bug reported by
+         Eric Kobrin <ekobrin@akamai.com>
+
+                                  10/2
+                                  ----
+jobs.c
+       - bgp_prune: don't do anything if bgpids.npid == 0 or bgpids.list == NULL.
+         This can happen if something gets run before the job control framework
+         is initialized.  Bug report from <mancha1@zoho.com>
+
+                                  10/3
+                                  ----
+parse.y
+       - xparse_dolparen: don't set token_to_read to newline after calling
+         parse_string() and cleaning up when the shell is not interactive.  This
+         makes the parser thing it's ok to read new commands even if it's not in
+         a state where that should be possible.  Underlying fix for bug reported
+         by Michal Zalewski <lcamtuf@coredump.cx> and designated CVE-6278
+       - parser_remaining_input: new function, returns the portion of
+         shell_input_line that hasn't yet been read
+       - current_input_line_state: removed
+
+shell.h
+       - parser_remaining_input: extern declaration
+       - current_input_line_state: removed
+
+builtins/evalstring.c
+       - parse_and_execute: change code that checks whether parse_command has
+         consumed the entire passed string when SEVAL_FUNCDEF is used to use
+         parser_remaining_input instead of messing around with (new)
+         current_input_line_state.  Part of fix for CVE-2014-6278
+
+variables.c
+       - initialize_shell_variables: if we don't call parse_and_execute, free the
+         temporary string, since parse_and_execute won't.  Report and fix from
+         Eric Kobrin <ekobrin@akamai.com>
+
+                                  10/4
+                                  ----
+print_cmd.c
+       - print_function_def: when in posix mode, print shell function
+         definitions as posix specifies them, without the leading
+         `function' keyword
+
+general.c
+       - exportable_function_name: return 1 if the passed string can be
+         added to the environment as an exported function name.  Currently
+         prohibits function names containing  `/' and `=' from being
+         exported
+
+general.h
+       - exportable_function_name: extern declaration
+
+builtins/setattr.def
+       - set_or_show_attributes: if exporting a function with export -f,
+         call exportable_function_name to determine whether the function
+         should be exported; don't export function if it returns 0
+
+                                  10/7
+                                  ----
+builtins/setattr.def
+       - set_or_show_attributes: don't show identifiers that are invisible
+         and imported from the environment, since that combination of
+         attributes means that the imported variable is not a valid shell
+         identifier.  Report from Stephane Chazelas <stephane.chazelas@gmail.com>
+
+                                  10/8
+                                  ----
+shell.c
+       - shell_initialize: set new variable should_be_restricted, which
+         says whether or not the shell will be a restricted one based on the
+         shell name; use in calls to initialize_shell_variables (to inhibit
+         importing shell functions) and initialize_shell_options (to inhibit
+         parsing $SHELLOPTS) and initialize_bashopts (to inhibit parsing
+         $BASHOPTS).  Report from <paulfm@umn.edu>
+
+                                  10/12
+                                  -----
+execute_cmd.c
+       - execute_function: unwind-protect loop_level, set loop_level to 0
+         when entering a function so break and continue in functions don't
+         break loops running outside of the function. Fix picked up from
+         dash via Herbert Xu <herbert@gnodor.apana.org.au>
+
+                                  10/13
+                                  -----
+doc/Makefile.in
+       - bashref.pdf: create using texi2dvi --pdf rather than postprocessing the
+         dvi file, so we have PDF bookmarks and links.  Fix from
+         Siep Kroonenberg <siepo@cybercomm.nl>
+
+                                  10/14
+                                  -----
+subst.h
+       - Q_ARITH: new quoting flag. Semantics are per Posix's spec for arithmetic
+         expansion: act as if string is quoted, but don't treat double quotes
+         specially (in this case, they will be removed by quote removal)
+       - Q_ARRAYSUB: new quoting flag, indicates we are expanding an indexed array
+         subscript
+
+subst.c
+       - expand_arith_string: if we are not expanding the string, but we saw a quote
+         with Q_ARITH specified as one of quoting flags, perform quote removal even
+         if Q_DOUBLE_QUOTES is specified
+       - param_expand: change calls to expand_arith_string for $[ and $(( cases to
+         specify Q_ARITH.  Now $(( "$x" )) and $(( "x" )) work if x has a value that
+         evaluates to a valid number, as Posix specifies
+       - expand_word_internal: add test for quoted&Q_ARITH to the tilde case, so we
+         continue to perform tilde expansion in arithmetic contexts
+       - expand_word_internal: if quoted&Q_ARITH, continue processing when we see a
+         `"', acting as if the double quote isn't present (already Q_DOUBLE_QUOTED)
+
+arrayfunc.c
+       - array_expand_index: pass Q_DOUBLE_QUOTED|Q_ARITH|Q_ARRAYSUB as quoted argument
+         in call to expand_arith_string.  This inhibits word splitting
+         (Q_DOUBLE_QUOTED) while discarding double quotes (Q_ARITH), identical to the
+         quote flags passed while expanding $(( )) and $[ ].  Q_ARRAYSUB reserved for
+         future use.  Fixes problem reported by Stephane Chazelas
+         <stephane.chazelas@gmail.com>
+
+                                  10/16
+                                  -----
+subst.c
+       - parameter_brace_expand_word: if the PF_ASSIGNRHS flag is set and we
+         are expanding what looks like an array subscripted with @ or *,
+         make sure the variable we're expanding is actually an array before
+         we add Q_DOUBLE_QUOTES to the flags.  If we don't, things like
+         scalar[@] will remain quoted.  Fixes ubuntu bug 1381567
+         https://bugs.launchpad.net/ubuntu/+source/bash/+bug/1381567
+
+                                  10/17
+                                  -----
+{jobs,nojobs}.c
+       - get_original_tty_job_signals: get original signal dispostions for
+         SIGTSTP, SIGTTIN, SIGTTOU before we start manipulating them in
+         make_child
+       - default_tty_job_signals: make sure we set SIGTSTP, SIGTTIN, or
+         SIGTTOU to SIG_IGN if they were ignored at shell startup instead of
+         unconditionally setting them to SIG_DFL.  Fixes bug reported by
+         idallen@idallen.ca
+
+jobs.h
+       - get_original_tty_job_signals: extern declaration
+
+trap.c
+       - initialize_traps: add call to get_original_tty_job_signals
+
+                                  10/22
+                                  -----
+subst.c
+       - expand_string_for_rhs: when expanding in this context (rhs of a word
+         expansion or pattern removal), we don't perform word splitting, so
+         we don't want to split $* if IFS is empty.  Fixes bug reported by
+         Stephane Chazelas <stephane.chazelas@gmail.com>
+
+                                  10/23
+                                  -----
+subst.c
+       - param_expand: when expanding $* in a pattern context where the
+         expansion is quoted (Q_PATQUOTE), don't quote the expansion --
+         the outer quotes don't make the characters in the expansion of
+         $* special.  Posix interp 221.  Reported by Stephane Chazelas
+         <stephane.chazelas@gmail.com>
+
+                                  10/28
+                                  -----
+lib/readline/bind.c
+       - enable-bracketed-paste: new bindable variable, enables support for
+         a terminal's `bracketed paste mode'.  Code contributed by
+         Daniel Colascione <dancol@dancol.org>
+
+doc/bash.1,lib/readline/doc/{readline.3,rluser.texi}
+       - enable-bracketed-paste: add description
+
+lib/readline/{readline.c,rlprivate.h}
+       - _rl_enable_bracketed_paste: declarations
+       - #defines for use by bracketed paste implementation
+
+lib/readline/rltty.c
+       - rl_prep_terminal: send BRACK_PASTE_INIT string to terminal if we
+         are supposed to enable bracketed-paste mode; change terminal_prepped
+         to indicate we sent that string and need to clean up
+       - rl_deprep_terminal: if terminal_prepped indicates we sent the
+         bracketed-paste mode init string to the terminal, send the cleanup
+         string before restoring the terminal modes
+
+lib/readline/kill.c
+       - rl_bracketed_paste_begin: function to read bracketed paste until
+         BRACK_PASTE_SUFF; discard the suffix, and insert the rest of the
+         paste as a single (undoable) object.  Bound to BRACK_PASTE_PREF
+
+lib/readline/funmap.c
+       - bracketed-paste-begin: new bindable command, executes
+         rl_bracketed_paste_begin
+
+lib/readline/readline.c
+       - bind_bracketed_paste_prefix: new function, sets up to recognize
+         the bracketed paste prefix sequence (BRACK_PASTE_PREF) in emacs
+         keymap and vi insertion keymap
+       - readline_initialize_everything: call bind_bracketed_paste_prefix
+
+                                  11/1
+                                  ----
+builtins/ulimit.def
+       - RLIMIT_POSIXLOCKS: now synonym for RLIMIT_LOCKS
+       - -k: new option: RLIMIT_KQUEUES, max kqueues allocated for this
+         process
+       - -P: new option: RLIMIT_NPTS, max number of pseudoterminals available
+         to this process
+
+doc/{bash.1,bashref.texi}
+       - document `ulimit -k' option
+       - document `ulimit -P' option
+
+parse.y
+       - `timespec list_terminator' production: if the list terminator is `;'
+         set last_read_token to `;' to allow things like `time ; command' to
+         time null commands and not throw a syntax error.  Patch from
+         Piotr Grzybowski <narsil.pl@gmail.com>
+       - `BANG list_terminator' production: do the same thing
+
+variables.c
+       - sv_optind: use find_shell_variable and get_variable_value so we can
+         have the variable's context in the case we need to do something
+         when we are restoring a previous variable context's value
+
+builtins/getopt.h
+       - sh_getopt_state_t: struct to save sh_getopt's internal state so we
+         can restore it around function calls in the event that we have a
+         local copy of OPTIND
+
+builtins/getopt.[ch]
+       - sh_getopt_{save,restore}_istate: new functions to save and restore
+         getopt's internal state
+       - sh_getopt_{alloc,dispose}_istate: new functions to allocate and
+         deallocate sh_getopt_istate_t objects
+
+execute_cmd.c
+       - maybe_restore_getopt_state: restore sh_getopt state after executing
+         function body iff the funtion declared a local copy of OPTIND
+       - execute_function: save sh_getopt state before executing function body
+       - execute_function: note in getopt_state->flags whether or not the
+         function declared a local copy of OPTIND; used by maybe_restore_getopt_state
+       - execute_function: maybe restore sh_getopt state before returning via
+         call to maybe_restore_getopt_state.  Fixes bugs with getopts and
+         state between calls reported in 2011 by Bernd Eggink <monoped@sudrala.de>
+         and in 2014 by Oyvind Hvidsten <oyvind.hvidsten@dampir.no>
+
+configure.ac
+       - enable-function-import: new option, controls whether function imports
+         are included.  Enabled by default.  Patch from David Galos
+         <davegalos@google.com>
+
+config.h.in
+       - FUNCTION_IMPORT: define controlled by enable-function-import above
+
+variables.c
+       - initialize_shell_variables: include code to import function definitions
+         from the environment if FUNCTION_IMPORT is defined
+
+doc/bashref.texi
+       - --enable_function-import: document new configuration option
+
+                                  11/5
+                                  ----
+lib/readline/history.c
+       - history_lines_read_from_file: new variable, set by read_history and
+         read_history_range to the actual number of lines read from the
+         history file.  The value is valid immediately after a call to one
+         of those functions
+       - history_lines_written_to_file: new variable, set by write_history,
+         history_do_write, and history_truncate_file to the actual number of
+         lines written to the history file.  The value is valid immediately
+         after a call to one of those functions
+
+variables.c
+       - sv_histsize: set history_lines_in_file after history_truncate_file()
+         only if hmax < history_lines_in_file (lines we've already read); a
+         cosmetic change only
+
+bashhist.c
+       - load_history: set history_lines_in_file after read_history() from
+         history_lines_read_from_file, since read_history reads all of the
+         lines from the history file even if it's more than $HISTSIZE
+       - maybe_save_shell_history: after calling write_history(), set
+         history_lines_in_file to history_lines_written_to_file, since we
+         can assume that we read everyhing we just wrote
+
+builtins/history.def
+       - history_builtin: after calling read_history (history -r), set the
+         new value of history_lines_in_file, for the same reason as above
+       - history_builtin: after calling read_history_range (history -n), set
+         history_lines_in_file from history_lines_read_from_file
+
+                                  11/6
+                                  ----
+lib/readline/histfile.c
+       - history_truncate_file: since we move the old file to a backup copy
+         before truncating, make sure the new file is owned by the same uid
+         as the old
+       - history_do_write: use chown in the same way as history_truncate_file
+
+                                  11/12
+                                  -----
+lib/readline/display.c
+       - expand_prompt: takes a new `flags' argument; only one flag defined
+         so far: PMT_MULTILINE
+       - expand_prompt: changed all callers to add new flags argument
+       - rl_expand_prompt, redraw_prompt: make sure to set PMT_MULTILINE in
+         FLAGS argument to expand_prompt if expanding parts of a prompt
+         containing embedded newlines
+       - expand_prompt: only add mode char to last line of a prompt with
+         embedded newlines, so mode indicator doesn't get lost and gets
+         updated properly.  Fixes problem reported by Renlin Li
+         <lirenlin@gmail.com>
+
+                                  11/13
+                                  -----
+
+lib/readline/display.c
+       - prompt_modestr: changed prompt_modechar to return a string denoting
+         the editing mode; default strings for emacs and both vi modes are
+         #defines in this file.  prompt_modestr takes an argument in which
+         it returns the length of the mode string
+       - expand_prompt: if expanding mode strings in the prompt, get the
+         mode string to use and add it at the beginning of the prompt string,
+         before expanding it.  This will allow future work allowing the mode
+         string to contain invisible characters
+
+                                  11/15
+                                  -----
+lib/readline/rlprivate.h
+       - _rl_{emacs,vi_cmd,vi_ins}_mode_str: extern declarations for
+         variables to hold current values of user-settable mode strings;
+         variables to hold lengths 
+
+lib/readline/rlconf.h
+       - defines for default values of the mode strings for each editing mode
+         and keymap
+
+lib/readline/display.c
+       - _rl_{emacs,vi_cmd,vi_ins}_mode_str: new variables to hold values of
+         user-settable mode strings
+       - _rl_{emacs,vi_cmd,vi_ins}_modestr_len: new variables to hold lengths
+         of corresponding mode string variables
+       - prompt_modestr: return appropriate user-settable mode string
+         variables
+
+lib/readline/bind.c
+       - {emacs,vi-ins,vi-cmd}-mode-string: new user-settable mode string
+         variables
+       - sv_{emacs,viins,vicmd}_modestr: variable handling functions for user-
+         settable mode string variables. Non-null values are run through
+         rl_translate_keyseq so users can include invisible character
+         sequences in the mode strings; null values restore the default
+       - _rl_get_string_variable_value: handle values for new user-settable
+         mode string variables. Original code contributed by Dylan Cali
+         <calid1984@gmail.com>
+
+lib/readline/doc/rluser.texi
+       - {emacs,vi-ins,vi-cmd}-mode-string: document, including the fact that
+         you can use \1 and \2 to bracket sequences of non-printing
+         characters
+
+                                  11/16
+                                  -----
+lib/readline/history.c
+       - add_history: replace loop that copies history list down one item
+         with call to memmove to take advantage of whatever efficiencies
+         libc can offer.  Won't be any slower than current loop
+
+lib/readline/display.c
+       - rl_redraw_prompt_last_line: new function, calls redraw_prompt if
+         the prompt contains multiple lines; calls rl_forced_update_display
+         if not
+
+lib/readline/readline.h
+       - rl_redraw_prompt_last_line: extern declaration, undocumented in
+         texinfo manual until I get it a little more work
+
+bashline.c
+       - bash_execute_unix_command: instead of unconditionally calling
+         rl_forced_update_display, call rl_redraw_prompt_last_line if we
+         cleared the last line before executing the command.  This keeps
+         commands that don't display any other output but just manipulate
+         the contents of the line buffer from redisplaying the prompt lines
+         before the last newline multiple times.  Fixes bug reported by
+         Jesper Nygards <jesper.nygards@gmail.com> and Rob Foehl
+         <rwf@loonybin.net>.  This means that commands that display output
+         will *only* display the final line of the prompt
+       - bash_execute_unix_command: if the command returns 124, we redraw
+         the line unconditionally, including all lines of the prompt
+
+                                  11/18
+                                  -----
+builtins/mapfile.def
+       - mapfile_builtin: don't allow a valid array reference through to
+         mapfile(), since it will just create a shell variable with that name.
+         Bug and fix from Eduardo A. Bustamante López <dualbus@gmail.com>
+
+                                  11/19
+                                  -----
+lib/readline/complete.c
+       - _rl_colored_completion_prefix: new variable, if non-zero, and color
+         support is compiled in, and the $LS_COLORS variable exists and
+         contains color definitions, display any common prefix of a set of
+         completions in blue when displaying all the possible completions.
+         Doesn't work with menu-complete, which inserts possible completions
+         inline
+       - colored_prefix_start(), colored_prefix_end(): new functions, used to
+         bracket colored completion prefixes
+       - fnprint: if prefix_bytes is non-zero, and _rl_colored_completion_prefix
+         is > 0, display the first PREFIX_BYTES bytes of the word bracketed
+         by calls to colored_prefix_start and colored_prefix_end
+       - print_filename: if _rl_colored_completion_prefix is > 0, compute the
+         length in bytes of the common prefix and pass that to fnprint
+
+lib/readline/readline.c
+       - readline_initialize_everything: initialize the colors from $LS_COLORS
+         if _rl_colored_completion_prefix is non-zero
+
+lib/readline/colors.c
+       - _rl_print_prefix_color: new function, changes text color to that
+         defined for the common prefix of a set of possible completions
+         (currently cyan, same as directories); currently uses C_PREFIX,
+         defined in colors.h as C_DIR
+
+lib/readline/colors.h
+       - _rl_print_prefix_color: new extern declaration
+
+lib/readline/bind.c
+       - colored-completion-prefix: new bindable variable, if set, common
+         prefix of a set of possible completions is displayed in color.
+         Feature requested by several, most recently by Richard Neill
+         <rn214@richardneill.org> (in a slightly different form) and
+         Duy Nguyen <pclouds@gmail.com>
+
+                                  11/20
+                                  -----
+builtins/printf.def
+       - printf_builtin: allow null (empty) format strings supplied with
+         -v var to set `var' to the empty string.  That is, printf -v var ""
+         is now the same as var="".  Change suggested by Mike Frysinger
+         <vapier@gentoo.org>
+
+pathexp.h
+       - FNMATCH_NOCASEGLOB: macro to decide whether or not to pass
+         FNM_CASEFOLD flag to strmatch depending on whether glob_ignore_case
+         is set; analogout to FNMATCH_IGNCASE
+
+pathexp.c
+       - glob_name_is_acceptable: use FNMATCH_NOCASEMATCH to determine flags
+         passed to strmatch; if nocaseglob is used to generate glob matches,
+         it should be used to generate ignored matches
+
+                                  11/21
+                                  -----
+pcomplete.c
+       - filter_stringlist: the call to strmatch now honors the setting of
+         nocasematch.  Feature request from Ville Skytta <ville.skytta@iki.fi>
+         back in 2010
+
+doc/bash.1,lib/readline/doc/rluser.texi
+       - complete -X: document that filtering the list of possible completions
+         honors the nocasematch option when performing matching
+
+lib/glob/gmisc.c
+       - include chartypes.h and strmatch.h for new defines
+       - match_pattern_{wchar,char}: now take new third FLAGS argument, flags
+         have same meanings as strmatch(); intent is to handle case
+         insensitive comparisons under same conditions as strmatch
+       - FOLD: imported case-folding define from sm_loop.c; wide and single-
+         byte character versions
+       - match_pattern_{wchar,char}: use FOLD when comparing characters to
+         honor FNM_CASEFOLD if set in FLAGS argument
+
+externs.h
+       - match_pattern_{wchar,char}: updated extern declarations
+
+subst.c
+       - match_{upattern,wpattern}: update strmatch/wcsmatch calls to include
+         FNMATCH_IGNCASE in flags argument
+       - match_{upattern,wpattern}: update match_pattern_{char,wchar} calls
+         to include FNMATCH_IGNCASE in flags argument (consistent with calls
+         to strmatch).  This makes pattern substitution word expansion honor
+         nocasematch shell option.  Feature requested by Davide Baldini
+         <baldiniebaldini@gmail.com>
+       - match_wpattern: make sure to fold case if necessary when doing simple
+         matching
+
+doc/{bash.1,bashref.texi}
+       - pattern substitution: updated description to include honoring setting
+         of nocasematch when performing matching
+
+subst.c
+       - expand_word_internal: optimize handling of "$@" idiom by calling
+         list_rest_of_args() and quote_list() directly at the top of the
+         function instead of going through normal code path
+       - cached_quoted_dollar_at: WORD_LIST of quoted positional parameters,
+         used by same code above that optimizes "$@"; if non-null we just
+         return a copy of the list; if null, we save a copy of the list we
+         create
+       - invalidate_cached_quoted_dollar_at: convenience function to allow
+         other parts of the shell (e.g., remember_args()) to destroy the
+         cached list of quoted positional parameter when the positional
+         parameters change
+
+builtins/common.c
+       - remember_args: call invalidate_cached_quoted_dollar_at()
+
+builtins/shift.def
+       - shift_builtin: call invalidate_cached_quoted_dollar_at after modifying
+         dollar_vars[]
+
+builtins/source.def
+       - maybe_pop_dollar_vars: call invalidate_cached_quoted_dollar_at just
+         to be safe
+
+                                  11/23
+                                  -----
+builtins/evalfile.c
+       - _evalfile: return -1 if errno == ENOENT and the flags don't include
+         FEVAL_ENOENTOK.  If we print an error message we should return an
+         error
+       - force_execute_file: new function, reads and executes commands from
+         a file but returns an error if file  doesn't exist
+
+builtins/common.h
+       - force_execute_file: new extern declaration
+
+shell.c
+       - main: call start_debugger even if dollar_vars[1] == 0 if the shell
+         isn't interactive (interactive_shell == 0)
+       - start_debugger: call force_execute_file instead of maybe_execute_file;
+         turn off debugging mode if it returns value < 0
+
+                                  11/24
+                                  -----
+hashlib.h
+       - DEFAULT_HASH_BUCKETS: doubled to 128, cost in memory use is small but
+         changes traversal order when not sorting results
+
+                                  11/25
+                                  -----
+doc/{bash.1,bashref.texi}
+       - make it clearer, by breaking it out into a separate paragraph, that
+         referencing an array without a subscript is equivalent to referencing
+         it with subscript 0
+       - add text saying that referencing any variable using a valid subscript
+         is OK
+
+                                  11/28
+                                  -----
+
+arrayfunc.c
+       - bind_array_variable, bind_assoc_variable: allow binding value to a
+         readonly variable if the ASS_FORCE flag is set in the FLAGS
+         argument
+
+subst.h
+       - ASS_FORCE: new assignment flag; means to allow assignment even if
+         variable is marked readonly
+
+builtins/declare.def
+       - when assigning a value to an array or assoc variable using
+         something like `declare -r foo=bar' where foo is an existing array
+         variable, pass the ASS_FORCE to assign_array_var_from_string so
+         the assignment is allowed.  Fixes debian bug 765759
+         http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=765759
+
+builtins/setattr.def
+       - var_attribute_string: new function to return (as argument) a char
+         array with attribute flag values for a given variable; returns the
+         length of the array
+
+lib/sh/shquote.c
+       - sh_quote_reusable: function returning a version of its string
+         argument that is quoted for reuse
+
+externs.h
+       - sh_quote_reusable: extern declaration
+
+builtins/common.h
+       - MAX_ATTRIBUTES: define used to size arrays for attribute flag
+         characters
+       - var_attribute_string: new extern function declaration
+
+subst.c
+       - array_remove_pattern: fixed a bug where `var' instead of `v' was
+         tested for invisible attribute
+       - get_var_and_type: fill in a valid *VARP if returning VT_VARIABLE
+         because callers may need to use it
+       - parameter_brace_transform: family of functions to implement the new
+         mksh-inspired ${param@spec} transformation word expansions.  Some
+         of the operators transform the (expanded) value of the parameter,
+         the rest expand to information about the parameter itself
+         (array_transform, parameter_list_transform, list_transform,
+         string_transform, pos_params_assignment, array_var_assignment,
+         string_var_assignment)
+       - parameter_brace_expand: changes to parse the new `@' word expansion
+         operator and call parameter_brace_transform appropriately
+       - parameter_brace_expand: make sure we handle ${#@} as we have before
+         even in the presence of the new `@' operator
+
+variables.c
+       - push_temp_var: make sure to call bind_variable_internal with the
+         ASS_FORCE flag so we override readonly variables created with
+         something like `tempvar=foo declare -r foo'.
+       - bind_variable_internal: honor ASS_FORCE flag to allow binding even
+         if a variable is readonly
+
+execute_cmd.c
+       - struct func_array_state: new state to save state of BASH_LINENO,
+         BASH_SOURCE, and FUNCNAME during function execution so it can be
+         restored on a jump to top level
+       - restore_funcarray_state: new function to restore func_array_state
+       - execute_function: fill in func_array_state variable, add unwind-
+         protect to restore it on jump to top level, call explicitly at
+         end of function if subshell != 0 (may not be necessary, but safe
+         for now).  Fixes bug with local assignments to FUNCNAME reported
+         by Arfrever Frehtes Taifersar Arahesis <arfrever.fta@gmail.com>
+
+                                  11/29
+                                  -----
+arrayfunc.c
+       - assign_compound_array_list: turn off ASS_APPEND flag when processing
+         each individual assignment inside the parens in var+=(...).  The
+         outer += should not affect assignments to existing subscripts;
+         those should be treated like usual assignments unless += supplied
+         inside the parens.  Bug report from Maarten Billemont
+         <lhunath@lyndir.com>, fix from Eduardo A. Bustamante López
+         <dualbus@gmail.com>
+
+config.h.in
+       - HAVE_PSELECT: define if pselect(2) available
+
+configure.ac
+       - check for pselect(2), define HAVE_PSELECT if found
+
+lib/readline/input.c
+       - rl_getc: use pselect(2) to wait for input ready on readline's
+         input fd or for a signal to arrive, will handle SIGWINCH (which
+         does not interrupt read(2)) and thus allow resize to happen without
+         having to wait to read more input.  Only works if pselect available
+         and returns -1/EINTR on a signal even if the signal was installed
+         with SA_RESTART.  From a suggestion from Egmont Koblinger
+         <egmont@gmail.com>
+
+                                  12/3
+                                  ----
+variables.c
+       - flush_temporary_env: new function, disposes all temp variables in
+         temporary_env hash table
+       - bind_variable: only try to update a temporary variable's value in the
+         temporary env if the value argument is not null.  Fixes bug reported
+         by <tangqinghao@360.cn>
+
+variables.h
+       - flush_temporary_env: new extern declaration
+
+subst.c
+       - command_substitute: if running command substitution as part of
+         expanding a redirection (expanding_redir == 1), flush any temporary
+         environment we've inherited as part of this command, since we are not
+         supposed to have access to the temporary environment.  Since
+         expanding_redir only controls access to the temporary environment for
+         variable lookup and binding, we can turn it off in the subshell
+
+                                  12/4
+                                  ----
+builtins/printf.def
+       - printstr: make sure a missing precision specifier after a `.' is
+         treated as 0, as printf(3) specifies.  Fixes ubuntu bash bug
+         1399087 (https://bugs.launchpad.net/ubuntu/+source/bash/+bug/1399087)
+
+                                  12/5
+                                  ----
+subst.c
+       - skip_to_delim: if scanning past process substitution (skipcmd == 1,
+         noprocsub == 0), use extract_delimited_string instead of
+         extract_process_subst, which was changed a while back (bash-4.3.23)
+         to use xparse_dolparen.  xparse_dolparen complains if the command
+         or process substitution is unterminated, since it runs the parser,
+         which is not what we want here.  Command substitution does the same
+         thing.  Fixes bug reported by  Daniel Kahn Gillmor
+         <dkg@fifthhorseman.net> as Debian bash bug 771968
+         (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=771968)
+
+                                  12/6
+                                  ----
+subst.c
+       - command_substitute: short-circuit without forking on a command string
+         that consists entirely of <blank>s and newlines
diff --git a/CWRU/POSIX.NOTES.old b/CWRU/POSIX.NOTES.old
new file mode 100644 (file)
index 0000000..1707ab1
--- /dev/null
@@ -0,0 +1,82 @@
+Starting bash with the `--posix' command-line option or executing
+`set -o posix' while bash is running will cause bash to conform more
+closely to the Posix.2 standard by changing the behavior to match that
+specified by Posix.2 in areas where the bash default differs.
+
+The following list is what's changed when `posix mode' is in effect:
+
+1.  When a command in the hash table no longer exists, bash will re-search
+    $PATH to find the new location.  This is also available with
+    `shopt -s checkhash'.
+
+2.  The >& redirection does not redirect stdout and stderr.
+
+3.  The message printed by the job control code and builtins when a job
+    exits with a non-zero status is `Done(status)'.
+
+4.  Reserved words may not be aliased.
+
+5.  The Posix.2 PS1 and PS2 expansions of `!' -> history number and
+    `!!' -> `!' are enabled, and parameter expansion is performed on
+    the value regardless of the setting of the `promptvars' option.
+
+6.  Interactive comments are enabled by default.  (Note that bash has
+    them on by default anyway.)
+
+7.  The Posix.2 startup files are executed ($ENV) rather than the normal
+    bash files.
+
+8.  Tilde expansion is only performed on assignments preceding a command
+    name, rather than on all assignment statements on the line.
+
+9.  The default history file is ~/.sh_history (default value of $HISTFILE).
+
+10. The output of `kill -l' prints all the signal names on a single line,
+    separated by spaces.
+
+11. Non-interactive shells exit if `file' in `. file' is not found.
+
+12. Redirection operators do not perform pathname expansion on the word
+    in the redirection unless the shell is interactive
+
+13. Function names must be valid shell identifiers.  That is, they may not
+    contain characters other than letters, digits, and underscores, and
+    may not start with a digit.  Declaring a function with an illegal name
+    causes a fatal syntax error in non-interactive shells.
+
+14. Posix.2 `special' builtins are found before shell functions during command
+    lookup.
+
+15. If a Posix.2 special builtin returns an error status, a non-interactive
+    shell exits.  The fatal errors are those listed in the POSIX.2 standard,
+    and include things like passing incorrect options, redirection errors,
+    variable assignment errors for assignments preceding the command name,
+    and so on.
+
+16. The environment passed to executed commands is not sorted.  Neither is
+    the output of `set'.  This is not strictly Posix.2 behavior, but sh
+    does it this way.  Ksh does not.  It's not necessary to sort the
+    environment; no program should rely on it being sorted.
+
+17. If the `cd' builtin finds a directory to change to using $CDPATH, the
+    value it assigns to $PWD does not contain any symbolic links, as if
+    `cd -P' had been executed.
+
+18. A non-interactive shell exits with an error status if a variable
+    assignment error occurs when no command name follows the assignment
+    statements.  A variable assignment error occurs, for example, when
+    trying to assign a value to a read-only variable.
+
+19. A non-interactive shell exits with an error status if the iteration
+    variable in a for statement or the selection variable in a select
+    statement is a read-only variable.
+
+20. Process substitution is not available.
+
+21. Assignment statements preceding POSIX.2 `special' builtins persist in
+    the shell environment after the builtin completes.
+
+There is other Posix.2 behavior that bash does not implement.  Specifically:
+
+1.  Assignment statements affect the execution environment of all builtins,
+    not just special ones.
diff --git a/CWRU/old/set.def.save b/CWRU/old/set.def.save
new file mode 100644 (file)
index 0000000..87b78d7
--- /dev/null
@@ -0,0 +1,544 @@
+This file is set.def, from which is created set.c.
+It implements the "set" and "unset" builtins in Bash.
+
+Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+
+This file is part of GNU Bash, the Bourne Again SHell.
+
+Bash is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 1, or (at your option) any later
+version.
+
+Bash is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with Bash; see the file COPYING.  If not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+$PRODUCES set.c
+
+#include <stdio.h>
+#include "../shell.h"
+#include "../flags.h"
+
+#include "bashgetopt.h"
+
+extern int interactive;
+extern int noclobber, posixly_correct;
+#if defined (READLINE)
+extern int rl_editing_mode, no_line_editing;
+#endif /* READLINE */
+
+$BUILTIN set
+$FUNCTION set_builtin
+$SHORT_DOC set [--abefhkmnptuvxldBCHP] [-o option] [arg ...]
+    -a  Mark variables which are modified or created for export.
+    -b  Notify of job termination immediately.
+    -e  Exit immediately if a command exits with a non-zero status.
+    -f  Disable file name generation (globbing).
+    -h  Locate and remember function commands as functions are
+        defined.  Function commands are normally looked up when
+        the function is executed.
+    -i  Force the shell to be an "interactive" one.  Interactive shells
+        always read `~/.bashrc' on startup.
+    -k  All keyword arguments are placed in the environment for a
+        command, not just those that precede the command name.
+    -m  Job control is enabled.
+    -n  Read commands but do not execute them.
+    -o option-name
+        Set the variable corresponding to option-name:
+            allexport    same as -a
+            braceexpand  same as -B
+#if defined (READLINE)
+            emacs        use an emacs-style line editing interface
+#endif /* READLINE */
+            errexit      same as -e
+            histexpand   same as -H
+            ignoreeof    the shell will not exit upon reading EOF
+            interactive-comments
+                         allow comments to appear in interactive commands
+            monitor      same as -m
+            noclobber    disallow redirection to existing files
+            noexec       same as -n
+            noglob       same as -f
+            nohash       same as -d
+            notify       save as -b
+            nounset      same as -u
+           physical     same as -P
+           posix        change the behavior of bash where the default
+                        operation differs from the 1003.2 standard to
+                        match the standard
+           privileged   same as -p
+            verbose      same as -v
+#if defined (READLINE)
+            vi           use a vi-style line editing interface
+#endif /* READLINE */
+            xtrace       same as -x
+    -p  Turned on whenever the real and effective user ids do not match.
+        Disables processing of the $ENV file and importing of shell
+        functions.  Turning this option off causes the effective uid and
+       gid to be set to the real uid and gid.
+    -t  Exit after reading and executing one command.
+    -u  Treat unset variables as an error when substituting.
+    -v  Print shell input lines as they are read.
+    -x  Print commands and their arguments as they are executed.
+    -l  Save and restore the binding of the NAME in a FOR command.
+    -d  Disable the hashing of commands that are looked up for execution.
+        Normally, commands are remembered in a hash table, and once
+        found, do not have to be looked up again.
+#if defined (BRACE_EXPANSION)
+    -B  the shell will perform brace expansion
+#endif /* BRACE_EXPANSION */
+#if defined (BANG_HISTORY)
+    -H  Enable ! style history substitution.  This flag is on
+        by default.
+#endif /* BANG_HISTORY */
+    -C  If set, disallow existing regular files to be overwritten
+        by redirection of output.
+    -P  If set, do not follow symbolic links when executing commands
+        such as cd which change the current directory.
+
+Using + rather than - causes these flags to be turned off.  The
+flags can also be used upon invocation of the shell.  The current
+set of flags may be found in $-.  The remaining n ARGs are positional
+parameters and are assigned, in order, to $1, $2, .. $n.  If no
+ARGs are given, all shell variables are printed.
+$END
+
+/* An a-list used to match long options for set -o to the corresponding
+   option letter. */
+struct {
+  char *name;
+  int letter;
+} o_options[] = {
+  { "allexport",  'a' },
+#if defined (BRACE_EXPANSION)
+  { "braceexpand",'B' },
+#endif
+  { "errexit",   'e' },
+  { "histexpand", 'H' },
+  { "monitor",   'm' },
+  { "noexec",    'n' },
+  { "noglob",    'f' },
+  { "nohash",    'd' },
+#if defined (JOB_CONTROL)
+  { "notify",    'b' },
+#endif /* JOB_CONTROL */
+  {"nounset",    'u' },
+  {"physical",    'P' },
+  {"privileged",  'p' },
+  {"verbose",    'v' },
+  {"xtrace",     'x' },
+  {(char *)NULL, 0},
+};
+
+#define MINUS_O_FORMAT "%-15s\t%s\n"
+
+void
+list_minus_o_opts ()
+{
+  register int i;
+  char *on = "on", *off = "off";
+
+  printf (MINUS_O_FORMAT, "noclobber", (noclobber == 1) ? on : off);
+
+  if (find_variable ("ignoreeof") || find_variable ("IGNOREEOF"))
+    printf (MINUS_O_FORMAT, "ignoreeof", on);
+  else
+    printf (MINUS_O_FORMAT, "ignoreeof", off);
+
+  printf (MINUS_O_FORMAT, "interactive-comments",
+         interactive_comments ? on : off);
+
+  printf (MINUS_O_FORMAT, "posix", posixly_correct ? on : off);
+
+#if defined (READLINE)
+  if (no_line_editing)
+    {
+      printf (MINUS_O_FORMAT, "emacs", off);
+      printf (MINUS_O_FORMAT, "vi", off);
+    }
+  else
+    {
+      /* Magic.  This code `knows' how readline handles rl_editing_mode. */
+      printf (MINUS_O_FORMAT, "emacs", (rl_editing_mode == 1) ? on : off);
+      printf (MINUS_O_FORMAT, "vi", (rl_editing_mode == 0) ? on : off);
+    }
+#endif /* READLINE */
+
+  for (i = 0; o_options[i].name; i++)
+    {
+      int *on_or_off, zero = 0;
+
+      on_or_off = find_flag (o_options[i].letter);
+      if (on_or_off == FLAG_UNKNOWN)
+       on_or_off = &zero;
+      printf (MINUS_O_FORMAT, o_options[i].name, (*on_or_off == 1) ? on : off);
+    }
+}
+
+set_minus_o_option (on_or_off, option_name)
+     int on_or_off;
+     char *option_name;
+{
+  int option_char = -1;
+
+  if (STREQ (option_name, "noclobber"))
+    {
+      if (on_or_off == FLAG_ON)
+       bind_variable ("noclobber", "");
+      else
+       unbind_variable ("noclobber");
+      stupidly_hack_special_variables ("noclobber");
+    }
+  else if (STREQ (option_name, "ignoreeof"))
+    {
+      unbind_variable ("ignoreeof");
+      unbind_variable ("IGNOREEOF");
+      if (on_or_off == FLAG_ON)
+       bind_variable ("IGNOREEOF", "10");
+      stupidly_hack_special_variables ("IGNOREEOF");
+    }
+  
+#if defined (READLINE)
+  else if ((STREQ (option_name, "emacs")) || (STREQ (option_name, "vi")))
+    {
+      if (on_or_off == FLAG_ON)
+       {
+         rl_variable_bind ("editing-mode", option_name);
+
+         if (interactive)
+           with_input_from_stdin ();
+         no_line_editing = 0;
+       }
+      else
+       {
+         int isemacs = (rl_editing_mode == 1);
+         if ((isemacs && STREQ (option_name, "emacs")) ||
+             (!isemacs && STREQ (option_name, "vi")))
+           {
+             if (interactive)
+               with_input_from_stream (stdin, "stdin");
+             no_line_editing = 1;
+           }
+         else
+           builtin_error ("not in %s editing mode", option_name);
+       }
+    }
+#endif /* READLINE */
+  else if (STREQ (option_name, "interactive-comments"))
+    interactive_comments = (on_or_off == FLAG_ON);
+  else if (STREQ (option_name, "posix"))
+    {
+      posixly_correct = (on_or_off == FLAG_ON);
+      unbind_variable ("POSIXLY_CORRECT");
+      unbind_variable ("POSIX_PEDANTIC");
+      if (on_or_off == FLAG_ON)
+       {
+         bind_variable ("POSIXLY_CORRECT", "");
+         stupidly_hack_special_variables ("POSIXLY_CORRECT");
+       }
+    }
+  else
+    {
+      register int i;
+      for (i = 0; o_options[i].name; i++)
+       {
+         if (STREQ (option_name, o_options[i].name))
+           {
+             option_char = o_options[i].letter;
+             break;
+           }
+       }
+      if (option_char == -1)
+       {
+         builtin_error ("%s: unknown option name", option_name);
+         return (EXECUTION_FAILURE);
+       }
+      if (change_flag (option_char, on_or_off) == FLAG_ERROR)
+       {
+         bad_option (option_name);
+         return (EXECUTION_FAILURE);
+       }
+    }
+  return (EXECUTION_SUCCESS);
+}
+
+/* Set some flags from the word values in the input list.  If LIST is empty,
+   then print out the values of the variables instead.  If LIST contains
+   non-flags, then set $1 - $9 to the successive words of LIST. */
+set_builtin (list)
+     WORD_LIST *list;
+{
+  int on_or_off, flag_name, force_assignment = 0;
+
+  if (!list)
+    {
+      SHELL_VAR **vars;
+
+      vars = all_shell_variables ();
+      if (vars)
+       {
+         print_var_list (vars);
+         free (vars);
+       }
+
+      vars = all_shell_functions ();
+      if (vars)
+       {
+         print_var_list (vars);
+         free (vars);
+       }
+
+      return (EXECUTION_SUCCESS);
+    }
+
+  /* Check validity of flag arguments. */
+  if (*list->word->word == '-' || *list->word->word == '+')
+    {
+      register char *arg;
+      WORD_LIST *save_list = list;
+
+      while (list && (arg = list->word->word))
+       {
+         char c;
+
+         if (arg[0] != '-' && arg[0] != '+')
+           break;
+
+         /* `-' or `--' signifies end of flag arguments. */
+         if (arg[0] == '-' &&
+             (!arg[1] || (arg[1] == '-' && !arg[2])))
+           break;
+
+         while (c = *++arg)
+           {
+             if (find_flag (c) == FLAG_UNKNOWN && c != 'o')
+               {
+                 char s[2];
+                 s[0] = c; s[1] = '\0';
+                 bad_option (s);
+                 if (c == '?')
+                   builtin_usage ();
+                 return (c == '?' ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
+               }
+           }
+         list = list->next;
+       }
+      list = save_list;
+    }
+
+  /* Do the set command.  While the list consists of words starting with
+     '-' or '+' treat them as flags, otherwise, start assigning them to
+     $1 ... $n. */
+  while (list)
+    {
+      char *string = list->word->word;
+
+      /* If the argument is `--' or `-' then signal the end of the list
+        and remember the remaining arguments. */
+      if (string[0] == '-' && (!string[1] || (string[1] == '-' && !string[2])))
+       {
+         list = list->next;
+
+         /* `set --' unsets the positional parameters. */
+         if (string[1] == '-')
+           force_assignment = 1;
+
+         /* Until told differently, the old shell behaviour of
+            `set - [arg ...]' being equivalent to `set +xv [arg ...]'
+            stands.  Posix.2 says the behaviour is marked as obsolescent. */
+         else
+           {
+             change_flag ('x', '+');
+             change_flag ('v', '+');
+           }
+
+         break;
+       }
+
+      if ((on_or_off = *string) &&
+         (on_or_off == '-' || on_or_off == '+'))
+       {
+         int i = 1;
+         while (flag_name = string[i++])
+           {
+             if (flag_name == '?')
+               {
+                 builtin_usage ();
+                 return (EXECUTION_SUCCESS);
+               }
+             else if (flag_name == 'o') /* -+o option-name */
+               {
+                 char *option_name;
+                 WORD_LIST *opt;
+
+                 opt = list->next;
+
+                 if (!opt)
+                   {
+                     list_minus_o_opts ();
+                     continue;
+                   }
+
+                 option_name = opt->word->word;
+
+                 if (!option_name || !*option_name || (*option_name == '-'))
+                   {
+                     list_minus_o_opts ();
+                     continue;
+                   }
+                 list = list->next; /* Skip over option name. */
+
+                 if (set_minus_o_option (on_or_off, option_name) != EXECUTION_SUCCESS)
+                   return (EXECUTION_FAILURE);
+               }
+             else
+               {
+                 if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
+                   {
+                     char opt[3];
+                     opt[0] = on_or_off;
+                     opt[1] = flag_name;
+                     opt[2] = '\0';
+                     bad_option (opt);
+                     builtin_usage ();
+                     return (EXECUTION_FAILURE);
+                   }
+               }
+           }
+       }
+      else
+       {
+         break;
+       }
+      list = list->next;
+    }
+
+  /* Assigning $1 ... $n */
+  if (list || force_assignment)
+    remember_args (list, 1);
+  return (EXECUTION_SUCCESS);
+}
+
+$BUILTIN unset
+$FUNCTION unset_builtin
+$SHORT_DOC unset [-f] [-v] [name ...]
+For each NAME, remove the corresponding variable or function.  Given
+the `-v', unset will only act on variables.  Given the `-f' flag,
+unset will only act on functions.  With neither flag, unset first
+tries to unset a variable, and if that fails, then tries to unset a
+function.  Some variables (such as PATH and IFS) cannot be unset; also
+see readonly.
+$END
+
+#define NEXT_VARIABLE()        any_failed++; list = list->next; continue;
+
+unset_builtin (list)
+  WORD_LIST *list;
+{
+  int unset_function, unset_variable, unset_array, opt, any_failed;
+  char *name;
+
+  unset_function = unset_variable = unset_array = any_failed = 0;
+
+  reset_internal_getopt ();
+  while ((opt = internal_getopt (list, "fv")) != -1)
+    {
+      switch (opt)
+       {
+       case 'f':
+         unset_function = 1;
+         break;
+       case 'v':
+         unset_variable = 1;
+         break;
+       default:
+         builtin_usage ();
+         return (EXECUTION_FAILURE);
+       }
+    }
+
+  list = loptend;
+
+  if (unset_function && unset_variable)
+    {
+      builtin_error ("cannot simultaneously unset a function and a variable");
+      return (EXECUTION_FAILURE);
+    }
+
+  while (list)
+    {
+      SHELL_VAR *var;
+      int tem;
+#if defined (ARRAY_VARS)
+      char *t;
+#endif
+
+      name = list->word->word;
+
+#if defined (ARRAY_VARS)
+      if (!unset_function && valid_array_reference (name))
+       {
+         t = strchr (name, '[');
+         *t++ = '\0';
+         unset_array++;
+       }
+#endif
+
+      var = unset_function ? find_function (name) : find_variable (name);
+
+      if (var && !unset_function && non_unsettable_p (var))
+       {
+         builtin_error ("%s: cannot unset", name);
+         NEXT_VARIABLE ();
+       }
+
+      /* Posix.2 says that unsetting readonly variables is an error. */
+      if (var && readonly_p (var))
+       {
+         builtin_error ("%s: cannot unset: readonly %s",
+                        name, unset_function ? "function" : "variable");
+         NEXT_VARIABLE ();
+       }
+
+      /* Unless the -f option is supplied, the name refers to a variable. */
+#if defined (ARRAY_VARS)
+      if (var && unset_array)
+       {
+         if (array_p (var) == 0)
+           {
+             builtin_error ("%s: not an array variable", name);
+             NEXT_VARIABLE ();
+           }
+         else
+           tem = unbind_array_element (var, t);
+       }
+      else
+#endif /* ARRAY_VARS */
+      tem = makunbound (name, unset_function ? shell_functions : shell_variables);
+
+      /* This is what Posix.2 draft 11+ says.  ``If neither -f nor -v
+        is specified, the name refers to a variable; if a variable by
+        that name does not exist, a function by that name, if any,
+        shall be unset.'' */
+      if ((tem == -1) && !unset_function && !unset_variable)
+       tem = makunbound (name, shell_functions);
+
+      if (tem == -1)
+       any_failed++;
+      else if (!unset_function)
+       stupidly_hack_special_variables (name);
+
+      list = list->next;
+    }
+
+  if (any_failed)
+    return (EXECUTION_FAILURE);
+  else
+    return (EXECUTION_SUCCESS);
+}
diff --git a/CWRU/save/unwind_prot.h.save b/CWRU/save/unwind_prot.h.save
new file mode 100644 (file)
index 0000000..998fd72
--- /dev/null
@@ -0,0 +1,50 @@
+/* unwind_prot.h - Macros and functions for hacking unwind protection. */
+
+/* Copyright (C) 1993 Free Software Foundation, Inc.
+
+   This file is part of GNU Bash, the Bourne Again SHell.
+
+   Bash is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2, or (at your option) any later
+   version.
+
+   Bash is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with Bash; see the file COPYING.  If not, write to the Free Software
+   Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#if !defined (_UNWIND_PROT_H)
+#define _UNWIND_PROT_H
+
+/* Run a function without interrupts. */
+extern void begin_unwind_frame ();
+extern void discard_unwind_frame ();
+extern void run_unwind_frame ();
+extern void add_unwind_protect ();
+extern void remove_unwind_protect ();
+extern void run_unwind_protects ();
+extern void unwind_protect_var ();
+
+/* Define for people who like their code to look a certain way. */
+#define end_unwind_frame()
+
+/* How to protect an integer. */
+#define unwind_protect_int(X) unwind_protect_var (&(X), (char *)(X), sizeof (int))
+
+/* How to protect a pointer to a string. */
+#define unwind_protect_string(X) \
+  unwind_protect_var ((int *)&(X), (X), sizeof (char *))
+
+/* How to protect any old pointer. */
+#define unwind_protect_pointer(X) unwind_protect_string (X)
+
+/* How to protect the contents of a jmp_buf. */
+#define unwind_protect_jmp_buf(X) \
+  unwind_protect_var ((int *)(X), (char *)(X), sizeof (procenv_t))
+
+#endif /* _UNWIND_PROT_H */
index fde32842782e4b8246ae2079a86bb71676bec24a..3a41c99c70a1429f6223787f5d9eba20a8ede21e 100644 (file)
@@ -495,7 +495,6 @@ declare_internal (list, local_var)
                }
              else
 #endif
-
              if (offset)
                var = mkglobal ? bind_global_variable (name, "", 0) : bind_variable (name, "", 0);
              else
index 6f20f7a396f27897d5254ad3fdb9525f5b567d8f..a3899bef54f222e1eedcb291571790aaab5cc292 100644 (file)
@@ -767,6 +767,8 @@ printstr (fmt, string, len, fieldwidth, precision)
          /* Error if precision > INT_MAX here? */
          pr = (mpr < 0 || mpr > INT_MAX) ? INT_MAX : mpr;
        }
+      else
+       pr = 0;         /* "a null digit string is treated as zero" */
     }
 
 #if 0
diff --git a/cross-build/cygwin32.cache.old b/cross-build/cygwin32.cache.old
new file mode 100644 (file)
index 0000000..640390f
--- /dev/null
@@ -0,0 +1,42 @@
+# This file is a shell script that caches the results of configure
+# tests for CYGWIN32 so they don't need to be done when cross-compiling.
+
+# AC_FUNC_GETPGRP should also define GETPGRP_VOID
+ac_cv_func_getpgrp_void=${ac_cv_func_getpgrp_void='yes'}
+# AC_FUNC_SETVBUF_REVERSED should not define anything else
+ac_cv_func_setvbuf_reversed=${ac_cv_func_setvbuf_reversed='no'}
+# on CYGWIN32, system calls do not restart
+ac_cv_sys_restartable_syscalls=${ac_cv_sys_restartable_syscalls='no'}
+bash_cv_sys_restartable_syscalls=${bash_cv_sys_restartable_syscalls='no'}
+
+# these may be necessary, but they are currently commented out
+#ac_cv_c_bigendian=${ac_cv_c_bigendian='no'}
+ac_cv_sizeof_char_p=${ac_cv_sizeof_char_p='4'}
+ac_cv_sizeof_int=${ac_cv_sizeof_int='4'}
+ac_cv_sizeof_long=${ac_cv_sizeof_long='4'}
+ac_cv_sizeof_double=${ac_cv_sizeof_double='8'}
+
+bash_cv_dup2_broken=${bash_cv_dup2_broken='no'}
+bash_cv_pgrp_pipe=${bash_cv_pgrp_pipe='no'}
+bash_cv_type_rlimit=${bash_cv_type_rlimit='long'}
+bash_cv_decl_under_sys_siglist=${bash_cv_decl_under_sys_siglist='no'}
+bash_cv_under_sys_siglist=${bash_cv_under_sys_siglist='no'}
+bash_cv_sys_siglist=${bash_cv_sys_siglist='no'}
+bash_cv_opendir_not_robust=${bash_cv_opendir_not_robust='no'}
+bash_cv_getenv_redef=${bash_cv_getenv_redef='yes'}
+bash_cv_printf_declared=${bash_cv_printf_declared='yes'}
+bash_cv_ulimit_maxfds=${bash_cv_ulimit_maxfds='no'}
+bash_cv_getcwd_calls_popen=${bash_cv_getcwd_calls_popen='no'}
+bash_cv_must_reinstall_sighandlers=${bash_cv_must_reinstall_sighandlers='no'}
+bash_cv_job_control_missing=${bash_cv_job_control_missing='present'}
+bash_cv_sys_named_pipes=${bash_cv_sys_named_pipes='missing'}
+bash_cv_func_sigsetjmp=${bash_cv_func_sigsetjmp='missing'}
+bash_cv_mail_dir=${bash_cv_mail_dir='unknown'}
+bash_cv_func_strcoll_broken=${bash_cv_func_strcoll_broken='no'}
+
+bash_cv_type_int32_t=${bash_cv_type_int32_t='int'}
+bash_cv_type_u_int32_t=${bash_cv_type_u_int32_t='int'}
+
+ac_cv_type_bits64_t=${ac_cv_type_bits64_t='no'}
+
+# end of cross-build/cygwin32.cache
diff --git a/doc/FAQ.orig b/doc/FAQ.orig
new file mode 100644 (file)
index 0000000..1cff3c8
--- /dev/null
@@ -0,0 +1,1745 @@
+This is the Bash FAQ, version 3.24, for Bash version 2.05b.
+
+This document contains a set of frequently-asked questions concerning
+Bash, the GNU Bourne-Again Shell.  Bash is a freely-available command
+interpreter with advanced features for both interactive use and shell
+programming.
+
+Another good source of basic information about shells is the collection
+of FAQ articles periodically posted to comp.unix.shell.
+
+Questions and comments concerning this document should be sent to
+chet@po.cwru.edu.
+
+This document is available for anonymous FTP with the URL
+
+ftp://ftp.cwru.edu/pub/bash/FAQ
+
+The Bash home page is http://cnswww.cns.cwru.edu/~chet/bash/bashtop.html
+
+----------
+Contents:
+
+Section A:  The Basics
+
+A1) What is it?
+A2) What's the latest version?
+A3) Where can I get it?
+A4) On what machines will bash run?
+A5) Will bash run on operating systems other than Unix?
+A6) How can I build bash with gcc?
+A7) How can I make bash my login shell?
+A8) I just changed my login shell to bash, and now I can't FTP into my
+    machine.  Why not?
+A9) What's the `POSIX 1003.2 standard'?
+A10) What is the bash `posix mode'?
+
+Section B:  The latest version
+
+B1) What's new in version 2.05b?
+B2) Are there any user-visible incompatibilities between bash-2.05b and
+    bash-1.14.7?
+
+Section C:  Differences from other Unix shells
+
+C1) How does bash differ from sh, the Bourne shell?
+C2) How does bash differ from the Korn shell, version ksh88?
+C3) Which new features in ksh-93 are not in bash, and which are?
+
+Section D:  Why does bash do some things differently than other Unix shells?
+
+D1) Why does bash run a different version of `command' than
+    `which command' says it will?
+D2) Why doesn't bash treat brace expansions exactly like csh?
+D3) Why doesn't bash have csh variable modifiers?
+D4) How can I make my csh aliases work when I convert to bash?
+D5) How can I pipe standard output and standard error from one command to
+    another, like csh does with `|&'?
+D6) Now that I've converted from ksh to bash, are there equivalents to
+    ksh features like autoloaded functions and the `whence' command?
+
+Section E:  Why does bash do certain things the way it does?
+
+E1) Why is the bash builtin `test' slightly different from /bin/test?
+E2) Why does bash sometimes say `Broken pipe'?
+E3) When I have terminal escape sequences in my prompt, why does bash
+    wrap lines at the wrong column?
+E4) If I pipe the output of a command into `read variable', why doesn't
+    the output show up in $variable when the read command finishes?
+E5) I have a bunch of shell scripts that use backslash-escaped characters
+    in arguments to `echo'.  Bash doesn't interpret these characters.  Why
+    not, and how can I make it understand them?
+E6) Why doesn't a while or for loop get suspended when I type ^Z?
+E7) What about empty for loops in Makefiles?
+E8) Why does the arithmetic evaluation code complain about `08'?
+E9) Why does the pattern matching expression [A-Z]* match files beginning
+    with every letter except `z'?
+E10) Why does `cd //' leave $PWD as `//'?
+E11) If I resize my xterm while another program is running, why doesn't bash
+     notice the change?
+
+Section F:  Things to watch out for on certain Unix versions
+
+F1) Why can't I use command line editing in my `cmdtool'?
+F2) I built bash on Solaris 2.  Why do globbing expansions and filename
+    completion chop off the first few characters of each filename?
+F3) Why does bash dump core after I interrupt username completion or
+    `~user' tilde expansion on a machine running NIS?
+F4) I'm running SVR4.2.  Why is the line erased every time I type `@'?
+F5) Why does bash report syntax errors when my C News scripts use a
+    redirection before a subshell command?
+F6) Why can't I use vi-mode editing on Red Hat Linux 6.1?
+F7) Why do bash-2.05a and  bash-2.05b fail to compile `printf.def' on
+    HP/UX 11.x?
+
+Section G:  How can I get bash to do certain common things?
+
+G1) How can I get bash to read and display eight-bit characters?
+G2) How do I write a function `x' to replace builtin command `x', but
+    still invoke the command from within the function?
+G3) How can I find the value of a shell variable whose name is the value
+    of another shell variable?
+G4) How can I make the bash `time' reserved word print timing output that
+    looks like the output from my system's /usr/bin/time?
+G5) How do I get the current directory into my prompt?
+G6) How can I rename "*.foo" to "*.bar"?
+G7) How can I translate a filename from uppercase to lowercase?
+G8) How can I write a filename expansion (globbing) pattern that will match
+    all files in the current directory except "." and ".."?
+
+Section H:  Where do I go from here?
+
+H1) How do I report bugs in bash, and where should I look for fixes and
+    advice?
+H2) What kind of bash documentation is there?
+H3) What's coming in future versions?
+H4) What's on the bash `wish list'?
+H5) When will the next release appear?
+
+----------
+Section A:  The Basics
+
+A1)  What is it?
+
+Bash is a Unix command interpreter (shell).  It is an implementation of
+the Posix 1003.2 shell standard, and resembles the Korn and System V
+shells.
+
+Bash contains a number of enhancements over those shells, both
+for interactive use and shell programming.  Features geared
+toward interactive use include command line editing, command
+history, job control, aliases, and prompt expansion.  Programming
+features include additional variable expansions, shell
+arithmetic, and a number of variables and options to control
+shell behavior.
+
+Bash was originally written by Brian Fox of the Free Software
+Foundation.  The current developer and maintainer is Chet Ramey
+of Case Western Reserve University.
+
+A2)  What's the latest version?
+
+The latest version is 2.05b, first made available on Wednesday, 17
+July, 2002.
+
+A3)  Where can I get it?
+
+Bash is the GNU project's shell, and so is available from the
+master GNU archive site, ftp.gnu.org, and its mirrors.  The
+latest version is also available for FTP from ftp.cwru.edu.
+The following URLs tell how to get version 2.05b:
+
+ftp://ftp.gnu.org/pub/gnu/bash/bash-2.05b.tar.gz
+ftp://ftp.cwru.edu/pub/bash/bash-2.05b.tar.gz
+
+Formatted versions of the documentation are available with the URLs:
+
+ftp://ftp.gnu.org/pub/gnu/bash/bash-doc-2.05b.tar.gz
+ftp://ftp.cwru.edu/pub/bash/bash-doc-2.05b.tar.gz
+
+A4)  On what machines will bash run?
+
+Bash has been ported to nearly every version of UNIX.  All you
+should have to do to build it on a machine for which a port
+exists is to type `configure' and then `make'.  The build process
+will attempt to discover the version of UNIX you have and tailor
+itself accordingly, using a script created by GNU autoconf.
+
+More information appears in the file `INSTALL' in the distribution.
+
+The Bash web page (http://cnswww.cns.cwru.edu/~chet/bash/bashtop.html)
+explains how to obtain binary versions of bash for most of the major
+commercial Unix systems.
+
+A5) Will bash run on operating systems other than Unix?
+
+Configuration specifics for Unix-like systems such as QNX and
+LynxOS are included in the distribution.  Bash-2.05 and later
+versions should compile and run on Minix 2.0 (patches were
+contributed), but I don't believe anyone has built bash-2.x on
+earlier Minix versions yet. 
+
+Bash has been ported to versions of Windows implementing the Win32
+programming interface.  This includes Windows 95 and Windows NT.
+The port was done by Cygnus Solutions as part of their CYGWIN
+project.  For more information about the project, look at the URLs
+
+http://www.cygwin.com/
+http://sourceware.cygnus.com/cygwin
+
+Cygnus originally ported bash-1.14.7, and that port was part of their
+early GNU-Win32 (the original name) releases.  Cygnus has also done a
+port of bash-2.05 to the CYGWIN environment, and it is available as
+part of their current release.
+
+Bash-2.05b should require no local Cygnus changes to build and run under
+CYGWIN.
+
+The Cygnus port works only on Intel machines.  There is a port of bash
+(I don't know which version) to the alpha/NT environment available from
+
+ftp://ftp.gnustep.org//pub/win32/bash-alpha-nt-1.01.tar.gz
+
+DJ Delorie has a port of bash-2.x which runs under MS-DOS, as part
+of the DJGPP project.  For more information on the project, see
+
+http://www.delorie.com/djgpp/
+
+I have been told that the original DJGPP port was done by Daisuke Aoyama.
+
+Mark Elbrecht <snowball3@bigfoot.com> has sent me notice that bash-2.04
+is available for DJGPP V2.  The files are available as:
+
+ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bsh204b.zip binary
+ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bsh204d.zip documentation
+ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bsh204s.zip source
+
+Mark has begun to work with bash-2.05, but I don't know the status.
+
+Ports of bash-1.12 and bash-2.0 are available for OS/2 from
+
+ftp://hobbes.nmsu.edu/pub/os2/util/shell/bash_112.zip
+ftp://hobbes.nmsu.edu/pub/os2/util/shell/bash-2.0(253).zip
+
+I haven't looked at either, but the second appears to be a binary-only
+distribution.  Beware.
+
+I have received word that Bash (I'm not sure which version, but I
+believe that it's at least bash-2.02.1) is the standard shell on
+BeOS.
+
+A6) How can I build bash with gcc? 
+
+Bash configures to use gcc by default if it is available.  Read the
+file INSTALL in the distribution for more information.
+
+A7)  How can I make bash my login shell?
+
+Some machines let you use `chsh' to change your login shell.  Other
+systems use `passwd -s' or `passwd -e'.  If one of these works for
+you, that's all you need.  Note that many systems require the full
+pathname to a shell to appear in /etc/shells before you can make it
+your login shell.  For this, you may need the assistance of your
+friendly local system administrator. 
+
+If you cannot do this, you can still use bash as your login shell, but
+you need to perform some tricks.  The basic idea is to add a command
+to your login shell's startup file to replace your login shell with
+bash.
+
+For example, if your login shell is csh or tcsh, and you have installed
+bash in /usr/gnu/bin/bash, add the following line to ~/.login:
+
+       if ( -f /usr/gnu/bin/bash ) exec /usr/gnu/bin/bash --login
+
+(the `--login' tells bash that it is a login shell).
+
+It's not a good idea to put this command into ~/.cshrc, because every
+csh you run without the `-f' option, even ones started to run csh scripts,
+reads that file.  If you must put the command in ~/.cshrc, use something
+like
+
+       if ( $?prompt ) exec /usr/gnu/bin/bash --login
+
+to ensure that bash is exec'd only when the csh is interactive.
+
+If your login shell is sh or ksh, you have to do two things.
+
+First, create an empty file in your home directory named `.bash_profile'.
+The existence of this file will prevent the exec'd bash from trying to
+read ~/.profile, and re-execing itself over and over again.  ~/.bash_profile
+is the first file bash tries to read initialization commands from when
+it is invoked as a login shell.
+
+Next, add a line similar to the above to ~/.profile:
+
+       [ -f /usr/gnu/bin/bash ] && [ -x /usr/gnu/bin/bash ] && \
+               exec /usr/gnu/bin/bash --login
+
+This will cause login shells to replace themselves with bash running as
+a login shell.  Once you have this working, you can copy your initialization
+code from ~/.profile to ~/.bash_profile.
+
+I have received word that the recipe supplied above is insufficient for
+machines running CDE.  CDE has a maze of twisty little startup files, all
+slightly different.
+
+If you cannot change your login shell in the password file to bash, you
+will have to (apparently) live with CDE using the shell in the password
+file to run its startup scripts.  If you have changed your shell to bash,
+there is code in the CDE startup files (on Solaris, at least) that attempts
+to do the right thing.  It is, however, often broken, and may require that
+you use the $BASH_ENV trick described below.
+
+`dtterm' claims to use $SHELL as the default program to start, so if you
+can change $SHELL in the CDE startup files, you should be able to use bash
+in your terminal windows.
+
+Setting DTSOURCEPROFILE in ~/.dtprofile will cause the `Xsession' program
+to read your login shell's startup files.  You may be able to use bash for
+the rest of the CDE programs by setting SHELL to bash in ~/.dtprofile as
+well, but I have not tried this.
+
+You can use the above `exec' recipe to start bash when not logging in with
+CDE by testing the value of the DT variable:
+
+       if [ -n "$DT" ]; then
+               [ -f /usr/gnu/bin/bash ] && exec /usr/gnu/bin/bash --login
+       fi
+
+If CDE starts its shells non-interactively during login, the login shell
+startup files (~/.profile, ~/.bash_profile) will not be sourced at login.
+To get around this problem, append a line similar to the following to your
+~/.dtprofile:
+
+       BASH_ENV=${HOME}/.bash_profile ; export BASH_ENV
+
+and add the following line to the beginning of ~/.bash_profile:
+
+       unset BASH_ENV
+
+A8) I just changed my login shell to bash, and now I can't FTP into my
+   machine.  Why not?
+
+You must add the full pathname to bash to the file /etc/shells.  As
+noted in the answer to the previous question, many systems require
+this before you can make bash your login shell. 
+
+Most versions of ftpd use this file to prohibit `special' users
+such as `uucp' and `news' from using FTP. 
+
+A9)  What's the `POSIX 1003.2 standard'?
+
+POSIX is a name originally coined by Richard Stallman for a
+family of open system standards based on UNIX.  There are a
+number of aspects of UNIX under consideration for
+standardization, from the basic system services at the system
+call and C library level to applications and tools to system
+administration and management.  Each area of standardization is
+assigned to a working group in the 1003 series. 
+
+The POSIX Shell and Utilities standard has been developed by IEEE
+Working Group 1003.2 (POSIX.2).  It concentrates on the command
+interpreter interface and utility programs commonly executed from
+the command line or by other programs.  An initial version of the
+standard has been approved and published by the IEEE, and work is
+currently underway to update it. 
+
+Bash is concerned with the aspects of the shell's behavior
+defined by POSIX.2.  The shell command language has of course
+been standardized, including the basic flow control and program
+execution constructs, I/O redirection and pipelining, argument
+handling, variable expansion, and quoting. 
+
+The `special' builtins, which must be implemented as part of the
+shell to provide the desired functionality, are specified as
+being part of the shell; examples of these are `eval' and
+`export'.  Other utilities appear in the sections of POSIX.2 not
+devoted to the shell which are commonly (and in some cases must
+be) implemented as builtin commands, such as `read' and `test'. 
+POSIX.2 also specifies aspects of the shell's interactive
+behavior as part of the UPE, including job control and command
+line editing.  Only vi-style line editing commands have been
+standardized; emacs editing commands were left out due to
+objections.
+
+The Open Group has made an older version of its Single Unix
+Specification (version 2), which is very similar to POSIX.2,
+available on the web at
+
+http://www.opengroup.org/onlinepubs/007908799/
+
+The Single Unix Specification, version 3, is available on the web at
+
+http://www.opengroup.org/onlinepubs/007904975/
+
+A10)  What is the bash `posix mode'?
+
+Although bash is an implementation of the POSIX.2 shell
+specification, there are areas where the bash default behavior
+differs from that spec.  The bash `posix mode' changes the bash
+behavior in these areas so that it obeys the spec more closely. 
+
+Posix mode is entered by starting bash with the --posix or
+'-o posix' option or executing `set -o posix' after bash is running.
+
+The specific aspects of bash which change when posix mode is
+active are listed in the file POSIX in the bash distribution.
+They are also listed in a section in the Bash Reference Manual
+(from which that file is generated).
+
+Section B:  The latest version
+
+B1) What's new in version 2.05b?
+
+The raison d'etre for bash-2.05b is to make a second intermediate
+release containing the first of the new features to be available
+in bash-3.0 and get feedback on those features before proceeding.
+The major new feature is multibyte character support in both Bash
+and Readline.
+
+Bash-2.05b contains the following new features (see the manual page for
+complete descriptions and the CHANGES and NEWS files in the bash-2.05b
+distribution):
+
+o support for multibyte characters has been added to both bash and readline
+
+o the DEBUG trap is now run *before* simple commands, ((...)) commands,
+  [[...]] conditional commands, and for ((...)) loops
+
+o the shell now performs arithmetic in the largest integer size the machine
+  supports (intmax_t)
+
+o there is a new \D{...} prompt expansion; passes the `...' to strftime(3)
+  and inserts the result into the expanded prompt
+
+o there is a new `here-string' redirection operator:  <<< word
+
+o when displaying variables, function attributes and definitions are shown
+  separately, allowing them to be re-used as input (attempting to re-use
+  the old output would result in syntax errors).
+
+o `read' has a new `-u fd' option to read from a specified file descriptor
+
+o the bash debugger in examples/bashdb has been modified to work with the
+  new DEBUG trap semantics, the command set has been made more gdb-like,
+  and the changes to $LINENO make debugging functions work better
+
+o the expansion of $LINENO inside a shell function is only relative to the
+  function start if the shell is interactive -- if the shell is running a
+  script, $LINENO expands to the line number in the script.  This is as
+  POSIX-2001 requires
+
+
+A short feature history dating from Bash-2.0:
+
+Bash-2.05a introduced the following new features:
+
+o The `printf' builtin has undergone major work
+
+o There is a new read-only `shopt' option: login_shell, which is set by
+  login shells and unset otherwise
+
+o New `\A' prompt string escape sequence; expanding to time in 24-hour
+  HH:MM format
+
+o New `-A group/-g' option to complete and compgen; goes group name
+  completion
+
+o New [+-]O invocation option to set and unset `shopt' options at startup
+
+o ksh-like `ERR' trap
+
+o `for' loops now allow empty word lists after the `in' reserved word
+
+o new `hard' and `soft' arguments for the `ulimit' builtin
+
+o Readline can be configured to place the user at the same point on the line
+  when retrieving commands from the history list
+
+o Readline can be configured to skip `hidden' files (filenames with a leading
+  `.' on Unix) when performing completion
+
+Bash-2.05 introduced the following new features:
+
+o This version has once again reverted to using locales and strcoll(3) when
+  processing pattern matching bracket expressions, as POSIX requires. 
+o Added a new `--init-file' invocation argument as a synonym for `--rcfile',
+  per the new GNU coding standards.
+o The /dev/tcp and /dev/udp redirections now accept service names as well as
+  port numbers.
+o `complete' and `compgen' now take a `-o value' option, which controls some
+   of the aspects of that compspec.  Valid values are:
+
+        default - perform bash default completion if programmable
+                  completion produces no matches
+        dirnames - perform directory name completion if programmable
+                   completion produces no matches
+        filenames - tell readline that the compspec produces filenames,
+                    so it can do things like append slashes to
+                    directory names and suppress trailing spaces
+o A new loadable builtin, realpath, which canonicalizes and expands symlinks
+  in pathname arguments.
+o When `set' is called without options, it prints function defintions in a
+  way that allows them to be reused as input.  This affects `declare' and 
+  `declare -p' as well.  This only happens when the shell is not in POSIX
+   mode, since POSIX.2 forbids this behavior.
+
+Bash-2.04 introduced the following new features:
+
+o Programmable word completion with the new `complete' and `compgen' builtins;
+  examples are provided in examples/complete/complete-examples
+o `history' has a new `-d' option to delete a history entry
+o `bind' has a new `-x' option to bind key sequences to shell commands
+o The prompt expansion code has new `\j' and `\l' escape sequences
+o The `no_empty_cmd_completion' shell option, if enabled, inhibits
+  command completion when TAB is typed on an empty line
+o `help' has a new `-s' option to print a usage synopsis
+o New arithmetic operators: var++, var--, ++var, --var, expr1,expr2 (comma)
+o New ksh93-style arithmetic for command:
+       for ((expr1 ; expr2; expr3 )); do list; done
+o `read' has new options: `-t', `-n', `-d', `-s'
+o The redirection code handles several filenames specially:  /dev/fd/N,
+  /dev/stdin, /dev/stdout, /dev/stderr
+o The redirection code now recognizes /dev/tcp/HOST/PORT and
+  /dev/udp/HOST/PORT and tries to open a TCP or UDP socket, respectively,
+  to the specified port on the specified host
+o The ${!prefix*} expansion has been implemented
+o A new FUNCNAME variable, which expands to the name of a currently-executing
+  function
+o The GROUPS variable is no longer readonly
+o A new shopt `xpg_echo' variable, to control the behavior of echo with
+  respect to backslash-escape sequences at runtime
+o The NON_INTERACTIVE_LOGIN_SHELLS #define has returned
+
+The version of Readline released with Bash-2.04, Readline-4.1, had several
+new features as well:
+
+o Parentheses matching is always compiled into readline, and controllable
+  with the new `blink-matching-paren' variable
+o The history-search-forward and history-search-backward functions now leave
+  point at the end of the line when the search string is empty, like
+  reverse-search-history, and forward-search-history
+o A new function for applications:  rl_on_new_line_with_prompt()
+o New variables for applications:  rl_already_prompted, and rl_gnu_readline_p
+
+
+Bash-2.03 had very few new features, in keeping with the convention
+that odd-numbered releases provide mainly bug fixes.  A number of new
+features were added to Readline, mostly at the request of the Cygnus
+folks.
+
+A new shopt option, `restricted_shell', so that startup files can test
+       whether or not the shell was started in restricted mode
+Filename generation is now performed on the words between ( and ) in
+       compound array assignments (this is really a bug fix)
+OLDPWD is now auto-exported, as POSIX.2 requires
+ENV and BASH_ENV are read-only variables in a restricted shell
+Bash may now be linked against an already-installed Readline library,
+       as long as the Readline library is version 4 or newer
+All shells begun with the `--login' option will source the login shell
+       startup files, even if the shell is not interactive
+
+There were lots of changes to the version of the Readline library released
+along with Bash-2.03.  For a complete list of the changes, read the file
+CHANGES in the Bash-2.03 distribution.
+
+Bash-2.02 contained the following new features:
+
+a new version of malloc (based on the old GNU malloc code in previous
+       bash versions) that is more page-oriented, more conservative
+       with memory usage, does not `orphan' large blocks when they
+       are freed, is usable on 64-bit machines, and has allocation
+       checking turned on unconditionally
+POSIX.2-style globbing character classes ([:alpha:], [:alnum:], etc.)
+POSIX.2-style globbing equivalence classes
+POSIX.2-style globbing collating symbols
+the ksh [[...]] extended conditional command
+the ksh egrep-style extended pattern matching operators
+a new `printf' builtin
+the ksh-like $(<filename) command substitution, which is equivalent to
+       $(cat filename)
+new tilde prefixes that expand to directories from the directory stack
+new `**' arithmetic operator to do exponentiation
+case-insensitive globbing (filename expansion)
+menu completion a la tcsh
+`magic-space' history expansion function like tcsh
+the readline inputrc `language' has a new file inclusion directive ($include)
+
+Bash-2.01 contained only a few new features:
+
+new `GROUPS' builtin array variable containing the user's group list
+new bindable readline commands: history-and-alias-expand-line and
+       alias-expand-line
+
+Bash-2.0 contained extensive changes and new features from bash-1.14.7.
+Here's a short list:
+
+new `time' reserved word to time pipelines, shell builtins, and
+       shell functions
+one-dimensional arrays with a new compound assignment statement,
+        appropriate expansion constructs and modifications to some
+       of the builtins (read, declare, etc.) to use them
+new quoting syntaxes for ANSI-C string expansion and locale-specific
+       string translation
+new expansions to do substring extraction, pattern replacement, and
+       indirect variable expansion
+new builtins: `disown' and `shopt'
+new variables: HISTIGNORE, SHELLOPTS, PIPESTATUS, DIRSTACK, GLOBIGNORE,
+              MACHTYPE, BASH_VERSINFO
+special handling of many unused or redundant variables removed
+       (e.g., $notify, $glob_dot_filenames, $no_exit_on_failed_exec)
+dynamic loading of new builtin commands; many loadable examples provided
+new prompt expansions: \a, \e, \n, \H, \T, \@, \v, \V
+history and aliases available in shell scripts
+new readline variables: enable-keypad, mark-directories, input-meta,
+       visible-stats, disable-completion, comment-begin
+new readline commands to manipulate the mark and operate on the region
+new readline emacs mode commands and bindings for ksh-88 compatibility
+updated and extended builtins
+new DEBUG trap
+expanded (and now documented) restricted shell mode
+
+implementation stuff:  
+autoconf-based configuration
+nearly all of the bugs reported since version 1.14 have been fixed
+most builtins converted to use builtin `getopt' for consistency
+most builtins use -p option to display output in a reusable form
+       (for consistency)
+grammar tighter and smaller (66 reduce-reduce conflicts gone)
+lots of code now smaller and faster
+test suite greatly expanded
+
+B2) Are there any user-visible incompatibilities between bash-2.05b and
+    bash-1.14.7?
+
+There are a few incompatibilities between version 1.14.7 and version 2.05b.
+They are detailed in the file COMPAT in the bash distribution.  That file
+is not meant to be all-encompassing; send mail to bash-maintainers@gnu.org
+if if you find something that's not mentioned there.
+
+Section C:  Differences from other Unix shells
+
+C1) How does bash differ from sh, the Bourne shell?
+
+This is a non-comprehensive list of features that differentiate bash
+from the SVR4.2 shell.  The bash manual page explains these more
+completely.
+
+Things bash has that sh does not:
+       long invocation options
+       [+-]O invocation option
+       -l invocation option
+       `!' reserved word to invert pipeline return value
+       `time' reserved word to time pipelines and shell builtins
+       the `function' reserved word
+       the `select' compound command and reserved word
+       arithmetic for command: for ((expr1 ; expr2; expr3 )); do list; done
+       new $'...' and $"..." quoting
+       the $(...) form of command substitution
+       the $(<filename) form of command substitution, equivalent to
+               $(cat filename)
+       the ${#param} parameter value length operator
+       the ${!param} indirect parameter expansion operator
+       the ${!param*} prefix expansion operator
+       the ${param:offset[:length]} parameter substring operator
+       the ${param/pat[/string]} parameter pattern substitution operator
+       expansions to perform substring removal (${p%[%]w}, ${p#[#]w})
+       expansion of positional parameters beyond $9 with ${num}
+       variables: BASH, BASH_VERSION, BASH_VERSINFO, UID, EUID, REPLY,
+                  TIMEFORMAT, PPID, PWD, OLDPWD, SHLVL, RANDOM, SECONDS,
+                  LINENO, HISTCMD, HOSTTYPE, OSTYPE, MACHTYPE, HOSTNAME,
+                  ENV, PS3, PS4, DIRSTACK, PIPESTATUS, HISTSIZE, HISTFILE,
+                  HISTFILESIZE, HISTCONTROL, HISTIGNORE, GLOBIGNORE, GROUPS,
+                  PROMPT_COMMAND, FCEDIT, FIGNORE, IGNOREEOF, INPUTRC,
+                  SHELLOPTS, OPTERR, HOSTFILE, TMOUT, FUNCNAME, histchars,
+                  auto_resume
+       DEBUG trap
+       ERR trap
+       variable arrays with new compound assignment syntax
+       redirections: <>, &>, >|, <<<, [n]<&word-, [n]>&word-
+       prompt string special char translation and variable expansion
+       auto-export of variables in initial environment
+       command search finds functions before builtins
+       bash return builtin will exit a file sourced with `.'
+       builtins: cd -/-L/-P, exec -l/-c/-a, echo -e/-E, hash -d/-l/-p/-t.
+                 export -n/-f/-p/name=value, pwd -L/-P,
+                 read -e/-p/-a/-t/-n/-d/-s/-u,
+                 readonly -a/-f/name=value, trap -l, set +o,
+                 set -b/-m/-o option/-h/-p/-B/-C/-H/-P,
+                 unset -f/-v, ulimit -m/-p/-u,
+                 type -a/-p/-t/-f/-P, suspend -f, kill -n,
+                 test -o optname/s1 == s2/s1 < s2/s1 > s2/-nt/-ot/-ef/-O/-G/-S
+       bash reads ~/.bashrc for interactive shells, $ENV for non-interactive
+       bash restricted shell mode is more extensive
+       bash allows functions and variables with the same name
+       brace expansion
+       tilde expansion
+       arithmetic expansion with $((...)) and `let' builtin
+       the `[[...]]' extended conditional command
+       process substitution
+       aliases and alias/unalias builtins
+       local variables in functions and `local' builtin
+       readline and command-line editing with programmable completion
+       command history and history/fc builtins
+       csh-like history expansion
+       other new bash builtins: bind, command, compgen, complete, builtin,
+                                declare/typeset, dirs, enable, fc, help,
+                                history, logout, popd, pushd, disown, shopt,
+                                printf
+       exported functions
+       filename generation when using output redirection (command >a*)
+       POSIX.2-style globbing character classes
+       POSIX.2-style globbing equivalence classes
+       POSIX.2-style globbing collating symbols
+       egrep-like extended pattern matching operators
+       case-insensitive pattern matching and globbing
+       variable assignments preceding commands affect only that command,
+               even for builtins and functions
+       posix mode
+       redirection to /dev/fd/N, /dev/stdin, /dev/stdout, /dev/stderr,
+               /dev/tcp/host/port, /dev/udp/host/port
+
+Things sh has that bash does not:
+       uses variable SHACCT to do shell accounting
+       includes `stop' builtin (bash can use alias stop='kill -s STOP')
+       `newgrp' builtin
+       turns on job control if called as `jsh'
+       $TIMEOUT (like bash $TMOUT)
+       `^' is a synonym for `|'
+       new SVR4.2 sh builtins: mldmode, priv
+
+Implementation differences:
+       redirection to/from compound commands causes sh to create a subshell
+       bash does not allow unbalanced quotes; sh silently inserts them at EOF
+       bash does not mess with signal 11
+       sh sets (euid, egid) to (uid, gid) if -p not supplied and uid < 100
+       bash splits only the results of expansions on IFS, using POSIX.2
+               field splitting rules; sh splits all words on IFS
+       sh does not allow MAILCHECK to be unset (?)
+       sh does not allow traps on SIGALRM or SIGCHLD
+       bash allows multiple option arguments when invoked (e.g. -x -v);
+               sh allows only a single option argument (`sh -x -v' attempts
+               to open a file named `-v', and, on SunOS 4.1.4, dumps core.
+               On Solaris 2.4 and earlier versions, sh goes into an infinite
+               loop.)
+       sh exits a script if any builtin fails; bash exits only if one of
+               the POSIX.2 `special' builtins fails
+
+C2)  How does bash differ from the Korn shell, version ksh88?
+
+Things bash has or uses that ksh88 does not:
+       long invocation options
+       [-+]O invocation option
+       -l invocation option
+       `!' reserved word
+       arithmetic for command: for ((expr1 ; expr2; expr3 )); do list; done
+       arithmetic in largest machine-supported size (intmax_t)
+       posix mode and posix conformance
+       command hashing
+       tilde expansion for assignment statements that look like $PATH
+       process substitution with named pipes if /dev/fd is not available
+       the ${!param} indirect parameter expansion operator
+       the ${!param*} prefix expansion operator
+       the ${param:offset[:length]} parameter substring operator
+       the ${param/pat[/string]} parameter pattern substitution operator
+       variables: BASH, BASH_VERSION, BASH_VERSINFO, UID, EUID, SHLVL,
+                  TIMEFORMAT, HISTCMD, HOSTTYPE, OSTYPE, MACHTYPE,
+                  HISTFILESIZE, HISTIGNORE, HISTCONTROL, PROMPT_COMMAND,
+                  IGNOREEOF, FIGNORE, INPUTRC, HOSTFILE, DIRSTACK,
+                  PIPESTATUS, HOSTNAME, OPTERR, SHELLOPTS, GLOBIGNORE,
+                  GROUPS, FUNCNAME, histchars, auto_resume
+       prompt expansion with backslash escapes and command substitution
+       redirection: &> (stdout and stderr), <<<, [n]<&word-, [n]>&word-
+       more extensive and extensible editing and programmable completion
+       builtins: bind, builtin, command, declare, dirs, echo -e/-E, enable,
+                 exec -l/-c/-a, fc -s, export -n/-f/-p, hash, help, history,
+                 jobs -x/-r/-s, kill -s/-n/-l, local, logout, popd, pushd,
+                 read -e/-p/-a/-t/-n/-d/-s, readonly -a/-n/-f/-p,
+                 set -o braceexpand/-o histexpand/-o interactive-comments/
+                 -o notify/-o physical/-o posix/-o hashall/-o onecmd/
+                 -h/-B/-C/-b/-H/-P, set +o, suspend, trap -l, type,
+                 typeset -a/-F/-p, ulimit -u, umask -S, alias -p, shopt,
+                 disown, printf, complete, compgen
+       `!' csh-style history expansion
+       POSIX.2-style globbing character classes
+       POSIX.2-style globbing equivalence classes
+       POSIX.2-style globbing collating symbols
+       egrep-like extended pattern matching operators
+       case-insensitive pattern matching and globbing
+       `**' arithmetic operator to do exponentiation
+       redirection to /dev/fd/N, /dev/stdin, /dev/stdout, /dev/stderr
+       arrays of unlimited size
+       TMOUT is default timeout for `read' and `select'
+
+Things ksh88 has or uses that bash does not:
+       tracked aliases (alias -t)
+       variables: ERRNO, FPATH, EDITOR, VISUAL
+       co-processes (|&, >&p, <&p)
+       weirdly-scoped functions
+       typeset +f to list all function names without definitions
+       text of command history kept in a file, not memory
+       builtins: alias -x, cd old new, fc -e -, newgrp, print,
+                 read -p/-s/var?prompt, set -A/-o gmacs/
+                 -o bgnice/-o markdirs/-o nolog/-o trackall/-o viraw/-s,
+                 typeset -H/-L/-R/-Z/-A/-ft/-fu/-fx/-l/-u/-t, whence
+       using environment to pass attributes of exported variables
+       arithmetic evaluation done on arguments to some builtins
+       reads .profile from $PWD when invoked as login shell
+
+Implementation differences:
+       ksh runs last command of a pipeline in parent shell context
+       bash has brace expansion by default (ksh88 compile-time option)
+       bash has fixed startup file for all interactive shells; ksh reads $ENV
+       bash has exported functions
+       bash command search finds functions before builtins
+       bash waits for all commands in pipeline to exit before returning status
+       emacs-mode editing has some slightly different key bindings
+
+C3)  Which new features in ksh-93 are not in bash, and which are?
+
+New things in ksh-93 not in bash-2.05b:
+       associative arrays
+       floating point arithmetic and variables
+       math library functions
+       ${!name[sub]} name of subscript for associative array
+       `.' is allowed in variable names to create a hierarchical namespace
+       more extensive compound assignment syntax
+       discipline functions
+       `sleep' and `getconf' builtins (bash has loadable versions)
+       typeset -n and `nameref' variables
+       KEYBD trap
+       variables: .sh.edchar, .sh.edmode, .sh.edcol, .sh.edtext, .sh.version,
+                  .sh.name, .sh.subscript, .sh.value, .sh.match, HISTEDIT
+       backreferences in pattern matching (\N)
+       `&' operator in pattern lists for matching
+       print -f (bash uses printf)
+       `fc' has been renamed to `hist'
+       `.' can execute shell functions
+       exit statuses between 0 and 255
+       set -o pipefail
+       `+=' variable assignment operator
+       FPATH and PATH mixing
+       getopts -a
+       -I invocation option
+       DEBUG trap now executed before each simple command, instead of after
+       printf %H, %P, %T, %Z modifiers, output base for %d
+       lexical scoping for local variables in `ksh' functions
+       no scoping for local variables in `POSIX' functions
+
+New things in ksh-93 present in bash-2.05b:
+       [n]<&word- and [n]>&word- redirections (combination dup and close)
+        for (( expr1; expr2; expr3 )) ; do list; done - arithmetic for command
+        ?:, ++, --, `expr1 , expr2' arithmetic operators
+       expansions: ${!param}, ${param:offset[:len]}, ${param/pat[/str]},
+                   ${!param*}
+       compound array assignment
+       the `!' reserved word
+       loadable builtins -- but ksh uses `builtin' while bash uses `enable'
+       `command', `builtin', `disown' builtins
+       new $'...' and $"..." quoting
+       FIGNORE (but bash uses GLOBIGNORE), HISTCMD
+       set -o notify/-C
+       changes to kill builtin
+       read -A (bash uses read -a)
+        read -t/-d
+       trap -p
+       exec -c/-a
+       `.' restores the positional parameters when it completes
+       POSIX.2 `test'
+       umask -S
+       unalias -a
+       command and arithmetic substitution performed on PS1, PS4, and ENV
+       command name completion
+       ENV processed only for interactive shells
+
+Section D:  Why does bash do some things differently than other Unix shells?
+
+D1) Why does bash run a different version of `command' than
+    `which command' says it will?
+
+On many systems, `which' is actually a csh script that assumes
+you're running csh.  In tcsh, `which' and its cousin `where'
+are builtins.  On other Unix systems, `which' is a perl script
+that uses the PATH environment variable.
+
+The csh script version reads the csh startup files from your
+home directory and uses those to determine which `command' will
+be invoked.  Since bash doesn't use any of those startup files,
+there's a good chance that your bash environment differs from
+your csh environment.  The bash `type' builtin does everything
+`which' does, and will report correct results for the running
+shell.  If you're really wedded to the name `which', try adding
+the following function definition to your .bashrc:
+
+       which()
+       {
+               builtin type "$@"
+       }
+
+If you're moving from tcsh and would like to bring `where' along
+as well, use this function:
+
+       where()
+       {
+               builtin type -a "$@"
+       }
+
+D2) Why doesn't bash treat brace expansions exactly like csh?
+
+The only difference between bash and csh brace expansion is that
+bash requires a brace expression to contain at least one unquoted
+comma if it is to be expanded.  Any brace-surrounded word not
+containing an unquoted comma is left unchanged by the brace
+expansion code.  This affords the greatest degree of sh
+compatibility. 
+
+Bash, ksh, zsh, and pd-ksh all implement brace expansion this way. 
+
+D3) Why doesn't bash have csh variable modifiers?
+
+Posix has specified a more powerful, albeit somewhat more cryptic,
+mechanism cribbed from ksh, and bash implements it.
+
+${parameter%word}
+        Remove smallest suffix pattern.  The WORD is expanded to produce
+        a pattern.  It then expands to the value of PARAMETER, with the
+        smallest portion of the suffix matched by the pattern deleted.
+
+        x=file.c
+        echo ${x%.c}.o
+        -->file.o
+
+${parameter%%word}
+
+        Remove largest suffix pattern.  The WORD is expanded to produce
+        a pattern.  It then expands to the value of PARAMETER, with the
+        largest portion of the suffix matched by the pattern deleted.
+
+        x=posix/src/std
+        echo ${x%%/*}
+        -->posix
+
+${parameter#word}
+        Remove smallest prefix pattern.  The WORD is expanded to produce
+        a pattern.  It then expands to the value of PARAMETER, with the
+        smallest portion of the prefix matched by the pattern deleted.
+
+        x=$HOME/src/cmd
+        echo ${x#$HOME}
+        -->/src/cmd
+
+${parameter##word}
+        Remove largest prefix pattern.  The WORD is expanded to produce
+        a pattern.  It then expands to the value of PARAMETER, with the
+        largest portion of the prefix matched by the pattern deleted.
+
+        x=/one/two/three
+        echo ${x##*/}
+        -->three
+
+
+Given
+       a=/a/b/c/d
+       b=b.xxx
+
+       csh                     bash            result
+       ---                     ----            ------
+       $a:h                    ${a%/*}            /a/b/c
+       $a:t                    ${a##*/}           d
+       $b:r                    ${b%.*}            b
+       $b:e                    ${b##*.}           xxx
+
+
+D4) How can I make my csh aliases work when I convert to bash?
+
+Bash uses a different syntax to support aliases than csh does. 
+The details can be found in the documentation.  We have provided
+a shell script which does most of the work of conversion for you;
+this script can be found in ./examples/misc/aliasconv.sh.  Here is
+how you use it:
+  
+Start csh in the normal way for you.  (e.g., `csh')
+  
+Pipe the output of `alias' through `aliasconv.sh', saving the
+results into `bash_aliases':
+  
+       alias | bash aliasconv.sh >bash_aliases
+  
+Edit `bash_aliases', carefully reading through any created
+functions.  You will need to change the names of some csh specific
+variables to the bash equivalents.  The script converts $cwd to
+$PWD, $term to $TERM, $home to $HOME, $user to $USER, and $prompt
+to $PS1.  You may also have to add quotes to avoid unwanted
+expansion.
+
+For example, the csh alias:
+  
+       alias cd 'cd \!*; echo $cwd'
+  
+is converted to the bash function:
+
+       cd () { command cd "$@"; echo $PWD ; }
+
+The only thing that needs to be done is to quote $PWD:
+  
+       cd () { command cd "$@"; echo "$PWD" ; }
+  
+Merge the edited file into your ~/.bashrc.
+
+There is an additional, more ambitious, script in
+examples/misc/cshtobash that attempts to convert your entire csh
+environment to its bash equivalent.  This script can be run as
+simply `cshtobash' to convert your normal interactive
+environment, or as `cshtobash ~/.login' to convert your login
+environment. 
+
+D5) How can I pipe standard output and standard error from one command to
+    another, like csh does with `|&'?
+
+Use
+       command 2>&1 | command2
+
+The key is to remember that piping is performed before redirection, so
+file descriptor 1 points to the pipe when it is duplicated onto file
+descriptor 2.
+
+D6) Now that I've converted from ksh to bash, are there equivalents to
+    ksh features like autoloaded functions and the `whence' command?
+
+There are features in ksh-88 and ksh-93 that do not have direct bash
+equivalents.  Most, however, can be emulated with very little trouble.
+
+ksh-88 feature         Bash equivalent
+--------------         ---------------
+compiled-in aliases    set up aliases in .bashrc; some ksh aliases are
+                       bash builtins (hash, history, type)
+coprocesses            named pipe pairs (one for read, one for write)
+typeset +f             declare -F
+cd, print, whence      function substitutes in examples/functions/kshenv
+autoloaded functions   examples/functions/autoload is the same as typeset -fu
+read var?prompt                read -p prompt var
+
+ksh-93 feature         Bash equivalent
+--------------         ---------------
+sleep, getconf         Bash has loadable versions in examples/loadables
+${.sh.version}         $BASH_VERSION
+print -f               printf
+hist                   alias hist=fc
+$HISTEDIT              $FCEDIT
+
+Section E:  How can I get bash to do certain things, and why does bash do
+           things the way it does?
+
+E1) Why is the bash builtin `test' slightly different from /bin/test?
+
+The specific example used here is [ ! x -o x ], which is false.
+
+Bash's builtin `test' implements the Posix.2 spec, which can be
+summarized as follows (the wording is due to David Korn):
+   
+Here is the set of rules for processing test arguments.
+  
+    0 Args: False
+    1 Arg:  True iff argument is not null.
+    2 Args: If first arg is !, True iff second argument is null.
+           If first argument is unary, then true if unary test is true
+           Otherwise error.
+    3 Args: If second argument is a binary operator, do binary test of $1 $3
+           If first argument is !, negate two argument test of $2 $3
+           If first argument is `(' and third argument is `)', do the
+           one-argument test of the second argument.
+           Otherwise error.
+    4 Args: If first argument is !, negate three argument test of $2 $3 $4.
+           Otherwise unspecified
+    5 or more Args: unspecified.  (Historical shells would use their
+    current algorithm).
+   
+The operators -a and -o are considered binary operators for the purpose
+of the 3 Arg case.
+   
+As you can see, the test becomes (not (x or x)), which is false.
+
+E2) Why does bash sometimes say `Broken pipe'?
+
+If a sequence of commands appears in a pipeline, and one of the
+reading commands finishes before the writer has finished, the
+writer receives a SIGPIPE signal.  Many other shells special-case
+SIGPIPE as an exit status in the pipeline and do not report it. 
+For example, in:
+  
+      ps -aux | head
+  
+`head' can finish before `ps' writes all of its output, and ps
+will try to write on a pipe without a reader.  In that case, bash
+will print `Broken pipe' to stderr when ps is killed by a
+SIGPIPE. 
+
+You can build a version of bash that will not report SIGPIPE errors
+by uncommenting the definition of DONT_REPORT_SIGPIPE in the file
+config-top.h.
+
+E3) When I have terminal escape sequences in my prompt, why does bash
+    wrap lines at the wrong column?
+
+Readline, the line editing library that bash uses, does not know
+that the terminal escape sequences do not take up space on the
+screen.  The redisplay code assumes, unless told otherwise, that
+each character in the prompt is a `printable' character that
+takes up one character position on the screen. 
+
+You can use the bash prompt expansion facility (see the PROMPTING
+section in the manual page) to tell readline that sequences of
+characters in the prompt strings take up no screen space. 
+
+Use the \[ escape to begin a sequence of non-printing characters,
+and the \] escape to signal the end of such a sequence. 
+
+E4) If I pipe the output of a command into `read variable', why doesn't
+    the output show up in $variable when the read command finishes?
+
+This has to do with the parent-child relationship between Unix
+processes.  It affects all commands run in pipelines, not just
+simple calls to `read'.  For example, piping a command's output
+into a `while' loop that repeatedly calls `read' will result in
+the same behavior.
+
+Each element of a pipeline runs in a separate process, a child of
+the shell running the pipeline.  A subprocess cannot affect its
+parent's environment.  When the `read' command sets the variable
+to the input, that variable is set only in the subshell, not the
+parent shell.  When the subshell exits, the value of the variable
+is lost. 
+
+Many pipelines that end with `read variable' can be converted
+into command substitutions, which will capture the output of
+a specified command.  The output can then be assigned to a
+variable:
+
+       grep ^gnu /usr/lib/news/active | wc -l | read ngroup
+
+can be converted into
+
+       ngroup=$(grep ^gnu /usr/lib/news/active | wc -l)
+
+This does not, unfortunately, work to split the text among
+multiple variables, as read does when given multiple variable
+arguments.  If you need to do this, you can either use the
+command substitution above to read the output into a variable
+and chop up the variable using the bash pattern removal
+expansion operators or use some variant of the following
+approach.
+
+Say /usr/local/bin/ipaddr is the following shell script:
+
+#! /bin/sh
+host `hostname` | awk '/address/ {print $NF}'
+
+Instead of using
+
+       /usr/local/bin/ipaddr | read A B C D
+
+to break the local machine's IP address into separate octets, use
+
+       OIFS="$IFS"
+       IFS=.
+       set -- $(/usr/local/bin/ipaddr)
+       IFS="$OIFS"
+       A="$1" B="$2" C="$3" D="$4"
+
+Beware, however, that this will change the shell's positional
+parameters.  If you need them, you should save them before doing
+this.
+
+This is the general approach -- in most cases you will not need to
+set $IFS to a different value.
+
+Some other user-supplied alternatives include:
+
+read A B C D << HERE
+    $(IFS=.; echo $(/usr/local/bin/ipaddr))
+HERE
+
+and, where process substitution is available,
+
+read A B C D < <(IFS=.; echo $(/usr/local/bin/ipaddr))
+
+E5) I have a bunch of shell scripts that use backslash-escaped characters
+    in arguments to `echo'.  Bash doesn't interpret these characters.  Why
+    not, and how can I make it understand them?
+
+This is the behavior of echo on most Unix System V machines.
+
+The bash builtin `echo' is modeled after the 9th Edition
+Research Unix version of `echo'.  It does not interpret
+backslash-escaped characters in its argument strings by default;
+it requires the use of the -e option to enable the
+interpretation.  The System V echo provides no way to disable the
+special characters; the bash echo has a -E option to disable
+them. 
+
+There is a configuration option that will make bash behave like
+the System V echo and interpret things like `\t' by default.  Run
+configure with the --enable-xpg-echo-default option to turn this
+on.  Be aware that this will cause some of the tests run when you
+type `make tests' to fail.
+
+There is a shell option, `xpg_echo', settable with `shopt', that will
+change the behavior of echo at runtime.  Enabling this option turns
+on expansion of backslash-escape sequences.
+
+E6) Why doesn't a while or for loop get suspended when I type ^Z?
+
+This is a consequence of how job control works on Unix.  The only
+thing that can be suspended is the process group.  This is a single
+command or pipeline of commands that the shell forks and executes.
+
+When you run a while or for loop, the only thing that the shell forks
+and executes are any commands in the while loop test and commands in
+the loop bodies.  These, therefore, are the only things that can be
+suspended when you type ^Z.
+
+If you want to be able to stop the entire loop, you need to put it
+within parentheses, which will force the loop into a subshell that
+may be stopped (and subsequently restarted) as a single unit.
+
+E7) What about empty for loops in Makefiles?
+
+It's fairly common to see constructs like this in automatically-generated
+Makefiles:
+
+SUBDIRS = @SUBDIRS@
+
+       ...
+
+subdirs-clean:
+       for d in ${SUBDIRS}; do \
+               ( cd $$d && ${MAKE} ${MFLAGS} clean ) \
+       done
+
+When SUBDIRS is empty, this results in a command like this being passed to
+bash:
+
+       for d in ; do
+               ( cd $d && ${MAKE} ${MFLAGS} clean )
+       done
+
+In versions of bash before bash-2.05a, this was a syntax error.  If the
+reserved word `in' was present, a word must follow it before the semicolon
+or newline.  The language in the manual page referring to the list of words
+being empty referred to the list after it is expanded.  These versions of
+bash required that there be at least one word following the `in' when the
+construct was parsed.
+
+The idiomatic Makefile solution is something like:
+
+SUBDIRS = @SUBDIRS@
+
+subdirs-clean:
+       subdirs=$SUBDIRS ; for d in $$subdirs; do \
+               ( cd $$d && ${MAKE} ${MFLAGS} clean ) \
+       done
+
+The latest drafts of the updated POSIX standard have changed this:  the
+word list is no longer required.  Bash versions 2.05a and later accept
+the new syntax.
+
+E8) Why does the arithmetic evaluation code complain about `08'?
+
+The bash arithmetic evaluation code (used for `let', $(()), (()), and in
+other places), interprets a leading `0' in numeric constants as denoting
+an octal number, and a leading `0x' as denoting hexadecimal.  This is
+in accordance with the POSIX.2 spec, section 2.9.2.1, which states that
+arithmetic constants should be handled as signed long integers as defined
+by the ANSI/ISO C standard.
+
+The POSIX.2 interpretation committee has confirmed this:
+
+http://www.pasc.org/interps/unofficial/db/p1003.2/pasc-1003.2-173.html
+
+E9) Why does the pattern matching expression [A-Z]* match files beginning
+    with every letter except `z'?
+
+Bash-2.03, Bash-2.05 and later versions honor the current locale setting
+when processing ranges within pattern matching bracket expressions ([A-Z]). 
+This is what POSIX.2 and SUSv3/XPG6 specify. 
+
+The behavior of the matcher in bash-2.05 and later versions depends on the
+current LC_COLLATE setting.  Setting this variable to `C' or `POSIX' will
+result in the traditional behavior ([A-Z] matches all uppercase ASCII
+characters).  Many other locales, including the en_US locale (the default
+on many US versions of Linux) collate the upper and lower case letters like
+this:
+
+       AaBb...Zz
+
+which means that [A-Z] matches every letter except `z'.  Others collate like
+
+       aAbBcC...zZ
+
+which means that [A-Z] matches every letter except `a'.
+
+The portable way to specify upper case letters is [:upper:] instead of
+A-Z; lower case may be specified as [:lower:] instead of a-z.
+
+Look at the manual pages for setlocale(3), strcoll(3), and, if it is
+present, locale(1).  If you have locale(1), you can use it to find
+your current locale information even if you do not have any of the
+LC_ variables set.
+
+My advice is to put
+
+       export LC_COLLATE=C
+
+into /etc/profile and inspect any shell scripts run from cron for
+constructs like [A-Z].  This will prevent things like
+
+       rm [A-Z]*
+
+from removing every file in the current directory except those beginning
+with `z' and still allow individual users to change the collation order.
+Users may put the above command into their own profiles as well, of course.
+
+E10) Why does `cd //' leave $PWD as `//'?
+
+POSIX.2, in its description of `cd', says that *three* or more leading
+slashes may be replaced with a single slash when canonicalizing the
+current working directory.
+
+This is, I presume, for historical compatibility.  Certain versions of
+Unix, and early network file systems, used paths of the form
+//hostname/path to access `path' on server `hostname'.
+
+E11) If I resize my xterm while another program is running, why doesn't bash
+     notice the change?
+
+This is another issue that deals with job control.
+
+The kernel maintains a notion of a current terminal process group.  Members
+of this process group (processes whose process group ID is equal to the
+current terminal process group ID) receive terminal-generated signals like
+SIGWINCH.  (For more details, see the JOB CONTROL section of the bash
+man page.)
+
+If a terminal is resized, the kernel sends SIGWINCH to each member of
+the terminal's current process group (the `foreground' process group).
+
+When bash is running with job control enabled, each pipeline (which may be
+a single command) is run in its own process group, different from bash's
+process group.  This foreground process group receives the SIGWINCH; bash
+does not.  Bash has no way of knowing that the terminal has been resized.
+
+There is a `checkwinsize' option, settable with the `shopt' builtin, that
+will cause bash to check the window size and adjust its idea of the
+terminal's dimensions each time a process stops or exits and returns control
+of the terminal to bash.  Enable it with `shopt -s checkwinsize'.
+
+Section F:  Things to watch out for on certain Unix versions
+
+F1) Why can't I use command line editing in my `cmdtool'?
+
+The problem is `cmdtool' and bash fighting over the input.  When
+scrolling is enabled in a cmdtool window, cmdtool puts the tty in
+`raw mode' to permit command-line editing using the mouse for
+applications that cannot do it themselves.  As a result, bash and
+cmdtool each try to read keyboard input immediately, with neither
+getting enough of it to be useful.
+
+This mode also causes cmdtool to not implement many of the
+terminal functions and control sequences appearing in the
+`sun-cmd' termcap entry.  For a more complete explanation, see
+that file examples/suncmd.termcap in the bash distribution. 
+
+`xterm' is a better choice, and gets along with bash much more
+smoothly.
+
+If you must use cmdtool, you can use the termcap description in
+examples/suncmd.termcap.  Set the TERMCAP variable to the terminal
+description contained in that file, i.e.
+
+TERMCAP='Mu|sun-cmd:am:bs:km:pt:li#34:co#80:cl=^L:ce=\E[K:cd=\E[J:rs=\E[s:'
+
+Then export TERMCAP and start a new cmdtool window from that shell.
+The bash command-line editing should behave better in the new
+cmdtool.  If this works, you can put the assignment to TERMCAP
+in your bashrc file.
+
+F2) I built bash on Solaris 2.  Why do globbing expansions and filename
+    completion chop off the first few characters of each filename?
+
+This is the consequence of building bash on SunOS 5 and linking
+with the libraries in /usr/ucblib, but using the definitions
+and structures from files in /usr/include. 
+
+The actual conflict is between the dirent structure in
+/usr/include/dirent.h and the struct returned by the version of
+`readdir' in libucb.a (a 4.3-BSD style `struct direct'). 
+
+Make sure you've got /usr/ccs/bin ahead of /usr/ucb in your $PATH
+when configuring and building bash.  This will ensure that you
+use /usr/ccs/bin/cc or acc instead of /usr/ucb/cc and that you
+link with libc before libucb. 
+
+If you have installed the Sun C compiler, you may also need to
+put /usr/ccs/bin and /opt/SUNWspro/bin into your $PATH before
+/usr/ucb.
+
+F3) Why does bash dump core after I interrupt username completion or
+    `~user' tilde expansion on a machine running NIS?
+
+This is a famous and long-standing bug in the SunOS YP (sorry, NIS)
+client library, which is part of libc.
+
+The YP library code keeps static state -- a pointer into the data
+returned from the server.  When YP initializes itself (setpwent),
+it looks at this pointer and calls free on it if it's non-null. 
+So far, so good. 
+
+If one of the YP functions is interrupted during getpwent (the
+exact function is interpretwithsave()), and returns NULL, the
+pointer is freed without being reset to NULL, and the function
+returns.  The next time getpwent is called, it sees that this
+pointer is non-null, calls free, and the bash free() blows up
+because it's being asked to free freed memory. 
+
+The traditional Unix mallocs allow memory to be freed multiple
+times; that's probably why this has never been fixed.  You can
+run configure with the `--without-gnu-malloc' option to use
+the C library malloc and avoid the problem.
+
+F4) I'm running SVR4.2.  Why is the line erased every time I type `@'?
+
+The `@' character is the default `line kill' character in most
+versions of System V, including SVR4.2.  You can change this
+character to whatever you want using `stty'.  For example, to
+change the line kill character to control-u, type
+
+       stty kill ^U
+
+where the `^' and `U' can be two separate characters.
+
+F5) Why does bash report syntax errors when my C News scripts use a
+    redirection before a subshell command?
+
+The actual command in question is something like
+
+       < file ( command )
+
+According to the grammar given in the POSIX.2 standard, this construct
+is, in fact, a syntax error.  Redirections may only precede `simple
+commands'.  A subshell construct such as the above is one of the shell's
+`compound commands'.  A redirection may only follow a compound command.
+
+This affects the mechanical transformation of commands that use `cat'
+to pipe a file into a command (a favorite Useless-Use-Of-Cat topic on
+comp.unix.shell).  While most commands of the form
+
+       cat file | command
+
+can be converted to `< file command', shell control structures such as
+loops and subshells require `command < file'.
+
+The file CWRU/sh-redir-hack in the bash-2.05a distribution is an
+(unofficial) patch to parse.y that will modify the grammar to
+support this construct.  It will not apply with `patch'; you must
+modify parse.y by hand.  Note that if you apply this, you must
+recompile with -DREDIRECTION_HACK.  This introduces a large
+number of reduce/reduce conflicts into the shell grammar. 
+
+F6) Why can't I use vi-mode editing on Red Hat Linux 6.1?
+
+The short answer is that Red Hat screwed up.
+
+The long answer is that they shipped an /etc/inputrc that only works
+for emacs mode editing, and then screwed all the vi users by setting
+INPUTRC to /etc/inputrc in /etc/profile.
+
+The short fix is to do one of the following: remove or rename
+/etc/inputrc, set INPUTRC=~/.inputrc in ~/.bashrc (or .bash_profile,
+but make sure you export it if you do), remove the assignment to
+INPUTRC from /etc/profile, add
+
+        set keymap emacs
+
+to the beginning of /etc/inputrc, or bracket the key bindings in
+/etc/inputrc with these lines
+
+       $if mode=emacs
+               [...]
+       $endif
+
+F7) Why do bash-2.05a and bash-2.05b fail to compile `printf.def' on
+    HP/UX 11.x?
+
+HP/UX's support for long double is imperfect at best.
+
+GCC will support it without problems, but the HP C library functions
+like strtold(3) and printf(3) don't actually work with long doubles.
+HP implemented a `long_double' type as a 4-element array of 32-bit
+ints, and that is what the library functions use.  The ANSI C
+`long double' type is a 128-bit floating point scalar.
+
+The easiest fix, until HP fixes things up, is to edit the generated
+config.h and #undef the HAVE_LONG_DOUBLE line.  After doing that,
+the compilation should complete successfully.
+
+Section G:  How can I get bash to do certain common things?
+
+G1) How can I get bash to read and display eight-bit characters?
+
+This is a process requiring several steps.
+
+First, you must ensure that the `physical' data path is a full eight
+bits.  For xterms, for example, the `vt100' resources `eightBitInput'
+and `eightBitOutput' should be set to `true'.
+
+Once you have set up an eight-bit path, you must tell the kernel and
+tty driver to leave the eighth bit of characters alone when processing
+keyboard input.  Use `stty' to do this:
+
+       stty cs8 -istrip -parenb
+
+For old BSD-style systems, you can use
+
+       stty pass8
+
+You may also need
+
+       stty even odd
+
+Finally, you need to tell readline that you will be inputting and
+displaying eight-bit characters.  You use readline variables to do
+this.  These variables can be set in your .inputrc or using the bash
+`bind' builtin.  Here's an example using `bind':
+
+       bash$ bind 'set convert-meta off'
+       bash$ bind 'set meta-flag on'
+       bash$ bind 'set output-meta on'
+
+The `set' commands between the single quotes may also be placed
+in ~/.inputrc.
+
+G2) How do I write a function `x' to replace builtin command `x', but
+    still invoke the command from within the function?
+
+This is why the `command' and `builtin' builtins exist.  The
+`command' builtin executes the command supplied as its first
+argument, skipping over any function defined with that name.  The
+`builtin' builtin executes the builtin command given as its first
+argument directly. 
+
+For example, to write a function to replace `cd' that writes the
+hostname and current directory to an xterm title bar, use
+something like the following:
+
+       cd()
+       {
+               builtin cd "$@" && xtitle "$HOST: $PWD"
+       }
+
+This could also be written using `command' instead of `builtin';
+the version above is marginally more efficient. 
+
+G3) How can I find the value of a shell variable whose name is the value
+    of another shell variable?
+
+Versions of Bash newer than Bash-2.0 support this directly.  You can use 
+
+       ${!var}
+
+For example, the following sequence of commands will echo `z':
+
+       var1=var2
+       var2=z
+       echo ${!var1}
+
+For sh compatibility, use the `eval' builtin.  The important
+thing to remember is that `eval' expands the arguments you give
+it again, so you need to quote the parts of the arguments that
+you want `eval' to act on. 
+
+For example, this expression prints the value of the last positional
+parameter:
+
+       eval echo \"\$\{$#\}\"
+
+The expansion of the quoted portions of this expression will be
+deferred until `eval' runs, while the `$#' will be expanded
+before `eval' is executed.  In versions of bash later than bash-2.0,
+
+       echo ${!#}
+
+does the same thing.
+
+This is not the same thing as ksh93 `nameref' variables, though the syntax
+is similar.  I may add namerefs in a future bash version.
+
+G4) How can I make the bash `time' reserved word print timing output that
+     looks like the output from my system's /usr/bin/time?
+
+The bash command timing code looks for a variable `TIMEFORMAT' and
+uses its value as a format string to decide how to display the
+timing statistics.
+
+The value of TIMEFORMAT is a string with `%' escapes expanded in a
+fashion similar in spirit to printf(3).  The manual page explains
+the meanings of the escape sequences in the format string.
+
+If TIMEFORMAT is not set, bash acts as if the following assignment had
+been performed:
+
+       TIMEFORMAT=$'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS'
+
+The POSIX.2 default time format (used by `time -p command') is
+
+       TIMEFORMAT=$'real %2R\nuser %2U\nsys %2S'
+
+The BSD /usr/bin/time format can be emulated with:
+
+       TIMEFORMAT=$'\t%1R real\t%1U user\t%1S sys'
+
+The System V /usr/bin/time format can be emulated with:
+
+       TIMEFORMAT=$'\nreal\t%1R\nuser\t%1U\nsys\t%1S'
+
+The ksh format can be emulated with:
+
+       TIMEFORMAT=$'\nreal\t%2lR\nuser\t%2lU\nsys\t%2lS'
+
+G5) How do I get the current directory into my prompt?
+
+Bash provides a number of backslash-escape sequences which are expanded
+when the prompt string (PS1 or PS2) is displayed.  The full list is in
+the manual page.
+
+The \w expansion gives the full pathname of the current directory, with
+a tilde (`~') substituted for the current value of $HOME.  The \W
+expansion gives the basename of the current directory.  To put the full
+pathname of the current directory into the path without any tilde
+subsitution, use $PWD.  Here are some examples:
+
+       PS1='\w$ '      # current directory with tilde
+       PS1='\W$ '      # basename of current directory
+       PS1='$PWD$ '    # full pathname of current directory
+
+The single quotes are important in the final example to prevent $PWD from
+being expanded when the assignment to PS1 is performed.
+
+G6) How can I rename "*.foo" to "*.bar"?
+
+Use the pattern removal functionality described in D3.  The following `for'
+loop will do the trick:
+
+       for f in *.foo; do
+               mv $f ${f%foo}bar
+       done
+
+G7) How can I translate a filename from uppercase to lowercase?
+
+The script examples/functions/lowercase, originally written by John DuBois,
+will do the trick.  The converse is left as an exercise.
+
+G8) How can I write a filename expansion (globbing) pattern that will match
+    all files in the current directory except "." and ".."?
+
+You must have set the `extglob' shell option using `shopt -s extglob' to use
+this:
+
+       echo .!(.|) *
+
+A solution that works without extended globbing is given in the Unix Shell
+FAQ, posted periodically to comp.unix.shell.
+
+Section H:  Where do I go from here?
+
+H1) How do I report bugs in bash, and where should I look for fixes and
+    advice?
+
+Use the `bashbug' script to report bugs.  It is built and
+installed at the same time as bash.  It provides a standard
+template for reporting a problem and automatically includes
+information about your configuration and build environment. 
+
+`bashbug' sends its reports to bug-bash@gnu.org, which
+is a large mailing list gatewayed to the usenet newsgroup gnu.bash.bug. 
+
+Bug fixes, answers to questions, and announcements of new releases
+are all posted to gnu.bash.bug.  Discussions concerning bash features
+and problems also take place there.
+
+To reach the bash maintainers directly, send mail to
+bash-maintainers@gnu.org.
+
+H2) What kind of bash documentation is there?
+
+First, look in the doc directory in the bash distribution.  It should
+contain at least the following files:
+
+bash.1         an extensive, thorough Unix-style manual page
+builtins.1     a manual page covering just bash builtin commands
+bashref.texi   a reference manual in GNU tex`info format
+bashref.info   an info version of the reference manual
+FAQ            this file
+article.ms     text of an article written for The Linux Journal
+readline.3     a man page describing readline
+
+Postscript, HTML, and ASCII files created from the above source are
+available in the documentation distribution.
+
+There is additional documentation available for anonymous FTP from host
+ftp.cwru.edu in the `pub/bash' directory.
+
+Cameron Newham and Bill Rosenblatt have written a book on bash, published
+by O'Reilly and Associates.  The book is based on Bill Rosenblatt's Korn
+Shell book.  The title is ``Learning the Bash Shell'', and the ISBN number
+is 1-56592-147-X.  Look for it in fine bookstores near you.  This book
+covers bash-1.14, but has an appendix describing some of the new features
+in bash-2.0.  
+
+A second edition of this book is available, published in January, 1998.
+The ISBN number is 1-56592-347-2.  Look for it in the same fine bookstores
+or on the web.
+
+The GNU Bash Reference Manual has been published as a printed book by
+Network Theory Ltd (Paperback, ISBN: 0-9541617-7-7, Feb 2003).  It covers
+bash-2.0 and is available from most online bookstores (see
+http://www.network-theory.co.uk/bash/manual/ for details).  The publisher
+will donate $1 to the Free Software Foundation for each copy sold. 
+
+H3) What's coming in future versions?
+
+These are features I hope to include in a future version of bash.
+
+a better bash debugger (a minimally-tested version is included with bash-2.05b)
+associative arrays
+co-processes, but with a new-style syntax that looks like function declaration
+
+H4) What's on the bash `wish list' for future versions?
+
+These are features that may or may not appear in a future version of bash.
+
+breaking some of the shell functionality into embeddable libraries
+a module system like zsh's, using dynamic loading like builtins
+better internationalization using GNU `gettext'
+date-stamped command history
+a bash programmer's guide with a chapter on creating loadable builtins
+a better loadable interface to perl with access to the shell builtins and
+       variables (contributions gratefully accepted)
+ksh93-like `nameref' variables
+ksh93-like `+=' variable assignment operator
+ksh93-like `xx.yy' variables (including some of the .sh.* variables) and
+       associated disipline functions
+Some of the new ksh93 pattern matching operators, like backreferencing
+
+H5) When will the next release appear?
+
+The next version will appear sometime in 2002.  Never make predictions. 
+
+
+This document is Copyright 1995-2003 by Chester Ramey.
+
+Permission is hereby granted, without written agreement and
+without license or royalty fees, to use, copy, and distribute
+this document for any purpose, provided that the above copyright
+notice appears in all copies of this document and that the
+contents of this document remain unaltered.
diff --git a/doc/aosa-bash.pdf.old b/doc/aosa-bash.pdf.old
new file mode 100644 (file)
index 0000000..006a767
Binary files /dev/null and b/doc/aosa-bash.pdf.old differ
index b9c4ee993acf169b80cc1952ebf34d473cae7341..06b0f43fb372585dbbd94480d2e290ae6e6f1099 100644 (file)
@@ -1365,94 +1365,97 @@ P\bPA\bAR\bRA\bAM\bME\bET\bTE\bER\bRS\bS
        expansion  of  the  special  parameters *\b* and @\b@ (see S\bSp\bpe\bec\bci\bia\bal\bl P\bPa\bar\bra\bam\bme\bet\bte\ber\brs\bs
        above).  ${#_\bn_\ba_\bm_\be[_\bs_\bu_\bb_\bs_\bc_\br_\bi_\bp_\bt]}  expands  to  the  length  of  ${_\bn_\ba_\bm_\be[_\bs_\bu_\bb_\b-
        _\bs_\bc_\br_\bi_\bp_\bt]}.   If _\bs_\bu_\bb_\bs_\bc_\br_\bi_\bp_\bt is *\b* or @\b@, the expansion is the number of ele-
-       ments in the array.  Referencing an array variable without a  subscript
-       is  equivalent  to referencing the array with a subscript of 0.  If the
-       _\bs_\bu_\bb_\bs_\bc_\br_\bi_\bp_\bt used to reference an element of an indexed array evaluates to
-       a  number  less than zero, it is interpreted as relative to one greater
-       than the maximum index of the array, so  negative  indices  count  back
-       from  the end of the array, and an index of -1 references the last ele-
-       ment.
-
-       An array variable is considered set if a subscript has been assigned  a
+       ments in the array.  If the _\bs_\bu_\bb_\bs_\bc_\br_\bi_\bp_\bt used to reference an  element  of
+       an  indexed  array  evaluates  to a number less than zero, it is inter-
+       preted as relative to one greater than the maximum index of the  array,
+       so  negative indices count back from the end of the array, and an index
+       of -1 references the last element.
+
+       Referencing an array variable without a subscript is equivalent to ref-
+       erencing  the array with a subscript of 0.  Any reference to a variable
+       using a valid subscript is legal, and b\bba\bas\bsh\bh will create an array if nec-
+       essary.
+
+       An  array variable is considered set if a subscript has been assigned a
        value.  The null string is a valid value.
 
-       It  is possible to obtain the keys (indices) of an array as well as the
-       values.  ${!\b!_\bn_\ba_\bm_\be[_\b@]} and ${!\b!_\bn_\ba_\bm_\be[_\b*]} expand to the indices assigned  in
+       It is possible to obtain the keys (indices) of an array as well as  the
+       values.   ${!\b!_\bn_\ba_\bm_\be[_\b@]} and ${!\b!_\bn_\ba_\bm_\be[_\b*]} expand to the indices assigned in
        array variable _\bn_\ba_\bm_\be.  The treatment when in double quotes is similar to
        the expansion of the special parameters _\b@ and _\b* within double quotes.
 
-       The u\bun\bns\bse\bet\bt builtin is used to  destroy  arrays.   u\bun\bns\bse\bet\b _\bn_\ba_\bm_\be[_\bs_\bu_\bb_\bs_\bc_\br_\bi_\bp_\bt]
-       destroys  the array element at index _\bs_\bu_\bb_\bs_\bc_\br_\bi_\bp_\bt.  Negative subscripts to
-       indexed arrays are interpreted as described above.  Care must be  taken
-       to  avoid  unwanted  side  effects caused by pathname expansion.  u\bun\bns\bse\bet\bt
+       The  u\bun\bns\bse\bet\bt  builtin  is  used to destroy arrays.  u\bun\bns\bse\bet\bt _\bn_\ba_\bm_\be[_\bs_\bu_\bb_\bs_\bc_\br_\bi_\bp_\bt]
+       destroys the array element at index _\bs_\bu_\bb_\bs_\bc_\br_\bi_\bp_\bt.  Negative subscripts  to
+       indexed  arrays are interpreted as described above.  Care must be taken
+       to avoid unwanted side effects caused  by  pathname  expansion.   u\bun\bns\bse\bet\bt
        _\bn_\ba_\bm_\be, where _\bn_\ba_\bm_\be is an array, or u\bun\bns\bse\bet\bt _\bn_\ba_\bm_\be[_\bs_\bu_\bb_\bs_\bc_\br_\bi_\bp_\bt], where _\bs_\bu_\bb_\bs_\bc_\br_\bi_\bp_\bt
        is *\b* or @\b@, removes the entire array.
 
-       The  d\bde\bec\bcl\bla\bar\bre\be,  l\blo\boc\bca\bal\bl,  and r\bre\bea\bad\bdo\bon\bnl\bly\by builtins each accept a -\b-a\ba option to
-       specify an indexed array and a -\b-A\bA  option  to  specify  an  associative
-       array.   If  both  options are supplied, -\b-A\bA takes precedence.  The r\bre\bea\bad\bd
-       builtin accepts a -\b-a\ba option to assign a list of  words  read  from  the
+       The d\bde\bec\bcl\bla\bar\bre\be, l\blo\boc\bca\bal\bl, and r\bre\bea\bad\bdo\bon\bnl\bly\by builtins each accept a  -\b-a\ba  option  to
+       specify  an  indexed  array  and  a -\b-A\bA option to specify an associative
+       array.  If both options are supplied, -\b-A\bA takes  precedence.   The  r\bre\bea\bad\bd
+       builtin  accepts  a  -\b-a\ba  option to assign a list of words read from the
        standard input to an array.  The s\bse\bet\bt and d\bde\bec\bcl\bla\bar\bre\be builtins display array
        values in a way that allows them to be reused as assignments.
 
 E\bEX\bXP\bPA\bAN\bNS\bSI\bIO\bON\bN
        Expansion is performed on the command line after it has been split into
-       words.   There are seven kinds of expansion performed: _\bb_\br_\ba_\bc_\be _\be_\bx_\bp_\ba_\bn_\bs_\bi_\bo_\bn,
-       _\bt_\bi_\bl_\bd_\b_\be_\bx_\bp_\ba_\bn_\bs_\bi_\bo_\bn, _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br _\ba_\bn_\bd _\bv_\ba_\br_\bi_\ba_\bb_\bl_\be  _\be_\bx_\bp_\ba_\bn_\bs_\bi_\bo_\bn,  _\bc_\bo_\bm_\bm_\ba_\bn_\b _\bs_\bu_\bb_\bs_\bt_\bi_\bt_\bu_\b-
+       words.  There are seven kinds of expansion performed: _\bb_\br_\ba_\bc_\b _\be_\bx_\bp_\ba_\bn_\bs_\bi_\bo_\bn,
+       _\bt_\bi_\bl_\bd_\b _\be_\bx_\bp_\ba_\bn_\bs_\bi_\bo_\bn,  _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br  _\ba_\bn_\bd _\bv_\ba_\br_\bi_\ba_\bb_\bl_\be _\be_\bx_\bp_\ba_\bn_\bs_\bi_\bo_\bn, _\bc_\bo_\bm_\bm_\ba_\bn_\bd _\bs_\bu_\bb_\bs_\bt_\bi_\bt_\bu_\b-
        _\bt_\bi_\bo_\bn, _\ba_\br_\bi_\bt_\bh_\bm_\be_\bt_\bi_\bc _\be_\bx_\bp_\ba_\bn_\bs_\bi_\bo_\bn, _\bw_\bo_\br_\bd _\bs_\bp_\bl_\bi_\bt_\bt_\bi_\bn_\bg, and _\bp_\ba_\bt_\bh_\bn_\ba_\bm_\be _\be_\bx_\bp_\ba_\bn_\bs_\bi_\bo_\bn.
 
        The order of expansions is: brace expansion; tilde expansion, parameter
-       and variable expansion, arithmetic expansion, and command  substitution
-       (done  in a left-to-right fashion); word splitting; and pathname expan-
+       and  variable expansion, arithmetic expansion, and command substitution
+       (done in a left-to-right fashion); word splitting; and pathname  expan-
        sion.
 
        On systems that can support it, there is an additional expansion avail-
-       able:  _\bp_\br_\bo_\bc_\be_\bs_\bs  _\bs_\bu_\bb_\bs_\bt_\bi_\bt_\bu_\bt_\bi_\bo_\bn.   This  is  performed at the same time as
-       tilde, parameter, variable, and arithmetic expansion and  command  sub-
+       able: _\bp_\br_\bo_\bc_\be_\bs_\bs _\bs_\bu_\bb_\bs_\bt_\bi_\bt_\bu_\bt_\bi_\bo_\bn.  This is performed  at  the  same  time  as
+       tilde,  parameter,  variable, and arithmetic expansion and command sub-
        stitution.
 
        Only brace expansion, word splitting, and pathname expansion can change
-       the number of words of the expansion; other expansions expand a  single
-       word  to a single word.  The only exceptions to this are the expansions
+       the  number of words of the expansion; other expansions expand a single
+       word to a single word.  The only exceptions to this are the  expansions
        of "$\b$@\b@" and "$\b${\b{_\bn_\ba_\bm_\be[\b[@\b@]\b]}\b}" as explained above (see P\bPA\bAR\bRA\bAM\bME\bET\bTE\bER\bRS\bS).
 
    B\bBr\bra\bac\bce\be E\bEx\bxp\bpa\ban\bns\bsi\bio\bon\bn
        _\bB_\br_\ba_\bc_\be _\be_\bx_\bp_\ba_\bn_\bs_\bi_\bo_\bn is a mechanism by which arbitrary strings may be gener-
-       ated.   This  mechanism is similar to _\bp_\ba_\bt_\bh_\bn_\ba_\bm_\be _\be_\bx_\bp_\ba_\bn_\bs_\bi_\bo_\bn, but the file-
+       ated.  This mechanism is similar to _\bp_\ba_\bt_\bh_\bn_\ba_\bm_\be _\be_\bx_\bp_\ba_\bn_\bs_\bi_\bo_\bn, but  the  file-
        names generated need not exist.  Patterns to be brace expanded take the
        form of an optional _\bp_\br_\be_\ba_\bm_\bb_\bl_\be, followed by either a series of comma-sep-
-       arated strings or a sequence expression between a pair of braces,  fol-
-       lowed  by  an  optional  _\bp_\bo_\bs_\bt_\bs_\bc_\br_\bi_\bp_\bt.   The preamble is prefixed to each
+       arated  strings or a sequence expression between a pair of braces, fol-
+       lowed by an optional _\bp_\bo_\bs_\bt_\bs_\bc_\br_\bi_\bp_\bt.  The  preamble  is  prefixed  to  each
        string contained within the braces, and the postscript is then appended
        to each resulting string, expanding left to right.
 
-       Brace  expansions  may  be nested.  The results of each expanded string
-       are not sorted;  left  to  right  order  is  preserved.   For  example,
+       Brace expansions may be nested.  The results of  each  expanded  string
+       are  not  sorted;  left  to  right  order  is  preserved.  For example,
        a{\b{d,c,b}\b}e expands into `ade ace abe'.
 
-       A  sequence expression takes the form {\b{_\bx.\b..\b._\by[\b[.\b..\b._\bi_\bn_\bc_\br]\b]}\b}, where _\bx and _\by are
-       either integers or single characters, and _\bi_\bn_\bc_\br, an optional  increment,
-       is  an  integer.  When integers are supplied, the expression expands to
-       each number between _\bx and _\by, inclusive.  Supplied integers may be  pre-
-       fixed  with _\b0 to force each term to have the same width.  When either _\bx
-       or _\by begins with a zero, the shell  attempts  to  force  all  generated
-       terms  to  contain the same number of digits, zero-padding where neces-
-       sary.  When characters are supplied, the  expression  expands  to  each
-       character  lexicographically  between  _\bx  and  _\by,  inclusive, using the
-       default C locale.  Note that both _\bx and _\by must be  of  the  same  type.
-       When  the  increment  is supplied, it is used as the difference between
+       A sequence expression takes the form {\b{_\bx.\b..\b._\by[\b[.\b..\b._\bi_\bn_\bc_\br]\b]}\b}, where _\bx and _\b are
+       either  integers or single characters, and _\bi_\bn_\bc_\br, an optional increment,
+       is an integer.  When integers are supplied, the expression  expands  to
+       each  number between _\bx and _\by, inclusive.  Supplied integers may be pre-
+       fixed with _\b0 to force each term to have the same width.  When either  _\bx
+       or  _\by  begins  with  a  zero, the shell attempts to force all generated
+       terms to contain the same number of digits, zero-padding  where  neces-
+       sary.   When  characters  are  supplied, the expression expands to each
+       character lexicographically between  _\bx  and  _\by,  inclusive,  using  the
+       default  C  locale.   Note  that both _\bx and _\by must be of the same type.
+       When the increment is supplied, it is used as  the  difference  between
        each term.  The default increment is 1 or -1 as appropriate.
 
        Brace expansion is performed before any other expansions, and any char-
-       acters  special to other expansions are preserved in the result.  It is
-       strictly textual.  B\bBa\bas\bsh\bh does not apply any syntactic interpretation  to
+       acters special to other expansions are preserved in the result.  It  is
+       strictly  textual.  B\bBa\bas\bsh\bh does not apply any syntactic interpretation to
        the context of the expansion or the text between the braces.
 
-       A  correctly-formed  brace  expansion must contain unquoted opening and
-       closing braces, and at least one unquoted comma  or  a  valid  sequence
-       expression.   Any incorrectly formed brace expansion is left unchanged.
+       A correctly-formed brace expansion must contain  unquoted  opening  and
+       closing  braces,  and  at  least one unquoted comma or a valid sequence
+       expression.  Any incorrectly formed brace expansion is left  unchanged.
        A {\b{ or ,\b, may be quoted with a backslash to prevent its being considered
-       part  of  a brace expression.  To avoid conflicts with parameter expan-
+       part of a brace expression.  To avoid conflicts with  parameter  expan-
        sion, the string $\b${\b{ is not considered eligible for brace expansion.
 
        This construct is typically used as shorthand when the common prefix of
@@ -1462,36 +1465,36 @@ E\bEX\bXP\bPA\bAN\bNS\bSI\bIO\bON\bN
        or
               chown root /usr/{ucb/{ex,edit},lib/{ex?.?*,how_ex}}
 
-       Brace  expansion  introduces  a  slight incompatibility with historical
-       versions of s\bsh\bh.  s\bsh\bh does not treat opening or closing braces  specially
-       when  they  appear as part of a word, and preserves them in the output.
-       B\bBa\bas\bsh\bremoves braces from words as a  consequence  of  brace  expansion.
-       For  example,  a word entered to s\bsh\bh as _\bf_\bi_\bl_\be_\b{_\b1_\b,_\b2_\b} appears identically in
-       the output.  The same word is output as _\bf_\bi_\bl_\be_\b1 _\bf_\bi_\bl_\be_\b2 after expansion  by
-       b\bba\bas\bsh\bh.   If strict compatibility with s\bsh\bh is desired, start b\bba\bas\bsh\bh with the
+       Brace expansion introduces a  slight  incompatibility  with  historical
+       versions  of s\bsh\bh.  s\bsh\bh does not treat opening or closing braces specially
+       when they appear as part of a word, and preserves them in  the  output.
+       B\bBa\bas\bsh\b removes  braces  from  words as a consequence of brace expansion.
+       For example, a word entered to s\bsh\bh as _\bf_\bi_\bl_\be_\b{_\b1_\b,_\b2_\b} appears  identically  in
+       the  output.  The same word is output as _\bf_\bi_\bl_\be_\b1 _\bf_\bi_\bl_\be_\b2 after expansion by
+       b\bba\bas\bsh\bh.  If strict compatibility with s\bsh\bh is desired, start b\bba\bas\bsh\bh with  the
        +\b+B\bB option or disable brace expansion with the +\b+B\bB option to the s\bse\bet\bt com-
        mand (see S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS below).
 
    T\bTi\bil\bld\bde\be E\bEx\bxp\bpa\ban\bns\bsi\bio\bon\bn
-       If  a  word  begins  with an unquoted tilde character (`~\b~'), all of the
-       characters preceding the first unquoted slash (or  all  characters,  if
-       there  is no unquoted slash) are considered a _\bt_\bi_\bl_\bd_\be_\b-_\bp_\br_\be_\bf_\bi_\bx.  If none of
-       the characters in the tilde-prefix are quoted, the  characters  in  the
-       tilde-prefix  following the tilde are treated as a possible _\bl_\bo_\bg_\bi_\bn _\bn_\ba_\bm_\be.
-       If this login name is the null string, the tilde is replaced  with  the
-       value  of  the shell parameter H\bHO\bOM\bME\bE.  If H\bHO\bOM\bME\bE is unset, the home direc-
-       tory of the user executing the shell is  substituted  instead.   Other-
-       wise,  the  tilde-prefix is replaced with the home directory associated
+       If a word begins with an unquoted tilde character  (`~\b~'),  all  of  the
+       characters  preceding  the  first unquoted slash (or all characters, if
+       there is no unquoted slash) are considered a _\bt_\bi_\bl_\bd_\be_\b-_\bp_\br_\be_\bf_\bi_\bx.  If none  of
+       the  characters  in  the tilde-prefix are quoted, the characters in the
+       tilde-prefix following the tilde are treated as a possible _\bl_\bo_\bg_\bi_\b _\bn_\ba_\bm_\be.
+       If  this  login name is the null string, the tilde is replaced with the
+       value of the shell parameter H\bHO\bOM\bME\bE.  If H\bHO\bOM\bME\bE is unset, the  home  direc-
+       tory  of  the  user executing the shell is substituted instead.  Other-
+       wise, the tilde-prefix is replaced with the home  directory  associated
        with the specified login name.
 
-       If the tilde-prefix is a `~+', the value  of  the  shell  variable  P\bPW\bWD\bD
+       If  the  tilde-prefix  is  a  `~+', the value of the shell variable P\bPW\bWD\bD
        replaces the tilde-prefix.  If the tilde-prefix is a `~-', the value of
-       the shell variable O\bOL\bLD\bDP\bPW\bWD\bD, if it is set, is substituted.  If the  char-
-       acters  following  the tilde in the tilde-prefix consist of a number _\bN,
-       optionally prefixed by a `+' or a `-',  the  tilde-prefix  is  replaced
+       the  shell variable O\bOL\bLD\bDP\bPW\bWD\bD, if it is set, is substituted.  If the char-
+       acters following the tilde in the tilde-prefix consist of a  number  _\bN,
+       optionally  prefixed  by  a  `+' or a `-', the tilde-prefix is replaced
        with the corresponding element from the directory stack, as it would be
        displayed by the d\bdi\bir\brs\bs builtin invoked with the tilde-prefix as an argu-
-       ment.   If  the characters following the tilde in the tilde-prefix con-
+       ment.  If the characters following the tilde in the  tilde-prefix  con-
        sist of a number without a leading `+' or `-', `+' is assumed.
 
        If the login name is invalid, or the tilde expansion fails, the word is
@@ -1499,206 +1502,235 @@ E\bEX\bXP\bPA\bAN\bNS\bSI\bIO\bON\bN
 
        Each variable assignment is checked for unquoted tilde-prefixes immedi-
        ately following a :\b: or the first =\b=.  In these cases, tilde expansion is
-       also  performed.   Consequently,  one  may use filenames with tildes in
-       assignments to P\bPA\bAT\bTH\bH, M\bMA\bAI\bIL\bLP\bPA\bAT\bTH\bH, and C\bCD\bDP\bPA\bAT\bTH\bH, and the  shell  assigns  the
+       also performed.  Consequently, one may use  filenames  with  tildes  in
+       assignments  to  P\bPA\bAT\bTH\bH,  M\bMA\bAI\bIL\bLP\bPA\bAT\bTH\bH, and C\bCD\bDP\bPA\bAT\bTH\bH, and the shell assigns the
        expanded value.
 
    P\bPa\bar\bra\bam\bme\bet\bte\ber\br E\bEx\bxp\bpa\ban\bns\bsi\bio\bon\bn
        The `$\b$' character introduces parameter expansion, command substitution,
-       or arithmetic expansion.  The parameter name or symbol to  be  expanded
-       may  be enclosed in braces, which are optional but serve to protect the
-       variable to be expanded from characters immediately following it  which
+       or  arithmetic  expansion.  The parameter name or symbol to be expanded
+       may be enclosed in braces, which are optional but serve to protect  the
+       variable  to be expanded from characters immediately following it which
        could be interpreted as part of the name.
 
-       When  braces  are  used, the matching ending brace is the first `}\b}' not
-       escaped by a backslash or within a quoted string,  and  not  within  an
+       When braces are used, the matching ending brace is the  first  `}\b}'  not
+       escaped  by  a  backslash  or within a quoted string, and not within an
        embedded  arithmetic  expansion,  command  substitution,  or  parameter
        expansion.
 
        ${_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br}
-              The value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is substituted.  The braces are  required
-              when  _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br  is  a  positional  parameter with more than one
+              The  value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is substituted.  The braces are required
+              when _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is a positional  parameter  with  more  than  one
               digit, or when _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is followed by a character which is not
               to be interpreted as part of its name.  The _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is a shell
-              parameter as described above P\bPA\bAR\bRA\bAM\bME\bET\bTE\bER\bRS\bS) or an  array  reference
+              parameter  as  described above P\bPA\bAR\bRA\bAM\bME\bET\bTE\bER\bRS\bS) or an array reference
               (A\bAr\brr\bra\bay\bys\bs).
 
-       If  the  first  character  of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is an exclamation point (!\b!), it
+       If the first character of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is an  exclamation  point  (!\b!),  it
        introduces a level of variable indirection.  B\bBa\bas\bsh\bh uses the value of the
        variable formed from the rest of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br as the name of the variable;
-       this variable is then expanded and that value is used in  the  rest  of
-       the  substitution,  rather than the value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br itself.  This is
+       this  variable  is  then expanded and that value is used in the rest of
+       the substitution, rather than the value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br itself.   This  is
        known as _\bi_\bn_\bd_\bi_\br_\be_\bc_\bt _\be_\bx_\bp_\ba_\bn_\bs_\bi_\bo_\bn.  The exceptions to this are the expansions
-       of  ${!\b!_\bp_\br_\be_\bf_\bi_\bx*\b*} and ${!\b!_\bn_\ba_\bm_\be[_\b@]} described below.  The exclamation point
-       must immediately follow the left brace in order to  introduce  indirec-
+       of ${!\b!_\bp_\br_\be_\bf_\bi_\bx*\b*} and ${!\b!_\bn_\ba_\bm_\be[_\b@]} described below.  The exclamation  point
+       must  immediately  follow the left brace in order to introduce indirec-
        tion.
 
        In each of the cases below, _\bw_\bo_\br_\bd is subject to tilde expansion, parame-
        ter expansion, command substitution, and arithmetic expansion.
 
-       When not performing substring expansion,  using  the  forms  documented
-       below  (e.g.,  :\b:-\b-),  b\bba\bas\bsh\bh  tests for a parameter that is unset or null.
-       Omitting the colon results in a test  only  for  a  parameter  that  is
+       When  not  performing  substring  expansion, using the forms documented
+       below (e.g., :\b:-\b-), b\bba\bas\bsh\bh tests for a parameter that  is  unset  or  null.
+       Omitting  the  colon  results  in  a  test only for a parameter that is
        unset.
 
        ${_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br:\b:-\b-_\bw_\bo_\br_\bd}
-              U\bUs\bse\b D\bDe\bef\bfa\bau\bul\blt\bt  V\bVa\bal\blu\bue\bes\bs.  If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is unset or null, the expan-
-              sion of _\bw_\bo_\br_\bd is substituted.  Otherwise, the value of  _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br
+              U\bUs\bse\bD\bDe\bef\bfa\bau\bul\blt\bt V\bVa\bal\blu\bue\bes\bs.  If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is unset or null,  the  expan-
+              sion  of _\bw_\bo_\br_\bd is substituted.  Otherwise, the value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br
               is substituted.
        ${_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br:\b:=\b=_\bw_\bo_\br_\bd}
-              A\bAs\bss\bsi\big\bgn\b D\bDe\bef\bfa\bau\bul\blt\bt  V\bVa\bal\blu\bue\bes\bs.   If  _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br  is  unset or null, the
+              A\bAs\bss\bsi\big\bgn\bD\bDe\bef\bfa\bau\bul\blt\bt V\bVa\bal\blu\bue\bes\bs.  If  _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br  is  unset  or  null,  the
               expansion of _\bw_\bo_\br_\bd is assigned to _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br.  The value of _\bp_\ba_\br_\ba_\bm_\b-
-              _\be_\bt_\be_\b is  then  substituted.   Positional parameters and special
+              _\be_\bt_\be_\bis then substituted.   Positional  parameters  and  special
               parameters may not be assigned to in this way.
        ${_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br:\b:?\b?_\bw_\bo_\br_\bd}
-              D\bDi\bis\bsp\bpl\bla\bay\bE\bEr\brr\bro\bor\br i\bif\bf N\bNu\bul\bll\bl o\bor\br U\bUn\bns\bse\bet\bt.  If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is null or  unset,
-              the  expansion  of  _\bw_\bo_\br_\bd (or a message to that effect if _\bw_\bo_\br_\bd is
-              not present) is written to the standard error and the shell,  if
+              D\bDi\bis\bsp\bpl\bla\bay\b E\bEr\brr\bro\bor\br i\bif\bf N\bNu\bul\bll\bl o\bor\br U\bUn\bns\bse\bet\bt.  If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is null or unset,
+              the expansion of _\bw_\bo_\br_\bd (or a message to that effect  if  _\bw_\bo_\br_\b is
+              not  present) is written to the standard error and the shell, if
               it is not interactive, exits.  Otherwise, the value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br
               is substituted.
        ${_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br:\b:+\b+_\bw_\bo_\br_\bd}
-              U\bUs\bse\bA\bAl\blt\bte\ber\brn\bna\bat\bte\be V\bVa\bal\blu\bue\be.  If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is null or unset, nothing  is
+              U\bUs\bse\b A\bAl\blt\bte\ber\brn\bna\bat\bte\be V\bVa\bal\blu\bue\be.  If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is null or unset, nothing is
               substituted, otherwise the expansion of _\bw_\bo_\br_\bd is substituted.
        ${_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br:\b:_\bo_\bf_\bf_\bs_\be_\bt}
        ${_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br:\b:_\bo_\bf_\bf_\bs_\be_\bt:\b:_\bl_\be_\bn_\bg_\bt_\bh}
-              S\bSu\bub\bbs\bst\btr\bri\bin\bng\b E\bEx\bxp\bpa\ban\bns\bsi\bio\bon\bn.  Expands to up to _\bl_\be_\bn_\bg_\bt_\bh characters of the
-              value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br starting at the character specified  by  _\bo_\bf_\bf_\b-
+              S\bSu\bub\bbs\bst\btr\bri\bin\bng\bE\bEx\bxp\bpa\ban\bns\bsi\bio\bon\bn.  Expands to up to _\bl_\be_\bn_\bg_\bt_\bh characters of  the
+              value  of  _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br starting at the character specified by _\bo_\bf_\bf_\b-
               _\bs_\be_\bt.  If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is @\b@, an indexed array subscripted by @\b@ or *\b*,
-              or an associative array name, the results  differ  as  described
-              below.   If  _\bl_\be_\bn_\bg_\bt_\bh  is omitted, expands to the substring of the
+              or  an  associative  array name, the results differ as described
+              below.  If _\bl_\be_\bn_\bg_\bt_\bh is omitted, expands to the  substring  of  the
               value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br starting at the character specified by _\bo_\bf_\bf_\bs_\be_\bt
-              and  extending  to  the end of the value.  _\bl_\be_\bn_\bg_\bt_\bh and _\bo_\bf_\bf_\bs_\be_\bt are
+              and extending to the end of the value.  _\bl_\be_\bn_\bg_\bt_\bh  and  _\bo_\bf_\bf_\bs_\be_\b are
               arithmetic expressions (see A\bAR\bRI\bIT\bTH\bHM\bME\bET\bTI\bIC\bC E\bEV\bVA\bAL\bLU\bUA\bAT\bTI\bIO\bON\bN below).
 
-              If _\bo_\bf_\bf_\bs_\be_\bt evaluates to a number less than  zero,  the  value  is
-              used  as  an  offset  in characters from the end of the value of
-              _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br.  If _\bl_\be_\bn_\bg_\bt_\bh evaluates to a number less than  zero,  it
-              is  interpreted  as  an offset in characters from the end of the
-              value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br rather than a number of characters,  and  the
-              expansion  is  the  characters  between  _\bo_\bf_\bf_\bs_\be_\bt and that result.
-              Note that a negative offset must be separated from the colon  by
-              at  least  one  space to avoid being confused with the :\b:-\b- expan-
+              If  _\bo_\bf_\bf_\bs_\be_\bt  evaluates  to  a number less than zero, the value is
+              used as an offset in characters from the end  of  the  value  of
+              _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br.   If  _\bl_\be_\bn_\bg_\bt_\bh evaluates to a number less than zero, it
+              is interpreted as an offset in characters from the  end  of  the
+              value  of  _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br rather than a number of characters, and the
+              expansion is the characters  between  _\bo_\bf_\bf_\bs_\be_\bt  and  that  result.
+              Note  that a negative offset must be separated from the colon by
+              at least one space to avoid being confused with  the  :\b:-\b expan-
               sion.
 
-              If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is @\b@, the result is  _\bl_\be_\bn_\bg_\bt_\bh  positional  parameters
+              If  _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br  is  @\b@, the result is _\bl_\be_\bn_\bg_\bt_\bh positional parameters
               beginning at _\bo_\bf_\bf_\bs_\be_\bt.  A negative _\bo_\bf_\bf_\bs_\be_\bt is taken relative to one
-              greater than the greatest positional parameter, so an offset  of
-              -1  evaluates to the last positional parameter.  It is an expan-
+              greater  than the greatest positional parameter, so an offset of
+              -1 evaluates to the last positional parameter.  It is an  expan-
               sion error if _\bl_\be_\bn_\bg_\bt_\bh evaluates to a number less than zero.
 
               If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is an indexed array name subscripted by @ or *, the
-              result  is  the  _\bl_\be_\bn_\bg_\bt_\bh  members  of  the  array  beginning with
-              ${_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br[_\bo_\bf_\bf_\bs_\be_\bt]}.  A negative _\bo_\bf_\bf_\bs_\be_\bt is  taken  relative  to
-              one  greater  than the maximum index of the specified array.  It
-              is an expansion error if _\bl_\be_\bn_\bg_\bt_\bh evaluates to a number less  than
+              result is  the  _\bl_\be_\bn_\bg_\bt_\bh  members  of  the  array  beginning  with
+              ${_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br[_\bo_\bf_\bf_\bs_\be_\bt]}.   A  negative  _\bo_\bf_\bf_\bs_\be_\bt is taken relative to
+              one greater than the maximum index of the specified  array.   It
+              is  an expansion error if _\bl_\be_\bn_\bg_\bt_\bh evaluates to a number less than
               zero.
 
-              Substring  expansion  applied  to  an associative array produces
+              Substring expansion applied to  an  associative  array  produces
               undefined results.
 
-              Substring indexing is zero-based unless the  positional  parame-
-              ters  are  used,  in  which  case  the  indexing  starts at 1 by
-              default.  If _\bo_\bf_\bf_\bs_\be_\bt is 0,  and  the  positional  parameters  are
+              Substring  indexing  is zero-based unless the positional parame-
+              ters are used, in  which  case  the  indexing  starts  at  1  by
+              default.   If  _\bo_\bf_\bf_\bs_\be_\bt  is  0,  and the positional parameters are
               used, $\b$0\b0 is prefixed to the list.
 
        ${!\b!_\bp_\br_\be_\bf_\bi_\bx*\b*}
        ${!\b!_\bp_\br_\be_\bf_\bi_\bx@\b@}
-              N\bNa\bam\bme\bes\b m\bma\bat\btc\bch\bhi\bin\bng\bg p\bpr\bre\bef\bfi\bix\bx.  Expands to the names of variables whose
+              N\bNa\bam\bme\bes\bm\bma\bat\btc\bch\bhi\bin\bng\bg p\bpr\bre\bef\bfi\bix\bx.  Expands to the names of variables  whose
               names begin with _\bp_\br_\be_\bf_\bi_\bx, separated by the first character of the
-              I\bIF\bFS\b special variable.  When _\b@ is used and the expansion appears
-              within double quotes, each variable name expands to  a  separate
+              I\bIF\bFS\bspecial variable.  When _\b@ is used and the expansion  appears
+              within  double  quotes, each variable name expands to a separate
               word.
 
        ${!\b!_\bn_\ba_\bm_\be[_\b@]}
        ${!\b!_\bn_\ba_\bm_\be[_\b*]}
-              L\bLi\bis\bst\b o\bof\bf  a\bar\brr\bra\bay\by  k\bke\bey\bys\bs.  If _\bn_\ba_\bm_\be is an array variable, expands to
-              the list of array indices (keys) assigned in _\bn_\ba_\bm_\be.  If  _\bn_\ba_\bm_\b is
-              not  an  array,  expands to 0 if _\bn_\ba_\bm_\be is set and null otherwise.
-              When _\b@ is used and the expansion appears within  double  quotes,
+              L\bLi\bis\bst\bo\bof\bf a\bar\brr\bra\bay\by k\bke\bey\bys\bs.  If _\bn_\ba_\bm_\be is an array  variable,  expands  to
+              the  list  of array indices (keys) assigned in _\bn_\ba_\bm_\be.  If _\bn_\ba_\bm_\be is
+              not an array, expands to 0 if _\bn_\ba_\bm_\be is set  and  null  otherwise.
+              When  _\b@  is used and the expansion appears within double quotes,
               each key expands to a separate word.
 
        ${#\b#_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br}
-              P\bPa\bar\bra\bam\bme\bet\bte\ber\b l\ble\ben\bng\bgt\bth\bh.   The  length  in  characters of the value of
-              _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\bis substituted.  If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is *\b*  or  @\b@,  the  value
-              substituted  is the number of positional parameters.  If _\bp_\ba_\br_\ba_\bm_\be_\b-
-              _\bt_\be_\bis an array name subscripted by *\b* or @\b@,  the  value  substi-
-              tuted  is  the number of elements in the array.  If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is
-              an indexed array name subscripted by  a  negative  number,  that
-              number  is interpreted as relative to one greater than the maxi-
-              mum index of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br, so negative indices count back from  the
-              end  of  the  array, and an index of -1 references the last ele-
+              P\bPa\bar\bra\bam\bme\bet\bte\ber\bl\ble\ben\bng\bgt\bth\bh.  The length in  characters  of  the  value  of
+              _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\b is  substituted.   If  _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is *\b* or @\b@, the value
+              substituted is the number of positional parameters.  If  _\bp_\ba_\br_\ba_\bm_\be_\b-
+              _\bt_\be_\b is  an  array name subscripted by *\b* or @\b@, the value substi-
+              tuted is the number of elements in the array.  If  _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\b is
+              an  indexed  array  name  subscripted by a negative number, that
+              number is interpreted as relative to one greater than the  maxi-
+              mum  index of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br, so negative indices count back from the
+              end of the array, and an index of -1 references  the  last  ele-
               ment.
 
        ${_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br#\b#_\bw_\bo_\br_\bd}
        ${_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br#\b##\b#_\bw_\bo_\br_\bd}
               R\bRe\bem\bmo\bov\bve\be m\bma\bat\btc\bch\bhi\bin\bng\bg p\bpr\bre\bef\bfi\bix\bx p\bpa\bat\btt\bte\ber\brn\bn.  The _\bw_\bo_\br_\bd is expanded to produce
               a pattern just as in pathname expansion.  If the pattern matches
-              the beginning of the value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br, then the result of  the
-              expansion  is  the expanded value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br with the shortest
-              matching pattern (the ``#\b#'' case) or the longest  matching  pat-
-              tern  (the  ``#\b##\b#''  case)  deleted.  If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is @\b@ or *\b*, the
-              pattern removal operation is applied to each positional  parame-
+              the  beginning of the value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br, then the result of the
+              expansion is the expanded value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br with  the  shortest
+              matching  pattern  (the ``#\b#'' case) or the longest matching pat-
+              tern (the ``#\b##\b#'' case) deleted.  If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is  @\b@  or  *\b*,  the
+              pattern  removal operation is applied to each positional parame-
               ter in turn, and the expansion is the resultant list.  If _\bp_\ba_\br_\ba_\bm_\b-
-              _\be_\bt_\be_\bis an array variable subscripted with @\b@ or *\b*,  the  pattern
-              removal  operation  is  applied  to  each member of the array in
+              _\be_\bt_\be_\b is  an array variable subscripted with @\b@ or *\b*, the pattern
+              removal operation is applied to each  member  of  the  array  in
               turn, and the expansion is the resultant list.
 
        ${_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br%\b%_\bw_\bo_\br_\bd}
        ${_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br%\b%%\b%_\bw_\bo_\br_\bd}
               R\bRe\bem\bmo\bov\bve\be m\bma\bat\btc\bch\bhi\bin\bng\bg s\bsu\buf\bff\bfi\bix\bx p\bpa\bat\btt\bte\ber\brn\bn.  The _\bw_\bo_\br_\bd is expanded to produce
               a pattern just as in pathname expansion.  If the pattern matches
-              a trailing portion of the expanded value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br, then  the
-              result  of the expansion is the expanded value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br with
-              the shortest matching pattern (the ``%\b%'' case)  or  the  longest
-              matching  pattern  (the ``%\b%%\b%'' case) deleted.  If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is @\b@
-              or *\b*, the pattern removal operation is  applied  to  each  posi-
-              tional  parameter  in  turn,  and the expansion is the resultant
-              list.  If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is an array variable subscripted with  @\b or
-              *\b*,  the  pattern  removal operation is applied to each member of
+              a  trailing portion of the expanded value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br, then the
+              result of the expansion is the expanded value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\b with
+              the  shortest  matching  pattern (the ``%\b%'' case) or the longest
+              matching pattern (the ``%\b%%\b%'' case) deleted.  If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br  is  @\b@
+              or  *\b*,  the  pattern  removal operation is applied to each posi-
+              tional parameter in turn, and the  expansion  is  the  resultant
+              list.   If  _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is an array variable subscripted with @\b@ or
+              *\b*, the pattern removal operation is applied to  each  member  of
               the array in turn, and the expansion is the resultant list.
 
        ${_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br/\b/_\bp_\ba_\bt_\bt_\be_\br_\bn/\b/_\bs_\bt_\br_\bi_\bn_\bg}
               P\bPa\bat\btt\bte\ber\brn\bn s\bsu\bub\bbs\bst\bti\bit\btu\but\bti\bio\bon\bn.  The _\bp_\ba_\bt_\bt_\be_\br_\bn is expanded to produce a pat-
-              tern  just  as in pathname expansion.  _\bP_\ba_\br_\ba_\bm_\be_\bt_\be_\br is expanded and
-              the longest match of _\bp_\ba_\bt_\bt_\be_\br_\bn against its value is replaced  with
-              _\bs_\bt_\br_\bi_\bn_\bg.   If  _\bp_\ba_\bt_\bt_\be_\br_\bn  begins with /\b/, all matches of _\bp_\ba_\bt_\bt_\be_\br_\bn are
-              replaced  with  _\bs_\bt_\br_\bi_\bn_\bg.   Normally  only  the  first  match   is
+              tern just as in pathname expansion.  _\bP_\ba_\br_\ba_\bm_\be_\bt_\be_\br is  expanded  and
+              the  longest match of _\bp_\ba_\bt_\bt_\be_\br_\bn against its value is replaced with
+              _\bs_\bt_\br_\bi_\bn_\bg.  If _\bp_\ba_\bt_\bt_\be_\br_\bn begins with /\b/, all matches  of  _\bp_\ba_\bt_\bt_\be_\br_\b are
+              replaced   with  _\bs_\bt_\br_\bi_\bn_\bg.   Normally  only  the  first  match  is
               replaced.  If _\bp_\ba_\bt_\bt_\be_\br_\bn begins with #\b#, it must match at the begin-
               ning of the expanded value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br.  If _\bp_\ba_\bt_\bt_\be_\br_\bn begins with
-              %\b%,  it must match at the end of the expanded value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br.
+              %\b%, it must match at the end of the expanded value of  _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br.
               If _\bs_\bt_\br_\bi_\bn_\bg is null, matches of _\bp_\ba_\bt_\bt_\be_\br_\bn are deleted and the /\b/ fol-
-              lowing  _\bp_\ba_\bt_\bt_\be_\br_\bn may be omitted.  If the n\bno\boc\bca\bas\bse\bem\bma\bat\btc\bch\bh shell option
+              lowing _\bp_\ba_\bt_\bt_\be_\br_\bn may be omitted.  If the n\bno\boc\bca\bas\bse\bem\bma\bat\btc\bch\bh shell  option
               is enabled, the match is performed without regard to the case of
               alphabetic characters.  If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is @\b@ or *\b*, the substitution
-              operation is applied to each positional parameter in  turn,  and
-              the  expansion  is the resultant list.  If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is an array
-              variable subscripted with @\b@ or *\b*, the substitution operation  is
-              applied  to  each member of the array in turn, and the expansion
+              operation  is  applied to each positional parameter in turn, and
+              the expansion is the resultant list.  If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is  an  array
+              variable  subscripted with @\b@ or *\b*, the substitution operation is
+              applied to each member of the array in turn, and  the  expansion
               is the resultant list.
 
        ${_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br^\b^_\bp_\ba_\bt_\bt_\be_\br_\bn}
        ${_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br^\b^^\b^_\bp_\ba_\bt_\bt_\be_\br_\bn}
        ${_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br,\b,_\bp_\ba_\bt_\bt_\be_\br_\bn}
        ${_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br,\b,,\b,_\bp_\ba_\bt_\bt_\be_\br_\bn}
-              C\bCa\bas\bse\bm\bmo\bod\bdi\bif\bfi\bic\bca\bat\bti\bio\bon\bn.  This expansion modifies the case  of  alpha-
-              betic  characters in _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br.  The _\bp_\ba_\bt_\bt_\be_\br_\bn is expanded to pro-
+              C\bCa\bas\bse\b m\bmo\bod\bdi\bif\bfi\bic\bca\bat\bti\bio\bon\bn.   This expansion modifies the case of alpha-
+              betic characters in _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br.  The _\bp_\ba_\bt_\bt_\be_\br_\bn is expanded to  pro-
               duce a pattern just as in pathname expansion.  Each character in
-              the  expanded value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is tested against _\bp_\ba_\bt_\bt_\be_\br_\bn, and,
-              if it matches the pattern, its case is converted.   The  pattern
-              should  not  attempt  to  match  more than one character.  The ^\b^
-              operator converts lowercase letters matching _\bp_\ba_\bt_\bt_\be_\br_\bn  to  upper-
+              the expanded value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is tested against _\bp_\ba_\bt_\bt_\be_\br_\bn,  and,
+              if  it  matches the pattern, its case is converted.  The pattern
+              should not attempt to match more  than  one  character.   The  ^\b^
+              operator  converts  lowercase letters matching _\bp_\ba_\bt_\bt_\be_\br_\bn to upper-
               case; the ,\b, operator converts matching uppercase letters to low-
               ercase.  The ^\b^^\b^ and ,\b,,\b, expansions convert each matched character
-              in  the expanded value; the ^\b^ and ,\b, expansions match and convert
-              only the first character in the expanded value.  If  _\bp_\ba_\bt_\bt_\be_\br_\b is
-              omitted,  it is treated like a ?\b?, which matches every character.
-              If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is @\b@ or  *\b*,  the  case  modification  operation  is
-              applied  to each positional parameter in turn, and the expansion
-              is the resultant list.  If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is an array  variable  sub-
+              in the expanded value; the ^\b^ and ,\b, expansions match and  convert
+              only  the  first character in the expanded value.  If _\bp_\ba_\bt_\bt_\be_\br_\bn is
+              omitted, it is treated like a ?\b?, which matches every  character.
+              If  _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br  is  @\b@  or  *\b*,  the case modification operation is
+              applied to each positional parameter in turn, and the  expansion
+              is  the  resultant list.  If _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is an array variable sub-
               scripted with @\b@ or *\b*, the case modification operation is applied
-              to each member of the array in turn, and the  expansion  is  the
+              to  each  member  of the array in turn, and the expansion is the
               resultant list.
 
+       ${_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br@\b@_\bo_\bp_\be_\br_\ba_\bt_\bo_\br}
+              P\bPa\bar\bra\bam\bme\bet\bte\ber\br t\btr\bra\ban\bns\bsf\bfo\bor\brm\bma\bat\bti\bio\bon\bn.  The expansion is either a transforma-
+              tion  of  the  value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br or information about _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br
+              itself, depending on the value of _\bo_\bp_\be_\br_\ba_\bt_\bo_\br.  Each _\bo_\bp_\be_\br_\ba_\bt_\bo_\br is  a
+              single letter:
+
+              Q\bQ      The  expansion is a string that is the value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br
+                     quoted in a format that can be reused as input.
+              E\bE      The expansion is a string that is the value of  _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br
+                     with  backslash  escape  sequences  expanded  as with the
+                     $\b$'\b'.\b..\b..\b.'\b' quoting mechansim.
+              P\bP      The expansion is a string that is the result of expanding
+                     the value of _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br as if it were a prompt string (see
+                     P\bPR\bRO\bOM\bMP\bPT\bTI\bIN\bNG\bG below).
+              A\bA      The expansion is a string in the form of a  d\bde\bec\bcl\bla\bar\bre\be  com-
+                     mand that, if evaluated, will recreate _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br with its
+                     attributes and value.
+              a\ba      The expansion is a string consisting of flag values  rep-
+                     resenting _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br's attributes.
+
+              If  _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br  is @\b@ or *\b*, the operation is applied to each posi-
+              tional parameter in turn, and the  expansion  is  the  resultant
+              list.   If  _\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br is an array variable subscripted with @\b@ or
+              *\b*, the case modification operation is applied to each member  of
+              the array in turn, and the expansion is the resultant list.
+
+              The  result  of  the  expansion is subject to word splitting and
+              pathname expansion as described below.
+
    C\bCo\bom\bmm\bma\ban\bnd\bd S\bSu\bub\bbs\bst\bti\bit\btu\but\bti\bio\bon\bn
        _\bC_\bo_\bm_\bm_\ba_\bn_\bd _\bs_\bu_\bb_\bs_\bt_\bi_\bt_\bu_\bt_\bi_\bo_\bn allows the output of a command to replace the com-
        mand name.  There are two forms:
@@ -1708,169 +1740,169 @@ E\bEX\bXP\bPA\bAN\bNS\bSI\bIO\bON\bN
               `\b`_\bc_\bo_\bm_\bm_\ba_\bn_\bd`\b`
 
        B\bBa\bas\bsh\bh performs the expansion by executing _\bc_\bo_\bm_\bm_\ba_\bn_\bd and replacing the com-
-       mand  substitution  with  the  standard output of the command, with any
+       mand substitution with the standard output of  the  command,  with  any
        trailing newlines deleted.  Embedded newlines are not deleted, but they
-       may  be  removed during word splitting.  The command substitution $\b$(\b(c\bca\bat\bt
+       may be removed during word splitting.  The command  substitution  $\b$(\b(c\bca\bat\bt
        _\bf_\bi_\bl_\be)\b) can be replaced by the equivalent but faster $\b$(\b(<\b< _\bf_\bi_\bl_\be)\b).
 
-       When the old-style backquote form of substitution  is  used,  backslash
-       retains  its  literal  meaning except when followed by $\b$, `\b`, or \\b\.  The
+       When  the  old-style  backquote form of substitution is used, backslash
+       retains its literal meaning except when followed by $\b$, `\b`,  or  \\b\.   The
        first backquote not preceded by a backslash terminates the command sub-
-       stitution.   When using the $(_\bc_\bo_\bm_\bm_\ba_\bn_\bd) form, all characters between the
+       stitution.  When using the $(_\bc_\bo_\bm_\bm_\ba_\bn_\bd) form, all characters between  the
        parentheses make up the command; none are treated specially.
 
        Command substitutions may be nested.  To nest when using the backquoted
        form, escape the inner backquotes with backslashes.
 
-       If  the  substitution  appears within double quotes, word splitting and
+       If the substitution appears within double quotes,  word  splitting  and
        pathname expansion are not performed on the results.
 
    A\bAr\bri\bit\bth\bhm\bme\bet\bti\bic\bc E\bEx\bxp\bpa\ban\bns\bsi\bio\bon\bn
-       Arithmetic expansion allows the evaluation of an arithmetic  expression
-       and  the  substitution of the result.  The format for arithmetic expan-
+       Arithmetic  expansion allows the evaluation of an arithmetic expression
+       and the substitution of the result.  The format for  arithmetic  expan-
        sion is:
 
               $\b$(\b((\b(_\be_\bx_\bp_\br_\be_\bs_\bs_\bi_\bo_\bn)\b))\b)
 
-       The _\be_\bx_\bp_\br_\be_\bs_\bs_\bi_\bo_\bn is treated as if it were within  double  quotes,  but  a
-       double  quote  inside  the  parentheses  is not treated specially.  All
+       The  _\be_\bx_\bp_\br_\be_\bs_\bs_\bi_\bo_\bn  is  treated  as if it were within double quotes, but a
+       double quote inside the parentheses  is  not  treated  specially.   All
        tokens in the expression undergo parameter and variable expansion, com-
-       mand  substitution,  and  quote  removal.  The result is treated as the
-       arithmetic expression to be evaluated.  Arithmetic  expansions  may  be
+       mand substitution, and quote removal.  The result  is  treated  as  the
+       arithmetic  expression  to  be evaluated.  Arithmetic expansions may be
        nested.
 
-       The  evaluation  is performed according to the rules listed below under
+       The evaluation is performed according to the rules listed  below  under
        A\bAR\bRI\bIT\bTH\bHM\bME\bET\bTI\bIC\bC E\bEV\bVA\bAL\bLU\bUA\bAT\bTI\bIO\bON\bN.  If _\be_\bx_\bp_\br_\be_\bs_\bs_\bi_\bo_\bn is invalid, b\bba\bas\bsh\bh prints a message
        indicating failure and no substitution occurs.
 
    P\bPr\bro\boc\bce\bes\bss\bs S\bSu\bub\bbs\bst\bti\bit\btu\but\bti\bio\bon\bn
-       _\bP_\br_\bo_\bc_\be_\bs_\b _\bs_\bu_\bb_\bs_\bt_\bi_\bt_\bu_\bt_\bi_\bo_\bn  is supported on systems that support named pipes
-       (_\bF_\bI_\bF_\bO_\bs) or the /\b/d\bde\bev\bv/\b/f\bfd\bd method of naming open files.  It takes the  form
-       of  <\b<(\b(_\bl_\bi_\bs_\bt)\b) or >\b>(\b(_\bl_\bi_\bs_\bt)\b).  The process _\bl_\bi_\bs_\bt is run with its input or out-
+       _\bP_\br_\bo_\bc_\be_\bs_\b_\bs_\bu_\bb_\bs_\bt_\bi_\bt_\bu_\bt_\bi_\bo_\bn is supported on systems that support  named  pipes
+       (_\bF_\bI_\bF_\bO_\bs)  or the /\b/d\bde\bev\bv/\b/f\bfd\bd method of naming open files.  It takes the form
+       of <\b<(\b(_\bl_\bi_\bs_\bt)\b) or >\b>(\b(_\bl_\bi_\bs_\bt)\b).  The process _\bl_\bi_\bs_\bt is run with its input or  out-
        put connected to a _\bF_\bI_\bF_\bO or some file in /\b/d\bde\bev\bv/\b/f\bfd\bd.  The name of this file
-       is  passed  as  an argument to the current command as the result of the
-       expansion.  If the >\b>(\b(_\bl_\bi_\bs_\bt)\b) form is used, writing to the file will  pro-
-       vide  input  for _\bl_\bi_\bs_\bt.  If the <\b<(\b(_\bl_\bi_\bs_\bt)\b) form is used, the file passed as
+       is passed as an argument to the current command as the  result  of  the
+       expansion.   If the >\b>(\b(_\bl_\bi_\bs_\bt)\b) form is used, writing to the file will pro-
+       vide input for _\bl_\bi_\bs_\bt.  If the <\b<(\b(_\bl_\bi_\bs_\bt)\b) form is used, the file  passed  as
        an argument should be read to obtain the output of _\bl_\bi_\bs_\bt.
 
-       When available, process substitution is performed  simultaneously  with
-       parameter  and variable expansion, command substitution, and arithmetic
+       When  available,  process substitution is performed simultaneously with
+       parameter and variable expansion, command substitution, and  arithmetic
        expansion.
 
    W\bWo\bor\brd\bd S\bSp\bpl\bli\bit\btt\bti\bin\bng\bg
-       The shell scans the results of parameter expansion,  command  substitu-
-       tion,  and arithmetic expansion that did not occur within double quotes
+       The  shell  scans the results of parameter expansion, command substitu-
+       tion, and arithmetic expansion that did not occur within double  quotes
        for _\bw_\bo_\br_\bd _\bs_\bp_\bl_\bi_\bt_\bt_\bi_\bn_\bg.
 
-       The shell treats each character of I\bIF\bFS\bS as a delimiter, and  splits  the
-       results  of  the  other expansions into words using these characters as
-       field  terminators.   If  I\bIF\bFS\bS  is  unset,  or  its  value  is   exactly
-       <\b<s\bsp\bpa\bac\bce\be>\b><\b<t\bta\bab\bb>\b><\b<n\bne\bew\bwl\bli\bin\bne\be>\b>,  the  default, then sequences of <\b<s\bsp\bpa\bac\bce\be>\b>, <\b<t\bta\bab\bb>\b>,
-       and <\b<n\bne\bew\bwl\bli\bin\bne\be>\b> at the beginning and end of the results of  the  previous
-       expansions  are  ignored, and any sequence of I\bIF\bFS\bS characters not at the
-       beginning or end serves to delimit words.  If I\bIF\bFS\bS  has  a  value  other
+       The  shell  treats each character of I\bIF\bFS\bS as a delimiter, and splits the
+       results of the other expansions into words using  these  characters  as
+       field   terminators.   If  I\bIF\bFS\bS  is  unset,  or  its  value  is  exactly
+       <\b<s\bsp\bpa\bac\bce\be>\b><\b<t\bta\bab\bb>\b><\b<n\bne\bew\bwl\bli\bin\bne\be>\b>, the default, then sequences of  <\b<s\bsp\bpa\bac\bce\be>\b>,  <\b<t\bta\bab\bb>\b>,
+       and  <\b<n\bne\bew\bwl\bli\bin\bne\be>\b>  at the beginning and end of the results of the previous
+       expansions are ignored, and any sequence of I\bIF\bFS\bS characters not  at  the
+       beginning  or  end  serves  to delimit words.  If I\bIF\bFS\bS has a value other
        than the default, then sequences of the whitespace characters s\bsp\bpa\bac\bce\be and
-       t\bta\bab\bare ignored at the beginning and end of the word, as  long  as  the
-       whitespace  character is in the value of I\bIF\bFS\bS (an I\bIF\bFS\bS whitespace charac-
-       ter).  Any character in I\bIF\bFS\bS that is not I\bIF\bFS\bS whitespace, along with  any
-       adjacent  I\bIF\bFS\bS  whitespace  characters, delimits a field.  A sequence of
+       t\bta\bab\b are  ignored  at the beginning and end of the word, as long as the
+       whitespace character is in the value of I\bIF\bFS\bS (an I\bIF\bFS\bS whitespace  charac-
+       ter).   Any character in I\bIF\bFS\bS that is not I\bIF\bFS\bS whitespace, along with any
+       adjacent I\bIF\bFS\bS whitespace characters, delimits a field.   A  sequence  of
        I\bIF\bFS\bS whitespace characters is also treated as a delimiter.  If the value
        of I\bIF\bFS\bS is null, no word splitting occurs.
 
-       Explicit  null  arguments  ("\b""\b"  or '\b''\b') are retained.  Unquoted implicit
+       Explicit null arguments ("\b""\b" or '\b''\b')  are  retained.   Unquoted  implicit
        null arguments, resulting from the expansion of parameters that have no
-       values,  are  removed.  If a parameter with no value is expanded within
+       values, are removed.  If a parameter with no value is  expanded  within
        double quotes, a null argument results and is retained.
 
        Note that if no expansion occurs, no splitting is performed.
 
    P\bPa\bat\bth\bhn\bna\bam\bme\be E\bEx\bxp\bpa\ban\bns\bsi\bio\bon\bn
-       After word splitting, unless the -\b-f\bf option has  been  set,  b\bba\bas\bsh\b scans
-       each  word  for the characters *\b*, ?\b?, and [\b[.  If one of these characters
-       appears, then the word is regarded as a _\bp_\ba_\bt_\bt_\be_\br_\bn, and replaced  with  an
-       alphabetically  sorted list of filenames matching the pattern (see P\bPa\bat\bt-\b-
-       t\bte\ber\brn\bM\bMa\bat\btc\bch\bhi\bin\bng\bg below).  If no matching  filenames  are  found,  and  the
-       shell  option  n\bnu\bul\bll\blg\bgl\blo\bob\bb is not enabled, the word is left unchanged.  If
-       the n\bnu\bul\bll\blg\bgl\blo\bob\bb option is set, and no  matches  are  found,  the  word  is
-       removed.   If  the  f\bfa\bai\bil\blg\bgl\blo\bob\bb  shell  option  is set, and no matches are
+       After  word  splitting,  unless  the -\b-f\bf option has been set, b\bba\bas\bsh\bh scans
+       each word for the characters *\b*, ?\b?, and [\b[.  If one of  these  characters
+       appears,  then  the word is regarded as a _\bp_\ba_\bt_\bt_\be_\br_\bn, and replaced with an
+       alphabetically sorted list of filenames matching the pattern (see  P\bPa\bat\bt-\b-
+       t\bte\ber\brn\b M\bMa\bat\btc\bch\bhi\bin\bng\bg  below).   If  no  matching filenames are found, and the
+       shell option n\bnu\bul\bll\blg\bgl\blo\bob\bb is not enabled, the word is left  unchanged.   If
+       the  n\bnu\bul\bll\blg\bgl\blo\bob\bb  option  is  set,  and  no matches are found, the word is
+       removed.  If the f\bfa\bai\bil\blg\bgl\blo\bob\bb shell option  is  set,  and  no  matches  are
        found, an error message is printed and the command is not executed.  If
-       the  shell option n\bno\boc\bca\bas\bse\beg\bgl\blo\bob\bb is enabled, the match is performed without
-       regard to the case of alphabetic characters.  When a  pattern  is  used
-       for  pathname expansion, the character `\b``\b`.\b.'\b''\b'  at the start of a name or
-       immediately following a slash must be matched  explicitly,  unless  the
+       the shell option n\bno\boc\bca\bas\bse\beg\bgl\blo\bob\bb is enabled, the match is performed  without
+       regard  to  the  case of alphabetic characters.  When a pattern is used
+       for pathname expansion, the character `\b``\b`.\b.'\b''\b'  at the start of a name  or
+       immediately  following  a  slash must be matched explicitly, unless the
        shell option d\bdo\bot\btg\bgl\blo\bob\bb is set.  When matching a pathname, the slash char-
-       acter must always be matched explicitly.  In  other  cases,  the  `\b``\b`.\b.'\b''\b'
+       acter  must  always  be  matched explicitly.  In other cases, the `\b``\b`.\b.'\b''\b'
        character is not treated specially.  See the description of s\bsh\bho\bop\bpt\bt below
        under S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS for a description of the n\bno\boc\bca\bas\bse\beg\bgl\blo\bob\bb, n\bnu\bul\bll\bl-\b-
        g\bgl\blo\bob\bb, f\bfa\bai\bil\blg\bgl\blo\bob\bb, and d\bdo\bot\btg\bgl\blo\bob\bb shell options.
 
-       The  G\bGL\bLO\bOB\bBI\bIG\bGN\bNO\bOR\bRE\bE shell variable may be used to restrict the set of file-
+       The G\bGL\bLO\bOB\bBI\bIG\bGN\bNO\bOR\bRE\bE shell variable may be used to restrict the set of  file-
        names matching a _\bp_\ba_\bt_\bt_\be_\br_\bn.  If G\bGL\bLO\bOB\bBI\bIG\bGN\bNO\bOR\bRE\bE is set, each matching filename
        that also matches one of the patterns in G\bGL\bLO\bOB\bBI\bIG\bGN\bNO\bOR\bRE\bE is removed from the
        list of matches.  If the n\bno\boc\bca\bas\bse\beg\bgl\blo\bob\bb option is set, the matching against
-       the  patterns  in  G\bGL\bLO\bOB\bBI\bIG\bGN\bNO\bOR\bRE\bE is performed without regard to case.  The
-       filenames `\b``\b`.\b.'\b''\b'  and `\b``\b`.\b..\b.'\b''\b'  are always ignored when G\bGL\bLO\bOB\bBI\bIG\bGN\bNO\bOR\bRE\bE is  set
-       and  not null.  However, setting G\bGL\bLO\bOB\bBI\bIG\bGN\bNO\bOR\bRE\bE to a non-null value has the
-       effect of enabling the d\bdo\bot\btg\bgl\blo\bob\bb shell option,  so  all  other  filenames
-       beginning  with a `\b``\b`.\b.'\b''\b'  will match.  To get the old behavior of ignor-
-       ing filenames beginning with a `\b``\b`.\b.'\b''\b', make `\b``\b`.\b.*\b*'\b''\b'  one of the  patterns
-       in  G\bGL\bLO\bOB\bBI\bIG\bGN\bNO\bOR\bRE\bE.   The  d\bdo\bot\btg\bgl\blo\bob\bb  option  is  disabled when G\bGL\bLO\bOB\bBI\bIG\bGN\bNO\bOR\bRE\bE is
+       the patterns in G\bGL\bLO\bOB\bBI\bIG\bGN\bNO\bOR\bRE\bE is performed without regard  to  case.   The
+       filenames  `\b``\b`.\b.'\b''\b'  and `\b``\b`.\b..\b.'\b''\b'  are always ignored when G\bGL\bLO\bOB\bBI\bIG\bGN\bNO\bOR\bRE\bE is set
+       and not null.  However, setting G\bGL\bLO\bOB\bBI\bIG\bGN\bNO\bOR\bRE\bE to a non-null value has  the
+       effect  of  enabling  the  d\bdo\bot\btg\bgl\blo\bob\bb shell option, so all other filenames
+       beginning with a `\b``\b`.\b.'\b''\b'  will match.  To get the old behavior of  ignor-
+       ing  filenames beginning with a `\b``\b`.\b.'\b''\b', make `\b``\b`.\b.*\b*'\b''\b'  one of the patterns
+       in G\bGL\bLO\bOB\bBI\bIG\bGN\bNO\bOR\bRE\bE.  The d\bdo\bot\btg\bgl\blo\bob\bb  option  is  disabled  when  G\bGL\bLO\bOB\bBI\bIG\bGN\bNO\bOR\bRE\b is
        unset.
 
        P\bPa\bat\btt\bte\ber\brn\bn M\bMa\bat\btc\bch\bhi\bin\bng\bg
 
        Any character that appears in a pattern, other than the special pattern
-       characters  described below, matches itself.  The NUL character may not
-       occur in a pattern.  A backslash escapes the following  character;  the
-       escaping  backslash  is  discarded  when matching.  The special pattern
+       characters described below, matches itself.  The NUL character may  not
+       occur  in  a pattern.  A backslash escapes the following character; the
+       escaping backslash is discarded when  matching.   The  special  pattern
        characters must be quoted if they are to be matched literally.
 
        The special pattern characters have the following meanings:
 
-              *\b*      Matches any string, including the null string.  When  the
-                     g\bgl\blo\bob\bbs\bst\bta\bar\b shell  option  is  enabled,  and *\b* is used in a
-                     pathname expansion context, two adjacent  *\b*s  used  as  a
-                     single  pattern  will  match  all  files and zero or more
-                     directories and subdirectories.  If followed by a /\b/,  two
-                     adjacent  *\b*s  will match only directories and subdirecto-
+              *\b*      Matches  any string, including the null string.  When the
+                     g\bgl\blo\bob\bbs\bst\bta\bar\bshell option is enabled, and  *\b*  is  used  in  a
+                     pathname  expansion  context,  two  adjacent *\b*s used as a
+                     single pattern will match all  files  and  zero  or  more
+                     directories  and subdirectories.  If followed by a /\b/, two
+                     adjacent *\b*s will match only directories  and  subdirecto-
                      ries.
               ?\b?      Matches any single character.
-              [\b[.\b..\b..\b.]\b]  Matches any one of the enclosed characters.   A  pair  of
-                     characters  separated by a hyphen denotes a _\br_\ba_\bn_\bg_\be _\be_\bx_\bp_\br_\be_\bs_\b-
-                     _\bs_\bi_\bo_\bn; any character that falls between those two  charac-
-                     ters,  inclusive,  using  the  current locale's collating
-                     sequence and character set, is  matched.   If  the  first
+              [\b[.\b..\b..\b.]\b]  Matches  any  one  of the enclosed characters.  A pair of
+                     characters separated by a hyphen denotes a _\br_\ba_\bn_\bg_\b _\be_\bx_\bp_\br_\be_\bs_\b-
+                     _\bs_\bi_\bo_\bn;  any character that falls between those two charac-
+                     ters, inclusive, using  the  current  locale's  collating
+                     sequence  and  character  set,  is matched.  If the first
                      character following the [\b[ is a !\b!  or a ^\b^ then any charac-
-                     ter not enclosed is matched.  The sorting order of  char-
-                     acters  in range expressions is determined by the current
-                     locale and the values of the L\bLC\bC_\b_C\bCO\bOL\bLL\bLA\bAT\bTE\bE or  L\bLC\bC_\b_A\bAL\bLL\b shell
+                     ter  not enclosed is matched.  The sorting order of char-
+                     acters in range expressions is determined by the  current
+                     locale  and  the values of the L\bLC\bC_\b_C\bCO\bOL\bLL\bLA\bAT\bTE\bE or L\bLC\bC_\b_A\bAL\bLL\bL shell
                      variables, if set.  To obtain the traditional interpreta-
-                     tion of range expressions, where [\b[a\ba-\b-d\bd]\b] is  equivalent  to
-                     [\b[a\bab\bbc\bcd\bd]\b],  set  value of the L\bLC\bC_\b_A\bAL\bLL\bL shell variable to C\bC, or
-                     enable the g\bgl\blo\bob\bba\bas\bsc\bci\bii\bir\bra\ban\bng\bge\bes\bs shell  option.   A  -\b-  may  be
+                     tion  of  range expressions, where [\b[a\ba-\b-d\bd]\b] is equivalent to
+                     [\b[a\bab\bbc\bcd\bd]\b], set value of the L\bLC\bC_\b_A\bAL\bLL\bL shell variable to  C\bC,  or
+                     enable  the  g\bgl\blo\bob\bba\bas\bsc\bci\bii\bir\bra\ban\bng\bge\bes\bs  shell  option.   A -\b- may be
                      matched by including it as the first or last character in
                      the set.  A ]\b] may be matched by including it as the first
                      character in the set.
 
-                     Within  [\b[ and ]\b], _\bc_\bh_\ba_\br_\ba_\bc_\bt_\be_\br _\bc_\bl_\ba_\bs_\bs_\be_\bs can be specified using
+                     Within [\b[ and ]\b], _\bc_\bh_\ba_\br_\ba_\bc_\bt_\be_\br _\bc_\bl_\ba_\bs_\bs_\be_\bs can be specified  using
                      the syntax [\b[:\b:_\bc_\bl_\ba_\bs_\bs:\b:]\b], where _\bc_\bl_\ba_\bs_\bs is one of the following
                      classes defined in the POSIX standard:
-                     a\bal\bln\bnu\bum\b a\bal\blp\bph\bha\ba  a\bas\bsc\bci\bii\bi  b\bbl\bla\ban\bnk\bk  c\bcn\bnt\btr\brl\bl d\bdi\big\bgi\bit\bt g\bgr\bra\bap\bph\bh l\blo\bow\bwe\ber\br p\bpr\bri\bin\bnt\bt
+                     a\bal\bln\bnu\bum\ba\bal\blp\bph\bha\ba a\bas\bsc\bci\bii\bi b\bbl\bla\ban\bnk\bk c\bcn\bnt\btr\brl\bl  d\bdi\big\bgi\bit\bt  g\bgr\bra\bap\bph\bh  l\blo\bow\bwe\ber\b p\bpr\bri\bin\bnt\bt
                      p\bpu\bun\bnc\bct\bt s\bsp\bpa\bac\bce\be u\bup\bpp\bpe\ber\br w\bwo\bor\brd\bd x\bxd\bdi\big\bgi\bit\bt
                      A character class matches any character belonging to that
                      class.  The w\bwo\bor\brd\bd character class matches letters, digits,
                      and the character _.
 
-                     Within [\b[ and ]\b], an _\be_\bq_\bu_\bi_\bv_\ba_\bl_\be_\bn_\bc_\be  _\bc_\bl_\ba_\bs_\bs  can  be  specified
+                     Within  [\b[  and  ]\b],  an _\be_\bq_\bu_\bi_\bv_\ba_\bl_\be_\bn_\bc_\be _\bc_\bl_\ba_\bs_\bs can be specified
                      using the syntax [\b[=\b=_\bc=\b=]\b], which matches all characters with
-                     the same collation weight  (as  defined  by  the  current
+                     the  same  collation  weight  (as  defined by the current
                      locale) as the character _\bc.
 
                      Within [\b[ and ]\b], the syntax [\b[.\b._\bs_\by_\bm_\bb_\bo_\bl.\b.]\b] matches the collat-
                      ing symbol _\bs_\by_\bm_\bb_\bo_\bl.
 
        If the e\bex\bxt\btg\bgl\blo\bob\bb shell option is enabled using the s\bsh\bho\bop\bpt\bt builtin, several
-       extended  pattern  matching operators are recognized.  In the following
+       extended pattern matching operators are recognized.  In  the  following
        description, a _\bp_\ba_\bt_\bt_\be_\br_\bn_\b-_\bl_\bi_\bs_\bt is a list of one or more patterns separated
        by a |\b|.  Composite patterns may be formed using one or more of the fol-
        lowing sub-patterns:
@@ -1888,58 +1920,58 @@ E\bEX\bXP\bPA\bAN\bNS\bSI\bIO\bON\bN
 
    Q\bQu\buo\bot\bte\be R\bRe\bem\bmo\bov\bva\bal\bl
        After the preceding expansions, all unquoted occurrences of the charac-
-       ters  \\b\,  '\b', and "\b" that did not result from one of the above expansions
+       ters \\b\, '\b', and "\b" that did not result from one of the  above  expansions
        are removed.
 
 R\bRE\bED\bDI\bIR\bRE\bEC\bCT\bTI\bIO\bON\bN
-       Before a command is executed, its input and output  may  be  _\br_\be_\bd_\bi_\br_\be_\bc_\bt_\be_\bd
-       using  a special notation interpreted by the shell.  Redirection allows
-       commands' file handles to be duplicated, opened, closed, made to  refer
+       Before  a  command  is executed, its input and output may be _\br_\be_\bd_\bi_\br_\be_\bc_\bt_\be_\bd
+       using a special notation interpreted by the shell.  Redirection  allows
+       commands'  file handles to be duplicated, opened, closed, made to refer
        to different files, and can change the files the command reads from and
-       writes to.  Redirection may also be used to modify file handles in  the
-       current  shell execution environment.  The following redirection opera-
+       writes  to.  Redirection may also be used to modify file handles in the
+       current shell execution environment.  The following redirection  opera-
        tors may precede or appear anywhere within a _\bs_\bi_\bm_\bp_\bl_\be _\bc_\bo_\bm_\bm_\ba_\bn_\bd or may fol-
-       low  a  _\bc_\bo_\bm_\bm_\ba_\bn_\bd.   Redirections are processed in the order they appear,
+       low a _\bc_\bo_\bm_\bm_\ba_\bn_\bd.  Redirections are processed in the  order  they  appear,
        from left to right.
 
-       Each redirection that may be preceded by a file descriptor  number  may
+       Each  redirection  that may be preceded by a file descriptor number may
        instead be preceded by a word of the form {_\bv_\ba_\br_\bn_\ba_\bm_\be}.  In this case, for
        each redirection operator except >&- and <&-, the shell will allocate a
-       file  descriptor  greater than or equal to 10 and assign it to _\bv_\ba_\br_\bn_\ba_\bm_\be.
-       If >&- or <&- is preceded by {_\bv_\ba_\br_\bn_\ba_\bm_\be}, the value  of  _\bv_\ba_\br_\bn_\ba_\bm_\b defines
+       file descriptor greater than or equal to 10 and assign it  to  _\bv_\ba_\br_\bn_\ba_\bm_\be.
+       If  >&-  or  <&- is preceded by {_\bv_\ba_\br_\bn_\ba_\bm_\be}, the value of _\bv_\ba_\br_\bn_\ba_\bm_\be defines
        the file descriptor to close.
 
-       In  the  following descriptions, if the file descriptor number is omit-
-       ted, and the first character of the redirection operator is <\b<, the  re-
-       direction  refers  to  the  standard input (file descriptor 0).  If the
-       first character of the  redirection  operator  is  >\b>,  the  redirection
+       In the following descriptions, if the file descriptor number  is  omit-
+       ted,  and the first character of the redirection operator is <\b<, the re-
+       direction refers to the standard input (file  descriptor  0).   If  the
+       first  character  of  the  redirection  operator  is >\b>, the redirection
        refers to the standard output (file descriptor 1).
 
-       The  word  following the redirection operator in the following descrip-
-       tions, unless otherwise noted, is subjected to brace  expansion,  tilde
-       expansion,  parameter  and  variable  expansion,  command substitution,
-       arithmetic expansion,  quote  removal,  pathname  expansion,  and  word
+       The word following the redirection operator in the  following  descrip-
+       tions,  unless  otherwise noted, is subjected to brace expansion, tilde
+       expansion, parameter  and  variable  expansion,  command  substitution,
+       arithmetic  expansion,  quote  removal,  pathname  expansion,  and word
        splitting.  If it expands to more than one word, b\bba\bas\bsh\bh reports an error.
 
-       Note  that  the order of redirections is significant.  For example, the
+       Note that the order of redirections is significant.  For  example,  the
        command
 
               ls >\b> dirlist 2>\b>&\b&1
 
-       directs both standard output and standard error to  the  file  _\bd_\bi_\br_\bl_\bi_\bs_\bt,
+       directs  both  standard  output and standard error to the file _\bd_\bi_\br_\bl_\bi_\bs_\bt,
        while the command
 
               ls 2>\b>&\b&1 >\b> dirlist
 
-       directs  only the standard output to file _\bd_\bi_\br_\bl_\bi_\bs_\bt, because the standard
-       error was duplicated from the standard output before the standard  out-
+       directs only the standard output to file _\bd_\bi_\br_\bl_\bi_\bs_\bt, because the  standard
+       error  was duplicated from the standard output before the standard out-
        put was redirected to _\bd_\bi_\br_\bl_\bi_\bs_\bt.
 
        B\bBa\bas\bsh\bh handles several filenames specially when they are used in redirec-
        tions, as described in the following table:
 
               /\b/d\bde\bev\bv/\b/f\bfd\bd/\b/_\bf_\bd
-                     If _\bf_\bd is a valid integer, file descriptor  _\bf_\bd  is  dupli-
+                     If  _\bf_\bd  is  a valid integer, file descriptor _\bf_\bd is dupli-
                      cated.
               /\b/d\bde\bev\bv/\b/s\bst\btd\bdi\bin\bn
                      File descriptor 0 is duplicated.
@@ -1949,22 +1981,22 @@ R\bRE\bED\bDI\bIR\bRE\bEC\bCT\bTI\bIO\bON\bN
                      File descriptor 2 is duplicated.
               /\b/d\bde\bev\bv/\b/t\btc\bcp\bp/\b/_\bh_\bo_\bs_\bt/\b/_\bp_\bo_\br_\bt
                      If _\bh_\bo_\bs_\bt is a valid hostname or Internet address, and _\bp_\bo_\br_\bt
-                     is an integer port number or service name, b\bba\bas\bsh\b attempts
+                     is  an integer port number or service name, b\bba\bas\bsh\bh attempts
                      to open the corresponding TCP socket.
               /\b/d\bde\bev\bv/\b/u\bud\bdp\bp/\b/_\bh_\bo_\bs_\bt/\b/_\bp_\bo_\br_\bt
                      If _\bh_\bo_\bs_\bt is a valid hostname or Internet address, and _\bp_\bo_\br_\bt
-                     is an integer port number or service name, b\bba\bas\bsh\b attempts
+                     is  an integer port number or service name, b\bba\bas\bsh\bh attempts
                      to open the corresponding UDP socket.
 
        A failure to open or create a file causes the redirection to fail.
 
-       Redirections  using file descriptors greater than 9 should be used with
-       care, as they may conflict with file descriptors the shell uses  inter-
+       Redirections using file descriptors greater than 9 should be used  with
+       care,  as they may conflict with file descriptors the shell uses inter-
        nally.
 
    R\bRe\bed\bdi\bir\bre\bec\bct\bti\bin\bng\bg I\bIn\bnp\bpu\but\bt
        Redirection of input causes the file whose name results from the expan-
-       sion of _\bw_\bo_\br_\bd to be opened for reading on  file  descriptor  _\bn,  or  the
+       sion  of  _\bw_\bo_\br_\bd  to  be  opened for reading on file descriptor _\bn, or the
        standard input (file descriptor 0) if _\bn is not specified.
 
        The general format for redirecting input is:
@@ -1972,27 +2004,27 @@ R\bRE\bED\bDI\bIR\bRE\bEC\bCT\bTI\bIO\bON\bN
               [_\bn]<\b<_\bw_\bo_\br_\bd
 
    R\bRe\bed\bdi\bir\bre\bec\bct\bti\bin\bng\bg O\bOu\but\btp\bpu\but\bt
-       Redirection  of  output  causes  the  file  whose name results from the
+       Redirection of output causes the  file  whose  name  results  from  the
        expansion of _\bw_\bo_\br_\bd to be opened for writing on file descriptor _\bn, or the
        standard output (file descriptor 1) if _\bn is not specified.  If the file
-       does not exist it is created; if it does exist it is truncated to  zero
+       does  not exist it is created; if it does exist it is truncated to zero
        size.
 
        The general format for redirecting output is:
 
               [_\bn]>\b>_\bw_\bo_\br_\bd
 
-       If  the  redirection operator is >\b>, and the n\bno\boc\bcl\blo\bob\bbb\bbe\ber\br option to the s\bse\bet\bt
-       builtin has been enabled, the redirection will fail if the  file  whose
-       name  results  from the expansion of _\bw_\bo_\br_\bd exists and is a regular file.
+       If the redirection operator is >\b>, and the n\bno\boc\bcl\blo\bob\bbb\bbe\ber\br option to  the  s\bse\bet\bt
+       builtin  has  been enabled, the redirection will fail if the file whose
+       name results from the expansion of _\bw_\bo_\br_\bd exists and is a  regular  file.
        If the redirection operator is >\b>|\b|, or the redirection operator is >\b> and
        the n\bno\boc\bcl\blo\bob\bbb\bbe\ber\br option to the s\bse\bet\bt builtin command is not enabled, the re-
        direction is attempted even if the file named by _\bw_\bo_\br_\bd exists.
 
    A\bAp\bpp\bpe\ben\bnd\bdi\bin\bng\bg R\bRe\bed\bdi\bir\bre\bec\bct\bte\bed\bd O\bOu\but\btp\bpu\but\bt
-       Redirection of output in  this  fashion  causes  the  file  whose  name
-       results  from  the expansion of _\bw_\bo_\br_\bd to be opened for appending on file
-       descriptor _\bn, or the standard output (file descriptor 1) if  _\bn  is  not
+       Redirection  of  output  in  this  fashion  causes  the file whose name
+       results from the expansion of _\bw_\bo_\br_\bd to be opened for appending  on  file
+       descriptor  _\bn,  or  the standard output (file descriptor 1) if _\bn is not
        specified.  If the file does not exist it is created.
 
        The general format for appending output is:
@@ -2000,11 +2032,11 @@ R\bRE\bED\bDI\bIR\bRE\bEC\bCT\bTI\bIO\bON\bN
               [_\bn]>\b>>\b>_\bw_\bo_\br_\bd
 
    R\bRe\bed\bdi\bir\bre\bec\bct\bti\bin\bng\bg S\bSt\bta\ban\bnd\bda\bar\brd\bd O\bOu\but\btp\bpu\but\bt a\ban\bnd\bd S\bSt\bta\ban\bnd\bda\bar\brd\bd E\bEr\brr\bro\bor\br
-       This  construct allows both the standard output (file descriptor 1) and
-       the standard error output (file descriptor 2) to be redirected  to  the
+       This construct allows both the standard output (file descriptor 1)  and
+       the  standard  error output (file descriptor 2) to be redirected to the
        file whose name is the expansion of _\bw_\bo_\br_\bd.
 
-       There  are  two  formats  for  redirecting standard output and standard
+       There are two formats for  redirecting  standard  output  and  standard
        error:
 
               &\b&>\b>_\bw_\bo_\br_\bd
@@ -2016,13 +2048,13 @@ R\bRE\bED\bDI\bIR\bRE\bEC\bCT\bTI\bIO\bON\bN
 
               >\b>_\bw_\bo_\br_\bd 2>\b>&\b&1
 
-       When  using  the second form, _\bw_\bo_\br_\bd may not expand to a number or -\b-.  If
-       it does,  other  redirection  operators  apply  (see  D\bDu\bup\bpl\bli\bic\bca\bat\bti\bin\bng\b F\bFi\bil\ble\be
+       When using the second form, _\bw_\bo_\br_\bd may not expand to a number or  -\b-.   If
+       it  does,  other  redirection  operators  apply  (see  D\bDu\bup\bpl\bli\bic\bca\bat\bti\bin\bng\bg F\bFi\bil\ble\be
        D\bDe\bes\bsc\bcr\bri\bip\bpt\bto\bor\brs\bs below) for compatibility reasons.
 
    A\bAp\bpp\bpe\ben\bnd\bdi\bin\bng\bg S\bSt\bta\ban\bnd\bda\bar\brd\bd O\bOu\but\btp\bpu\but\bt a\ban\bnd\bd S\bSt\bta\ban\bnd\bda\bar\brd\bd E\bEr\brr\bro\bor\br
-       This  construct allows both the standard output (file descriptor 1) and
-       the standard error output (file descriptor 2) to  be  appended  to  the
+       This construct allows both the standard output (file descriptor 1)  and
+       the  standard  error  output  (file descriptor 2) to be appended to the
        file whose name is the expansion of _\bw_\bo_\br_\bd.
 
        The format for appending standard output and standard error is:
@@ -2036,10 +2068,10 @@ R\bRE\bED\bDI\bIR\bRE\bEC\bCT\bTI\bIO\bON\bN
        (see D\bDu\bup\bpl\bli\bic\bca\bat\bti\bin\bng\bg F\bFi\bil\ble\be D\bDe\bes\bsc\bcr\bri\bip\bpt\bto\bor\brs\bs below).
 
    H\bHe\ber\bre\be D\bDo\boc\bcu\bum\bme\ben\bnt\bts\bs
-       This  type  of  redirection  instructs the shell to read input from the
+       This type of redirection instructs the shell to  read  input  from  the
        current source until a line containing only _\bd_\be_\bl_\bi_\bm_\bi_\bt_\be_\br (with no trailing
-       blanks)  is seen.  All of the lines read up to that point are then used
-       as the standard input (or file descriptor _\bn if _\bn is  specified)  for  a
+       blanks) is seen.  All of the lines read up to that point are then  used
+       as  the  standard  input (or file descriptor _\bn if _\bn is specified) for a
        command.
 
        The format of here-documents is:
@@ -2048,18 +2080,18 @@ R\bRE\bED\bDI\bIR\bRE\bEC\bCT\bTI\bIO\bON\bN
                       _\bh_\be_\br_\be_\b-_\bd_\bo_\bc_\bu_\bm_\be_\bn_\bt
               _\bd_\be_\bl_\bi_\bm_\bi_\bt_\be_\br
 
-       No  parameter  and variable expansion, command substitution, arithmetic
-       expansion, or pathname expansion is performed on _\bw_\bo_\br_\bd.  If any  charac-
-       ters  in  _\bw_\bo_\br_\bd are quoted, the _\bd_\be_\bl_\bi_\bm_\bi_\bt_\be_\br is the result of quote removal
-       on _\bw_\bo_\br_\bd, and the lines in the here-document are not expanded.  If  _\bw_\bo_\br_\bd
-       is  unquoted, all lines of the here-document are subjected to parameter
-       expansion, command substitution, and arithmetic expansion, the  charac-
-       ter  sequence  \\b\<\b<n\bne\bew\bwl\bli\bin\bne\be>\b>  is  ignored, and \\b\ must be used to quote the
+       No parameter and variable expansion, command  substitution,  arithmetic
+       expansion,  or pathname expansion is performed on _\bw_\bo_\br_\bd.  If any charac-
+       ters in _\bw_\bo_\br_\bd are quoted, the _\bd_\be_\bl_\bi_\bm_\bi_\bt_\be_\br is the result of  quote  removal
+       on  _\bw_\bo_\br_\bd, and the lines in the here-document are not expanded.  If _\bw_\bo_\br_\bd
+       is unquoted, all lines of the here-document are subjected to  parameter
+       expansion,  command substitution, and arithmetic expansion, the charac-
+       ter sequence \\b\<\b<n\bne\bew\bwl\bli\bin\bne\be>\b> is ignored, and \\b\ must be  used  to  quote  the
        characters \\b\, $\b$, and `\b`.
 
        If the redirection operator is <\b<<\b<-\b-, then all leading tab characters are
-       stripped  from  input  lines  and  the line containing _\bd_\be_\bl_\bi_\bm_\bi_\bt_\be_\br.  This
-       allows here-documents within shell scripts to be indented in a  natural
+       stripped from input lines and  the  line  containing  _\bd_\be_\bl_\bi_\bm_\bi_\bt_\be_\br.   This
+       allows  here-documents within shell scripts to be indented in a natural
        fashion.
 
    H\bHe\ber\bre\be S\bSt\btr\bri\bin\bng\bgs\bs
@@ -2067,10 +2099,10 @@ R\bRE\bED\bDI\bIR\bRE\bEC\bCT\bTI\bIO\bON\bN
 
               [_\bn]<\b<<\b<<\b<_\bw_\bo_\br_\bd
 
-       The  _\bw_\bo_\br_\bd  undergoes  brace  expansion,  tilde expansion, parameter and
-       variable expansion, command  substitution,  arithmetic  expansion,  and
-       quote  removal.   Pathname  expansion  and  word splitting are not per-
-       formed.  The result is supplied as a single string to  the  command  on
+       The _\bw_\bo_\br_\bd undergoes brace  expansion,  tilde  expansion,  parameter  and
+       variable  expansion,  command  substitution,  arithmetic expansion, and
+       quote removal.  Pathname expansion and  word  splitting  are  not  per-
+       formed.   The  result  is supplied as a single string to the command on
        its standard input (or file descriptor _\bn if _\bn is specified).
 
    D\bDu\bup\bpl\bli\bic\bca\bat\bti\bin\bng\bg F\bFi\bil\ble\be D\bDe\bes\bsc\bcr\bri\bip\bpt\bto\bor\brs\bs
@@ -2079,22 +2111,22 @@ R\bRE\bED\bDI\bIR\bRE\bEC\bCT\bTI\bIO\bON\bN
               [_\bn]<\b<&\b&_\bw_\bo_\br_\bd
 
        is used to duplicate input file descriptors.  If _\bw_\bo_\br_\bd expands to one or
-       more digits, the file descriptor denoted by _\bn is made to be a  copy  of
-       that  file  descriptor.   If  the  digits in _\bw_\bo_\br_\bd do not specify a file
-       descriptor open for input, a redirection error occurs.  If _\bw_\bo_\br_\b evalu-
-       ates  to  -\b-,  file  descriptor _\bn is closed.  If _\bn is not specified, the
+       more  digits,  the file descriptor denoted by _\bn is made to be a copy of
+       that file descriptor.  If the digits in _\bw_\bo_\br_\bd  do  not  specify  a  file
+       descriptor  open for input, a redirection error occurs.  If _\bw_\bo_\br_\bd evalu-
+       ates to -\b-, file descriptor _\bn is closed.  If _\bn  is  not  specified,  the
        standard input (file descriptor 0) is used.
 
        The operator
 
               [_\bn]>\b>&\b&_\bw_\bo_\br_\bd
 
-       is used similarly to duplicate output file descriptors.  If  _\bn  is  not
-       specified,  the  standard  output  (file descriptor 1) is used.  If the
-       digits in _\bw_\bo_\br_\bd do not specify a file descriptor open for output, a  re-
-       direction  error  occurs.  If _\bw_\bo_\br_\bd evaluates to -\b-, file descriptor _\bn is
-       closed.  As a special case, if _\bn is omitted, and _\bw_\bo_\br_\bd does  not  expand
-       to  one or more digits or -\b-, the standard output and standard error are
+       is  used  similarly  to duplicate output file descriptors.  If _\bn is not
+       specified, the standard output (file descriptor 1)  is  used.   If  the
+       digits  in _\bw_\bo_\br_\bd do not specify a file descriptor open for output, a re-
+       direction error occurs.  If _\bw_\bo_\br_\bd evaluates to -\b-, file descriptor  _\b is
+       closed.   As  a special case, if _\bn is omitted, and _\bw_\bo_\br_\bd does not expand
+       to one or more digits or -\b-, the standard output and standard error  are
        redirected as described previously.
 
    M\bMo\bov\bvi\bin\bng\bg F\bFi\bil\ble\be D\bDe\bes\bsc\bcr\bri\bip\bpt\bto\bor\brs\bs
@@ -2102,7 +2134,7 @@ R\bRE\bED\bDI\bIR\bRE\bEC\bCT\bTI\bIO\bON\bN
 
               [_\bn]<\b<&\b&_\bd_\bi_\bg_\bi_\bt-\b-
 
-       moves the file descriptor _\bd_\bi_\bg_\bi_\bt to file descriptor _\bn, or  the  standard
+       moves  the  file descriptor _\bd_\bi_\bg_\bi_\bt to file descriptor _\bn, or the standard
        input (file descriptor 0) if _\bn is not specified.  _\bd_\bi_\bg_\bi_\bt is closed after
        being duplicated to _\bn.
 
@@ -2110,7 +2142,7 @@ R\bRE\bED\bDI\bIR\bRE\bEC\bCT\bTI\bIO\bON\bN
 
               [_\bn]>\b>&\b&_\bd_\bi_\bg_\bi_\bt-\b-
 
-       moves the file descriptor _\bd_\bi_\bg_\bi_\bt to file descriptor _\bn, or  the  standard
+       moves  the  file descriptor _\bd_\bi_\bg_\bi_\bt to file descriptor _\bn, or the standard
        output (file descriptor 1) if _\bn is not specified.
 
    O\bOp\bpe\ben\bni\bin\bng\bg F\bFi\bil\ble\be D\bDe\bes\bsc\bcr\bri\bip\bpt\bto\bor\brs\bs f\bfo\bor\br R\bRe\bea\bad\bdi\bin\bng\bg a\ban\bnd\bd W\bWr\bri\bit\bti\bin\bng\bg
@@ -2118,117 +2150,117 @@ R\bRE\bED\bDI\bIR\bRE\bEC\bCT\bTI\bIO\bON\bN
 
               [_\bn]<\b<>\b>_\bw_\bo_\br_\bd
 
-       causes  the  file  whose name is the expansion of _\bw_\bo_\br_\bd to be opened for
-       both reading and writing on file descriptor _\bn, or on file descriptor  0
+       causes the file whose name is the expansion of _\bw_\bo_\br_\bd to  be  opened  for
+       both  reading and writing on file descriptor _\bn, or on file descriptor 0
        if _\bn is not specified.  If the file does not exist, it is created.
 
 A\bAL\bLI\bIA\bAS\bSE\bES\bS
-       _\bA_\bl_\bi_\ba_\bs_\be_\b allow a string to be substituted for a word when it is used as
-       the first word of a simple command.  The  shell  maintains  a  list  of
-       aliases  that  may  be set and unset with the a\bal\bli\bia\bas\bs and u\bun\bna\bal\bli\bia\bas\bs builtin
-       commands (see S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS below).  The first  word  of  each
-       simple  command, if unquoted, is checked to see if it has an alias.  If
-       so, that word is replaced by the text of the alias.  The characters  /\b/,
-       $\b$,  `\b`,  and =\b= and any of the shell _\bm_\be_\bt_\ba_\bc_\bh_\ba_\br_\ba_\bc_\bt_\be_\br_\bs or quoting characters
+       _\bA_\bl_\bi_\ba_\bs_\be_\ballow a string to be substituted for a word when it is used  as
+       the  first  word  of  a  simple command.  The shell maintains a list of
+       aliases that may be set and unset with the a\bal\bli\bia\bas\bs  and  u\bun\bna\bal\bli\bia\bas\b builtin
+       commands  (see  S\bSH\bHE\bEL\bLL\bL  B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS below).  The first word of each
+       simple command, if unquoted, is checked to see if it has an alias.   If
+       so,  that word is replaced by the text of the alias.  The characters /\b/,
+       $\b$, `\b`, and =\b= and any of the shell _\bm_\be_\bt_\ba_\bc_\bh_\ba_\br_\ba_\bc_\bt_\be_\br_\bs or  quoting  characters
        listed above may not appear in an alias name.  The replacement text may
-       contain  any  valid  shell  input, including shell metacharacters.  The
-       first word of the replacement text is tested for aliases,  but  a  word
-       that  is  identical to an alias being expanded is not expanded a second
-       time.  This means that one may alias l\bls\bs to l\bls\bs  -\b-F\bF,  for  instance,  and
-       b\bba\bas\bsh\b does  not try to recursively expand the replacement text.  If the
-       last character of the alias value is a _\bb_\bl_\ba_\bn_\bk,  then  the  next  command
+       contain any valid shell input,  including  shell  metacharacters.   The
+       first  word  of  the replacement text is tested for aliases, but a word
+       that is identical to an alias being expanded is not expanded  a  second
+       time.   This  means  that  one may alias l\bls\bs to l\bls\bs -\b-F\bF, for instance, and
+       b\bba\bas\bsh\bdoes not try to recursively expand the replacement text.   If  the
+       last  character  of  the  alias value is a _\bb_\bl_\ba_\bn_\bk, then the next command
        word following the alias is also checked for alias expansion.
 
        Aliases are created and listed with the a\bal\bli\bia\bas\bs command, and removed with
        the u\bun\bna\bal\bli\bia\bas\bs command.
 
-       There is no mechanism for using arguments in the replacement text.   If
-       arguments  are  needed,  a shell function should be used (see F\bFU\bUN\bNC\bCT\bTI\bIO\bON\bNS\bS
+       There  is no mechanism for using arguments in the replacement text.  If
+       arguments are needed, a shell function should be  used  (see  F\bFU\bUN\bNC\bCT\bTI\bIO\bON\bNS\bS
        below).
 
-       Aliases are not expanded when the shell is not interactive, unless  the
-       e\bex\bxp\bpa\ban\bnd\bd_\b_a\bal\bli\bia\bas\bse\bes\b shell option is set using s\bsh\bho\bop\bpt\bt (see the description of
+       Aliases  are not expanded when the shell is not interactive, unless the
+       e\bex\bxp\bpa\ban\bnd\bd_\b_a\bal\bli\bia\bas\bse\bes\bshell option is set using s\bsh\bho\bop\bpt\bt (see the description  of
        s\bsh\bho\bop\bpt\bt under S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS below).
 
-       The rules concerning the definition and use  of  aliases  are  somewhat
-       confusing.   B\bBa\bas\bsh\bh  always  reads  at  least  one complete line of input
-       before executing any  of  the  commands  on  that  line.   Aliases  are
-       expanded  when  a command is read, not when it is executed.  Therefore,
-       an alias definition appearing on the same line as another command  does
-       not  take  effect  until  the next line of input is read.  The commands
+       The  rules  concerning  the  definition and use of aliases are somewhat
+       confusing.  B\bBa\bas\bsh\bh always reads at  least  one  complete  line  of  input
+       before  executing  any  of  the  commands  on  that  line.  Aliases are
+       expanded when a command is read, not when it is  executed.   Therefore,
+       an  alias definition appearing on the same line as another command does
+       not take effect until the next line of input  is  read.   The  commands
        following the alias definition on that line are not affected by the new
-       alias.   This  behavior  is  also an issue when functions are executed.
-       Aliases are expanded when a function definition is read, not  when  the
-       function  is  executed,  because a function definition is itself a com-
-       mand.  As a consequence, aliases defined in a function are  not  avail-
-       able  until  after  that  function is executed.  To be safe, always put
-       alias definitions on a separate line, and do not use a\bal\bli\bia\bas\bs in  compound
+       alias.  This behavior is also an issue  when  functions  are  executed.
+       Aliases  are  expanded when a function definition is read, not when the
+       function is executed, because a function definition is  itself  a  com-
+       mand.   As  a consequence, aliases defined in a function are not avail-
+       able until after that function is executed.  To  be  safe,  always  put
+       alias  definitions on a separate line, and do not use a\bal\bli\bia\bas\bs in compound
        commands.
 
        For almost every purpose, aliases are superseded by shell functions.
 
 F\bFU\bUN\bNC\bCT\bTI\bIO\bON\bNS\bS
-       A  shell  function,  defined  as  described  above under S\bSH\bHE\bEL\bLL\bL G\bGR\bRA\bAM\bMM\bMA\bAR\bR,
-       stores a series of commands for later execution.  When the  name  of  a
-       shell  function  is used as a simple command name, the list of commands
+       A shell function, defined  as  described  above  under  S\bSH\bHE\bEL\bLL\b G\bGR\bRA\bAM\bMM\bMA\bAR\bR,
+       stores  a  series  of commands for later execution.  When the name of a
+       shell function is used as a simple command name, the list  of  commands
        associated with that function name is executed.  Functions are executed
-       in  the  context  of  the  current  shell; no new process is created to
-       interpret them (contrast this with the execution of  a  shell  script).
-       When  a  function is executed, the arguments to the function become the
+       in the context of the current shell;  no  new  process  is  created  to
+       interpret  them  (contrast  this with the execution of a shell script).
+       When a function is executed, the arguments to the function  become  the
        positional parameters during its execution.  The special parameter #\b# is
-       updated  to reflect the change.  Special parameter 0\b0 is unchanged.  The
-       first element of the F\bFU\bUN\bNC\bCN\bNA\bAM\bME\bE variable is set to the name of the  func-
+       updated to reflect the change.  Special parameter 0\b0 is unchanged.   The
+       first  element of the F\bFU\bUN\bNC\bCN\bNA\bAM\bME\bE variable is set to the name of the func-
        tion while the function is executing.
 
-       All  other  aspects  of  the  shell execution environment are identical
-       between a function and its caller with these exceptions: the D\bDE\bEB\bBU\bUG\b and
-       R\bRE\bET\bTU\bUR\bRN\b traps  (see  the  description  of  the t\btr\bra\bap\bp builtin under S\bSH\bHE\bEL\bLL\bL
-       B\bBU\bUI\bIL\bLT\bTI\bIN\bC\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS below) are not inherited unless the function has  been
-       given  the  t\btr\bra\bac\bce\be attribute (see the description of the d\bde\bec\bcl\bla\bar\bre\be builtin
-       below) or the -\b-o\bo f\bfu\bun\bnc\bct\btr\bra\bac\bce\be shell option has been enabled with  the  s\bse\bet\bt
-       builtin  (in  which  case  all  functions  inherit the D\bDE\bEB\bBU\bUG\bG and R\bRE\bET\bTU\bUR\bRN\bN
-       traps), and the E\bER\bRR\bR trap is not inherited unless the -\b-o\bo e\ber\brr\brt\btr\bra\bac\bce\b shell
+       All other aspects of the  shell  execution  environment  are  identical
+       between  a function and its caller with these exceptions: the D\bDE\bEB\bBU\bUG\bG and
+       R\bRE\bET\bTU\bUR\bRN\btraps (see the description  of  the  t\btr\bra\bap\bp  builtin  under  S\bSH\bHE\bEL\bLL\bL
+       B\bBU\bUI\bIL\bLT\bTI\bIN\b C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS below) are not inherited unless the function has been
+       given the t\btr\bra\bac\bce\be attribute (see the description of the  d\bde\bec\bcl\bla\bar\bre\b builtin
+       below)  or  the -\b-o\bo f\bfu\bun\bnc\bct\btr\bra\bac\bce\be shell option has been enabled with the s\bse\bet\bt
+       builtin (in which case all  functions  inherit  the  D\bDE\bEB\bBU\bUG\bG  and  R\bRE\bET\bTU\bUR\bRN\bN
+       traps),  and the E\bER\bRR\bR trap is not inherited unless the -\b-o\bo e\ber\brr\brt\btr\bra\bac\bce\be shell
        option has been enabled.
 
-       Variables  local to the function may be declared with the l\blo\boc\bca\bal\bl builtin
+       Variables local to the function may be declared with the l\blo\boc\bca\bal\b builtin
        command.  Ordinarily, variables and their values are shared between the
        function and its caller.
 
-       The  F\bFU\bUN\bNC\bCN\bNE\bES\bST\bT  variable,  if  set  to  a  numeric value greater than 0,
-       defines a maximum function nesting level.   Function  invocations  that
+       The F\bFU\bUN\bNC\bCN\bNE\bES\bST\bT variable, if set  to  a  numeric  value  greater  than  0,
+       defines  a  maximum  function nesting level.  Function invocations that
        exceed the limit cause the entire command to abort.
 
-       If  the  builtin command r\bre\bet\btu\bur\brn\bn is executed in a function, the function
-       completes and execution resumes with the next command after  the  func-
-       tion  call.   Any  command  associated with the R\bRE\bET\bTU\bUR\bRN\bN trap is executed
+       If the builtin command r\bre\bet\btu\bur\brn\bn is executed in a function,  the  function
+       completes  and  execution resumes with the next command after the func-
+       tion call.  Any command associated with the  R\bRE\bET\bTU\bUR\bRN\bN  trap  is  executed
        before execution resumes.  When a function completes, the values of the
-       positional  parameters  and the special parameter #\b# are restored to the
+       positional parameters and the special parameter #\b# are restored  to  the
        values they had prior to the function's execution.
 
-       Function names and definitions may be listed with the -\b-f\bf option to  the
+       Function  names and definitions may be listed with the -\b-f\bf option to the
        d\bde\bec\bcl\bla\bar\bre\be or t\bty\byp\bpe\bes\bse\bet\bt builtin commands.  The -\b-F\bF option to d\bde\bec\bcl\bla\bar\bre\be or t\bty\byp\bpe\be-\b-
-       s\bse\bet\bwill list the function names only (and optionally the  source  file
-       and  line  number, if the e\bex\bxt\btd\bde\beb\bbu\bug\bg shell option is enabled).  Functions
-       may be exported so that subshells automatically have them defined  with
-       the  -\b-f\bf  option  to  the  e\bex\bxp\bpo\bor\brt\bt builtin.  A function definition may be
-       deleted using the -\b-f\bf option to the  u\bun\bns\bse\bet\bt  builtin.   Note  that  shell
+       s\bse\bet\b will  list the function names only (and optionally the source file
+       and line number, if the e\bex\bxt\btd\bde\beb\bbu\bug\bg shell option is  enabled).   Functions
+       may  be exported so that subshells automatically have them defined with
+       the -\b-f\bf option to the e\bex\bxp\bpo\bor\brt\bt builtin.   A  function  definition  may  be
+       deleted  using  the  -\b-f\bf  option  to the u\bun\bns\bse\bet\bt builtin.  Note that shell
        functions and variables with the same name may result in multiple iden-
-       tically-named entries in the environment passed to  the  shell's  chil-
+       tically-named  entries  in  the environment passed to the shell's chil-
        dren.  Care should be taken in cases where this may cause a problem.
 
        Functions may be recursive.  The F\bFU\bUN\bNC\bCN\bNE\bES\bST\bT variable may be used to limit
-       the depth of the function call stack and restrict the number  of  func-
-       tion  invocations.   By  default,  no limit is imposed on the number of
+       the  depth  of the function call stack and restrict the number of func-
+       tion invocations.  By default, no limit is imposed  on  the  number  of
        recursive calls.
 
 A\bAR\bRI\bIT\bTH\bHM\bME\bET\bTI\bIC\bC E\bEV\bVA\bAL\bLU\bUA\bAT\bTI\bIO\bON\bN
-       The shell allows arithmetic expressions to be evaluated, under  certain
-       circumstances  (see the l\ble\bet\bt and d\bde\bec\bcl\bla\bar\bre\be builtin commands and A\bAr\bri\bit\bth\bhm\bme\bet\bti\bic\bc
-       E\bEx\bxp\bpa\ban\bns\bsi\bio\bon\bn).  Evaluation is done in fixed-width integers with  no  check
-       for  overflow, though division by 0 is trapped and flagged as an error.
-       The operators and their precedence, associativity, and values  are  the
-       same  as in the C language.  The following list of operators is grouped
-       into levels of equal-precedence operators.  The levels  are  listed  in
+       The  shell allows arithmetic expressions to be evaluated, under certain
+       circumstances (see the l\ble\bet\bt and d\bde\bec\bcl\bla\bar\bre\be builtin commands and  A\bAr\bri\bit\bth\bhm\bme\bet\bti\bic\bc
+       E\bEx\bxp\bpa\ban\bns\bsi\bio\bon\bn).   Evaluation  is done in fixed-width integers with no check
+       for overflow, though division by 0 is trapped and flagged as an  error.
+       The  operators  and their precedence, associativity, and values are the
+       same as in the C language.  The following list of operators is  grouped
+       into  levels  of  equal-precedence operators.  The levels are listed in
        order of decreasing precedence.
 
        _\bi_\bd+\b++\b+ _\bi_\bd-\b--\b-
@@ -2256,46 +2288,46 @@ A\bAR\bRI\bIT\bTH\bHM\bME\bET\bTI\bIC\bC E\bEV\bVA\bAL\bLU\bUA\bAT\bTI\bIO\bON\bN
        _\be_\bx_\bp_\br_\b1 ,\b, _\be_\bx_\bp_\br_\b2
               comma
 
-       Shell  variables  are  allowed as operands; parameter expansion is per-
+       Shell variables are allowed as operands; parameter  expansion  is  per-
        formed before the expression is evaluated.  Within an expression, shell
-       variables  may  also  be referenced by name without using the parameter
-       expansion syntax.  A shell variable that is null or unset evaluates  to
+       variables may also be referenced by name without  using  the  parameter
+       expansion  syntax.  A shell variable that is null or unset evaluates to
        0 when referenced by name without using the parameter expansion syntax.
-       The value of a variable is evaluated as an arithmetic  expression  when
-       it  is  referenced, or when a variable which has been given the _\bi_\bn_\bt_\be_\bg_\be_\br
+       The  value  of a variable is evaluated as an arithmetic expression when
+       it is referenced, or when a variable which has been given  the  _\bi_\bn_\bt_\be_\bg_\be_\br
        attribute using d\bde\bec\bcl\bla\bar\bre\be -\b-i\bi is assigned a value.  A null value evaluates
-       to  0.   A shell variable need not have its _\bi_\bn_\bt_\be_\bg_\be_\br attribute turned on
+       to 0.  A shell variable need not have its _\bi_\bn_\bt_\be_\bg_\be_\br attribute  turned  on
        to be used in an expression.
 
        Constants with a leading 0 are interpreted as octal numbers.  A leading
-       0x  or  0X  denotes  hexadecimal.   Otherwise,  numbers  take  the form
-       [_\bb_\ba_\bs_\be_\b#]n, where the optional _\bb_\ba_\bs_\be is a decimal number between 2 and  64
-       representing  the  arithmetic base, and _\bn is a number in that base.  If
-       _\bb_\ba_\bs_\be_\bis omitted, then base 10 is used.  When specifying _\bn, the  digits
+       0x or  0X  denotes  hexadecimal.   Otherwise,  numbers  take  the  form
+       [_\bb_\ba_\bs_\be_\b#]n,  where the optional _\bb_\ba_\bs_\be is a decimal number between 2 and 64
+       representing the arithmetic base, and _\bn is a number in that  base.   If
+       _\bb_\ba_\bs_\be_\b is omitted, then base 10 is used.  When specifying _\bn, the digits
        greater< than 9 are represented by the lowercase letters, the uppercase
        letters, @, and _, in that order.  If _\bb_\ba_\bs_\be is less than or equal to 36,
-       lowercase  and  uppercase letters may be used interchangeably to repre-
+       lowercase and uppercase letters may be used interchangeably  to  repre-
        sent numbers between 10 and 35.
 
-       Operators are evaluated in order  of  precedence.   Sub-expressions  in
-       parentheses  are  evaluated first and may override the precedence rules
+       Operators  are  evaluated  in  order of precedence.  Sub-expressions in
+       parentheses are evaluated first and may override the  precedence  rules
        above.
 
 C\bCO\bON\bND\bDI\bIT\bTI\bIO\bON\bNA\bAL\bL E\bEX\bXP\bPR\bRE\bES\bSS\bSI\bIO\bON\bNS\bS
-       Conditional expressions are used by the [\b[[\b[  compound  command  and  the
-       t\bte\bes\bst\b and [\b[ builtin commands to test file attributes and perform string
-       and arithmetic comparisons.  Expressions are formed from the  following
-       unary  or  binary  primaries.   If any _\bf_\bi_\bl_\be argument to one of the pri-
+       Conditional  expressions  are  used  by the [\b[[\b[ compound command and the
+       t\bte\bes\bst\band [\b[ builtin commands to test file attributes and perform  string
+       and  arithmetic comparisons.  Expressions are formed from the following
+       unary or binary primaries.  If any _\bf_\bi_\bl_\be argument to  one  of  the  pri-
        maries is of the form _\b/_\bd_\be_\bv_\b/_\bf_\bd_\b/_\bn, then file descriptor _\bn is checked.  If
-       the  _\bf_\bi_\bl_\be  argument  to  one  of  the  primaries  is one of _\b/_\bd_\be_\bv_\b/_\bs_\bt_\bd_\bi_\bn,
-       _\b/_\bd_\be_\bv_\b/_\bs_\bt_\bd_\bo_\bu_\bt, or _\b/_\bd_\be_\bv_\b/_\bs_\bt_\bd_\be_\br_\br, file descriptor 0, 1, or 2,  respectively,
+       the _\bf_\bi_\bl_\be argument to  one  of  the  primaries  is  one  of  _\b/_\bd_\be_\bv_\b/_\bs_\bt_\bd_\bi_\bn,
+       _\b/_\bd_\be_\bv_\b/_\bs_\bt_\bd_\bo_\bu_\bt,  or _\b/_\bd_\be_\bv_\b/_\bs_\bt_\bd_\be_\br_\br, file descriptor 0, 1, or 2, respectively,
        is checked.
 
        Unless otherwise specified, primaries that operate on files follow sym-
        bolic links and operate on the target of the link, rather than the link
        itself.
 
-       When  used  with [\b[[\b[, the <\b< and >\b> operators sort lexicographically using
+       When used with [\b[[\b[, the <\b< and >\b> operators sort  lexicographically  using
        the current locale.  The t\bte\bes\bst\bt command sorts using ASCII ordering.
 
        -\b-a\ba _\bf_\bi_\bl_\be
@@ -2334,30 +2366,30 @@ C\bCO\bON\bND\bDI\bIT\bTI\bIO\bON\bNA\bAL\bL E\bEX\bXP\bPR\bRE\bES\bSS\bSI\bIO\bON\bNS\bS
        -\b-L\bL _\bf_\bi_\bl_\be
               True if _\bf_\bi_\bl_\be exists and is a symbolic link.
        -\b-N\bN _\bf_\bi_\bl_\be
-              True if _\bf_\bi_\bl_\be exists and has been  modified  since  it  was  last
+              True  if  _\bf_\bi_\bl_\be  exists  and  has been modified since it was last
               read.
        -\b-O\bO _\bf_\bi_\bl_\be
               True if _\bf_\bi_\bl_\be exists and is owned by the effective user id.
        -\b-S\bS _\bf_\bi_\bl_\be
               True if _\bf_\bi_\bl_\be exists and is a socket.
        _\bf_\bi_\bl_\be_\b1 -\b-e\bef\bf _\bf_\bi_\bl_\be_\b2
-              True  if _\bf_\bi_\bl_\be_\b1 and _\bf_\bi_\bl_\be_\b2 refer to the same device and inode num-
+              True if _\bf_\bi_\bl_\be_\b1 and _\bf_\bi_\bl_\be_\b2 refer to the same device and inode  num-
               bers.
        _\bf_\bi_\bl_\be_\b1 -n\bnt\bt _\bf_\bi_\bl_\be_\b2
-              True if _\bf_\bi_\bl_\be_\b1 is newer (according  to  modification  date)  than
+              True  if  _\bf_\bi_\bl_\be_\b1  is  newer (according to modification date) than
               _\bf_\bi_\bl_\be_\b2, or if _\bf_\bi_\bl_\be_\b1 exists and _\bf_\bi_\bl_\be_\b2 does not.
        _\bf_\bi_\bl_\be_\b1 -o\bot\bt _\bf_\bi_\bl_\be_\b2
-              True  if _\bf_\bi_\bl_\be_\b1 is older than _\bf_\bi_\bl_\be_\b2, or if _\bf_\bi_\bl_\be_\b2 exists and _\bf_\bi_\bl_\be_\b1
+              True if _\bf_\bi_\bl_\be_\b1 is older than _\bf_\bi_\bl_\be_\b2, or if _\bf_\bi_\bl_\be_\b2 exists and  _\bf_\bi_\bl_\be_\b1
               does not.
        -\b-o\bo _\bo_\bp_\bt_\bn_\ba_\bm_\be
-              True if the shell option _\bo_\bp_\bt_\bn_\ba_\bm_\be is enabled.  See  the  list  of
-              options  under  the  description  of  the  -\b-o\bo  option to the s\bse\bet\bt
+              True  if  the  shell option _\bo_\bp_\bt_\bn_\ba_\bm_\be is enabled.  See the list of
+              options under the description  of  the  -\b-o\bo  option  to  the  s\bse\bet\bt
               builtin below.
        -\b-v\bv _\bv_\ba_\br_\bn_\ba_\bm_\be
-              True if the shell variable _\bv_\ba_\br_\bn_\ba_\bm_\be is set (has been  assigned  a
+              True  if  the shell variable _\bv_\ba_\br_\bn_\ba_\bm_\be is set (has been assigned a
               value).
        -\b-R\bR _\bv_\ba_\br_\bn_\ba_\bm_\be
-              True  if  the shell variable _\bv_\ba_\br_\bn_\ba_\bm_\be is set and is a name refer-
+              True if the shell variable _\bv_\ba_\br_\bn_\ba_\bm_\be is set and is a  name  refer-
               ence.
        -\b-z\bz _\bs_\bt_\br_\bi_\bn_\bg
               True if the length of _\bs_\bt_\br_\bi_\bn_\bg is zero.
@@ -2367,8 +2399,8 @@ C\bCO\bON\bND\bDI\bIT\bTI\bIO\bON\bNA\bAL\bL E\bEX\bXP\bPR\bRE\bES\bSS\bSI\bIO\bON\bNS\bS
 
        _\bs_\bt_\br_\bi_\bn_\bg_\b1 =\b==\b= _\bs_\bt_\br_\bi_\bn_\bg_\b2
        _\bs_\bt_\br_\bi_\bn_\bg_\b1 =\b= _\bs_\bt_\br_\bi_\bn_\bg_\b2
-              True if the strings are equal.  =\b= should be used with  the  t\bte\bes\bst\bt
-              command  for  POSIX conformance.  When used with the [\b[[\b[ command,
+              True  if  the strings are equal.  =\b= should be used with the t\bte\bes\bst\bt
+              command for POSIX conformance.  When used with the  [\b[[\b command,
               this performs pattern matching as described above (C\bCo\bom\bmp\bpo\bou\bun\bnd\bd C\bCo\bom\bm-\b-
               m\bma\ban\bnd\bds\bs).
 
@@ -2382,106 +2414,106 @@ C\bCO\bON\bND\bDI\bIT\bTI\bIO\bON\bNA\bAL\bL E\bEX\bXP\bPR\bRE\bES\bSS\bSI\bIO\bON\bNS\bS
               True if _\bs_\bt_\br_\bi_\bn_\bg_\b1 sorts after _\bs_\bt_\br_\bi_\bn_\bg_\b2 lexicographically.
 
        _\ba_\br_\bg_\b1 O\bOP\bP _\ba_\br_\bg_\b2
-              O\bOP\b is one of -\b-e\beq\bq, -\b-n\bne\be, -\b-l\blt\bt, -\b-l\ble\be, -\b-g\bgt\bt, or -\b-g\bge\be.  These arithmetic
-              binary operators return true if _\ba_\br_\bg_\b1 is equal to, not equal  to,
-              less  than, less than or equal to, greater than, or greater than
-              or equal to _\ba_\br_\bg_\b2, respectively.  _\bA_\br_\bg_\b1 and _\ba_\br_\bg_\b2 may  be  positive
+              O\bOP\bis one of -\b-e\beq\bq, -\b-n\bne\be, -\b-l\blt\bt, -\b-l\ble\be, -\b-g\bgt\bt, or -\b-g\bge\be.  These  arithmetic
+              binary  operators return true if _\ba_\br_\bg_\b1 is equal to, not equal to,
+              less than, less than or equal to, greater than, or greater  than
+              or  equal  to _\ba_\br_\bg_\b2, respectively.  _\bA_\br_\bg_\b1 and _\ba_\br_\bg_\b2 may be positive
               or negative integers.
 
 S\bSI\bIM\bMP\bPL\bLE\bE C\bCO\bOM\bMM\bMA\bAN\bND\bD E\bEX\bXP\bPA\bAN\bNS\bSI\bIO\bON\bN
-       When  a  simple  command  is executed, the shell performs the following
+       When a simple command is executed, the  shell  performs  the  following
        expansions, assignments, and redirections, from left to right.
 
-       1.     The words that the parser has  marked  as  variable  assignments
-              (those  preceding  the  command name) and redirections are saved
+       1.     The  words  that  the  parser has marked as variable assignments
+              (those preceding the command name) and  redirections  are  saved
               for later processing.
 
-       2.     The words that are not variable assignments or redirections  are
-              expanded.   If  any words remain after expansion, the first word
-              is taken to be the name of the command and the  remaining  words
+       2.     The  words that are not variable assignments or redirections are
+              expanded.  If any words remain after expansion, the  first  word
+              is  taken  to be the name of the command and the remaining words
               are the arguments.
 
        3.     Redirections are performed as described above under R\bRE\bED\bDI\bIR\bRE\bEC\bCT\bTI\bIO\bON\bN.
 
        4.     The text after the =\b= in each variable assignment undergoes tilde
               expansion, parameter expansion, command substitution, arithmetic
-              expansion,  and quote removal before being assigned to the vari-
+              expansion, and quote removal before being assigned to the  vari-
               able.
 
        If no command name results, the variable assignments affect the current
-       shell  environment.  Otherwise, the variables are added to the environ-
-       ment of the executed command and do not affect the current shell  envi-
-       ronment.   If  any  of  the assignments attempts to assign a value to a
-       readonly variable, an error occurs, and the command exits with  a  non-
+       shell environment.  Otherwise, the variables are added to the  environ-
+       ment  of the executed command and do not affect the current shell envi-
+       ronment.  If any of the assignments attempts to assign  a  value  to  a
+       readonly  variable,  an error occurs, and the command exits with a non-
        zero status.
 
-       If  no  command  name  results,  redirections are performed, but do not
-       affect the current shell environment.  A redirection error  causes  the
+       If no command name results, redirections  are  performed,  but  do  not
+       affect  the  current shell environment.  A redirection error causes the
        command to exit with a non-zero status.
 
-       If  there is a command name left after expansion, execution proceeds as
-       described below.  Otherwise, the command exits.  If one of  the  expan-
-       sions  contained a command substitution, the exit status of the command
-       is the exit status of the  last  command  substitution  performed.   If
+       If there is a command name left after expansion, execution proceeds  as
+       described  below.   Otherwise, the command exits.  If one of the expan-
+       sions contained a command substitution, the exit status of the  command
+       is  the  exit  status  of  the last command substitution performed.  If
        there were no command substitutions, the command exits with a status of
        zero.
 
 C\bCO\bOM\bMM\bMA\bAN\bND\bD E\bEX\bXE\bEC\bCU\bUT\bTI\bIO\bON\bN
-       After a command has been split into words, if it results  in  a  simple
-       command  and  an  optional list of arguments, the following actions are
+       After  a  command  has been split into words, if it results in a simple
+       command and an optional list of arguments, the  following  actions  are
        taken.
 
-       If the command name contains no slashes, the shell attempts  to  locate
-       it.   If  there  exists a shell function by that name, that function is
-       invoked as described above in F\bFU\bUN\bNC\bCT\bTI\bIO\bON\bNS\bS.  If the name does not match  a
-       function,  the shell searches for it in the list of shell builtins.  If
+       If  the  command name contains no slashes, the shell attempts to locate
+       it.  If there exists a shell function by that name,  that  function  is
+       invoked  as described above in F\bFU\bUN\bNC\bCT\bTI\bIO\bON\bNS\bS.  If the name does not match a
+       function, the shell searches for it in the list of shell builtins.   If
        a match is found, that builtin is invoked.
 
-       If the name is neither a shell function nor a builtin, and contains  no
-       slashes,  b\bba\bas\bsh\bh  searches  each element of the P\bPA\bAT\bTH\bH for a directory con-
-       taining an executable file by that name.  B\bBa\bas\bsh\bh uses  a  hash  table  to
-       remember  the  full pathnames of executable files (see h\bha\bas\bsh\bh under S\bSH\bHE\bEL\bLL\bL
-       B\bBU\bUI\bIL\bLT\bTI\bIN\bC\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS below).  A full search of the directories in  P\bPA\bAT\bTH\b is
-       performed  only  if the command is not found in the hash table.  If the
+       If  the name is neither a shell function nor a builtin, and contains no
+       slashes, b\bba\bas\bsh\bh searches each element of the P\bPA\bAT\bTH\bH for  a  directory  con-
+       taining  an  executable  file  by that name.  B\bBa\bas\bsh\bh uses a hash table to
+       remember the full pathnames of executable files (see h\bha\bas\bsh\bh  under  S\bSH\bHE\bEL\bLL\bL
+       B\bBU\bUI\bIL\bLT\bTI\bIN\b C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS  below).  A full search of the directories in P\bPA\bAT\bTH\bH is
+       performed only if the command is not found in the hash table.   If  the
        search is unsuccessful, the shell searches for a defined shell function
        named c\bco\bom\bmm\bma\ban\bnd\bd_\b_n\bno\bot\bt_\b_f\bfo\bou\bun\bnd\bd_\b_h\bha\ban\bnd\bdl\ble\be.  If that function exists, it is invoked
-       with the original command and the original command's arguments  as  its
-       arguments,  and  the  function's exit status becomes the exit status of
-       the shell.  If that function is not defined, the shell prints an  error
+       with  the  original command and the original command's arguments as its
+       arguments, and the function's exit status becomes the  exit  status  of
+       the  shell.  If that function is not defined, the shell prints an error
        message and returns an exit status of 127.
 
-       If  the  search  is  successful, or if the command name contains one or
+       If the search is successful, or if the command  name  contains  one  or
        more slashes, the shell executes the named program in a separate execu-
        tion environment.  Argument 0 is set to the name given, and the remain-
        ing arguments to the command are set to the arguments given, if any.
 
-       If this execution fails because the file is not in  executable  format,
-       and  the file is not a directory, it is assumed to be a _\bs_\bh_\be_\bl_\bl _\bs_\bc_\br_\bi_\bp_\bt, a
-       file containing shell commands.  A subshell is spawned to  execute  it.
-       This  subshell  reinitializes itself, so that the effect is as if a new
-       shell had been invoked to handle the script, with  the  exception  that
-       the  locations  of  commands  remembered  by the parent (see h\bha\bas\bsh\bh below
+       If  this  execution fails because the file is not in executable format,
+       and the file is not a directory, it is assumed to be a _\bs_\bh_\be_\bl_\bl _\bs_\bc_\br_\bi_\bp_\bt,  a
+       file  containing  shell commands.  A subshell is spawned to execute it.
+       This subshell reinitializes itself, so that the effect is as if  a  new
+       shell  had  been  invoked to handle the script, with the exception that
+       the locations of commands remembered by  the  parent  (see  h\bha\bas\bsh\b below
        under S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS) are retained by the child.
 
-       If the program is a file beginning with #\b#!\b!, the remainder of the  first
-       line  specifies an interpreter for the program.  The shell executes the
+       If  the program is a file beginning with #\b#!\b!, the remainder of the first
+       line specifies an interpreter for the program.  The shell executes  the
        specified interpreter on operating systems that do not handle this exe-
        cutable format themselves.  The arguments to the interpreter consist of
-       a single optional argument following the interpreter name on the  first
-       line  of  the program, followed by the name of the program, followed by
+       a  single optional argument following the interpreter name on the first
+       line of the program, followed by the name of the program,  followed  by
        the command arguments, if any.
 
 C\bCO\bOM\bMM\bMA\bAN\bND\bD E\bEX\bXE\bEC\bCU\bUT\bTI\bIO\bON\bN E\bEN\bNV\bVI\bIR\bRO\bON\bNM\bME\bEN\bNT\bT
-       The shell has an _\be_\bx_\be_\bc_\bu_\bt_\bi_\bo_\bn _\be_\bn_\bv_\bi_\br_\bo_\bn_\bm_\be_\bn_\bt, which consists of  the  follow-
+       The  shell  has an _\be_\bx_\be_\bc_\bu_\bt_\bi_\bo_\bn _\be_\bn_\bv_\bi_\br_\bo_\bn_\bm_\be_\bn_\bt, which consists of the follow-
        ing:
 
-       +\bo      open  files inherited by the shell at invocation, as modified by
+       +\bo      open files inherited by the shell at invocation, as modified  by
               redirections supplied to the e\bex\bxe\bec\bc builtin
 
-       +\bo      the current working directory as set by c\bcd\bd, p\bpu\bus\bsh\bhd\bd, or  p\bpo\bop\bpd\bd,  or
+       +\bo      the  current  working directory as set by c\bcd\bd, p\bpu\bus\bsh\bhd\bd, or p\bpo\bop\bpd\bd, or
               inherited by the shell at invocation
 
-       +\bo      the  file  creation  mode mask as set by u\bum\bma\bas\bsk\bk or inherited from
+       +\bo      the file creation mode mask as set by u\bum\bma\bas\bsk\bk  or  inherited  from
               the shell's parent
 
        +\bo      current traps set by t\btr\bra\bap\bp
@@ -2489,243 +2521,243 @@ C\bCO\bOM\bMM\bMA\bAN\bND\bD E\bEX\bXE\bEC\bCU\bUT\bTI\bIO\bON\bN E\bEN\bNV\bVI\bIR\bRO\bON\bNM\bME\bEN\bN
        +\bo      shell parameters that are set by variable assignment or with s\bse\bet\bt
               or inherited from the shell's parent in the environment
 
-       +\bo      shell  functions  defined during execution or inherited from the
+       +\bo      shell functions defined during execution or inherited  from  the
               shell's parent in the environment
 
-       +\bo      options enabled at invocation (either by default  or  with  com-
+       +\bo      options  enabled  at  invocation (either by default or with com-
               mand-line arguments) or by s\bse\bet\bt
 
        +\bo      options enabled by s\bsh\bho\bop\bpt\bt
 
        +\bo      shell aliases defined with a\bal\bli\bia\bas\bs
 
-       +\bo      various  process  IDs,  including  those of background jobs, the
+       +\bo      various process IDs, including those  of  background  jobs,  the
               value of $\b$$\b$, and the value of P\bPP\bPI\bID\bD
 
-       When a simple command other than a builtin or shell function is  to  be
-       executed,  it  is invoked in a separate execution environment that con-
-       sists of the following.  Unless otherwise noted, the values are  inher-
+       When  a  simple command other than a builtin or shell function is to be
+       executed, it is invoked in a separate execution environment  that  con-
+       sists  of the following.  Unless otherwise noted, the values are inher-
        ited from the shell.
 
 
-       +\bo      the  shell's  open  files,  plus any modifications and additions
+       +\bo      the shell's open files, plus  any  modifications  and  additions
               specified by redirections to the command
 
        +\bo      the current working directory
 
        +\bo      the file creation mode mask
 
-       +\bo      shell variables and functions  marked  for  export,  along  with
+       +\bo      shell  variables  and  functions  marked  for export, along with
               variables exported for the command, passed in the environment
 
        +\bo      traps caught by the shell are reset to the values inherited from
               the shell's parent, and traps ignored by the shell are ignored
 
-       A command invoked  in  this  separate  environment  cannot  affect  the
+       A  command  invoked  in  this  separate  environment  cannot affect the
        shell's execution environment.
 
-       Command  substitution, commands grouped with parentheses, and asynchro-
+       Command substitution, commands grouped with parentheses, and  asynchro-
        nous commands are invoked in a subshell environment that is a duplicate
-       of  the  shell  environment,  except that traps caught by the shell are
+       of the shell environment, except that traps caught  by  the  shell  are
        reset to the values that the shell inherited from its parent at invoca-
        tion.  Builtin commands that are invoked as part of a pipeline are also
        executed in a subshell environment.  Changes made to the subshell envi-
        ronment cannot affect the shell's execution environment.
 
        Subshells spawned to execute command substitutions inherit the value of
-       the -\b-e\be option from the parent shell.  When  not  in  _\bp_\bo_\bs_\bi_\bx  mode,  b\bba\bas\bsh\bh
+       the  -\b-e\be  option  from  the  parent shell.  When not in _\bp_\bo_\bs_\bi_\bx mode, b\bba\bas\bsh\bh
        clears the -\b-e\be option in such subshells.
 
-       If  a  command  is  followed  by a &\b& and job control is not active, the
-       default standard input for the command is  the  empty  file  _\b/_\bd_\be_\bv_\b/_\bn_\bu_\bl_\bl.
-       Otherwise,  the  invoked  command  inherits the file descriptors of the
+       If a command is followed by a &\b& and job  control  is  not  active,  the
+       default  standard  input  for  the command is the empty file _\b/_\bd_\be_\bv_\b/_\bn_\bu_\bl_\bl.
+       Otherwise, the invoked command inherits the  file  descriptors  of  the
        calling shell as modified by redirections.
 
 E\bEN\bNV\bVI\bIR\bRO\bON\bNM\bME\bEN\bNT\bT
-       When a program is invoked it is given an array of  strings  called  the
+       When  a  program  is invoked it is given an array of strings called the
        _\be_\bn_\bv_\bi_\br_\bo_\bn_\bm_\be_\bn_\bt.   This  is  a  list  of  _\bn_\ba_\bm_\be-_\bv_\ba_\bl_\bu_\be  pairs,  of  the  form
        _\bn_\ba_\bm_\be=_\bv_\ba_\bl_\bu_\be.
 
-       The shell provides several ways  to  manipulate  the  environment.   On
+       The  shell  provides  several  ways  to manipulate the environment.  On
        invocation, the shell scans its own environment and creates a parameter
-       for each name found, automatically marking it for _\be_\bx_\bp_\bo_\br_\bt to child  pro-
-       cesses.   Executed  commands  inherit  the environment.  The e\bex\bxp\bpo\bor\brt\bt and
-       d\bde\bec\bcl\bla\bar\bre\b-\b-x\bx commands allow parameters and functions to be added  to  and
+       for  each name found, automatically marking it for _\be_\bx_\bp_\bo_\br_\bt to child pro-
+       cesses.  Executed commands inherit the  environment.   The  e\bex\bxp\bpo\bor\brt\b and
+       d\bde\bec\bcl\bla\bar\bre\b -\b-x\bx  commands allow parameters and functions to be added to and
        deleted from the environment.  If the value of a parameter in the envi-
-       ronment is modified, the new value becomes  part  of  the  environment,
-       replacing  the  old.  The environment inherited by any executed command
-       consists of the shell's initial environment, whose values may be  modi-
-       fied  in  the  shell, less any pairs removed by the u\bun\bns\bse\bet\bt command, plus
+       ronment  is  modified,  the  new value becomes part of the environment,
+       replacing the old.  The environment inherited by any  executed  command
+       consists  of the shell's initial environment, whose values may be modi-
+       fied in the shell, less any pairs removed by the  u\bun\bns\bse\bet\bt  command,  plus
        any additions via the e\bex\bxp\bpo\bor\brt\bt and d\bde\bec\bcl\bla\bar\bre\be -\b-x\bx commands.
 
-       The environment for any _\bs_\bi_\bm_\bp_\bl_\be _\bc_\bo_\bm_\bm_\ba_\bn_\bd or  function  may  be  augmented
-       temporarily  by  prefixing  it with parameter assignments, as described
+       The  environment  for  any  _\bs_\bi_\bm_\bp_\bl_\be _\bc_\bo_\bm_\bm_\ba_\bn_\bd or function may be augmented
+       temporarily by prefixing it with parameter  assignments,  as  described
        above in P\bPA\bAR\bRA\bAM\bME\bET\bTE\bER\bRS\bS.  These assignment statements affect only the envi-
        ronment seen by that command.
 
-       If  the  -\b-k\bk option is set (see the s\bse\bet\bt builtin command below), then _\ba_\bl_\bl
-       parameter assignments are placed in the environment for a command,  not
+       If the -\b-k\bk option is set (see the s\bse\bet\bt builtin command below),  then  _\ba_\bl_\bl
+       parameter  assignments are placed in the environment for a command, not
        just those that precede the command name.
 
-       When  b\bba\bas\bsh\bh  invokes  an  external command, the variable _\b_ is set to the
+       When b\bba\bas\bsh\bh invokes an external command, the variable _\b_  is  set  to  the
        full filename of the command and passed to that command in its environ-
        ment.
 
 E\bEX\bXI\bIT\bT S\bST\bTA\bAT\bTU\bUS\bS
-       The  exit  status  of  an executed command is the value returned by the
+       The exit status of an executed command is the  value  returned  by  the
        _\bw_\ba_\bi_\bt_\bp_\bi_\bd system call or equivalent function.  Exit statuses fall between
-       0  and  255, though, as explained below, the shell may use values above
+       0 and 255, though, as explained below, the shell may use  values  above
        125 specially.  Exit statuses from shell builtins and compound commands
        are also limited to this range.  Under certain circumstances, the shell
        will use special values to indicate specific failure modes.
 
        For the shell's purposes, a command which exits with a zero exit status
-       has  succeeded.   An exit status of zero indicates success.  A non-zero
-       exit status indicates failure.  When a command terminates  on  a  fatal
+       has succeeded.  An exit status of zero indicates success.   A  non-zero
+       exit  status  indicates  failure.  When a command terminates on a fatal
        signal _\bN, b\bba\bas\bsh\bh uses the value of 128+_\bN as the exit status.
 
-       If  a  command  is  not  found, the child process created to execute it
-       returns a status of 127.  If a command is found but is not  executable,
+       If a command is not found, the child  process  created  to  execute  it
+       returns  a status of 127.  If a command is found but is not executable,
        the return status is 126.
 
        If a command fails because of an error during expansion or redirection,
        the exit status is greater than zero.
 
-       Shell builtin commands return a status of 0 (_\bt_\br_\bu_\be) if  successful,  and
-       non-zero  (_\bf_\ba_\bl_\bs_\be)  if an error occurs while they execute.  All builtins
-       return an exit status of  2  to  indicate  incorrect  usage,  generally
+       Shell  builtin  commands return a status of 0 (_\bt_\br_\bu_\be) if successful, and
+       non-zero (_\bf_\ba_\bl_\bs_\be) if an error occurs while they execute.   All  builtins
+       return  an  exit  status  of  2  to indicate incorrect usage, generally
        invalid options or missing arguments.
 
-       B\bBa\bas\bsh\b itself  returns  the  exit  status  of the last command executed,
-       unless a syntax error occurs, in which case it exits  with  a  non-zero
+       B\bBa\bas\bsh\bitself returns the exit  status  of  the  last  command  executed,
+       unless  a  syntax  error occurs, in which case it exits with a non-zero
        value.  See also the e\bex\bxi\bit\bt builtin command below.
 
 S\bSI\bIG\bGN\bNA\bAL\bLS\bS
-       When  b\bba\bas\bsh\bh  is  interactive,  in  the  absence of any traps, it ignores
+       When b\bba\bas\bsh\bh is interactive, in the  absence  of  any  traps,  it  ignores
        S\bSI\bIG\bGT\bTE\bER\bRM\bM (so that k\bki\bil\bll\bl 0\b0 does not kill an interactive shell), and S\bSI\bIG\bGI\bIN\bNT\bT
-       is  caught and handled (so that the w\bwa\bai\bit\bt builtin is interruptible).  In
-       all cases, b\bba\bas\bsh\bh ignores S\bSI\bIG\bGQ\bQU\bUI\bIT\bT.  If job control  is  in  effect,  b\bba\bas\bsh\bh
+       is caught and handled (so that the w\bwa\bai\bit\bt builtin is interruptible).   In
+       all  cases,  b\bba\bas\bsh\bh  ignores  S\bSI\bIG\bGQ\bQU\bUI\bIT\bT.  If job control is in effect, b\bba\bas\bsh\bh
        ignores S\bSI\bIG\bGT\bTT\bTI\bIN\bN, S\bSI\bIG\bGT\bTT\bTO\bOU\bU, and S\bSI\bIG\bGT\bTS\bST\bTP\bP.
 
        Non-builtin commands run by b\bba\bas\bsh\bh have signal handlers set to the values
-       inherited by the shell from its parent.  When job  control  is  not  in
-       effect,  asynchronous commands ignore S\bSI\bIG\bGI\bIN\bNT\bT and S\bSI\bIG\bGQ\bQU\bUI\bIT\bT in addition to
-       these inherited handlers.  Commands run as a result of command  substi-
+       inherited  by  the  shell  from its parent.  When job control is not in
+       effect, asynchronous commands ignore S\bSI\bIG\bGI\bIN\bNT\bT and S\bSI\bIG\bGQ\bQU\bUI\bIT\bT in addition  to
+       these  inherited handlers.  Commands run as a result of command substi-
        tution ignore the keyboard-generated job control signals S\bSI\bIG\bGT\bTT\bTI\bIN\bN, S\bSI\bIG\bGT\bT-\b-
        T\bTO\bOU\bU, and S\bSI\bIG\bGT\bTS\bST\bTP\bP.
 
-       The shell exits by default upon receipt of a S\bSI\bIG\bGH\bHU\bUP\bP.   Before  exiting,
-       an  interactive  shell  resends  the  S\bSI\bIG\bGH\bHU\bUP\bP  to  all  jobs, running or
+       The  shell  exits by default upon receipt of a S\bSI\bIG\bGH\bHU\bUP\bP.  Before exiting,
+       an interactive shell  resends  the  S\bSI\bIG\bGH\bHU\bUP\bP  to  all  jobs,  running  or
        stopped.  Stopped jobs are sent S\bSI\bIG\bGC\bCO\bON\bNT\bT to ensure that they receive the
-       S\bSI\bIG\bGH\bHU\bUP\bP.   To  prevent the shell from sending the signal to a particular
-       job, it should be removed from the jobs table with the  d\bdi\bis\bso\bow\bwn\b builtin
-       (see  S\bSH\bHE\bEL\bLL\bL  B\bBU\bUI\bIL\bLT\bTI\bIN\bN  C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS  below)  or marked to not receive S\bSI\bIG\bGH\bHU\bUP\bP
+       S\bSI\bIG\bGH\bHU\bUP\bP.  To prevent the shell from sending the signal to  a  particular
+       job,  it  should be removed from the jobs table with the d\bdi\bis\bso\bow\bwn\bn builtin
+       (see S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS below) or  marked  to  not  receive  S\bSI\bIG\bGH\bHU\bUP\bP
        using d\bdi\bis\bso\bow\bwn\bn -\b-h\bh.
 
-       If the h\bhu\bup\bpo\bon\bne\bex\bxi\bit\bt shell option has been set with  s\bsh\bho\bop\bpt\bt,  b\bba\bas\bsh\bh  sends  a
+       If  the  h\bhu\bup\bpo\bon\bne\bex\bxi\bit\bt  shell  option has been set with s\bsh\bho\bop\bpt\bt, b\bba\bas\bsh\bh sends a
        S\bSI\bIG\bGH\bHU\bUP\bP to all jobs when an interactive login shell exits.
 
-       If  b\bba\bas\bsh\bh is waiting for a command to complete and receives a signal for
+       If b\bba\bas\bsh\bh is waiting for a command to complete and receives a signal  for
        which a trap has been set, the trap will not be executed until the com-
-       mand  completes.   When b\bba\bas\bsh\bh is waiting for an asynchronous command via
-       the w\bwa\bai\bit\bt builtin, the reception of a signal for which a trap  has  been
+       mand completes.  When b\bba\bas\bsh\bh is waiting for an asynchronous  command  via
+       the  w\bwa\bai\bit\bt  builtin, the reception of a signal for which a trap has been
        set will cause the w\bwa\bai\bit\bt builtin to return immediately with an exit sta-
        tus greater than 128, immediately after which the trap is executed.
 
 J\bJO\bOB\bB C\bCO\bON\bNT\bTR\bRO\bOL\bL
-       _\bJ_\bo_\b_\bc_\bo_\bn_\bt_\br_\bo_\bl refers to the ability to  selectively  stop  (_\bs_\bu_\bs_\bp_\be_\bn_\bd)  the
+       _\bJ_\bo_\b _\bc_\bo_\bn_\bt_\br_\bo_\bl  refers  to  the ability to selectively stop (_\bs_\bu_\bs_\bp_\be_\bn_\bd) the
        execution of processes and continue (_\br_\be_\bs_\bu_\bm_\be) their execution at a later
-       point.  A user typically  employs  this  facility  via  an  interactive
-       interface  supplied  jointly  by the operating system kernel's terminal
+       point.   A  user  typically  employs  this  facility via an interactive
+       interface supplied jointly by the operating  system  kernel's  terminal
        driver and b\bba\bas\bsh\bh.
 
-       The shell associates a _\bj_\bo_\bb with each pipeline.  It  keeps  a  table  of
-       currently  executing  jobs,  which may be listed with the j\bjo\bob\bbs\bs command.
-       When b\bba\bas\bsh\bh starts a job asynchronously (in the _\bb_\ba_\bc_\bk_\bg_\br_\bo_\bu_\bn_\bd), it prints  a
+       The  shell  associates  a  _\bj_\bo_\bb with each pipeline.  It keeps a table of
+       currently executing jobs, which may be listed with  the  j\bjo\bob\bbs\b command.
+       When  b\bba\bas\bsh\bh starts a job asynchronously (in the _\bb_\ba_\bc_\bk_\bg_\br_\bo_\bu_\bn_\bd), it prints a
        line that looks like:
 
               [1] 25647
 
        indicating that this job is job number 1 and that the process ID of the
        last process in the pipeline associated with this job is 25647.  All of
-       the  processes  in a single pipeline are members of the same job.  B\bBa\bas\bsh\bh
+       the processes in a single pipeline are members of the same  job.   B\bBa\bas\bsh\bh
        uses the _\bj_\bo_\bb abstraction as the basis for job control.
 
-       To facilitate the implementation of the user interface to job  control,
+       To  facilitate the implementation of the user interface to job control,
        the operating system maintains the notion of a _\bc_\bu_\br_\br_\be_\bn_\bt _\bt_\be_\br_\bm_\bi_\bn_\ba_\bl _\bp_\br_\bo_\bc_\be_\bs_\bs
        _\bg_\br_\bo_\bu_\bp _\bI_\bD.  Members of this process group (processes whose process group
        ID is equal to the current terminal process group ID) receive keyboard-
-       generated signals such as S\bSI\bIG\bGI\bIN\bNT\bT.  These processes are said  to  be  in
-       the  _\bf_\bo_\br_\be_\bg_\br_\bo_\bu_\bn_\bd.  _\bB_\ba_\bc_\bk_\bg_\br_\bo_\bu_\bn_\bd processes are those whose process group ID
+       generated  signals  such  as S\bSI\bIG\bGI\bIN\bNT\bT.  These processes are said to be in
+       the _\bf_\bo_\br_\be_\bg_\br_\bo_\bu_\bn_\bd.  _\bB_\ba_\bc_\bk_\bg_\br_\bo_\bu_\bn_\bd processes are those whose process group  ID
        differs from the terminal's; such processes are immune to keyboard-gen-
        erated signals.  Only foreground processes are allowed to read from or,
-       if the user so specifies with  stty  tostop,  write  to  the  terminal.
-       Background  processes  which  attempt  to read from (write to when stty
-       tostop is in effect) the terminal are sent a S\bSI\bIG\bGT\bTT\bTI\bIN\bN  (\b(S\bSI\bIG\bGT\bTT\bTO\bOU\bU)\b signal
-       by  the  kernel's  terminal  driver, which, unless caught, suspends the
+       if  the  user  so  specifies  with  stty tostop, write to the terminal.
+       Background processes which attempt to read from  (write  to  when  stty
+       tostop  is  in effect) the terminal are sent a S\bSI\bIG\bGT\bTT\bTI\bIN\bN (\b(S\bSI\bIG\bGT\bTT\bTO\bOU\bU)\b) signal
+       by the kernel's terminal driver, which,  unless  caught,  suspends  the
        process.
 
-       If the operating system on which b\bba\bas\bsh\bh is running supports job  control,
+       If  the operating system on which b\bba\bas\bsh\bh is running supports job control,
        b\bba\bas\bsh\bh contains facilities to use it.  Typing the _\bs_\bu_\bs_\bp_\be_\bn_\bd character (typ-
        ically ^\b^Z\bZ, Control-Z) while a process is running causes that process to
-       be  stopped  and  returns  control to b\bba\bas\bsh\bh.  Typing the _\bd_\be_\bl_\ba_\by_\be_\bd _\bs_\bu_\bs_\bp_\be_\bn_\bd
-       character (typically ^\b^Y\bY, Control-Y) causes the process  to  be  stopped
-       when  it  attempts  to  read input from the terminal, and control to be
-       returned to b\bba\bas\bsh\bh.  The user may then manipulate the state of this  job,
-       using  the  b\bbg\bg command to continue it in the background, the f\bfg\bg command
+       be stopped and returns control to b\bba\bas\bsh\bh.   Typing  the  _\bd_\be_\bl_\ba_\by_\be_\b _\bs_\bu_\bs_\bp_\be_\bn_\bd
+       character  (typically  ^\b^Y\bY,  Control-Y) causes the process to be stopped
+       when it attempts to read input from the terminal,  and  control  to  be
+       returned  to b\bba\bas\bsh\bh.  The user may then manipulate the state of this job,
+       using the b\bbg\bg command to continue it in the background, the  f\bfg\b command
        to continue it in the foreground, or the k\bki\bil\bll\bl command to kill it.  A ^\b^Z\bZ
        takes effect immediately, and has the additional side effect of causing
        pending output and typeahead to be discarded.
 
        There are a number of ways to refer to a job in the shell.  The charac-
-       ter  %\b%  introduces  a job specification (_\bj_\bo_\bb_\bs_\bp_\be_\bc).  Job number _\bn may be
+       ter %\b% introduces a job specification (_\bj_\bo_\bb_\bs_\bp_\be_\bc).  Job number  _\bn  may  be
        referred to as %\b%n\bn.  A job may also be referred to using a prefix of the
        name used to start it, or using a substring that appears in its command
-       line.  For example, %\b%c\bce\be refers to  a  stopped  c\bce\be  job.   If  a  prefix
-       matches  more  than one job, b\bba\bas\bsh\bh reports an error.  Using %\b%?\b?c\bce\be, on the
-       other hand, refers to any job containing the string c\bce\be in  its  command
-       line.   If  the  substring  matches  more than one job, b\bba\bas\bsh\bh reports an
-       error.  The symbols %\b%%\b% and %\b%+\b+ refer to the shell's notion of  the  _\bc_\bu_\br_\b-
-       _\br_\be_\bn_\b _\bj_\bo_\bb, which is the last job stopped while it was in the foreground
+       line.   For  example,  %\b%c\bce\be  refers  to  a  stopped c\bce\be job.  If a prefix
+       matches more than one job, b\bba\bas\bsh\bh reports an error.  Using %\b%?\b?c\bce\be,  on  the
+       other  hand,  refers to any job containing the string c\bce\be in its command
+       line.  If the substring matches more than  one  job,  b\bba\bas\bsh\bh  reports  an
+       error.   The  symbols %\b%%\b% and %\b%+\b+ refer to the shell's notion of the _\bc_\bu_\br_\b-
+       _\br_\be_\bn_\b_\bj_\bo_\bb, which is the last job stopped while it was in the  foreground
        or started in the background.  The _\bp_\br_\be_\bv_\bi_\bo_\bu_\bs _\bj_\bo_\bb may be referenced using
        %\b%-\b-.  If there is only a single job, %\b%+\b+ and %\b%-\b- can both be used to refer
-       to that job.  In output pertaining to jobs (e.g.,  the  output  of  the
+       to  that  job.   In  output pertaining to jobs (e.g., the output of the
        j\bjo\bob\bbs\bs command), the current job is always flagged with a +\b+, and the pre-
-       vious job with a -\b-.  A single % (with no  accompanying  job  specifica-
+       vious  job  with  a -\b-.  A single % (with no accompanying job specifica-
        tion) also refers to the current job.
 
-       Simply  naming a job can be used to bring it into the foreground: %\b%1\b1 is
-       a synonym for `\b``\b`f\bfg\bg %\b%1\b1'\b''\b', bringing job 1 from the  background  into  the
-       foreground.   Similarly,  `\b``\b`%\b%1\b1  &\b&'\b''\b'  resumes  job  1 in the background,
+       Simply naming a job can be used to bring it into the foreground: %\b%1\b is
+       a  synonym  for  `\b``\b`f\bfg\bg %\b%1\b1'\b''\b', bringing job 1 from the background into the
+       foreground.  Similarly, `\b``\b`%\b%1\b1 &\b&'\b''\b'  resumes  job  1  in  the  background,
        equivalent to `\b``\b`b\bbg\bg %\b%1\b1'\b''\b'.
 
-       The shell learns immediately whenever a job changes  state.   Normally,
+       The  shell  learns immediately whenever a job changes state.  Normally,
        b\bba\bas\bsh\bh waits until it is about to print a prompt before reporting changes
-       in a job's status so as to not interrupt any other output.  If  the  -\b-b\bb
+       in  a  job's status so as to not interrupt any other output.  If the -\b-b\bb
        option to the s\bse\bet\bt builtin command is enabled, b\bba\bas\bsh\bh reports such changes
-       immediately.  Any trap on S\bSI\bIG\bGC\bCH\bHL\bLD\bD  is  executed  for  each  child  that
+       immediately.   Any  trap  on  S\bSI\bIG\bGC\bCH\bHL\bLD\bD  is  executed for each child that
        exits.
 
-       If  an  attempt to exit b\bba\bas\bsh\bh is made while jobs are stopped (or, if the
-       c\bch\bhe\bec\bck\bkj\bjo\bob\bbs\bshell option has been enabled using the s\bsh\bho\bop\bpt\bt  builtin,  run-
+       If an attempt to exit b\bba\bas\bsh\bh is made while jobs are stopped (or,  if  the
+       c\bch\bhe\bec\bck\bkj\bjo\bob\bbs\b shell  option has been enabled using the s\bsh\bho\bop\bpt\bt builtin, run-
        ning), the shell prints a warning message, and, if the c\bch\bhe\bec\bck\bkj\bjo\bob\bbs\bs option
-       is enabled, lists the jobs and their statuses.  The  j\bjo\bob\bbs\bs  command  may
-       then  be  used to inspect their status.  If a second attempt to exit is
-       made without an intervening command, the shell does not  print  another
+       is  enabled,  lists  the jobs and their statuses.  The j\bjo\bob\bbs\bs command may
+       then be used to inspect their status.  If a second attempt to  exit  is
+       made  without  an intervening command, the shell does not print another
        warning, and any stopped jobs are terminated.
 
 P\bPR\bRO\bOM\bMP\bPT\bTI\bIN\bNG\bG
        When executing interactively, b\bba\bas\bsh\bh displays the primary prompt P\bPS\bS1\b1 when
-       it is ready to read a command, and the secondary  prompt  P\bPS\bS2\b2  when  it
-       needs  more  input  to  complete  a  command.  B\bBa\bas\bsh\bh allows these prompt
-       strings to be customized by inserting  a  number  of  backslash-escaped
+       it  is  ready  to  read a command, and the secondary prompt P\bPS\bS2\b2 when it
+       needs more input to complete  a  command.   B\bBa\bas\bsh\bh  allows  these  prompt
+       strings  to  be  customized  by inserting a number of backslash-escaped
        special characters that are decoded as follows:
               \\b\a\ba     an ASCII bell character (07)
-              \\b\d\bd     the  date  in "Weekday Month Date" format (e.g., "Tue May
+              \\b\d\bd     the date in "Weekday Month Date" format (e.g.,  "Tue  May
                      26")
               \\b\D\bD{\b{_\bf_\bo_\br_\bm_\ba_\bt}\b}
-                     the _\bf_\bo_\br_\bm_\ba_\bt is passed to _\bs_\bt_\br_\bf_\bt_\bi_\bm_\be(3)  and  the  result  is
-                     inserted  into the prompt string; an empty _\bf_\bo_\br_\bm_\ba_\bt results
+                     the  _\bf_\bo_\br_\bm_\ba_\bt  is  passed  to _\bs_\bt_\br_\bf_\bt_\bi_\bm_\be(3) and the result is
+                     inserted into the prompt string; an empty _\bf_\bo_\br_\bm_\ba_\b results
                      in a locale-specific time representation.  The braces are
                      required
               \\b\e\be     an ASCII escape character (033)
@@ -2735,7 +2767,7 @@ P\bPR\bRO\bOM\bMP\bPT\bTI\bIN\bNG\bG
               \\b\l\bl     the basename of the shell's terminal device name
               \\b\n\bn     newline
               \\b\r\br     carriage return
-              \\b\s\bs     the  name  of  the shell, the basename of $\b$0\b0 (the portion
+              \\b\s\bs     the name of the shell, the basename of  $\b$0\b0  (the  portion
                      following the final slash)
               \\b\t\bt     the current time in 24-hour HH:MM:SS format
               \\b\T\bT     the current time in 12-hour HH:MM:SS format
@@ -2744,8 +2776,8 @@ P\bPR\bRO\bOM\bMP\bPT\bTI\bIN\bNG\bG
               \\b\u\bu     the username of the current user
               \\b\v\bv     the version of b\bba\bas\bsh\bh (e.g., 2.00)
               \\b\V\bV     the release of b\bba\bas\bsh\bh, version + patch level (e.g., 2.00.0)
-              \\b\w\bw     the current working  directory,  with  $\b$H\bHO\bOM\bME\b abbreviated
-                     with  a tilde (uses the value of the P\bPR\bRO\bOM\bMP\bPT\bT_\b_D\bDI\bIR\bRT\bTR\bRI\bIM\bM vari-
+              \\b\w\bw     the  current  working  directory,  with $\b$H\bHO\bOM\bME\bE abbreviated
+                     with a tilde (uses the value of the P\bPR\bRO\bOM\bMP\bPT\bT_\b_D\bDI\bIR\bRT\bTR\bRI\bIM\b vari-
                      able)
               \\b\W\bW     the basename of the current working directory, with $\b$H\bHO\bOM\bME\bE
                      abbreviated with a tilde
@@ -2754,66 +2786,66 @@ P\bPR\bRO\bOM\bMP\bPT\bTI\bIN\bNG\bG
               \\b\$\b$     if the effective UID is 0, a #\b#, otherwise a $\b$
               \\b\_\bn_\bn_\bn   the character corresponding to the octal number _\bn_\bn_\bn
               \\b\\\b\     a backslash
-              \\b\[\b[     begin  a sequence of non-printing characters, which could
-                     be used to embed a terminal  control  sequence  into  the
+              \\b\[\b[     begin a sequence of non-printing characters, which  could
+                     be  used  to  embed  a terminal control sequence into the
                      prompt
               \\b\]\b]     end a sequence of non-printing characters
 
-       The  command  number  and the history number are usually different: the
-       history number of a command is its position in the history list,  which
-       may  include  commands  restored  from  the  history  file (see H\bHI\bIS\bST\bTO\bOR\bRY\bY
-       below), while the command number is the position  in  the  sequence  of
-       commands  executed  during the current shell session.  After the string
-       is decoded, it is expanded via parameter expansion,  command  substitu-
-       tion,  arithmetic expansion, and quote removal, subject to the value of
-       the p\bpr\bro\bom\bmp\bpt\btv\bva\bar\brs\bs shell option (see the description of the  s\bsh\bho\bop\bpt\b command
+       The command number and the history number are  usually  different:  the
+       history  number of a command is its position in the history list, which
+       may include commands  restored  from  the  history  file  (see  H\bHI\bIS\bST\bTO\bOR\bRY\bY
+       below),  while  the  command  number is the position in the sequence of
+       commands executed during the current shell session.  After  the  string
+       is  decoded,  it is expanded via parameter expansion, command substitu-
+       tion, arithmetic expansion, and quote removal, subject to the value  of
+       the  p\bpr\bro\bom\bmp\bpt\btv\bva\bar\brs\bs  shell option (see the description of the s\bsh\bho\bop\bpt\bt command
        under S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS below).
 
 R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE
-       This  is  the library that handles reading input when using an interac-
+       This is the library that handles reading input when using  an  interac-
        tive shell, unless the -\b--\b-n\bno\boe\bed\bdi\bit\bti\bin\bng\bg option is given at shell invocation.
        Line editing is also used when using the -\b-e\be option to the r\bre\bea\bad\bd builtin.
        By default, the line editing commands are similar to those of Emacs.  A
        vi-style line editing interface is also available.  Line editing can be
-       enabled at any time using the -\b-o\bo e\bem\bma\bac\bcs\bs or -\b-o\bo  v\bvi\bi  options  to  the  s\bse\bet\bt
-       builtin  (see  S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS below).  To turn off line editing
-       after the shell is running, use the +\b+o\bo e\bem\bma\bac\bcs\bs or +\b+o\bo v\bvi\bi  options  to  the
+       enabled  at  any  time  using  the -\b-o\bo e\bem\bma\bac\bcs\bs or -\b-o\bo v\bvi\bi options to the s\bse\bet\bt
+       builtin (see S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS below).  To turn off  line  editing
+       after  the  shell  is running, use the +\b+o\bo e\bem\bma\bac\bcs\bs or +\b+o\bo v\bvi\bi options to the
        s\bse\bet\bt builtin.
 
    R\bRe\bea\bad\bdl\bli\bin\bne\be N\bNo\bot\bta\bat\bti\bio\bon\bn
        In this section, the Emacs-style notation is used to denote keystrokes.
-       Control keys are denoted by C-_\bk_\be_\by, e.g., C-n  means  Control-N.   Simi-
-       larly,  _\bm_\be_\bt_\ba  keys are denoted by M-_\bk_\be_\by, so M-x means Meta-X.  (On key-
-       boards without a _\bm_\be_\bt_\ba key, M-_\bx means ESC _\bx, i.e., press the Escape  key
+       Control  keys  are  denoted by C-_\bk_\be_\by, e.g., C-n means Control-N.  Simi-
+       larly, _\bm_\be_\bt_\ba keys are denoted by M-_\bk_\be_\by, so M-x means Meta-X.   (On  key-
+       boards  without a _\bm_\be_\bt_\ba key, M-_\bx means ESC _\bx, i.e., press the Escape key
        then the _\bx key.  This makes ESC the _\bm_\be_\bt_\ba _\bp_\br_\be_\bf_\bi_\bx.  The combination M-C-_\bx
-       means ESC-Control-_\bx, or press the Escape key then hold the Control  key
+       means  ESC-Control-_\bx, or press the Escape key then hold the Control key
        while pressing the _\bx key.)
 
        Readline commands may be given numeric _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs, which normally act as
-       a repeat count.  Sometimes, however, it is the  sign  of  the  argument
-       that  is  significant.   Passing  a negative argument to a command that
-       acts in the forward direction (e.g., k\bki\bil\bll\bl-\b-l\bli\bin\bne\be) causes that command  to
-       act  in  a  backward direction.  Commands whose behavior with arguments
+       a  repeat  count.   Sometimes,  however, it is the sign of the argument
+       that is significant.  Passing a negative argument  to  a  command  that
+       acts  in the forward direction (e.g., k\bki\bil\bll\bl-\b-l\bli\bin\bne\be) causes that command to
+       act in a backward direction.  Commands whose  behavior  with  arguments
        deviates from this are noted below.
 
-       When a command is described as _\bk_\bi_\bl_\bl_\bi_\bn_\bg text, the text deleted is  saved
+       When  a command is described as _\bk_\bi_\bl_\bl_\bi_\bn_\bg text, the text deleted is saved
        for possible future retrieval (_\by_\ba_\bn_\bk_\bi_\bn_\bg).  The killed text is saved in a
        _\bk_\bi_\bl_\bl _\br_\bi_\bn_\bg.  Consecutive kills cause the text to be accumulated into one
        unit, which can be yanked all at once.  Commands which do not kill text
        separate the chunks of text on the kill ring.
 
    R\bRe\bea\bad\bdl\bli\bin\bne\be I\bIn\bni\bit\bti\bia\bal\bli\biz\bza\bat\bti\bio\bon\bn
-       Readline is customized by putting commands in  an  initialization  file
-       (the  _\bi_\bn_\bp_\bu_\bt_\br_\bc  file).  The name of this file is taken from the value of
-       the I\bIN\bNP\bPU\bUT\bTR\bRC\bC variable.  If  that  variable  is  unset,  the  default  is
-       _\b~_\b/_\b._\bi_\bn_\bp_\bu_\bt_\br_\bc.   When a program which uses the readline library starts up,
+       Readline  is  customized  by putting commands in an initialization file
+       (the _\bi_\bn_\bp_\bu_\bt_\br_\bc file).  The name of this file is taken from the  value  of
+       the  I\bIN\bNP\bPU\bUT\bTR\bRC\bC  variable.   If  that  variable  is  unset, the default is
+       _\b~_\b/_\b._\bi_\bn_\bp_\bu_\bt_\br_\bc.  When a program which uses the readline library starts  up,
        the initialization file is read, and the key bindings and variables are
-       set.   There  are  only  a few basic constructs allowed in the readline
-       initialization file.  Blank lines are ignored.  Lines beginning with  a
-       #\b are  comments.   Lines  beginning with a $\b$ indicate conditional con-
+       set.  There are only a few basic constructs  allowed  in  the  readline
+       initialization  file.  Blank lines are ignored.  Lines beginning with a
+       #\bare comments.  Lines beginning with a  $\b$  indicate  conditional  con-
        structs.  Other lines denote key bindings and variable settings.
 
-       The default key-bindings may be changed with an  _\bi_\bn_\bp_\bu_\bt_\br_\bc  file.   Other
+       The  default  key-bindings  may be changed with an _\bi_\bn_\bp_\bu_\bt_\br_\bc file.  Other
        programs that use this library may add their own commands and bindings.
 
        For example, placing
@@ -2821,18 +2853,18 @@ R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE
               M-Control-u: universal-argument
        or
               C-Meta-u: universal-argument
-       into  the _\bi_\bn_\bp_\bu_\bt_\br_\bc would make M-C-u execute the readline command _\bu_\bn_\bi_\bv_\be_\br_\b-
+       into the _\bi_\bn_\bp_\bu_\bt_\br_\bc would make M-C-u execute the readline command  _\bu_\bn_\bi_\bv_\be_\br_\b-
        _\bs_\ba_\bl_\b-_\ba_\br_\bg_\bu_\bm_\be_\bn_\bt.
 
-       The following symbolic character names  are  recognized:  _\bR_\bU_\bB_\bO_\bU_\bT,  _\bD_\bE_\bL,
+       The  following  symbolic  character  names are recognized: _\bR_\bU_\bB_\bO_\bU_\bT, _\bD_\bE_\bL,
        _\bE_\bS_\bC, _\bL_\bF_\bD, _\bN_\bE_\bW_\bL_\bI_\bN_\bE, _\bR_\bE_\bT, _\bR_\bE_\bT_\bU_\bR_\bN, _\bS_\bP_\bC, _\bS_\bP_\bA_\bC_\bE, and _\bT_\bA_\bB.
 
-       In  addition  to  command  names, readline allows keys to be bound to a
+       In addition to command names, readline allows keys to  be  bound  to  a
        string that is inserted when the key is pressed (a _\bm_\ba_\bc_\br_\bo).
 
    R\bRe\bea\bad\bdl\bli\bin\bne\be K\bKe\bey\by B\bBi\bin\bnd\bdi\bin\bng\bgs\bs
-       The syntax for controlling key bindings in the _\bi_\bn_\bp_\bu_\bt_\br_\bc file is  simple.
-       All  that is required is the name of the command or the text of a macro
+       The  syntax for controlling key bindings in the _\bi_\bn_\bp_\bu_\bt_\br_\bc file is simple.
+       All that is required is the name of the command or the text of a  macro
        and a key sequence to which it should be bound.  The name may be speci-
        fied in one of two ways: as a symbolic key name, possibly with _\bM_\be_\bt_\ba_\b- or
        _\bC_\bo_\bn_\bt_\br_\bo_\bl_\b- prefixes, or as a key sequence.
@@ -2844,15 +2876,15 @@ R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE
               Meta-Rubout: backward-kill-word
               Control-o: "> output"
 
-       In  the above example, _\bC_\b-_\bu is bound to the function u\bun\bni\biv\bve\ber\brs\bsa\bal\bl-\b-a\bar\brg\bgu\bum\bme\ben\bnt\bt,
-       _\bM_\b-_\bD_\bE_\bis bound to the function b\bba\bac\bck\bkw\bwa\bar\brd\bd-\b-k\bki\bil\bll\bl-\b-w\bwo\bor\brd\bd, and _\bC_\b-_\bo is bound  to
-       run  the macro expressed on the right hand side (that is, to insert the
+       In the above example, _\bC_\b-_\bu is bound to the function  u\bun\bni\biv\bve\ber\brs\bsa\bal\bl-\b-a\bar\brg\bgu\bum\bme\ben\bnt\bt,
+       _\bM_\b-_\bD_\bE_\b is bound to the function b\bba\bac\bck\bkw\bwa\bar\brd\bd-\b-k\bki\bil\bll\bl-\b-w\bwo\bor\brd\bd, and _\bC_\b-_\bo is bound to
+       run the macro expressed on the right hand side (that is, to insert  the
        text ``> output'' into the line).
 
-       In the second form, "\b"k\bke\bey\bys\bse\beq\bq"\b":_\bf_\bu_\bn_\bc_\bt_\bi_\bo_\bn_\b-_\bn_\ba_\bm_\be  or  _\bm_\ba_\bc_\br_\bo,  k\bke\bey\bys\bse\beq\b differs
-       from  k\bke\bey\byn\bna\bam\bme\be above in that strings denoting an entire key sequence may
-       be specified by placing the sequence within double  quotes.   Some  GNU
-       Emacs  style  key escapes can be used, as in the following example, but
+       In  the  second  form,  "\b"k\bke\bey\bys\bse\beq\bq"\b":_\bf_\bu_\bn_\bc_\bt_\bi_\bo_\bn_\b-_\bn_\ba_\bm_\be or _\bm_\ba_\bc_\br_\bo, k\bke\bey\bys\bse\beq\bq differs
+       from k\bke\bey\byn\bna\bam\bme\be above in that strings denoting an entire key sequence  may
+       be  specified  by  placing the sequence within double quotes.  Some GNU
+       Emacs style key escapes can be used, as in the following  example,  but
        the symbolic character names are not recognized.
 
               "\C-u": universal-argument
@@ -2860,7 +2892,7 @@ R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE
               "\e[11~": "Function Key 1"
 
        In this example, _\bC_\b-_\bu is again bound to the function u\bun\bni\biv\bve\ber\brs\bsa\bal\bl-\b-a\bar\brg\bgu\bum\bme\ben\bnt\bt.
-       _\bC_\b-_\b _\bC_\b-_\br is bound to the function r\bre\be-\b-r\bre\bea\bad\bd-\b-i\bin\bni\bit\bt-\b-f\bfi\bil\ble\be, and _\bE_\bS_\bC _\b[ _\b1 _\b1 _\b~ is
+       _\bC_\b-_\b_\bC_\b-_\br is bound to the function r\bre\be-\b-r\bre\bea\bad\bd-\b-i\bin\bni\bit\bt-\b-f\bfi\bil\ble\be, and _\bE_\bS_\bC _\b[ _\b1 _\b1 _\b is
        bound to insert the text ``Function Key 1''.
 
        The full set of GNU Emacs style escape sequences is
@@ -2871,7 +2903,7 @@ R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE
               \\b\"\b"     literal "
               \\b\'\b'     literal '
 
-       In addition to the GNU Emacs style escape sequences, a  second  set  of
+       In  addition  to  the GNU Emacs style escape sequences, a second set of
        backslash escapes is available:
               \\b\a\ba     alert (bell)
               \\b\b\bb     backspace
@@ -2881,20 +2913,20 @@ R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE
               \\b\r\br     carriage return
               \\b\t\bt     horizontal tab
               \\b\v\bv     vertical tab
-              \\b\_\bn_\bn_\bn   the  eight-bit  character  whose value is the octal value
+              \\b\_\bn_\bn_\bn   the eight-bit character whose value is  the  octal  value
                      _\bn_\bn_\bn (one to three digits)
-              \\b\x\bx_\bH_\bH   the eight-bit character whose value  is  the  hexadecimal
+              \\b\x\bx_\bH_\bH   the  eight-bit  character  whose value is the hexadecimal
                      value _\bH_\bH (one or two hex digits)
 
        When entering the text of a macro, single or double quotes must be used
        to indicate a macro definition.  Unquoted text is assumed to be a func-
-       tion  name.   In  the macro body, the backslash escapes described above
-       are expanded.  Backslash will quote any other character  in  the  macro
+       tion name.  In the macro body, the backslash  escapes  described  above
+       are  expanded.   Backslash  will quote any other character in the macro
        text, including " and '.
 
-       B\bBa\bas\bsh\b allows the current readline key bindings to be displayed or modi-
-       fied with the b\bbi\bin\bnd\bd builtin command.  The editing mode may  be  switched
-       during  interactive  use by using the -\b-o\bo option to the s\bse\bet\bt builtin com-
+       B\bBa\bas\bsh\ballows the current readline key bindings to be displayed or  modi-
+       fied  with  the b\bbi\bin\bnd\bd builtin command.  The editing mode may be switched
+       during interactive use by using the -\b-o\bo option to the s\bse\bet\bt  builtin  com-
        mand (see S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS below).
 
    R\bRe\bea\bad\bdl\bli\bin\bne\be V\bVa\bar\bri\bia\bab\bbl\ble\bes\bs
@@ -2904,249 +2936,249 @@ R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE
 
               s\bse\bet\bt _\bv_\ba_\br_\bi_\ba_\bb_\bl_\be_\b-_\bn_\ba_\bm_\be _\bv_\ba_\bl_\bu_\be
 
-       Except where noted, readline variables can take the values  O\bOn\bn  or  O\bOf\bff\bf
-       (without  regard  to  case).   Unrecognized variable names are ignored.
-       When a variable value is read, empty or null values, "on"  (case-insen-
+       Except  where  noted,  readline variables can take the values O\bOn\bn or O\bOf\bff\bf
+       (without regard to case).  Unrecognized  variable  names  are  ignored.
+       When  a variable value is read, empty or null values, "on" (case-insen-
        sitive), and "1" are equivalent to O\bOn\bn.  All other values are equivalent
        to O\bOf\bff\bf.  The variables and their default values are:
 
        b\bbe\bel\bll\bl-\b-s\bst\bty\byl\ble\be (\b(a\bau\bud\bdi\bib\bbl\ble\be)\b)
-              Controls what happens when readline wants to ring  the  terminal
+              Controls  what  happens when readline wants to ring the terminal
               bell.  If set to n\bno\bon\bne\be, readline never rings the bell.  If set to
-              v\bvi\bis\bsi\bib\bbl\ble\be, readline uses a visible bell if one is  available.   If
+              v\bvi\bis\bsi\bib\bbl\ble\be,  readline  uses a visible bell if one is available.  If
               set to a\bau\bud\bdi\bib\bbl\ble\be, readline attempts to ring the terminal's bell.
        b\bbi\bin\bnd\bd-\b-t\btt\bty\by-\b-s\bsp\bpe\bec\bci\bia\bal\bl-\b-c\bch\bha\bar\brs\bs (\b(O\bOn\bn)\b)
-              If  set  to O\bOn\bn, readline attempts to bind the control characters
+              If set to O\bOn\bn, readline attempts to bind the  control  characters
               treated specially by the kernel's terminal driver to their read-
               line equivalents.
        c\bco\bol\blo\bor\bre\bed\bd-\b-c\bco\bom\bmp\bpl\ble\bet\bti\bio\bon\bn-\b-p\bpr\bre\bef\bfi\bix\bx (\b(O\bOf\bff\bf)\b)
-              If  set  to  O\bOn\bn, when listing completions, readline displays the
+              If set to O\bOn\bn, when listing completions,  readline  displays  the
               common prefix of the set of possible completions using a differ-
-              ent  color.   The  color definitions are taken from the value of
+              ent color.  The color definitions are taken from  the  value  of
               the L\bLS\bS_\b_C\bCO\bOL\bLO\bOR\bRS\bS environment variable.
        c\bco\bol\blo\bor\bre\bed\bd-\b-s\bst\bta\bat\bts\bs (\b(O\bOf\bff\bf)\b)
-              If set to O\bOn\bn, readline displays possible completions using  dif-
-              ferent  colors  to  indicate their file type.  The color defini-
-              tions are taken from the  value  of  the  L\bLS\bS_\b_C\bCO\bOL\bLO\bOR\bRS\b environment
+              If  set to O\bOn\bn, readline displays possible completions using dif-
+              ferent colors to indicate their file type.   The  color  defini-
+              tions  are  taken  from  the  value of the L\bLS\bS_\b_C\bCO\bOL\bLO\bOR\bRS\bS environment
               variable.
        c\bco\bom\bmm\bme\ben\bnt\bt-\b-b\bbe\beg\bgi\bin\bn (\b(`\b``\b`#\b#'\b''\b')\b)
-              The  string  that  is  inserted when the readline i\bin\bns\bse\ber\brt\bt-\b-c\bco\bom\bmm\bme\ben\bnt\bt
+              The string that is inserted  when  the  readline  i\bin\bns\bse\ber\brt\bt-\b-c\bco\bom\bmm\bme\ben\bnt\bt
               command is executed.  This command is bound to M\bM-\b-#\b# in emacs mode
               and to #\b# in vi command mode.
        c\bco\bom\bmp\bpl\ble\bet\bti\bio\bon\bn-\b-i\big\bgn\bno\bor\bre\be-\b-c\bca\bas\bse\be (\b(O\bOf\bff\bf)\b)
               If set to O\bOn\bn, readline performs filename matching and completion
               in a case-insensitive fashion.
        c\bco\bom\bmp\bpl\ble\bet\bti\bio\bon\bn-\b-p\bpr\bre\bef\bfi\bix\bx-\b-d\bdi\bis\bsp\bpl\bla\bay\by-\b-l\ble\ben\bng\bgt\bth\bh (\b(0\b0)\b)
-              The length in characters of the common prefix of a list of  pos-
-              sible  completions that is displayed without modification.  When
-              set to a value greater than zero, common  prefixes  longer  than
-              this  value are replaced with an ellipsis when displaying possi-
+              The  length in characters of the common prefix of a list of pos-
+              sible completions that is displayed without modification.   When
+              set  to  a  value greater than zero, common prefixes longer than
+              this value are replaced with an ellipsis when displaying  possi-
               ble completions.
        c\bco\bom\bmp\bpl\ble\bet\bti\bio\bon\bn-\b-q\bqu\bue\ber\bry\by-\b-i\bit\bte\bem\bms\bs (\b(1\b10\b00\b0)\b)
-              This determines when the user is queried about viewing the  num-
-              ber  of  possible  completions generated by the p\bpo\bos\bss\bsi\bib\bbl\ble\be-\b-c\bco\bom\bmp\bpl\ble\be-\b-
-              t\bti\bio\bon\bns\bcommand.  It may be set to any integer value greater  than
-              or  equal  to  zero.   If  the number of possible completions is
+              This  determines when the user is queried about viewing the num-
+              ber of possible completions generated  by  the  p\bpo\bos\bss\bsi\bib\bbl\ble\be-\b-c\bco\bom\bmp\bpl\ble\be-\b-
+              t\bti\bio\bon\bns\b command.  It may be set to any integer value greater than
+              or equal to zero.  If the  number  of  possible  completions  is
               greater than or equal to the value of this variable, the user is
-              asked  whether or not he wishes to view them; otherwise they are
+              asked whether or not he wishes to view them; otherwise they  are
               simply listed on the terminal.
        c\bco\bon\bnv\bve\ber\brt\bt-\b-m\bme\bet\bta\ba (\b(O\bOn\bn)\b)
-              If set to O\bOn\bn, readline will convert characters with  the  eighth
+              If  set  to O\bOn\bn, readline will convert characters with the eighth
               bit set to an ASCII key sequence by stripping the eighth bit and
-              prefixing an escape character (in effect, using  escape  as  the
+              prefixing  an  escape  character (in effect, using escape as the
               _\bm_\be_\bt_\ba _\bp_\br_\be_\bf_\bi_\bx).
        d\bdi\bis\bsa\bab\bbl\ble\be-\b-c\bco\bom\bmp\bpl\ble\bet\bti\bio\bon\bn (\b(O\bOf\bff\bf)\b)
               If set to O\bOn\bn, readline will inhibit word completion.  Completion
-              characters will be inserted into the line as if  they  had  been
+              characters  will  be  inserted into the line as if they had been
               mapped to s\bse\bel\blf\bf-\b-i\bin\bns\bse\ber\brt\bt.
        e\bed\bdi\bit\bti\bin\bng\bg-\b-m\bmo\bod\bde\be (\b(e\bem\bma\bac\bcs\bs)\b)
               Controls whether readline begins with a set of key bindings sim-
               ilar to _\bE_\bm_\ba_\bc_\bs or _\bv_\bi.  e\bed\bdi\bit\bti\bin\bng\bg-\b-m\bmo\bod\bde\be can be set to either e\bem\bma\bac\bcs\bs or
               v\bvi\bi.
        e\bec\bch\bho\bo-\b-c\bco\bon\bnt\btr\bro\bol\bl-\b-c\bch\bha\bar\bra\bac\bct\bte\ber\brs\bs (\b(O\bOn\bn)\b)
-              When  set to O\bOn\bn, on operating systems that indicate they support
+              When set to O\bOn\bn, on operating systems that indicate they  support
               it, readline echoes a character corresponding to a signal gener-
               ated from the keyboard.
        e\ben\bna\bab\bbl\ble\be-\b-b\bbr\bra\bac\bck\bke\bet\bte\bed\bd-\b-p\bpa\bas\bst\bte\be (\b(O\bOf\bff\bf)\b)
-              When  set  to  O\bOn\bn, readline will configure the terminal in a way
+              When set to O\bOn\bn, readline will configure the terminal  in  a  way
               that will enable it to insert each paste into the editing buffer
               as a single string of characters, instead of treating each char-
-              acter as if it had been read from the keyboard.  This  can  pre-
-              vent  pasted  characters  from being interpreted as editing com-
+              acter  as  if it had been read from the keyboard.  This can pre-
+              vent pasted characters from being interpreted  as  editing  com-
               mands.
        e\ben\bna\bab\bbl\ble\be-\b-k\bke\bey\byp\bpa\bad\bd (\b(O\bOf\bff\bf)\b)
               When set to O\bOn\bn, readline will try to enable the application key-
-              pad  when  it  is  called.  Some systems need this to enable the
+              pad when it is called.  Some systems need  this  to  enable  the
               arrow keys.
        e\ben\bna\bab\bbl\ble\be-\b-m\bme\bet\bta\ba-\b-k\bke\bey\by (\b(O\bOn\bn)\b)
-              When set to O\bOn\bn, readline will try to enable  any  meta  modifier
-              key  the  terminal claims to support when it is called.  On many
+              When  set  to  O\bOn\bn, readline will try to enable any meta modifier
+              key the terminal claims to support when it is called.   On  many
               terminals, the meta key is used to send eight-bit characters.
        e\bex\bxp\bpa\ban\bnd\bd-\b-t\bti\bil\bld\bde\be (\b(O\bOf\bff\bf)\b)
-              If set  to  O\bOn\bn,  tilde  expansion  is  performed  when  readline
+              If  set  to  O\bOn\bn,  tilde  expansion  is  performed  when readline
               attempts word completion.
        h\bhi\bis\bst\bto\bor\bry\by-\b-p\bpr\bre\bes\bse\ber\brv\bve\be-\b-p\bpo\boi\bin\bnt\bt (\b(O\bOf\bff\bf)\b)
-              If  set  to  O\bOn\bn, the history code attempts to place point at the
-              same location on each history line retrieved with  p\bpr\bre\bev\bvi\bio\bou\bus\bs-\b-h\bhi\bis\bs-\b-
+              If set to O\bOn\bn, the history code attempts to place  point  at  the
+              same  location on each history line retrieved with p\bpr\bre\bev\bvi\bio\bou\bus\bs-\b-h\bhi\bis\bs-\b-
               t\bto\bor\bry\by or n\bne\bex\bxt\bt-\b-h\bhi\bis\bst\bto\bor\bry\by.
        h\bhi\bis\bst\bto\bor\bry\by-\b-s\bsi\biz\bze\be (\b(u\bun\bns\bse\bet\bt)\b)
-              Set  the  maximum number of history entries saved in the history
-              list.  If set to zero, any existing history entries are  deleted
+              Set the maximum number of history entries saved in  the  history
+              list.   If set to zero, any existing history entries are deleted
               and no new entries are saved.  If set to a value less than zero,
-              the number of history entries is not limited.  By  default,  the
+              the  number  of history entries is not limited.  By default, the
               number of history entries is not limited.
        h\bho\bor\bri\biz\bzo\bon\bnt\bta\bal\bl-\b-s\bsc\bcr\bro\bol\bll\bl-\b-m\bmo\bod\bde\be (\b(O\bOf\bff\bf)\b)
-              When  set  to  O\bOn\bn, makes readline use a single line for display,
+              When set to O\bOn\bn, makes readline use a single  line  for  display,
               scrolling the input horizontally on a single screen line when it
-              becomes  longer  than the screen width rather than wrapping to a
+              becomes longer than the screen width rather than wrapping  to  a
               new line.
        i\bin\bnp\bpu\but\bt-\b-m\bme\bet\bta\ba (\b(O\bOf\bff\bf)\b)
-              If set to O\bOn\bn, readline will enable eight-bit input (that is,  it
-              will  not  strip  the  high  bit  from the characters it reads),
+              If  set to O\bOn\bn, readline will enable eight-bit input (that is, it
+              will not strip the high  bit  from  the  characters  it  reads),
               regardless of what the terminal claims it can support.  The name
               m\bme\bet\bta\ba-\b-f\bfl\bla\bag\bg is a synonym for this variable.
        i\bis\bse\bea\bar\brc\bch\bh-\b-t\bte\ber\brm\bmi\bin\bna\bat\bto\bor\brs\bs (\b(`\b``\b`C\bC-\b-[\b[C\bC-\b-J\bJ'\b''\b')\b)
-              The  string  of  characters that should terminate an incremental
-              search without subsequently executing the character  as  a  com-
-              mand.   If this variable has not been given a value, the charac-
+              The string of characters that should  terminate  an  incremental
+              search  without  subsequently  executing the character as a com-
+              mand.  If this variable has not been given a value, the  charac-
               ters _\bE_\bS_\bC and _\bC_\b-_\bJ will terminate an incremental search.
        k\bke\bey\bym\bma\bap\bp (\b(e\bem\bma\bac\bcs\bs)\b)
-              Set the current readline keymap.  The set of valid keymap  names
-              is  _\be_\bm_\ba_\bc_\bs_\b,  _\be_\bm_\ba_\bc_\bs_\b-_\bs_\bt_\ba_\bn_\bd_\ba_\br_\bd_\b,  _\be_\bm_\ba_\bc_\bs_\b-_\bm_\be_\bt_\ba_\b, _\be_\bm_\ba_\bc_\bs_\b-_\bc_\bt_\bl_\bx_\b, _\bv_\bi_\b, _\bv_\bi_\b-_\bc_\bo_\bm_\b-
-              _\bm_\ba_\bn_\bd, and _\bv_\bi_\b-_\bi_\bn_\bs_\be_\br_\bt.  _\bv_\bi is equivalent to _\bv_\bi_\b-_\bc_\bo_\bm_\bm_\ba_\bn_\bd;  _\be_\bm_\ba_\bc_\b is
-              equivalent  to  _\be_\bm_\ba_\bc_\bs_\b-_\bs_\bt_\ba_\bn_\bd_\ba_\br_\bd.  The default value is _\be_\bm_\ba_\bc_\bs; the
+              Set  the current readline keymap.  The set of valid keymap names
+              is _\be_\bm_\ba_\bc_\bs_\b, _\be_\bm_\ba_\bc_\bs_\b-_\bs_\bt_\ba_\bn_\bd_\ba_\br_\bd_\b, _\be_\bm_\ba_\bc_\bs_\b-_\bm_\be_\bt_\ba_\b,  _\be_\bm_\ba_\bc_\bs_\b-_\bc_\bt_\bl_\bx_\b,  _\bv_\bi_\b _\bv_\bi_\b-_\bc_\bo_\bm_\b-
+              _\bm_\ba_\bn_\bd,  and  _\bv_\bi_\b-_\bi_\bn_\bs_\be_\br_\bt.  _\bv_\bi is equivalent to _\bv_\bi_\b-_\bc_\bo_\bm_\bm_\ba_\bn_\bd; _\be_\bm_\ba_\bc_\bs is
+              equivalent to _\be_\bm_\ba_\bc_\bs_\b-_\bs_\bt_\ba_\bn_\bd_\ba_\br_\bd.  The default value is  _\be_\bm_\ba_\bc_\bs;  the
               value of e\bed\bdi\bit\bti\bin\bng\bg-\b-m\bmo\bod\bde\be also affects the default keymap.
        e\bem\bma\bac\bcs\bs-\b-m\bmo\bod\bde\be-\b-s\bst\btr\bri\bin\bng\bg (\b(@\b@)\b)
               This string is displayed immediately before the last line of the
-              primary  prompt when emacs editing mode is active.  The value is
-              expanded like a key binding, so the standard set  of  meta-  and
-              control  prefixes  and  backslash escape sequences is available.
-              Use the \1 and \2 escapes to begin and  end  sequences  of  non-
-              printing  characters, which can be used to embed a terminal con-
+              primary prompt when emacs editing mode is active.  The value  is
+              expanded  like  a  key binding, so the standard set of meta- and
+              control prefixes and backslash escape  sequences  is  available.
+              Use  the  \1  and  \2 escapes to begin and end sequences of non-
+              printing characters, which can be used to embed a terminal  con-
               trol sequence into the mode string.
        k\bke\bey\bys\bse\beq\bq-\b-t\bti\bim\bme\beo\bou\but\bt (\b(5\b50\b00\b0)\b)
-              Specifies the duration _\br_\be_\ba_\bd_\bl_\bi_\bn_\be will wait for a  character  when
-              reading  an ambiguous key sequence (one that can form a complete
+              Specifies  the  duration _\br_\be_\ba_\bd_\bl_\bi_\bn_\be will wait for a character when
+              reading an ambiguous key sequence (one that can form a  complete
               key sequence using the input read so far, or can take additional
-              input  to  complete  a  longer  key  sequence).   If no input is
-              received within the timeout, _\br_\be_\ba_\bd_\bl_\bi_\bn_\be will use the  shorter  but
-              complete  key sequence.  The value is specified in milliseconds,
-              so a value of 1000 means that _\br_\be_\ba_\bd_\bl_\bi_\bn_\be will wait one second  for
-              additional  input.  If this variable is set to a value less than
-              or equal to zero, or to a non-numeric value, _\br_\be_\ba_\bd_\bl_\bi_\bn_\be will  wait
-              until  another  key  is  pressed to decide which key sequence to
+              input to complete a  longer  key  sequence).   If  no  input  is
+              received  within  the timeout, _\br_\be_\ba_\bd_\bl_\bi_\bn_\be will use the shorter but
+              complete key sequence.  The value is specified in  milliseconds,
+              so  a value of 1000 means that _\br_\be_\ba_\bd_\bl_\bi_\bn_\be will wait one second for
+              additional input.  If this variable is set to a value less  than
+              or  equal to zero, or to a non-numeric value, _\br_\be_\ba_\bd_\bl_\bi_\bn_\be will wait
+              until another key is pressed to decide  which  key  sequence  to
               complete.
        m\bma\bar\brk\bk-\b-d\bdi\bir\bre\bec\bct\bto\bor\bri\bie\bes\bs (\b(O\bOn\bn)\b)
               If set to O\bOn\bn, completed directory names have a slash appended.
        m\bma\bar\brk\bk-\b-m\bmo\bod\bdi\bif\bfi\bie\bed\bd-\b-l\bli\bin\bne\bes\bs (\b(O\bOf\bff\bf)\b)
-              If set to O\bOn\bn, history lines that have  been  modified  are  dis-
+              If  set  to  O\bOn\bn,  history lines that have been modified are dis-
               played with a preceding asterisk (*\b*).
        m\bma\bar\brk\bk-\b-s\bsy\bym\bml\bli\bin\bnk\bke\bed\bd-\b-d\bdi\bir\bre\bec\bct\bto\bor\bri\bie\bes\bs (\b(O\bOf\bff\bf)\b)
               If set to O\bOn\bn, completed names which are symbolic links to direc-
-              tories  have  a  slash  appended  (subject  to  the   value   of
+              tories   have   a  slash  appended  (subject  to  the  value  of
               m\bma\bar\brk\bk-\b-d\bdi\bir\bre\bec\bct\bto\bor\bri\bie\bes\bs).
        m\bma\bat\btc\bch\bh-\b-h\bhi\bid\bdd\bde\ben\bn-\b-f\bfi\bil\ble\bes\bs (\b(O\bOn\bn)\b)
-              This  variable,  when  set to O\bOn\bn, causes readline to match files
-              whose names begin with a  `.'  (hidden  files)  when  performing
-              filename  completion.   If  set  to O\bOf\bff\bf, the leading `.' must be
+              This variable, when set to O\bOn\bn, causes readline  to  match  files
+              whose  names  begin  with  a  `.' (hidden files) when performing
+              filename completion.  If set to O\bOf\bff\bf, the  leading  `.'  must  be
               supplied by the user in the filename to be completed.
        m\bme\ben\bnu\bu-\b-c\bco\bom\bmp\bpl\ble\bet\bte\be-\b-d\bdi\bis\bsp\bpl\bla\bay\by-\b-p\bpr\bre\bef\bfi\bix\bx (\b(O\bOf\bff\bf)\b)
-              If set to O\bOn\bn, menu completion displays the common prefix of  the
+              If  set to O\bOn\bn, menu completion displays the common prefix of the
               list of possible completions (which may be empty) before cycling
               through the list.
        o\bou\but\btp\bpu\but\bt-\b-m\bme\bet\bta\ba (\b(O\bOf\bff\bf)\b)
-              If set to O\bOn\bn, readline will display characters with  the  eighth
+              If  set  to O\bOn\bn, readline will display characters with the eighth
               bit set directly rather than as a meta-prefixed escape sequence.
        p\bpa\bag\bge\be-\b-c\bco\bom\bmp\bpl\ble\bet\bti\bio\bon\bns\bs (\b(O\bOn\bn)\b)
-              If  set to O\bOn\bn, readline uses an internal _\bm_\bo_\br_\be-like pager to dis-
+              If set to O\bOn\bn, readline uses an internal _\bm_\bo_\br_\be-like pager to  dis-
               play a screenful of possible completions at a time.
        p\bpr\bri\bin\bnt\bt-\b-c\bco\bom\bmp\bpl\ble\bet\bti\bio\bon\bns\bs-\b-h\bho\bor\bri\biz\bzo\bon\bnt\bta\bal\bll\bly\by (\b(O\bOf\bff\bf)\b)
-              If set to O\bOn\bn, readline will  display  completions  with  matches
-              sorted  horizontally in alphabetical order, rather than down the
+              If  set  to  O\bOn\bn,  readline will display completions with matches
+              sorted horizontally in alphabetical order, rather than down  the
               screen.
        r\bre\bev\bve\ber\brt\bt-\b-a\bal\bll\bl-\b-a\bat\bt-\b-n\bne\bew\bwl\bli\bin\bne\be (\b(O\bOf\bff\bf)\b)
-              If set to O\bOn\bn, readline will undo all changes  to  history  lines
+              If  set  to  O\bOn\bn, readline will undo all changes to history lines
               before returning when a\bac\bcc\bce\bep\bpt\bt-\b-l\bli\bin\bne\be is executed.  By default, his-
-              tory lines may be modified  and  retain  individual  undo  lists
+              tory  lines  may  be  modified  and retain individual undo lists
               across calls to r\bre\bea\bad\bdl\bli\bin\bne\be.
        s\bsh\bho\bow\bw-\b-a\bal\bll\bl-\b-i\bif\bf-\b-a\bam\bmb\bbi\big\bgu\buo\bou\bus\bs (\b(O\bOf\bff\bf)\b)
-              This  alters  the  default behavior of the completion functions.
+              This alters the default behavior of  the  completion  functions.
               If set to O\bOn\bn, words which have more than one possible completion
-              cause  the  matches  to be listed immediately instead of ringing
+              cause the matches to be listed immediately  instead  of  ringing
               the bell.
        s\bsh\bho\bow\bw-\b-a\bal\bll\bl-\b-i\bif\bf-\b-u\bun\bnm\bmo\bod\bdi\bif\bfi\bie\bed\bd (\b(O\bOf\bff\bf)\b)
-              This alters the default behavior of the completion functions  in
+              This  alters the default behavior of the completion functions in
               a fashion similar to s\bsh\bho\bow\bw-\b-a\bal\bll\bl-\b-i\bif\bf-\b-a\bam\bmb\bbi\big\bgu\buo\bou\bus\bs.  If set to O\bOn\bn, words
-              which have more than one possible completion without any  possi-
-              ble  partial  completion (the possible completions don't share a
-              common prefix)  cause  the  matches  to  be  listed  immediately
+              which  have more than one possible completion without any possi-
+              ble partial completion (the possible completions don't  share  a
+              common  prefix)  cause  the  matches  to  be  listed immediately
               instead of ringing the bell.
        s\bsh\bho\bow\bw-\b-m\bmo\bod\bde\be-\b-i\bin\bn-\b-p\bpr\bro\bom\bmp\bpt\bt (\b(O\bOf\bff\bf)\b)
-              If  set  to  O\bOn\bn,  add a character to the beginning of the prompt
-              indicating the editing mode: emacs (@), vi  command  (:)  or  vi
+              If set to O\bOn\bn, add a character to the  beginning  of  the  prompt
+              indicating  the  editing  mode:  emacs (@), vi command (:) or vi
               insertion (+).
        s\bsk\bki\bip\bp-\b-c\bco\bom\bmp\bpl\ble\bet\bte\bed\bd-\b-t\bte\bex\bxt\bt (\b(O\bOf\bff\bf)\b)
-              If  set  to O\bOn\bn, this alters the default completion behavior when
-              inserting a single match into the line.  It's only  active  when
-              performing  completion  in  the  middle  of a word.  If enabled,
-              readline does not insert characters  from  the  completion  that
-              match  characters  after  point  in the word being completed, so
+              If set to O\bOn\bn, this alters the default completion  behavior  when
+              inserting  a  single match into the line.  It's only active when
+              performing completion in the middle  of  a  word.   If  enabled,
+              readline  does  not  insert  characters from the completion that
+              match characters after point in the  word  being  completed,  so
               portions of the word following the cursor are not duplicated.
        v\bvi\bi-\b-c\bcm\bmd\bd-\b-m\bmo\bod\bde\be-\b-s\bst\btr\bri\bin\bng\bg (\b((\b(c\bcm\bmd\bd)\b))\b)
               This string is displayed immediately before the last line of the
-              primary  prompt  when  vi  editing mode is active and in command
+              primary prompt when vi editing mode is  active  and  in  command
               mode.  The value is expanded like a key binding, so the standard
               set of meta- and control prefixes and backslash escape sequences
-              is available.  Use the \1  and  \2  escapes  to  begin  and  end
+              is  available.   Use  the  \1  and  \2  escapes to begin and end
               sequences of non-printing characters, which can be used to embed
               a terminal control sequence into the mode string.
        v\bvi\bi-\b-i\bin\bns\bs-\b-m\bmo\bod\bde\be-\b-s\bst\btr\bri\bin\bng\bg (\b((\b(i\bin\bns\bs)\b))\b)
               This string is displayed immediately before the last line of the
-              primary  prompt  when vi editing mode is active and in insertion
+              primary prompt when vi editing mode is active and  in  insertion
               mode.  The value is expanded like a key binding, so the standard
               set of meta- and control prefixes and backslash escape sequences
-              is available.  Use the \1  and  \2  escapes  to  begin  and  end
+              is  available.   Use  the  \1  and  \2  escapes to begin and end
               sequences of non-printing characters, which can be used to embed
               a terminal control sequence into the mode string.
        v\bvi\bis\bsi\bib\bbl\ble\be-\b-s\bst\bta\bat\bts\bs (\b(O\bOf\bff\bf)\b)
-              If set to O\bOn\bn, a character denoting a file's type as reported  by
-              _\bs_\bt_\ba_\bt(2)  is  appended to the filename when listing possible com-
+              If  set to O\bOn\bn, a character denoting a file's type as reported by
+              _\bs_\bt_\ba_\bt(2) is appended to the filename when listing  possible  com-
               pletions.
 
    R\bRe\bea\bad\bdl\bli\bin\bne\be C\bCo\bon\bnd\bdi\bit\bti\bio\bon\bna\bal\bl C\bCo\bon\bns\bst\btr\bru\buc\bct\bts\bs
-       Readline implements a facility similar in  spirit  to  the  conditional
-       compilation  features  of  the C preprocessor which allows key bindings
-       and variable settings to be performed as the result  of  tests.   There
+       Readline  implements  a  facility  similar in spirit to the conditional
+       compilation features of the C preprocessor which  allows  key  bindings
+       and  variable  settings  to be performed as the result of tests.  There
        are four parser directives used.
 
-       $\b$i\bif\bf    The  $\b$i\bif\bf construct allows bindings to be made based on the edit-
-              ing mode, the terminal being  used,  or  the  application  using
-              readline.   The text of the test extends to the end of the line;
+       $\b$i\bif\bf    The $\b$i\bif\bf construct allows bindings to be made based on the  edit-
+              ing  mode,  the  terminal  being  used, or the application using
+              readline.  The text of the test extends to the end of the  line;
               no characters are required to isolate it.
 
-              m\bmo\bod\bde\be   The m\bmo\bod\bde\be=\b= form of the  $\b$i\bif\bf  directive  is  used  to  test
-                     whether  readline  is  in  emacs or vi mode.  This may be
-                     used in conjunction with  the  s\bse\bet\bt  k\bke\bey\bym\bma\bap\bp  command,  for
-                     instance,  to  set  bindings  in  the  _\be_\bm_\ba_\bc_\bs_\b-_\bs_\bt_\ba_\bn_\bd_\ba_\br_\bd and
-                     _\be_\bm_\ba_\bc_\bs_\b-_\bc_\bt_\bl_\bkeymaps only if readline is  starting  out  in
+              m\bmo\bod\bde\be   The  m\bmo\bod\bde\be=\b=  form  of  the  $\b$i\bif\bf  directive is used to test
+                     whether readline is in emacs or vi  mode.   This  may  be
+                     used  in  conjunction  with  the  s\bse\bet\bt k\bke\bey\bym\bma\bap\bp command, for
+                     instance, to  set  bindings  in  the  _\be_\bm_\ba_\bc_\bs_\b-_\bs_\bt_\ba_\bn_\bd_\ba_\br_\b and
+                     _\be_\bm_\ba_\bc_\bs_\b-_\bc_\bt_\bl_\b keymaps  only  if readline is starting out in
                      emacs mode.
 
-              t\bte\ber\brm\bm   The  t\bte\ber\brm\bm=\b=  form may be used to include terminal-specific
+              t\bte\ber\brm\bm   The t\bte\ber\brm\bm=\b= form may be used to  include  terminal-specific
                      key bindings, perhaps to bind the key sequences output by
                      the terminal's function keys.  The word on the right side
                      of the =\b= is tested against the both full name of the ter-
-                     minal  and  the  portion  of the terminal name before the
-                     first -\b-.  This allows _\bs_\bu_\bn to match both _\bs_\bu_\bn and  _\bs_\bu_\bn_\b-_\bc_\bm_\bd,
+                     minal and the portion of the  terminal  name  before  the
+                     first  -\b-.  This allows _\bs_\bu_\bn to match both _\bs_\bu_\bn and _\bs_\bu_\bn_\b-_\bc_\bm_\bd,
                      for instance.
 
               a\bap\bpp\bpl\bli\bic\bca\bat\bti\bio\bon\bn
                      The a\bap\bpp\bpl\bli\bic\bca\bat\bti\bio\bon\bn construct is used to include application-
                      specific  settings.   Each  program  using  the  readline
-                     library  sets the _\ba_\bp_\bp_\bl_\bi_\bc_\ba_\bt_\bi_\bo_\bn _\bn_\ba_\bm_\be, and an initialization
+                     library sets the _\ba_\bp_\bp_\bl_\bi_\bc_\ba_\bt_\bi_\bo_\bn _\bn_\ba_\bm_\be, and an  initialization
                      file can test for a particular value.  This could be used
-                     to  bind key sequences to functions useful for a specific
-                     program.  For instance, the following command adds a  key
-                     sequence  that  quotes  the  current  or previous word in
+                     to bind key sequences to functions useful for a  specific
+                     program.   For instance, the following command adds a key
+                     sequence that quotes the  current  or  previous  word  in
                      b\bba\bas\bsh\bh:
 
                      $\b$i\bif\bf Bash
@@ -3161,51 +3193,51 @@ R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE
               test fails.
 
        $\b$i\bin\bnc\bcl\blu\bud\bde\be
-              This directive takes a single filename as an argument and  reads
-              commands  and bindings from that file.  For example, the follow-
+              This  directive takes a single filename as an argument and reads
+              commands and bindings from that file.  For example, the  follow-
               ing directive would read _\b/_\be_\bt_\bc_\b/_\bi_\bn_\bp_\bu_\bt_\br_\bc:
 
               $\b$i\bin\bnc\bcl\blu\bud\bde\be  _\b/_\be_\bt_\bc_\b/_\bi_\bn_\bp_\bu_\bt_\br_\bc
 
    S\bSe\bea\bar\brc\bch\bhi\bin\bng\bg
-       Readline provides commands for searching through  the  command  history
+       Readline  provides  commands  for searching through the command history
        (see H\bHI\bIS\bST\bTO\bOR\bRY\bY below) for lines containing a specified string.  There are
        two search modes: _\bi_\bn_\bc_\br_\be_\bm_\be_\bn_\bt_\ba_\bl and _\bn_\bo_\bn_\b-_\bi_\bn_\bc_\br_\be_\bm_\be_\bn_\bt_\ba_\bl.
 
-       Incremental searches begin before the  user  has  finished  typing  the
-       search  string.  As each character of the search string is typed, read-
+       Incremental  searches  begin  before  the  user has finished typing the
+       search string.  As each character of the search string is typed,  read-
        line displays the next entry from the history matching the string typed
-       so  far.   An  incremental  search  requires only as many characters as
-       needed to find the desired history entry.  The  characters  present  in
-       the  value of the i\bis\bse\bea\bar\brc\bch\bh-\b-t\bte\ber\brm\bmi\bin\bna\bat\bto\bor\brs\bs variable are used to terminate an
+       so far.  An incremental search requires  only  as  many  characters  as
+       needed  to  find  the desired history entry.  The characters present in
+       the value of the i\bis\bse\bea\bar\brc\bch\bh-\b-t\bte\ber\brm\bmi\bin\bna\bat\bto\bor\brs\bs variable are used to terminate  an
        incremental search.  If that variable has not been assigned a value the
-       Escape  and  Control-J characters will terminate an incremental search.
-       Control-G will abort an incremental search  and  restore  the  original
-       line.   When the search is terminated, the history entry containing the
+       Escape and Control-J characters will terminate an  incremental  search.
+       Control-G  will  abort  an  incremental search and restore the original
+       line.  When the search is terminated, the history entry containing  the
        search string becomes the current line.
 
-       To find other matching entries in the history list, type  Control-S  or
-       Control-R  as appropriate.  This will search backward or forward in the
-       history for the next entry matching the search  string  typed  so  far.
-       Any  other  key sequence bound to a readline command will terminate the
-       search and execute that command.  For instance, a _\bn_\be_\bw_\bl_\bi_\bn_\be  will  termi-
+       To  find  other matching entries in the history list, type Control-S or
+       Control-R as appropriate.  This will search backward or forward in  the
+       history  for  the  next  entry matching the search string typed so far.
+       Any other key sequence bound to a readline command will  terminate  the
+       search  and  execute that command.  For instance, a _\bn_\be_\bw_\bl_\bi_\bn_\be will termi-
        nate the search and accept the line, thereby executing the command from
        the history list.
 
        Readline remembers the last incremental search string.  If two Control-
-       Rs  are  typed without any intervening characters defining a new search
+       Rs are typed without any intervening characters defining a  new  search
        string, any remembered search string is used.
 
-       Non-incremental searches read the entire search string before  starting
-       to  search  for matching history lines.  The search string may be typed
+       Non-incremental  searches read the entire search string before starting
+       to search for matching history lines.  The search string may  be  typed
        by the user or be part of the contents of the current line.
 
    R\bRe\bea\bad\bdl\bli\bin\bne\be C\bCo\bom\bmm\bma\ban\bnd\bd N\bNa\bam\bme\bes\bs
-       The following is a list of the names of the commands  and  the  default
+       The  following  is  a list of the names of the commands and the default
        key sequences to which they are bound.  Command names without an accom-
        panying key sequence are unbound by default.  In the following descrip-
-       tions,  _\bp_\bo_\bi_\bn_\bt refers to the current cursor position, and _\bm_\ba_\br_\bk refers to
-       a cursor position saved by the s\bse\bet\bt-\b-m\bma\bar\brk\bk command.  The text between  the
+       tions, _\bp_\bo_\bi_\bn_\bt refers to the current cursor position, and _\bm_\ba_\br_\bk refers  to
+       a  cursor position saved by the s\bse\bet\bt-\b-m\bma\bar\brk\bk command.  The text between the
        point and mark is referred to as the _\br_\be_\bg_\bi_\bo_\bn.
 
    C\bCo\bom\bmm\bma\ban\bnd\bds\bs f\bfo\bor\br M\bMo\bov\bvi\bin\bng\bg
@@ -3221,17 +3253,17 @@ R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE
               Move forward to the end of the next word.  Words are composed of
               alphanumeric characters (letters and digits).
        b\bba\bac\bck\bkw\bwa\bar\brd\bd-\b-w\bwo\bor\brd\bd (\b(M\bM-\b-b\bb)\b)
-              Move back to the start of the current or previous  word.   Words
+              Move  back  to the start of the current or previous word.  Words
               are composed of alphanumeric characters (letters and digits).
        s\bsh\bhe\bel\bll\bl-\b-f\bfo\bor\brw\bwa\bar\brd\bd-\b-w\bwo\bor\brd\bd
-              Move  forward  to the end of the next word.  Words are delimited
+              Move forward to the end of the next word.  Words  are  delimited
               by non-quoted shell metacharacters.
        s\bsh\bhe\bel\bll\bl-\b-b\bba\bac\bck\bkw\bwa\bar\brd\bd-\b-w\bwo\bor\brd\bd
-              Move back to the start of the current or previous  word.   Words
+              Move  back  to the start of the current or previous word.  Words
               are delimited by non-quoted shell metacharacters.
        c\bcl\ble\bea\bar\br-\b-s\bsc\bcr\bre\bee\ben\bn (\b(C\bC-\b-l\bl)\b)
-              Clear  the  screen  leaving  the  current line at the top of the
-              screen.  With an argument,  refresh  the  current  line  without
+              Clear the screen leaving the current line  at  the  top  of  the
+              screen.   With  an  argument,  refresh  the current line without
               clearing the screen.
        r\bre\bed\bdr\bra\baw\bw-\b-c\bcu\bur\brr\bre\ben\bnt\bt-\b-l\bli\bin\bne\be
               Refresh the current line.
@@ -3239,60 +3271,60 @@ R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE
    C\bCo\bom\bmm\bma\ban\bnd\bds\bs f\bfo\bor\br M\bMa\ban\bni\bip\bpu\bul\bla\bat\bti\bin\bng\bg t\bth\bhe\be H\bHi\bis\bst\bto\bor\bry\by
        a\bac\bcc\bce\bep\bpt\bt-\b-l\bli\bin\bne\be (\b(N\bNe\bew\bwl\bli\bin\bne\be,\b, R\bRe\bet\btu\bur\brn\bn)\b)
               Accept the line regardless of where the cursor is.  If this line
-              is non-empty, add it to the history list according to the  state
-              of  the H\bHI\bIS\bST\bTC\bCO\bON\bNT\bTR\bRO\bOL\bL variable.  If the line is a modified history
+              is  non-empty, add it to the history list according to the state
+              of the H\bHI\bIS\bST\bTC\bCO\bON\bNT\bTR\bRO\bOL\bL variable.  If the line is a modified  history
               line, then restore the history line to its original state.
        p\bpr\bre\bev\bvi\bio\bou\bus\bs-\b-h\bhi\bis\bst\bto\bor\bry\by (\b(C\bC-\b-p\bp)\b)
               Fetch the previous command from the history list, moving back in
               the list.
        n\bne\bex\bxt\bt-\b-h\bhi\bis\bst\bto\bor\bry\by (\b(C\bC-\b-n\bn)\b)
-              Fetch  the next command from the history list, moving forward in
+              Fetch the next command from the history list, moving forward  in
               the list.
        b\bbe\beg\bgi\bin\bnn\bni\bin\bng\bg-\b-o\bof\bf-\b-h\bhi\bis\bst\bto\bor\bry\by (\b(M\bM-\b-<\b<)\b)
               Move to the first line in the history.
        e\ben\bnd\bd-\b-o\bof\bf-\b-h\bhi\bis\bst\bto\bor\bry\by (\b(M\bM-\b->\b>)\b)
-              Move to the end of the input history, i.e., the  line  currently
+              Move  to  the end of the input history, i.e., the line currently
               being entered.
        r\bre\bev\bve\ber\brs\bse\be-\b-s\bse\bea\bar\brc\bch\bh-\b-h\bhi\bis\bst\bto\bor\bry\by (\b(C\bC-\b-r\br)\b)
-              Search  backward  starting  at  the current line and moving `up'
-              through the  history  as  necessary.   This  is  an  incremental
+              Search backward starting at the current  line  and  moving  `up'
+              through  the  history  as  necessary.   This  is  an incremental
               search.
        f\bfo\bor\brw\bwa\bar\brd\bd-\b-s\bse\bea\bar\brc\bch\bh-\b-h\bhi\bis\bst\bto\bor\bry\by (\b(C\bC-\b-s\bs)\b)
-              Search  forward  starting  at the current line and moving `down'
-              through the  history  as  necessary.   This  is  an  incremental
+              Search forward starting at the current line  and  moving  `down'
+              through  the  history  as  necessary.   This  is  an incremental
               search.
        n\bno\bon\bn-\b-i\bin\bnc\bcr\bre\bem\bme\ben\bnt\bta\bal\bl-\b-r\bre\bev\bve\ber\brs\bse\be-\b-s\bse\bea\bar\brc\bch\bh-\b-h\bhi\bis\bst\bto\bor\bry\by (\b(M\bM-\b-p\bp)\b)
               Search backward through the history starting at the current line
-              using a non-incremental search for  a  string  supplied  by  the
+              using  a  non-incremental  search  for  a string supplied by the
               user.
        n\bno\bon\bn-\b-i\bin\bnc\bcr\bre\bem\bme\ben\bnt\bta\bal\bl-\b-f\bfo\bor\brw\bwa\bar\brd\bd-\b-s\bse\bea\bar\brc\bch\bh-\b-h\bhi\bis\bst\bto\bor\bry\by (\b(M\bM-\b-n\bn)\b)
-              Search  forward  through  the  history  using  a non-incremental
+              Search forward  through  the  history  using  a  non-incremental
               search for a string supplied by the user.
        h\bhi\bis\bst\bto\bor\bry\by-\b-s\bse\bea\bar\brc\bch\bh-\b-f\bfo\bor\brw\bwa\bar\brd\bd
-              Search forward through the history for the string of  characters
-              between  the start of the current line and the point.  This is a
+              Search  forward through the history for the string of characters
+              between the start of the current line and the point.  This is  a
               non-incremental search.
        h\bhi\bis\bst\bto\bor\bry\by-\b-s\bse\bea\bar\brc\bch\bh-\b-b\bba\bac\bck\bkw\bwa\bar\brd\bd
               Search backward through the history for the string of characters
-              between  the start of the current line and the point.  This is a
+              between the start of the current line and the point.  This is  a
               non-incremental search.
        y\bya\ban\bnk\bk-\b-n\bnt\bth\bh-\b-a\bar\brg\bg (\b(M\bM-\b-C\bC-\b-y\by)\b)
-              Insert the first argument to the previous command  (usually  the
+              Insert  the  first argument to the previous command (usually the
               second word on the previous line) at point.  With an argument _\bn,
-              insert the _\bnth word from the previous command (the words in  the
-              previous  command  begin  with  word  0).   A  negative argument
+              insert  the _\bnth word from the previous command (the words in the
+              previous command  begin  with  word  0).   A  negative  argument
               inserts the _\bnth word from the end of the previous command.  Once
-              the  argument _\bn is computed, the argument is extracted as if the
+              the argument _\bn is computed, the argument is extracted as if  the
               "!_\bn" history expansion had been specified.
        y\bya\ban\bnk\bk-\b-l\bla\bas\bst\bt-\b-a\bar\brg\bg (\b(M\bM-\b-.\b.,\b, M\bM-\b-_\b_)\b)
-              Insert the last argument to the previous command (the last  word
+              Insert  the last argument to the previous command (the last word
               of the previous history entry).  With a numeric argument, behave
-              exactly like y\bya\ban\bnk\bk-\b-n\bnt\bth\bh-\b-a\bar\brg\bg.  Successive  calls  to  y\bya\ban\bnk\bk-\b-l\bla\bas\bst\bt-\b-a\bar\brg\bg
-              move  back through the history list, inserting the last word (or
-              the word specified by the argument to the first  call)  of  each
+              exactly  like  y\bya\ban\bnk\bk-\b-n\bnt\bth\bh-\b-a\bar\brg\bg.   Successive calls to y\bya\ban\bnk\bk-\b-l\bla\bas\bst\bt-\b-a\bar\brg\bg
+              move back through the history list, inserting the last word  (or
+              the  word  specified  by the argument to the first call) of each
               line in turn.  Any numeric argument supplied to these successive
-              calls determines the direction to move through the  history.   A
-              negative  argument  switches  the  direction through the history
+              calls  determines  the direction to move through the history.  A
+              negative argument switches the  direction  through  the  history
               (back or forward).  The history expansion facilities are used to
               extract the last word, as if the "!$" history expansion had been
               specified.
@@ -3301,79 +3333,79 @@ R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE
               tory expansion as well as all of the shell word expansions.  See
               H\bHI\bIS\bST\bTO\bOR\bRY\bY E\bEX\bXP\bPA\bAN\bNS\bSI\bIO\bON\bN below for a description of history expansion.
        h\bhi\bis\bst\bto\bor\bry\by-\b-e\bex\bxp\bpa\ban\bnd\bd-\b-l\bli\bin\bne\be (\b(M\bM-\b-^\b^)\b)
-              Perform history expansion on  the  current  line.   See  H\bHI\bIS\bST\bTO\bOR\bRY\bY
+              Perform  history  expansion  on  the  current line.  See H\bHI\bIS\bST\bTO\bOR\bRY\bY
               E\bEX\bXP\bPA\bAN\bNS\bSI\bIO\bON\bN below for a description of history expansion.
        m\bma\bag\bgi\bic\bc-\b-s\bsp\bpa\bac\bce\be
-              Perform  history  expansion  on  the  current  line and insert a
+              Perform history expansion on  the  current  line  and  insert  a
               space.  See H\bHI\bIS\bST\bTO\bOR\bRY\bY E\bEX\bXP\bPA\bAN\bNS\bSI\bIO\bON\bN below for a description of history
               expansion.
        a\bal\bli\bia\bas\bs-\b-e\bex\bxp\bpa\ban\bnd\bd-\b-l\bli\bin\bne\be
-              Perform  alias expansion on the current line.  See A\bAL\bLI\bIA\bAS\bSE\bES\bS above
+              Perform alias expansion on the current line.  See A\bAL\bLI\bIA\bAS\bSE\bES\b above
               for a description of alias expansion.
        h\bhi\bis\bst\bto\bor\bry\by-\b-a\ban\bnd\bd-\b-a\bal\bli\bia\bas\bs-\b-e\bex\bxp\bpa\ban\bnd\bd-\b-l\bli\bin\bne\be
               Perform history and alias expansion on the current line.
        i\bin\bns\bse\ber\brt\bt-\b-l\bla\bas\bst\bt-\b-a\bar\brg\bgu\bum\bme\ben\bnt\bt (\b(M\bM-\b-.\b.,\b, M\bM-\b-_\b_)\b)
               A synonym for y\bya\ban\bnk\bk-\b-l\bla\bas\bst\bt-\b-a\bar\brg\bg.
        o\bop\bpe\ber\bra\bat\bte\be-\b-a\ban\bnd\bd-\b-g\bge\bet\bt-\b-n\bne\bex\bxt\bt (\b(C\bC-\b-o\bo)\b)
-              Accept the current line for execution and fetch  the  next  line
-              relative  to the current line from the history for editing.  Any
+              Accept  the  current  line for execution and fetch the next line
+              relative to the current line from the history for editing.   Any
               argument is ignored.
        e\bed\bdi\bit\bt-\b-a\ban\bnd\bd-\b-e\bex\bxe\bec\bcu\but\bte\be-\b-c\bco\bom\bmm\bma\ban\bnd\bd (\b(C\bC-\b-x\bxC\bC-\b-e\be)\b)
-              Invoke an editor on the current command line,  and  execute  the
-              result  as  shell  commands.   B\bBa\bas\bsh\bh  attempts to invoke $\b$V\bVI\bIS\bSU\bUA\bAL\bL,
+              Invoke  an  editor  on the current command line, and execute the
+              result as shell commands.   B\bBa\bas\bsh\bh  attempts  to  invoke  $\b$V\bVI\bIS\bSU\bUA\bAL\bL,
               $\b$E\bED\bDI\bIT\bTO\bOR\bR, and _\be_\bm_\ba_\bc_\bs as the editor, in that order.
 
    C\bCo\bom\bmm\bma\ban\bnd\bds\bs f\bfo\bor\br C\bCh\bha\ban\bng\bgi\bin\bng\bg T\bTe\bex\bxt\bt
        _\be_\bn_\bd_\b-_\bo_\bf_\b-_\bf_\bi_\bl_\be (\b(u\bus\bsu\bua\bal\bll\bly\by C\bC-\b-d\bd)\b)
-              The character indicating end-of-file as  set,  for  example,  by
-              ``stty''.   If  this character is read when there are no charac-
-              ters on the line, and point is at the  beginning  of  the  line,
+              The  character  indicating  end-of-file  as set, for example, by
+              ``stty''.  If this character is read when there are  no  charac-
+              ters  on  the  line,  and point is at the beginning of the line,
               Readline interprets it as the end of input and returns E\bEO\bOF\bF.
        d\bde\bel\ble\bet\bte\be-\b-c\bch\bha\bar\br (\b(C\bC-\b-d\bd)\b)
               Delete the character at point.  If this function is bound to the
               same character as the tty E\bEO\bOF\bF character, as C\bC-\b-d\bd commonly is, see
               above for the effects.
        b\bba\bac\bck\bkw\bwa\bar\brd\bd-\b-d\bde\bel\ble\bet\bte\be-\b-c\bch\bha\bar\br (\b(R\bRu\bub\bbo\bou\but\bt)\b)
-              Delete  the  character  behind the cursor.  When given a numeric
+              Delete the character behind the cursor.  When  given  a  numeric
               argument, save the deleted text on the kill ring.
        f\bfo\bor\brw\bwa\bar\brd\bd-\b-b\bba\bac\bck\bkw\bwa\bar\brd\bd-\b-d\bde\bel\ble\bet\bte\be-\b-c\bch\bha\bar\br
-              Delete the character under the cursor, unless the cursor  is  at
+              Delete  the  character under the cursor, unless the cursor is at
               the end of the line, in which case the character behind the cur-
               sor is deleted.
        q\bqu\buo\bot\bte\bed\bd-\b-i\bin\bns\bse\ber\brt\bt (\b(C\bC-\b-q\bq,\b, C\bC-\b-v\bv)\b)
-              Add the next character typed to the line verbatim.  This is  how
+              Add  the next character typed to the line verbatim.  This is how
               to insert characters like C\bC-\b-q\bq, for example.
        t\bta\bab\bb-\b-i\bin\bns\bse\ber\brt\bt (\b(C\bC-\b-v\bv T\bTA\bAB\bB)\b)
               Insert a tab character.
        s\bse\bel\blf\bf-\b-i\bin\bns\bse\ber\brt\bt (\b(a\ba,\b, b\bb,\b, A\bA,\b, 1\b1,\b, !\b!,\b, .\b..\b..\b.)\b)
               Insert the character typed.
        t\btr\bra\ban\bns\bsp\bpo\bos\bse\be-\b-c\bch\bha\bar\brs\bs (\b(C\bC-\b-t\bt)\b)
-              Drag  the  character  before point forward over the character at
-              point, moving point forward as well.  If point is at the end  of
-              the  line, then this transposes the two characters before point.
+              Drag the character before point forward over  the  character  at
+              point,  moving point forward as well.  If point is at the end of
+              the line, then this transposes the two characters before  point.
               Negative arguments have no effect.
        t\btr\bra\ban\bns\bsp\bpo\bos\bse\be-\b-w\bwo\bor\brd\bds\bs (\b(M\bM-\b-t\bt)\b)
-              Drag the word before point past the  word  after  point,  moving
-              point  over  that  word  as well.  If point is at the end of the
+              Drag  the  word  before  point past the word after point, moving
+              point over that word as well.  If point is at  the  end  of  the
               line, this transposes the last two words on the line.
        u\bup\bpc\bca\bas\bse\be-\b-w\bwo\bor\brd\bd (\b(M\bM-\b-u\bu)\b)
-              Uppercase the current (or  following)  word.   With  a  negative
+              Uppercase  the  current  (or  following)  word.  With a negative
               argument, uppercase the previous word, but do not move point.
        d\bdo\bow\bwn\bnc\bca\bas\bse\be-\b-w\bwo\bor\brd\bd (\b(M\bM-\b-l\bl)\b)
-              Lowercase  the  current  (or  following)  word.  With a negative
+              Lowercase the current (or  following)  word.   With  a  negative
               argument, lowercase the previous word, but do not move point.
        c\bca\bap\bpi\bit\bta\bal\bli\biz\bze\be-\b-w\bwo\bor\brd\bd (\b(M\bM-\b-c\bc)\b)
-              Capitalize the current (or following)  word.   With  a  negative
+              Capitalize  the  current  (or  following) word.  With a negative
               argument, capitalize the previous word, but do not move point.
        o\bov\bve\ber\brw\bwr\bri\bit\bte\be-\b-m\bmo\bod\bde\be
-              Toggle  overwrite mode.  With an explicit positive numeric argu-
+              Toggle overwrite mode.  With an explicit positive numeric  argu-
               ment, switches to overwrite mode.  With an explicit non-positive
               numeric argument, switches to insert mode.  This command affects
-              only e\bem\bma\bac\bcs\bs mode; v\bvi\bi mode does overwrite differently.  Each  call
+              only  e\bem\bma\bac\bcs\bs mode; v\bvi\bi mode does overwrite differently.  Each call
               to _\br_\be_\ba_\bd_\bl_\bi_\bn_\be_\b(_\b) starts in insert mode.  In overwrite mode, charac-
-              ters bound to s\bse\bel\blf\bf-\b-i\bin\bns\bse\ber\brt\bt replace the text at point rather  than
-              pushing  the  text  to  the  right.   Characters  bound to b\bba\bac\bck\bk-\b-
-              w\bwa\bar\brd\bd-\b-d\bde\bel\ble\bet\bte\be-\b-c\bch\bha\bar\breplace  the  character  before  point  with  a
+              ters  bound to s\bse\bel\blf\bf-\b-i\bin\bns\bse\ber\brt\bt replace the text at point rather than
+              pushing the text  to  the  right.   Characters  bound  to  b\bba\bac\bck\bk-\b-
+              w\bwa\bar\brd\bd-\b-d\bde\bel\ble\bet\bte\be-\b-c\bch\bha\bar\b replace  the  character  before  point  with a
               space.  By default, this command is unbound.
 
    K\bKi\bil\bll\bli\bin\bng\bg a\ban\bnd\bd Y\bYa\ban\bnk\bki\bin\bng\bg
@@ -3382,31 +3414,31 @@ R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE
        b\bba\bac\bck\bkw\bwa\bar\brd\bd-\b-k\bki\bil\bll\bl-\b-l\bli\bin\bne\be (\b(C\bC-\b-x\bx R\bRu\bub\bbo\bou\but\bt)\b)
               Kill backward to the beginning of the line.
        u\bun\bni\bix\bx-\b-l\bli\bin\bne\be-\b-d\bdi\bis\bsc\bca\bar\brd\bd (\b(C\bC-\b-u\bu)\b)
-              Kill  backward  from  point  to  the beginning of the line.  The
+              Kill backward from point to the  beginning  of  the  line.   The
               killed text is saved on the kill-ring.
        k\bki\bil\bll\bl-\b-w\bwh\bho\bol\ble\be-\b-l\bli\bin\bne\be
-              Kill all characters on the current line, no matter  where  point
+              Kill  all  characters on the current line, no matter where point
               is.
        k\bki\bil\bll\bl-\b-w\bwo\bor\brd\bd (\b(M\bM-\b-d\bd)\b)
-              Kill  from  point  to the end of the current word, or if between
-              words, to the end of the next word.   Word  boundaries  are  the
+              Kill from point to the end of the current word,  or  if  between
+              words,  to  the  end  of the next word.  Word boundaries are the
               same as those used by f\bfo\bor\brw\bwa\bar\brd\bd-\b-w\bwo\bor\brd\bd.
        b\bba\bac\bck\bkw\bwa\bar\brd\bd-\b-k\bki\bil\bll\bl-\b-w\bwo\bor\brd\bd (\b(M\bM-\b-R\bRu\bub\bbo\bou\but\bt)\b)
-              Kill  the  word  behind  point.  Word boundaries are the same as
+              Kill the word behind point.  Word boundaries  are  the  same  as
               those used by b\bba\bac\bck\bkw\bwa\bar\brd\bd-\b-w\bwo\bor\brd\bd.
        s\bsh\bhe\bel\bll\bl-\b-k\bki\bil\bll\bl-\b-w\bwo\bor\brd\bd
-              Kill from point to the end of the current word,  or  if  between
-              words,  to  the  end  of the next word.  Word boundaries are the
+              Kill  from  point  to the end of the current word, or if between
+              words, to the end of the next word.   Word  boundaries  are  the
               same as those used by s\bsh\bhe\bel\bll\bl-\b-f\bfo\bor\brw\bwa\bar\brd\bd-\b-w\bwo\bor\brd\bd.
        s\bsh\bhe\bel\bll\bl-\b-b\bba\bac\bck\bkw\bwa\bar\brd\bd-\b-k\bki\bil\bll\bl-\b-w\bwo\bor\brd\bd
-              Kill the word behind point.  Word boundaries  are  the  same  as
+              Kill  the  word  behind  point.  Word boundaries are the same as
               those used by s\bsh\bhe\bel\bll\bl-\b-b\bba\bac\bck\bkw\bwa\bar\brd\bd-\b-w\bwo\bor\brd\bd.
        u\bun\bni\bix\bx-\b-w\bwo\bor\brd\bd-\b-r\bru\bub\bbo\bou\but\bt (\b(C\bC-\b-w\bw)\b)
-              Kill  the  word behind point, using white space as a word bound-
+              Kill the word behind point, using white space as a  word  bound-
               ary.  The killed text is saved on the kill-ring.
        u\bun\bni\bix\bx-\b-f\bfi\bil\ble\ben\bna\bam\bme\be-\b-r\bru\bub\bbo\bou\but\bt
-              Kill the word behind point, using  white  space  and  the  slash
-              character  as  the word boundaries.  The killed text is saved on
+              Kill  the  word  behind  point,  using white space and the slash
+              character as the word boundaries.  The killed text is  saved  on
               the kill-ring.
        d\bde\bel\ble\bet\bte\be-\b-h\bho\bor\bri\biz\bzo\bon\bnt\bta\bal\bl-\b-s\bsp\bpa\bac\bce\be (\b(M\bM-\b-\\b\)\b)
               Delete all spaces and tabs around point.
@@ -3415,65 +3447,65 @@ R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE
        c\bco\bop\bpy\by-\b-r\bre\beg\bgi\bio\bon\bn-\b-a\bas\bs-\b-k\bki\bil\bll\bl
               Copy the text in the region to the kill buffer.
        c\bco\bop\bpy\by-\b-b\bba\bac\bck\bkw\bwa\bar\brd\bd-\b-w\bwo\bor\brd\bd
-              Copy the word before point to the kill buffer.  The word  bound-
+              Copy  the word before point to the kill buffer.  The word bound-
               aries are the same as b\bba\bac\bck\bkw\bwa\bar\brd\bd-\b-w\bwo\bor\brd\bd.
        c\bco\bop\bpy\by-\b-f\bfo\bor\brw\bwa\bar\brd\bd-\b-w\bwo\bor\brd\bd
-              Copy  the  word  following  point  to the kill buffer.  The word
+              Copy the word following point to  the  kill  buffer.   The  word
               boundaries are the same as f\bfo\bor\brw\bwa\bar\brd\bd-\b-w\bwo\bor\brd\bd.
        y\bya\ban\bnk\bk (\b(C\bC-\b-y\by)\b)
               Yank the top of the kill ring into the buffer at point.
        y\bya\ban\bnk\bk-\b-p\bpo\bop\bp (\b(M\bM-\b-y\by)\b)
-              Rotate the kill ring, and yank the new top.  Only works  follow-
+              Rotate  the kill ring, and yank the new top.  Only works follow-
               ing y\bya\ban\bnk\bk or y\bya\ban\bnk\bk-\b-p\bpo\bop\bp.
 
    N\bNu\bum\bme\ber\bri\bic\bc A\bAr\brg\bgu\bum\bme\ben\bnt\bts\bs
        d\bdi\big\bgi\bit\bt-\b-a\bar\brg\bgu\bum\bme\ben\bnt\bt (\b(M\bM-\b-0\b0,\b, M\bM-\b-1\b1,\b, .\b..\b..\b.,\b, M\bM-\b--\b-)\b)
-              Add  this digit to the argument already accumulating, or start a
+              Add this digit to the argument already accumulating, or start  a
               new argument.  M-- starts a negative argument.
        u\bun\bni\biv\bve\ber\brs\bsa\bal\bl-\b-a\bar\brg\bgu\bum\bme\ben\bnt\bt
-              This is another way to specify an argument.  If this command  is
-              followed  by one or more digits, optionally with a leading minus
-              sign, those digits define the argument.  If the command is  fol-
-              lowed  by  digits,  executing  u\bun\bni\biv\bve\ber\brs\bsa\bal\bl-\b-a\bar\brg\bgu\bum\bme\ben\bnt\bt again ends the
-              numeric argument, but is otherwise ignored.  As a special  case,
-              if  this  command is immediately followed by a character that is
-              neither a digit or minus sign, the argument count for  the  next
-              command  is multiplied by four.  The argument count is initially
-              one, so executing this function the first time makes  the  argu-
+              This  is another way to specify an argument.  If this command is
+              followed by one or more digits, optionally with a leading  minus
+              sign,  those digits define the argument.  If the command is fol-
+              lowed by digits, executing  u\bun\bni\biv\bve\ber\brs\bsa\bal\bl-\b-a\bar\brg\bgu\bum\bme\ben\bnt\bt  again  ends  the
+              numeric  argument, but is otherwise ignored.  As a special case,
+              if this command is immediately followed by a character  that  is
+              neither  a  digit or minus sign, the argument count for the next
+              command is multiplied by four.  The argument count is  initially
+              one,  so  executing this function the first time makes the argu-
               ment count four, a second time makes the argument count sixteen,
               and so on.
 
    C\bCo\bom\bmp\bpl\ble\bet\bti\bin\bng\bg
        c\bco\bom\bmp\bpl\ble\bet\bte\be (\b(T\bTA\bAB\bB)\b)
-              Attempt to perform completion on the text  before  point.   B\bBa\bas\bsh\bh
+              Attempt  to  perform  completion on the text before point.  B\bBa\bas\bsh\bh
               attempts completion treating the text as a variable (if the text
-              begins with $\b$), username (if the text begins with  ~\b~),  hostname
-              (if  the  text begins with @\b@), or command (including aliases and
+              begins  with  $\b$), username (if the text begins with ~\b~), hostname
+              (if the text begins with @\b@), or command (including  aliases  and
               functions) in turn.  If none of these produces a match, filename
               completion is attempted.
        p\bpo\bos\bss\bsi\bib\bbl\ble\be-\b-c\bco\bom\bmp\bpl\ble\bet\bti\bio\bon\bns\bs (\b(M\bM-\b-?\b?)\b)
               List the possible completions of the text before point.
        i\bin\bns\bse\ber\brt\bt-\b-c\bco\bom\bmp\bpl\ble\bet\bti\bio\bon\bns\bs (\b(M\bM-\b-*\b*)\b)
-              Insert  all completions of the text before point that would have
+              Insert all completions of the text before point that would  have
               been generated by p\bpo\bos\bss\bsi\bib\bbl\ble\be-\b-c\bco\bom\bmp\bpl\ble\bet\bti\bio\bon\bns\bs.
        m\bme\ben\bnu\bu-\b-c\bco\bom\bmp\bpl\ble\bet\bte\be
-              Similar to c\bco\bom\bmp\bpl\ble\bet\bte\be, but replaces the word to be completed  with
-              a  single match from the list of possible completions.  Repeated
-              execution of m\bme\ben\bnu\bu-\b-c\bco\bom\bmp\bpl\ble\bet\bte\be steps through the  list  of  possible
-              completions,  inserting  each  match in turn.  At the end of the
+              Similar  to c\bco\bom\bmp\bpl\ble\bet\bte\be, but replaces the word to be completed with
+              a single match from the list of possible completions.   Repeated
+              execution  of  m\bme\ben\bnu\bu-\b-c\bco\bom\bmp\bpl\ble\bet\bte\be  steps through the list of possible
+              completions, inserting each match in turn.  At the  end  of  the
               list of completions, the bell is rung (subject to the setting of
               b\bbe\bel\bll\bl-\b-s\bst\bty\byl\ble\be) and the original text is restored.  An argument of _\bn
-              moves _\bn positions forward in the list  of  matches;  a  negative
-              argument  may  be  used to move backward through the list.  This
-              command is intended to be  bound  to  T\bTA\bAB\bB,  but  is  unbound  by
+              moves  _\bn  positions  forward  in the list of matches; a negative
+              argument may be used to move backward through  the  list.   This
+              command  is  intended  to  be  bound  to  T\bTA\bAB\bB, but is unbound by
               default.
        m\bme\ben\bnu\bu-\b-c\bco\bom\bmp\bpl\ble\bet\bte\be-\b-b\bba\bac\bck\bkw\bwa\bar\brd\bd
-              Identical  to m\bme\ben\bnu\bu-\b-c\bco\bom\bmp\bpl\ble\bet\bte\be, but moves backward through the list
-              of possible completions, as if m\bme\ben\bnu\bu-\b-c\bco\bom\bmp\bpl\ble\bet\bte\be had  been  given  a
+              Identical to m\bme\ben\bnu\bu-\b-c\bco\bom\bmp\bpl\ble\bet\bte\be, but moves backward through the  list
+              of  possible  completions,  as if m\bme\ben\bnu\bu-\b-c\bco\bom\bmp\bpl\ble\bet\bte\be had been given a
               negative argument.  This command is unbound by default.
        d\bde\bel\ble\bet\bte\be-\b-c\bch\bha\bar\br-\b-o\bor\br-\b-l\bli\bis\bst\bt
-              Deletes  the  character under the cursor if not at the beginning
-              or end of the line (like d\bde\bel\ble\bet\bte\be-\b-c\bch\bha\bar\br).  If at  the  end  of  the
+              Deletes the character under the cursor if not at  the  beginning
+              or  end  of  the  line (like d\bde\bel\ble\bet\bte\be-\b-c\bch\bha\bar\br).  If at the end of the
               line, behaves identically to p\bpo\bos\bss\bsi\bib\bbl\ble\be-\b-c\bco\bom\bmp\bpl\ble\bet\bti\bio\bon\bns\bs.  This command
               is unbound by default.
        c\bco\bom\bmp\bpl\ble\bet\bte\be-\b-f\bfi\bil\ble\ben\bna\bam\bme\be (\b(M\bM-\b-/\b/)\b)
@@ -3482,263 +3514,263 @@ R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE
               List the possible completions of the text before point, treating
               it as a filename.
        c\bco\bom\bmp\bpl\ble\bet\bte\be-\b-u\bus\bse\ber\brn\bna\bam\bme\be (\b(M\bM-\b-~\b~)\b)
-              Attempt  completion  on  the text before point, treating it as a
+              Attempt completion on the text before point, treating  it  as  a
               username.
        p\bpo\bos\bss\bsi\bib\bbl\ble\be-\b-u\bus\bse\ber\brn\bna\bam\bme\be-\b-c\bco\bom\bmp\bpl\ble\bet\bti\bio\bon\bns\bs (\b(C\bC-\b-x\bx ~\b~)\b)
               List the possible completions of the text before point, treating
               it as a username.
        c\bco\bom\bmp\bpl\ble\bet\bte\be-\b-v\bva\bar\bri\bia\bab\bbl\ble\be (\b(M\bM-\b-$\b$)\b)
-              Attempt  completion  on  the text before point, treating it as a
+              Attempt completion on the text before point, treating  it  as  a
               shell variable.
        p\bpo\bos\bss\bsi\bib\bbl\ble\be-\b-v\bva\bar\bri\bia\bab\bbl\ble\be-\b-c\bco\bom\bmp\bpl\ble\bet\bti\bio\bon\bns\bs (\b(C\bC-\b-x\bx $\b$)\b)
               List the possible completions of the text before point, treating
               it as a shell variable.
        c\bco\bom\bmp\bpl\ble\bet\bte\be-\b-h\bho\bos\bst\btn\bna\bam\bme\be (\b(M\bM-\b-@\b@)\b)
-              Attempt  completion  on  the text before point, treating it as a
+              Attempt completion on the text before point, treating  it  as  a
               hostname.
        p\bpo\bos\bss\bsi\bib\bbl\ble\be-\b-h\bho\bos\bst\btn\bna\bam\bme\be-\b-c\bco\bom\bmp\bpl\ble\bet\bti\bio\bon\bns\bs (\b(C\bC-\b-x\bx @\b@)\b)
               List the possible completions of the text before point, treating
               it as a hostname.
        c\bco\bom\bmp\bpl\ble\bet\bte\be-\b-c\bco\bom\bmm\bma\ban\bnd\bd (\b(M\bM-\b-!\b!)\b)
-              Attempt  completion  on  the text before point, treating it as a
-              command name.  Command completion attempts  to  match  the  text
-              against   aliases,   reserved   words,  shell  functions,  shell
+              Attempt completion on the text before point, treating  it  as  a
+              command  name.   Command  completion  attempts to match the text
+              against  aliases,  reserved  words,   shell   functions,   shell
               builtins, and finally executable filenames, in that order.
        p\bpo\bos\bss\bsi\bib\bbl\ble\be-\b-c\bco\bom\bmm\bma\ban\bnd\bd-\b-c\bco\bom\bmp\bpl\ble\bet\bti\bio\bon\bns\bs (\b(C\bC-\b-x\bx !\b!)\b)
               List the possible completions of the text before point, treating
               it as a command name.
        d\bdy\byn\bna\bam\bmi\bic\bc-\b-c\bco\bom\bmp\bpl\ble\bet\bte\be-\b-h\bhi\bis\bst\bto\bor\bry\by (\b(M\bM-\b-T\bTA\bAB\bB)\b)
-              Attempt  completion on the text before point, comparing the text
-              against lines from the  history  list  for  possible  completion
+              Attempt completion on the text before point, comparing the  text
+              against  lines  from  the  history  list for possible completion
               matches.
        d\bda\bab\bbb\bbr\bre\bev\bv-\b-e\bex\bxp\bpa\ban\bnd\bd
-              Attempt  menu completion on the text before point, comparing the
+              Attempt menu completion on the text before point, comparing  the
               text against lines from the history list for possible completion
               matches.
        c\bco\bom\bmp\bpl\ble\bet\bte\be-\b-i\bin\bnt\bto\bo-\b-b\bbr\bra\bac\bce\bes\bs (\b(M\bM-\b-{\b{)\b)
               Perform filename completion and insert the list of possible com-
-              pletions enclosed within braces so the list is available to  the
+              pletions  enclosed within braces so the list is available to the
               shell (see B\bBr\bra\bac\bce\be E\bEx\bxp\bpa\ban\bns\bsi\bio\bon\bn above).
 
    K\bKe\bey\byb\bbo\boa\bar\brd\bd M\bMa\bac\bcr\bro\bos\bs
        s\bst\bta\bar\brt\bt-\b-k\bkb\bbd\bd-\b-m\bma\bac\bcr\bro\bo (\b(C\bC-\b-x\bx (\b()\b)
-              Begin  saving  the  characters  typed  into the current keyboard
+              Begin saving the characters  typed  into  the  current  keyboard
               macro.
        e\ben\bnd\bd-\b-k\bkb\bbd\bd-\b-m\bma\bac\bcr\bro\bo (\b(C\bC-\b-x\bx )\b))\b)
               Stop saving the characters typed into the current keyboard macro
               and store the definition.
        c\bca\bal\bll\bl-\b-l\bla\bas\bst\bt-\b-k\bkb\bbd\bd-\b-m\bma\bac\bcr\bro\bo (\b(C\bC-\b-x\bx e\be)\b)
-              Re-execute  the last keyboard macro defined, by making the char-
+              Re-execute the last keyboard macro defined, by making the  char-
               acters in the macro appear as if typed at the keyboard.
        p\bpr\bri\bin\bnt\bt-\b-l\bla\bas\bst\bt-\b-k\bkb\bbd\bd-\b-m\bma\bac\bcr\bro\bo (\b()\b)
-              Print the last keyboard macro defined in a format  suitable  for
+              Print  the  last keyboard macro defined in a format suitable for
               the _\bi_\bn_\bp_\bu_\bt_\br_\bc file.
 
    M\bMi\bis\bsc\bce\bel\bll\bla\ban\bne\beo\bou\bus\bs
        r\bre\be-\b-r\bre\bea\bad\bd-\b-i\bin\bni\bit\bt-\b-f\bfi\bil\ble\be (\b(C\bC-\b-x\bx C\bC-\b-r\br)\b)
-              Read  in  the  contents of the _\bi_\bn_\bp_\bu_\bt_\br_\bc file, and incorporate any
+              Read in the contents of the _\bi_\bn_\bp_\bu_\bt_\br_\bc file,  and  incorporate  any
               bindings or variable assignments found there.
        a\bab\bbo\bor\brt\bt (\b(C\bC-\b-g\bg)\b)
-              Abort the current editing command and ring the  terminal's  bell
+              Abort  the  current editing command and ring the terminal's bell
               (subject to the setting of b\bbe\bel\bll\bl-\b-s\bst\bty\byl\ble\be).
        d\bdo\bo-\b-u\bup\bpp\bpe\ber\brc\bca\bas\bse\be-\b-v\bve\ber\brs\bsi\bio\bon\bn (\b(M\bM-\b-a\ba,\b, M\bM-\b-b\bb,\b, M\bM-\b-_\bx,\b, .\b..\b..\b.)\b)
-              If  the  metafied character _\bx is lowercase, run the command that
+              If the metafied character _\bx is lowercase, run the  command  that
               is bound to the corresponding uppercase character.
        p\bpr\bre\bef\bfi\bix\bx-\b-m\bme\bet\bta\ba (\b(E\bES\bSC\bC)\b)
               Metafy the next character typed.  E\bES\bSC\bC f\bf is equivalent to M\bMe\bet\bta\ba-\b-f\bf.
        u\bun\bnd\bdo\bo (\b(C\bC-\b-_\b_,\b, C\bC-\b-x\bx C\bC-\b-u\bu)\b)
               Incremental undo, separately remembered for each line.
        r\bre\bev\bve\ber\brt\bt-\b-l\bli\bin\bne\be (\b(M\bM-\b-r\br)\b)
-              Undo all changes made to this line.  This is like executing  the
-              u\bun\bnd\bdo\b command  enough  times  to  return the line to its initial
+              Undo  all changes made to this line.  This is like executing the
+              u\bun\bnd\bdo\bcommand enough times to return  the  line  to  its  initial
               state.
        t\bti\bil\bld\bde\be-\b-e\bex\bxp\bpa\ban\bnd\bd (\b(M\bM-\b-&\b&)\b)
               Perform tilde expansion on the current word.
        s\bse\bet\bt-\b-m\bma\bar\brk\bk (\b(C\bC-\b-@\b@,\b, M\bM-\b-<\b<s\bsp\bpa\bac\bce\be>\b>)\b)
-              Set the mark to the point.  If a numeric argument  is  supplied,
+              Set  the  mark to the point.  If a numeric argument is supplied,
               the mark is set to that position.
        e\bex\bxc\bch\bha\ban\bng\bge\be-\b-p\bpo\boi\bin\bnt\bt-\b-a\ban\bnd\bd-\b-m\bma\bar\brk\bk (\b(C\bC-\b-x\bx C\bC-\b-x\bx)\b)
-              Swap  the  point  with the mark.  The current cursor position is
-              set to the saved position, and the old cursor position is  saved
+              Swap the point with the mark.  The current  cursor  position  is
+              set  to the saved position, and the old cursor position is saved
               as the mark.
        c\bch\bha\bar\bra\bac\bct\bte\ber\br-\b-s\bse\bea\bar\brc\bch\bh (\b(C\bC-\b-]\b])\b)
               A character is read and point is moved to the next occurrence of
-              that character.  A negative count searches for  previous  occur-
+              that  character.   A negative count searches for previous occur-
               rences.
        c\bch\bha\bar\bra\bac\bct\bte\ber\br-\b-s\bse\bea\bar\brc\bch\bh-\b-b\bba\bac\bck\bkw\bwa\bar\brd\bd (\b(M\bM-\b-C\bC-\b-]\b])\b)
-              A  character  is  read and point is moved to the previous occur-
-              rence of that character.  A negative count searches  for  subse-
+              A character is read and point is moved to  the  previous  occur-
+              rence  of  that character.  A negative count searches for subse-
               quent occurrences.
        s\bsk\bki\bip\bp-\b-c\bcs\bsi\bi-\b-s\bse\beq\bqu\bue\ben\bnc\bce\be
-              Read  enough  characters to consume a multi-key sequence such as
-              those defined for keys like Home and End.  Such sequences  begin
+              Read enough characters to consume a multi-key sequence  such  as
+              those  defined for keys like Home and End.  Such sequences begin
               with a Control Sequence Indicator (CSI), usually ESC-[.  If this
-              sequence is bound to "\[", keys producing  such  sequences  will
-              have  no  effect  unless explicitly bound to a readline command,
-              instead of inserting stray characters into the  editing  buffer.
+              sequence  is  bound  to "\[", keys producing such sequences will
+              have no effect unless explicitly bound to  a  readline  command,
+              instead  of  inserting stray characters into the editing buffer.
               This is unbound by default, but usually bound to ESC-[.
        i\bin\bns\bse\ber\brt\bt-\b-c\bco\bom\bmm\bme\ben\bnt\bt (\b(M\bM-\b-#\b#)\b)
-              Without  a  numeric  argument,  the  value  of the readline c\bco\bom\bm-\b-
-              m\bme\ben\bnt\bt-\b-b\bbe\beg\bgi\bin\bvariable is inserted at the beginning of the  current
+              Without a numeric argument,  the  value  of  the  readline  c\bco\bom\bm-\b-
+              m\bme\ben\bnt\bt-\b-b\bbe\beg\bgi\bin\b variable is inserted at the beginning of the current
               line.  If a numeric argument is supplied, this command acts as a
-              toggle: if the characters at the beginning of the  line  do  not
-              match  the value of c\bco\bom\bmm\bme\ben\bnt\bt-\b-b\bbe\beg\bgi\bin\bn, the value is inserted, other-
+              toggle:  if  the  characters at the beginning of the line do not
+              match the value of c\bco\bom\bmm\bme\ben\bnt\bt-\b-b\bbe\beg\bgi\bin\bn, the value is inserted,  other-
               wise the characters in c\bco\bom\bmm\bme\ben\bnt\bt-\b-b\bbe\beg\bgi\bin\bn are deleted from the begin-
-              ning  of the line.  In either case, the line is accepted as if a
-              newline had been typed.   The  default  value  of  c\bco\bom\bmm\bme\ben\bnt\bt-\b-b\bbe\beg\bgi\bin\bn
-              causes  this  command  to make the current line a shell comment.
-              If a  numeric  argument  causes  the  comment  character  to  be
+              ning of the line.  In either case, the line is accepted as if  a
+              newline  had  been  typed.   The  default value of c\bco\bom\bmm\bme\ben\bnt\bt-\b-b\bbe\beg\bgi\bin\bn
+              causes this command to make the current line  a  shell  comment.
+              If  a  numeric  argument  causes  the  comment  character  to be
               removed, the line will be executed by the shell.
        g\bgl\blo\bob\bb-\b-c\bco\bom\bmp\bpl\ble\bet\bte\be-\b-w\bwo\bor\brd\bd (\b(M\bM-\b-g\bg)\b)
-              The  word  before  point  is  treated  as a pattern for pathname
-              expansion, with an asterisk implicitly appended.   This  pattern
-              is  used  to  generate a list of matching filenames for possible
+              The word before point is  treated  as  a  pattern  for  pathname
+              expansion,  with  an asterisk implicitly appended.  This pattern
+              is used to generate a list of matching  filenames  for  possible
               completions.
        g\bgl\blo\bob\bb-\b-e\bex\bxp\bpa\ban\bnd\bd-\b-w\bwo\bor\brd\bd (\b(C\bC-\b-x\bx *\b*)\b)
-              The word before point is  treated  as  a  pattern  for  pathname
-              expansion,  and  the  list  of  matching  filenames is inserted,
-              replacing the word.  If  a  numeric  argument  is  supplied,  an
+              The  word  before  point  is  treated  as a pattern for pathname
+              expansion, and the  list  of  matching  filenames  is  inserted,
+              replacing  the  word.   If  a  numeric  argument is supplied, an
               asterisk is appended before pathname expansion.
        g\bgl\blo\bob\bb-\b-l\bli\bis\bst\bt-\b-e\bex\bxp\bpa\ban\bns\bsi\bio\bon\bns\bs (\b(C\bC-\b-x\bx g\bg)\b)
-              The  list  of  expansions  that  would  have  been  generated by
-              g\bgl\blo\bob\bb-\b-e\bex\bxp\bpa\ban\bnd\bd-\b-w\bwo\bor\brd\bis displayed, and the line is  redrawn.   If  a
-              numeric  argument  is  supplied,  an asterisk is appended before
+              The list  of  expansions  that  would  have  been  generated  by
+              g\bgl\blo\bob\bb-\b-e\bex\bxp\bpa\ban\bnd\bd-\b-w\bwo\bor\brd\b is  displayed,  and the line is redrawn.  If a
+              numeric argument is supplied, an  asterisk  is  appended  before
               pathname expansion.
        d\bdu\bum\bmp\bp-\b-f\bfu\bun\bnc\bct\bti\bio\bon\bns\bs
-              Print all of the functions and their key bindings to  the  read-
+              Print  all  of the functions and their key bindings to the read-
               line output stream.  If a numeric argument is supplied, the out-
-              put is formatted in such a way that it can be made  part  of  an
+              put  is  formatted  in such a way that it can be made part of an
               _\bi_\bn_\bp_\bu_\bt_\br_\bc file.
        d\bdu\bum\bmp\bp-\b-v\bva\bar\bri\bia\bab\bbl\ble\bes\bs
               Print all of the settable readline variables and their values to
-              the readline output stream.  If a numeric argument is  supplied,
-              the  output  is formatted in such a way that it can be made part
+              the  readline output stream.  If a numeric argument is supplied,
+              the output is formatted in such a way that it can be  made  part
               of an _\bi_\bn_\bp_\bu_\bt_\br_\bc file.
        d\bdu\bum\bmp\bp-\b-m\bma\bac\bcr\bro\bos\bs
-              Print all of the readline key sequences bound to macros and  the
-              strings  they  output.   If  a numeric argument is supplied, the
+              Print  all of the readline key sequences bound to macros and the
+              strings they output.  If a numeric  argument  is  supplied,  the
               output is formatted in such a way that it can be made part of an
               _\bi_\bn_\bp_\bu_\bt_\br_\bc file.
        d\bdi\bis\bsp\bpl\bla\bay\by-\b-s\bsh\bhe\bel\bll\bl-\b-v\bve\ber\brs\bsi\bio\bon\bn (\b(C\bC-\b-x\bx C\bC-\b-v\bv)\b)
               Display version information about the current instance of b\bba\bas\bsh\bh.
 
    P\bPr\bro\bog\bgr\bra\bam\bmm\bma\bab\bbl\ble\be C\bCo\bom\bmp\bpl\ble\bet\bti\bio\bon\bn
-       When  word  completion  is  attempted  for an argument to a command for
-       which a completion specification (a _\bc_\bo_\bm_\bp_\bs_\bp_\be_\bc) has  been  defined  using
-       the  c\bco\bom\bmp\bpl\ble\bet\bte\be  builtin (see S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS below), the program-
+       When word completion is attempted for an  argument  to  a  command  for
+       which  a  completion  specification (a _\bc_\bo_\bm_\bp_\bs_\bp_\be_\bc) has been defined using
+       the c\bco\bom\bmp\bpl\ble\bet\bte\be builtin (see S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS below),  the  program-
        mable completion facilities are invoked.
 
-       First, the command name is identified.  If  the  command  word  is  the
-       empty  string (completion attempted at the beginning of an empty line),
-       any compspec defined with the -\b-E\bE option to  c\bco\bom\bmp\bpl\ble\bet\bte\be  is  used.   If  a
-       compspec  has  been  defined  for that command, the compspec is used to
+       First,  the  command  name  is  identified.  If the command word is the
+       empty string (completion attempted at the beginning of an empty  line),
+       any  compspec  defined  with  the  -\b-E\bE option to c\bco\bom\bmp\bpl\ble\bet\bte\be is used.  If a
+       compspec has been defined for that command, the  compspec  is  used  to
        generate the list of possible completions for the word.  If the command
-       word  is  a full pathname, a compspec for the full pathname is searched
-       for first.  If no compspec is found for the full pathname,  an  attempt
-       is  made  to find a compspec for the portion following the final slash.
-       If those searches do not result in a  compspec,  any  compspec  defined
+       word is a full pathname, a compspec for the full pathname  is  searched
+       for  first.   If no compspec is found for the full pathname, an attempt
+       is made to find a compspec for the portion following the  final  slash.
+       If  those  searches  do  not result in a compspec, any compspec defined
        with the -\b-D\bD option to c\bco\bom\bmp\bpl\ble\bet\bte\be is used as the default.
 
-       Once  a  compspec  has  been  found, it is used to generate the list of
-       matching words.  If a compspec is not found, the default  b\bba\bas\bsh\b comple-
+       Once a compspec has been found, it is used  to  generate  the  list  of
+       matching  words.   If a compspec is not found, the default b\bba\bas\bsh\bh comple-
        tion as described above under C\bCo\bom\bmp\bpl\ble\bet\bti\bin\bng\bg is performed.
 
-       First,  the  actions  specified by the compspec are used.  Only matches
-       which are prefixed by the word being completed are returned.  When  the
-       -\b-f\b or -\b-d\bd option is used for filename or directory name completion, the
+       First, the actions specified by the compspec are  used.   Only  matches
+       which  are prefixed by the word being completed are returned.  When the
+       -\b-f\bor -\b-d\bd option is used for filename or directory name completion,  the
        shell variable F\bFI\bIG\bGN\bNO\bOR\bRE\bE is used to filter the matches.
 
-       Any completions specified by a pathname expansion  pattern  to  the  -\b-G\bG
+       Any  completions  specified  by  a pathname expansion pattern to the -\b-G\bG
        option are generated next.  The words generated by the pattern need not
-       match the word being completed.  The G\bGL\bLO\bOB\bBI\bIG\bGN\bNO\bOR\bRE\bE shell variable  is  not
+       match  the  word being completed.  The G\bGL\bLO\bOB\bBI\bIG\bGN\bNO\bOR\bRE\bE shell variable is not
        used to filter the matches, but the F\bFI\bIG\bGN\bNO\bOR\bRE\bE variable is used.
 
-       Next,  the string specified as the argument to the -\b-W\bW option is consid-
-       ered.  The string is first split using the characters in the  I\bIF\bFS\b spe-
-       cial  variable  as delimiters.  Shell quoting is honored.  Each word is
-       then expanded using brace expansion,  tilde  expansion,  parameter  and
-       variable  expansion, command substitution, and arithmetic expansion, as
+       Next, the string specified as the argument to the -\b-W\bW option is  consid-
+       ered.   The  string is first split using the characters in the I\bIF\bFS\bS spe-
+       cial variable as delimiters.  Shell quoting is honored.  Each  word  is
+       then  expanded  using  brace  expansion, tilde expansion, parameter and
+       variable expansion, command substitution, and arithmetic expansion,  as
        described above under E\bEX\bXP\bPA\bAN\bNS\bSI\bIO\bON\bN.  The results are split using the rules
        described above under W\bWo\bor\brd\bd S\bSp\bpl\bli\bit\btt\bti\bin\bng\bg.  The results of the expansion are
        prefix-matched against the word being completed, and the matching words
        become the possible completions.
 
-       After  these matches have been generated, any shell function or command
-       specified with the -\b-F\bF and -\b-C\bC options is invoked.  When the  command  or
+       After these matches have been generated, any shell function or  command
+       specified  with  the -\b-F\bF and -\b-C\bC options is invoked.  When the command or
        function is invoked, the C\bCO\bOM\bMP\bP_\b_L\bLI\bIN\bNE\bE, C\bCO\bOM\bMP\bP_\b_P\bPO\bOI\bIN\bNT\bT, C\bCO\bOM\bMP\bP_\b_K\bKE\bEY\bY, and C\bCO\bOM\bMP\bP_\b_T\bTY\bYP\bPE\bE
        variables are assigned values as described above under S\bSh\bhe\bel\bll\bl V\bVa\bar\bri\bia\bab\bbl\ble\bes\bs.
-       If  a  shell  function  is being invoked, the C\bCO\bOM\bMP\bP_\b_W\bWO\bOR\bRD\bDS\bS and C\bCO\bOM\bMP\bP_\b_C\bCW\bWO\bOR\bRD\bD
-       variables are also set.  When the function or command is  invoked,  the
-       first  argument  ($\b$1\b1)  is  the  name of the command whose arguments are
-       being completed, the second argument ($\b$2\b2) is the word being  completed,
-       and  the  third argument ($\b$3\b3) is the word preceding the word being com-
+       If a shell function is being invoked,  the  C\bCO\bOM\bMP\bP_\b_W\bWO\bOR\bRD\bDS\bS  and  C\bCO\bOM\bMP\bP_\b_C\bCW\bWO\bOR\bRD\bD
+       variables  are  also set.  When the function or command is invoked, the
+       first argument ($\b$1\b1) is the name of  the  command  whose  arguments  are
+       being  completed, the second argument ($\b$2\b2) is the word being completed,
+       and the third argument ($\b$3\b3) is the word preceding the word  being  com-
        pleted on the current command line.  No filtering of the generated com-
        pletions against the word being completed is performed; the function or
        command has complete freedom in generating the matches.
 
-       Any function specified with -\b-F\bF is invoked first.  The function may  use
-       any  of  the  shell facilities, including the c\bco\bom\bmp\bpg\bge\ben\bn builtin described
-       below, to generate the matches.  It must put the  possible  completions
+       Any  function specified with -\b-F\bF is invoked first.  The function may use
+       any of the shell facilities, including the  c\bco\bom\bmp\bpg\bge\ben\bn  builtin  described
+       below,  to  generate the matches.  It must put the possible completions
        in the C\bCO\bOM\bMP\bPR\bRE\bEP\bPL\bLY\bY array variable, one per array element.
 
-       Next,  any  command specified with the -\b-C\bC option is invoked in an envi-
-       ronment equivalent to command substitution.  It should print a list  of
-       completions,  one  per  line, to the standard output.  Backslash may be
+       Next, any command specified with the -\b-C\bC option is invoked in  an  envi-
+       ronment  equivalent to command substitution.  It should print a list of
+       completions, one per line, to the standard output.   Backslash  may  be
        used to escape a newline, if necessary.
 
-       After all of the possible completions are generated, any filter  speci-
-       fied  with  the -\b-X\bX option is applied to the list.  The filter is a pat-
-       tern as used for pathname expansion; a &\b& in  the  pattern  is  replaced
-       with  the text of the word being completed.  A literal &\b& may be escaped
-       with a backslash; the backslash is removed before attempting  a  match.
-       Any  completion that matches the pattern will be removed from the list.
+       After  all of the possible completions are generated, any filter speci-
+       fied with the -\b-X\bX option is applied to the list.  The filter is  a  pat-
+       tern  as  used  for  pathname expansion; a &\b& in the pattern is replaced
+       with the text of the word being completed.  A literal &\b& may be  escaped
+       with  a  backslash; the backslash is removed before attempting a match.
+       Any completion that matches the pattern will be removed from the  list.
        A leading !\b! negates the pattern; in this case any completion not match-
-       ing  the  pattern  will be removed.  If the n\bno\boc\bca\bas\bse\bem\bma\bat\btc\bch\bh shell option is
-       enabled, the match is performed without regard to the  case  of  alpha-
+       ing the pattern will be removed.  If the n\bno\boc\bca\bas\bse\bem\bma\bat\btc\bch\bh  shell  option  is
+       enabled,  the  match  is performed without regard to the case of alpha-
        betic characters.
 
        Finally, any prefix and suffix specified with the -\b-P\bP and -\b-S\bS options are
        added to each member of the completion list, and the result is returned
        to the readline completion code as the list of possible completions.
 
-       If  the previously-applied actions do not generate any matches, and the
-       -\b-o\bd\bdi\bir\brn\bna\bam\bme\bes\bs option was supplied  to  c\bco\bom\bmp\bpl\ble\bet\bte\be  when  the  compspec  was
+       If the previously-applied actions do not generate any matches, and  the
+       -\b-o\b d\bdi\bir\brn\bna\bam\bme\bes\bs  option  was  supplied  to  c\bco\bom\bmp\bpl\ble\bet\bte\be when the compspec was
        defined, directory name completion is attempted.
 
-       If  the  -\b-o\bo  p\bpl\blu\bus\bsd\bdi\bir\brs\bs option was supplied to c\bco\bom\bmp\bpl\ble\bet\bte\be when the compspec
+       If the -\b-o\bo p\bpl\blu\bus\bsd\bdi\bir\brs\bs option was supplied to c\bco\bom\bmp\bpl\ble\bet\bte\be  when  the  compspec
        was defined, directory name completion is attempted and any matches are
        added to the results of the other actions.
 
-       By  default,  if a compspec is found, whatever it generates is returned
-       to the completion code as the full set of  possible  completions.   The
+       By default, if a compspec is found, whatever it generates  is  returned
+       to  the  completion  code as the full set of possible completions.  The
        default b\bba\bas\bsh\bh completions are not attempted, and the readline default of
        filename completion is disabled.  If the -\b-o\bo b\bba\bas\bsh\bhd\bde\bef\bfa\bau\bul\blt\bt option was sup-
-       plied  to c\bco\bom\bmp\bpl\ble\bet\bte\be when the compspec was defined, the b\bba\bas\bsh\bh default com-
+       plied to c\bco\bom\bmp\bpl\ble\bet\bte\be when the compspec was defined, the b\bba\bas\bsh\bh default  com-
        pletions are attempted if the compspec generates no matches.  If the -\b-o\bo
-       d\bde\bef\bfa\bau\bul\blt\b option was supplied to c\bco\bom\bmp\bpl\ble\bet\bte\be when the compspec was defined,
-       readline's default completion will be performed if the  compspec  (and,
+       d\bde\bef\bfa\bau\bul\blt\boption was supplied to c\bco\bom\bmp\bpl\ble\bet\bte\be when the compspec was  defined,
+       readline's  default  completion will be performed if the compspec (and,
        if attempted, the default b\bba\bas\bsh\bh completions) generate no matches.
 
-       When  a  compspec  indicates that directory name completion is desired,
-       the programmable completion functions force readline to append a  slash
-       to  completed names which are symbolic links to directories, subject to
-       the value of the m\bma\bar\brk\bk-\b-d\bdi\bir\bre\bec\bct\bto\bor\bri\bie\bes\bs readline variable, regardless of  the
+       When a compspec indicates that directory name  completion  is  desired,
+       the  programmable completion functions force readline to append a slash
+       to completed names which are symbolic links to directories, subject  to
+       the  value of the m\bma\bar\brk\bk-\b-d\bdi\bir\bre\bec\bct\bto\bor\bri\bie\bes\bs readline variable, regardless of the
        setting of the m\bma\bar\brk\bk-\b-s\bsy\bym\bml\bli\bin\bnk\bke\bed\bd-\b-d\bdi\bir\bre\bec\bct\bto\bor\bri\bie\bes\bs readline variable.
 
-       There  is  some support for dynamically modifying completions.  This is
-       most useful when used in combination with a default  completion  speci-
-       fied  with  c\bco\bom\bmp\bpl\ble\bet\bte\be -\b-D\bD.  It's possible for shell functions executed as
-       completion handlers to indicate that completion should  be  retried  by
-       returning  an exit status of 124.  If a shell function returns 124, and
+       There is some support for dynamically modifying completions.   This  is
+       most  useful  when used in combination with a default completion speci-
+       fied with c\bco\bom\bmp\bpl\ble\bet\bte\be -\b-D\bD.  It's possible for shell functions  executed  as
+       completion  handlers  to  indicate that completion should be retried by
+       returning an exit status of 124.  If a shell function returns 124,  and
        changes the compspec associated with the command on which completion is
-       being  attempted  (supplied  as the first argument when the function is
+       being attempted (supplied as the first argument when  the  function  is
        executed), programmable completion restarts from the beginning, with an
-       attempt  to find a new compspec for that command.  This allows a set of
-       completions to be built dynamically as completion is attempted,  rather
+       attempt to find a new compspec for that command.  This allows a set  of
+       completions  to be built dynamically as completion is attempted, rather
        than being loaded all at once.
 
-       For  instance, assuming that there is a library of compspecs, each kept
-       in a file corresponding to the  name  of  the  command,  the  following
+       For instance, assuming that there is a library of compspecs, each  kept
+       in  a  file  corresponding  to  the  name of the command, the following
        default completion function would load completions dynamically:
 
        _completion_loader()
@@ -3749,159 +3781,159 @@ R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE
 
 
 H\bHI\bIS\bST\bTO\bOR\bRY\bY
-       When  the  -\b-o\bo  h\bhi\bis\bst\bto\bor\bry\by  option to the s\bse\bet\bt builtin is enabled, the shell
+       When the -\b-o\bo h\bhi\bis\bst\bto\bor\bry\by option to the s\bse\bet\bt builtin  is  enabled,  the  shell
        provides access to the _\bc_\bo_\bm_\bm_\ba_\bn_\bd _\bh_\bi_\bs_\bt_\bo_\br_\by, the list of commands previously
-       typed.   The  value  of  the H\bHI\bIS\bST\bTS\bSI\bIZ\bZE\bE variable is used as the number of
+       typed.  The value of the H\bHI\bIS\bST\bTS\bSI\bIZ\bZE\bE variable is used  as  the  number  of
        commands to save in a history list.  The text of the last H\bHI\bIS\bST\bTS\bSI\bIZ\bZE\bE com-
-       mands  (default  500)  is  saved.  The shell stores each command in the
-       history list prior to parameter and variable expansion  (see  E\bEX\bXP\bPA\bAN\bNS\bSI\bIO\bON\bN
-       above)  but after history expansion is performed, subject to the values
+       mands (default 500) is saved.  The shell stores  each  command  in  the
+       history  list  prior to parameter and variable expansion (see E\bEX\bXP\bPA\bAN\bNS\bSI\bIO\bON\bN
+       above) but after history expansion is performed, subject to the  values
        of the shell variables H\bHI\bIS\bST\bTI\bIG\bGN\bNO\bOR\bRE\bE and H\bHI\bIS\bST\bTC\bCO\bON\bNT\bTR\bRO\bOL\bL.
 
        On startup, the history is initialized from the file named by the vari-
-       able  H\bHI\bIS\bST\bTF\bFI\bIL\bLE\bE  (default _\b~_\b/_\b._\bb_\ba_\bs_\bh_\b__\bh_\bi_\bs_\bt_\bo_\br_\by).  The file named by the value
-       of H\bHI\bIS\bST\bTF\bFI\bIL\bLE\bE is truncated, if necessary, to contain  no  more  than  the
-       number  of  lines specified by the value of H\bHI\bIS\bST\bTF\bFI\bIL\bLE\bES\bSI\bIZ\bZE\bE.  If H\bHI\bIS\bST\bTF\bFI\bIL\bLE\bE-\b-
-       S\bSI\bIZ\bZE\bis unset, or set to null, a non-numeric value, or a numeric  value
-       less  than  zero,  the history file is not truncated.  When the history
-       file is read, lines beginning with the history comment  character  fol-
+       able H\bHI\bIS\bST\bTF\bFI\bIL\bLE\bE (default _\b~_\b/_\b._\bb_\ba_\bs_\bh_\b__\bh_\bi_\bs_\bt_\bo_\br_\by).  The file named by  the  value
+       of  H\bHI\bIS\bST\bTF\bFI\bIL\bLE\bE  is  truncated,  if necessary, to contain no more than the
+       number of lines specified by the value of H\bHI\bIS\bST\bTF\bFI\bIL\bLE\bES\bSI\bIZ\bZE\bE.   If  H\bHI\bIS\bST\bTF\bFI\bIL\bLE\bE-\b-
+       S\bSI\bIZ\bZE\b is unset, or set to null, a non-numeric value, or a numeric value
+       less than zero, the history file is not truncated.   When  the  history
+       file  is  read, lines beginning with the history comment character fol-
        lowed immediately by a digit are interpreted as timestamps for the pre-
        ceding history line.  These timestamps are optionally displayed depend-
-       ing  on  the  value  of the H\bHI\bIS\bST\bTT\bTI\bIM\bME\bEF\bFO\bOR\bRM\bMA\bAT\bT variable.  When a shell with
-       history enabled exits, the last $\b$H\bHI\bIS\bST\bTS\bSI\bIZ\bZE\bE lines  are  copied  from  the
-       history  list  to $\b$H\bHI\bIS\bST\bTF\bFI\bIL\bLE\bE.  If the h\bhi\bis\bst\bta\bap\bpp\bpe\ben\bnd\bd shell option is enabled
-       (see the description of s\bsh\bho\bop\bpt\bt under S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS below),  the
-       lines  are  appended to the history file, otherwise the history file is
+       ing on the value of the H\bHI\bIS\bST\bTT\bTI\bIM\bME\bEF\bFO\bOR\bRM\bMA\bAT\bT variable.   When  a  shell  with
+       history  enabled  exits,  the  last $\b$H\bHI\bIS\bST\bTS\bSI\bIZ\bZE\bE lines are copied from the
+       history list to $\b$H\bHI\bIS\bST\bTF\bFI\bIL\bLE\bE.  If the h\bhi\bis\bst\bta\bap\bpp\bpe\ben\bnd\bd shell option  is  enabled
+       (see  the description of s\bsh\bho\bop\bpt\bt under S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS below), the
+       lines are appended to the history file, otherwise the history  file  is
        overwritten.   If  H\bHI\bIS\bST\bTF\bFI\bIL\bLE\bE  is  unset,  or  if  the  history  file  is
-       unwritable,  the  history is not saved.  If the H\bHI\bIS\bST\bTT\bTI\bIM\bME\bEF\bFO\bOR\bRM\bMA\bAT\bT variable
-       is set, time stamps are written to the history file,  marked  with  the
-       history  comment  character, so they may be preserved across shell ses-
-       sions.  This uses the history comment character  to  distinguish  time-
+       unwritable, the history is not saved.  If the  H\bHI\bIS\bST\bTT\bTI\bIM\bME\bEF\bFO\bOR\bRM\bMA\bAT\b variable
+       is  set,  time  stamps are written to the history file, marked with the
+       history comment character, so they may be preserved across  shell  ses-
+       sions.   This  uses  the history comment character to distinguish time-
        stamps from other history lines.  After saving the history, the history
        file is truncated to contain no more than H\bHI\bIS\bST\bTF\bFI\bIL\bLE\bES\bSI\bIZ\bZE\bE lines.  If H\bHI\bIS\bST\bT-\b-
-       F\bFI\bIL\bLE\bES\bSI\bIZ\bZE\b is  unset,  or set to null, a non-numeric value, or a numeric
+       F\bFI\bIL\bLE\bES\bSI\bIZ\bZE\bis unset, or set to null, a non-numeric value,  or  a  numeric
        value less than zero, the history file is not truncated.
 
-       The builtin command f\bfc\bc (see S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS below) may  be  used
+       The  builtin  command f\bfc\bc (see S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS below) may be used
        to list or edit and re-execute a portion of the history list.  The h\bhi\bis\bs-\b-
-       t\bto\bor\bry\bbuiltin may be used to display or  modify  the  history  list  and
-       manipulate  the  history file.  When using command-line editing, search
-       commands are available in each editing mode that provide access to  the
+       t\bto\bor\bry\b builtin  may  be  used  to display or modify the history list and
+       manipulate the history file.  When using command-line  editing,  search
+       commands  are available in each editing mode that provide access to the
        history list.
 
-       The  shell  allows control over which commands are saved on the history
+       The shell allows control over which commands are saved on  the  history
        list.  The H\bHI\bIS\bST\bTC\bCO\bON\bNT\bTR\bRO\bOL\bL and H\bHI\bIS\bST\bTI\bIG\bGN\bNO\bOR\bRE\bE variables may be set to cause the
        shell to save only a subset of the commands entered.  The c\bcm\bmd\bdh\bhi\bis\bst\bt shell
-       option, if enabled, causes the shell to attempt to save each line of  a
-       multi-line  command  in the same history entry, adding semicolons where
-       necessary to preserve syntactic correctness.  The l\bli\bit\bth\bhi\bis\bst\bt shell  option
-       causes  the shell to save the command with embedded newlines instead of
+       option,  if enabled, causes the shell to attempt to save each line of a
+       multi-line command in the same history entry, adding  semicolons  where
+       necessary  to preserve syntactic correctness.  The l\bli\bit\bth\bhi\bis\bst\bt shell option
+       causes the shell to save the command with embedded newlines instead  of
        semicolons.  See the description of the s\bsh\bho\bop\bpt\bt builtin below under S\bSH\bHE\bEL\bLL\bL
        B\bBU\bUI\bIL\bLT\bTI\bIN\bN  C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS  for  information  on  setting  and  unsetting  shell
        options.
 
 H\bHI\bIS\bST\bTO\bOR\bRY\bY E\bEX\bXP\bPA\bAN\bNS\bSI\bIO\bON\bN
-       The shell supports a history expansion feature that is similar  to  the
-       history  expansion in c\bcs\bsh\bh.\b.  This section describes what syntax features
-       are available.  This feature is  enabled  by  default  for  interactive
+       The  shell  supports a history expansion feature that is similar to the
+       history expansion in c\bcs\bsh\bh.\b.  This section describes what syntax  features
+       are  available.   This  feature  is  enabled by default for interactive
        shells, and can be disabled using the +\b+H\bH option to the s\bse\bet\bt builtin com-
        mand (see S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS below).  Non-interactive shells do not
        perform history expansion by default.
 
        History expansions introduce words from the history list into the input
-       stream, making it easy to repeat commands, insert the  arguments  to  a
+       stream,  making  it  easy to repeat commands, insert the arguments to a
        previous command into the current input line, or fix errors in previous
        commands quickly.
 
-       History expansion is performed immediately after  a  complete  line  is
-       read,  before  the  shell  breaks it into words.  It takes place in two
-       parts.  The first is to determine which line from the history  list  to
+       History  expansion  is  performed  immediately after a complete line is
+       read, before the shell breaks it into words.  It  takes  place  in  two
+       parts.   The  first is to determine which line from the history list to
        use during substitution.  The second is to select portions of that line
        for inclusion into the current one.  The line selected from the history
-       is  the  _\be_\bv_\be_\bn_\bt,  and  the portions of that line that are acted upon are
-       _\bw_\bo_\br_\bd_\bs.  Various _\bm_\bo_\bd_\bi_\bf_\bi_\be_\br_\bs are  available  to  manipulate  the  selected
+       is the _\be_\bv_\be_\bn_\bt, and the portions of that line that  are  acted  upon  are
+       _\bw_\bo_\br_\bd_\bs.   Various  _\bm_\bo_\bd_\bi_\bf_\bi_\be_\br_\bs  are  available  to manipulate the selected
        words.  The line is broken into words in the same fashion as when read-
-       ing input, so that several _\bm_\be_\bt_\ba_\bc_\bh_\ba_\br_\ba_\bc_\bt_\be_\br-separated words surrounded  by
-       quotes  are  considered one word.  History expansions are introduced by
-       the appearance of the  history  expansion  character,  which  is  !\b by
-       default.   Only  backslash  (\\b\) and single quotes can quote the history
+       ing  input, so that several _\bm_\be_\bt_\ba_\bc_\bh_\ba_\br_\ba_\bc_\bt_\be_\br-separated words surrounded by
+       quotes are considered one word.  History expansions are  introduced  by
+       the  appearance  of  the  history  expansion  character,  which is !\b! by
+       default.  Only backslash (\\b\) and single quotes can  quote  the  history
        expansion character.
 
-       Several characters inhibit history expansion if found immediately  fol-
-       lowing  the history expansion character, even if it is unquoted: space,
-       tab, newline, carriage return, and =\b=.  If the e\bex\bxt\btg\bgl\blo\bob\bb shell  option  is
+       Several  characters inhibit history expansion if found immediately fol-
+       lowing the history expansion character, even if it is unquoted:  space,
+       tab,  newline,  carriage return, and =\b=.  If the e\bex\bxt\btg\bgl\blo\bob\bb shell option is
        enabled, (\b( will also inhibit expansion.
 
-       Several  shell  options  settable with the s\bsh\bho\bop\bpt\bt builtin may be used to
-       tailor the behavior of history  expansion.   If  the  h\bhi\bis\bst\btv\bve\ber\bri\bif\bfy\b shell
+       Several shell options settable with the s\bsh\bho\bop\bpt\bt builtin may  be  used  to
+       tailor  the  behavior  of  history  expansion.  If the h\bhi\bis\bst\btv\bve\ber\bri\bif\bfy\by shell
        option is enabled (see the description of the s\bsh\bho\bop\bpt\bt builtin below), and
-       r\bre\bea\bad\bdl\bli\bin\bne\bis being  used,  history  substitutions  are  not  immediately
-       passed  to  the  shell  parser.  Instead, the expanded line is reloaded
+       r\bre\bea\bad\bdl\bli\bin\bne\b is  being  used,  history  substitutions  are not immediately
+       passed to the shell parser.  Instead, the  expanded  line  is  reloaded
        into the r\bre\bea\bad\bdl\bli\bin\bne\be editing buffer for further modification.  If r\bre\bea\bad\bdl\bli\bin\bne\be
-       is  being  used,  and  the h\bhi\bis\bst\btr\bre\bee\bed\bdi\bit\bt shell option is enabled, a failed
-       history substitution will be reloaded into the r\bre\bea\bad\bdl\bli\bin\bne\be editing  buffer
-       for  correction.   The  -\b-p\bp option to the h\bhi\bis\bst\bto\bor\bry\by builtin command may be
-       used to see what a history expansion will do before using it.   The  -\b-s\bs
+       is being used, and the h\bhi\bis\bst\btr\bre\bee\bed\bdi\bit\bt shell option  is  enabled,  a  failed
+       history  substitution will be reloaded into the r\bre\bea\bad\bdl\bli\bin\bne\be editing buffer
+       for correction.  The -\b-p\bp option to the h\bhi\bis\bst\bto\bor\bry\by builtin  command  may  be
+       used  to  see what a history expansion will do before using it.  The -\b-s\bs
        option to the h\bhi\bis\bst\bto\bor\bry\by builtin may be used to add commands to the end of
-       the history list without actually executing  them,  so  that  they  are
+       the  history  list  without  actually  executing them, so that they are
        available for subsequent recall.
 
-       The  shell allows control of the various characters used by the history
+       The shell allows control of the various characters used by the  history
        expansion mechanism (see the description of h\bhi\bis\bst\btc\bch\bha\bar\brs\bs above under S\bSh\bhe\bel\bll\bl
-       V\bVa\bar\bri\bia\bab\bbl\ble\bes\bs).   The shell uses the history comment character to mark his-
+       V\bVa\bar\bri\bia\bab\bbl\ble\bes\bs).  The shell uses the history comment character to mark  his-
        tory timestamps when writing the history file.
 
    E\bEv\bve\ben\bnt\bt D\bDe\bes\bsi\big\bgn\bna\bat\bto\bor\brs\bs
-       An event designator is a reference to a command line entry in the  his-
-       tory  list.   Unless  the reference is absolute, events are relative to
+       An  event designator is a reference to a command line entry in the his-
+       tory list.  Unless the reference is absolute, events  are  relative  to
        the current position in the history list.
 
-       !\b!      Start a history substitution, except when followed by  a  b\bbl\bla\ban\bnk\bk,
-              newline,  carriage return, = or ( (when the e\bex\bxt\btg\bgl\blo\bob\bb shell option
+       !\b!      Start  a  history substitution, except when followed by a b\bbl\bla\ban\bnk\bk,
+              newline, carriage return, = or ( (when the e\bex\bxt\btg\bgl\blo\bob\bb shell  option
               is enabled using the s\bsh\bho\bop\bpt\bt builtin).
        !\b!_\bn     Refer to command line _\bn.
        !\b!-\b-_\bn    Refer to the current command minus _\bn.
        !\b!!\b!     Refer to the previous command.  This is a synonym for `!-1'.
        !\b!_\bs_\bt_\br_\bi_\bn_\bg
-              Refer to the most recent command preceding the current  position
+              Refer  to the most recent command preceding the current position
               in the history list starting with _\bs_\bt_\br_\bi_\bn_\bg.
        !\b!?\b?_\bs_\bt_\br_\bi_\bn_\bg[\b[?\b?]\b]
-              Refer  to the most recent command preceding the current position
-              in the history list containing _\bs_\bt_\br_\bi_\bn_\bg.  The trailing  ?\b?  may  be
+              Refer to the most recent command preceding the current  position
+              in  the  history  list containing _\bs_\bt_\br_\bi_\bn_\bg.  The trailing ?\b? may be
               omitted if _\bs_\bt_\br_\bi_\bn_\bg is followed immediately by a newline.
        ^\b^_\bs_\bt_\br_\bi_\bn_\bg_\b1^\b^_\bs_\bt_\br_\bi_\bn_\bg_\b2^\b^
-              Quick  substitution.   Repeat  the  previous  command, replacing
-              _\bs_\bt_\br_\bi_\bn_\bg_\bwith _\bs_\bt_\br_\bi_\bn_\bg_\b2.  Equivalent  to  ``!!:s/_\bs_\bt_\br_\bi_\bn_\bg_\b1/_\bs_\bt_\br_\bi_\bn_\bg_\b2/''
+              Quick substitution.   Repeat  the  previous  command,  replacing
+              _\bs_\bt_\br_\bi_\bn_\bg_\b with  _\bs_\bt_\br_\bi_\bn_\bg_\b2.  Equivalent to ``!!:s/_\bs_\bt_\br_\bi_\bn_\bg_\b1/_\bs_\bt_\br_\bi_\bn_\bg_\b2/''
               (see M\bMo\bod\bdi\bif\bfi\bie\ber\brs\bs below).
        !\b!#\b#     The entire command line typed so far.
 
    W\bWo\bor\brd\bd D\bDe\bes\bsi\big\bgn\bna\bat\bto\bor\brs\bs
-       Word  designators are used to select desired words from the event.  A :\b:
-       separates the event specification from the word designator.  It may  be
-       omitted  if  the word designator begins with a ^\b^, $\b$, *\b*, -\b-, or %\b%.  Words
-       are numbered from the beginning of the line, with the first word  being
-       denoted  by  0  (zero).  Words are inserted into the current line sepa-
+       Word designators are used to select desired words from the event.  A  :\b:
+       separates  the event specification from the word designator.  It may be
+       omitted if the word designator begins with a ^\b^, $\b$, *\b*, -\b-, or  %\b%.   Words
+       are  numbered from the beginning of the line, with the first word being
+       denoted by 0 (zero).  Words are inserted into the  current  line  sepa-
        rated by single spaces.
 
        0\b0 (\b(z\bze\ber\bro\bo)\b)
               The zeroth word.  For the shell, this is the command word.
        _\bn      The _\bnth word.
        ^\b^      The first argument.  That is, word 1.
-       $\b$      The last word.  This is usually  the  last  argument,  but  will
+       $\b$      The  last  word.   This  is  usually the last argument, but will
               expand to the zeroth word if there is only one word in the line.
        %\b%      The word matched by the most recent `?_\bs_\bt_\br_\bi_\bn_\bg?' search.
        _\bx-\b-_\by    A range of words; `-_\by' abbreviates `0-_\by'.
-       *\b*      All  of  the words but the zeroth.  This is a synonym for `_\b1_\b-_\b$'.
-              It is not an error to use *\b* if there is just  one  word  in  the
+       *\b*      All of the words but the zeroth.  This is a synonym  for  `_\b1_\b-_\b$'.
+              It  is  not  an  error to use *\b* if there is just one word in the
               event; the empty string is returned in that case.
        x\bx*\b*     Abbreviates _\bx_\b-_\b$.
        x\bx-\b-     Abbreviates _\bx_\b-_\b$ like x\bx*\b*, but omits the last word.
 
-       If  a  word  designator is supplied without an event specification, the
+       If a word designator is supplied without an  event  specification,  the
        previous command is used as the event.
 
    M\bMo\bod\bdi\bif\bfi\bie\ber\brs\bs
-       After the optional word designator, there may appear a sequence of  one
+       After  the optional word designator, there may appear a sequence of one
        or more of the following modifiers, each preceded by a `:'.
 
        h\bh      Remove a trailing filename component, leaving only the head.
@@ -3910,74 +3942,74 @@ H\bHI\bIS\bST\bTO\bOR\bRY\bY E\bEX\bXP\bPA\bAN\bNS\bSI\bIO\bON\bN
        e\be      Remove all but the trailing suffix.
        p\bp      Print the new command but do not execute it.
        q\bq      Quote the substituted words, escaping further substitutions.
-       x\bx      Quote  the  substituted words as with q\bq, but break into words at
+       x\bx      Quote the substituted words as with q\bq, but break into  words  at
               b\bbl\bla\ban\bnk\bks\bs and newlines.
        s\bs/\b/_\bo_\bl_\bd/\b/_\bn_\be_\bw/\b/
-              Substitute _\bn_\be_\bw for the first occurrence  of  _\bo_\bl_\bd  in  the  event
-              line.   Any  delimiter  can  be  used  in place of /.  The final
-              delimiter is optional if it is the last character of  the  event
-              line.   The delimiter may be quoted in _\bo_\bl_\bd and _\bn_\be_\bw with a single
-              backslash.  If & appears in _\bn_\be_\bw, it is replaced by _\bo_\bl_\bd.  A  sin-
-              gle  backslash  will  quote the &.  If _\bo_\bl_\bd is null, it is set to
-              the last _\bo_\bl_\bd substituted, or, if no previous  history  substitu-
+              Substitute  _\bn_\be_\bw  for  the  first  occurrence of _\bo_\bl_\bd in the event
+              line.  Any delimiter can be used  in  place  of  /.   The  final
+              delimiter  is  optional if it is the last character of the event
+              line.  The delimiter may be quoted in _\bo_\bl_\bd and _\bn_\be_\bw with a  single
+              backslash.   If & appears in _\bn_\be_\bw, it is replaced by _\bo_\bl_\bd.  A sin-
+              gle backslash will quote the &.  If _\bo_\bl_\bd is null, it  is  set  to
+              the  last  _\bo_\bl_\bd substituted, or, if no previous history substitu-
               tions took place, the last _\bs_\bt_\br_\bi_\bn_\bg in a !\b!?\b?_\bs_\bt_\br_\bi_\bn_\bg[\b[?\b?]\b]  search.
        &\b&      Repeat the previous substitution.
        g\bg      Cause changes to be applied over the entire event line.  This is
-              used in conjunction with `:\b:s\bs' (e.g.,  `:\b:g\bgs\bs/\b/_\bo_\bl_\bd/\b/_\bn_\be_\bw/\b/')  or  `:\b:&\b&'.
-              If  used with `:\b:s\bs', any delimiter can be used in place of /, and
-              the final delimiter is optional if it is the last  character  of
+              used  in  conjunction  with `:\b:s\bs' (e.g., `:\b:g\bgs\bs/\b/_\bo_\bl_\bd/\b/_\bn_\be_\bw/\b/') or `:\b:&\b&'.
+              If used with `:\b:s\bs', any delimiter can be used in place of /,  and
+              the  final  delimiter is optional if it is the last character of
               the event line.  An a\ba may be used as a synonym for g\bg.
-       G\bG      Apply  the following `s\bs' modifier once to each word in the event
+       G\bG      Apply the following `s\bs' modifier once to each word in the  event
               line.
 
 S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS
        Unless otherwise noted, each builtin command documented in this section
        as accepting options preceded by -\b- accepts -\b--\b- to signify the end of the
-       options.  The :\b:, t\btr\bru\bue\be, f\bfa\bal\bls\bse\be, and t\bte\bes\bst\bt builtins do not  accept  options
+       options.   The  :\b:, t\btr\bru\bue\be, f\bfa\bal\bls\bse\be, and t\bte\bes\bst\bt builtins do not accept options
        and do not treat -\b--\b- specially.  The e\bex\bxi\bit\bt, l\blo\bog\bgo\bou\but\bt, b\bbr\bre\bea\bak\bk, c\bco\bon\bnt\bti\bin\bnu\bue\be, l\ble\bet\bt,
-       and s\bsh\bhi\bif\bft\bt builtins accept and process arguments beginning with -\b with-
-       out  requiring  -\b--\b-.   Other  builtins that accept arguments but are not
-       specified as accepting options interpret arguments beginning with -\b as
+       and  s\bsh\bhi\bif\bft\bt builtins accept and process arguments beginning with -\b- with-
+       out requiring -\b--\b-.  Other builtins that accept  arguments  but  are  not
+       specified  as accepting options interpret arguments beginning with -\b- as
        invalid options and require -\b--\b- to prevent this interpretation.
        :\b: [_\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs]
-              No  effect;  the command does nothing beyond expanding _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs
-              and performing any specified redirections.  A zero exit code  is
+              No effect; the command does nothing beyond  expanding  _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs
+              and  performing any specified redirections.  A zero exit code is
               returned.
 
         .\b.  _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be [_\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs]
        s\bso\bou\bur\brc\bce\be _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be [_\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs]
-              Read  and  execute  commands  from _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be in the current shell
-              environment and return the exit status of the last command  exe-
-              cuted  from  _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be.   If  _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be  does not contain a slash,
-              filenames in P\bPA\bAT\bTH\bH are used  to  find  the  directory  containing
+              Read and execute commands from _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be  in  the  current  shell
+              environment  and return the exit status of the last command exe-
+              cuted from _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be.  If _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be  does  not  contain  a  slash,
+              filenames  in  P\bPA\bAT\bTH\bH  are  used  to find the directory containing
               _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be.  The file searched for in P\bPA\bAT\bTH\bH need not be executable.
-              When b\bba\bas\bsh\bh is  not  in  _\bp_\bo_\bs_\bi_\bx  _\bm_\bo_\bd_\be,  the  current  directory  is
-              searched  if no file is found in P\bPA\bAT\bTH\bH.  If the s\bso\bou\bur\brc\bce\bep\bpa\bat\bth\bh option
-              to the s\bsh\bho\bop\bpt\bt builtin command is turned  off,  the  P\bPA\bAT\bTH\bH  is  not
-              searched.   If any _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs are supplied, they become the posi-
-              tional parameters when  _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be  is  executed.   Otherwise  the
-              positional  parameters  are unchanged.  The return status is the
-              status of the last command exited within the  script  (0  if  no
-              commands  are  executed),  and false if _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be is not found or
+              When  b\bba\bas\bsh\bh  is  not  in  _\bp_\bo_\bs_\bi_\bx  _\bm_\bo_\bd_\be,  the  current directory is
+              searched if no file is found in P\bPA\bAT\bTH\bH.  If the s\bso\bou\bur\brc\bce\bep\bpa\bat\bth\b option
+              to  the  s\bsh\bho\bop\bpt\bt  builtin  command  is turned off, the P\bPA\bAT\bTH\bH is not
+              searched.  If any _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs are supplied, they become the  posi-
+              tional  parameters  when  _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be  is  executed.  Otherwise the
+              positional parameters are unchanged.  The return status  is  the
+              status  of  the  last  command exited within the script (0 if no
+              commands are executed), and false if _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be is  not  found  or
               cannot be read.
 
        a\bal\bli\bia\bas\bs [-\b-p\bp] [_\bn_\ba_\bm_\be[=_\bv_\ba_\bl_\bu_\be] ...]
               A\bAl\bli\bia\bas\bs with no arguments or with the -\b-p\bp option prints the list of
-              aliases  in  the form a\bal\bli\bia\bas\bs _\bn_\ba_\bm_\be=_\bv_\ba_\bl_\bu_\be on standard output.  When
-              arguments are supplied, an alias is defined for each _\bn_\ba_\bm_\b whose
-              _\bv_\ba_\bl_\bu_\b is given.  A trailing space in _\bv_\ba_\bl_\bu_\be causes the next word
+              aliases in the form a\bal\bli\bia\bas\bs _\bn_\ba_\bm_\be=_\bv_\ba_\bl_\bu_\be on standard  output.   When
+              arguments  are supplied, an alias is defined for each _\bn_\ba_\bm_\be whose
+              _\bv_\ba_\bl_\bu_\bis given.  A trailing space in _\bv_\ba_\bl_\bu_\be causes the next  word
               to be checked for alias substitution when the alias is expanded.
-              For  each  _\bn_\ba_\bm_\be  in the argument list for which no _\bv_\ba_\bl_\bu_\be is sup-
-              plied, the name and  value  of  the  alias  is  printed.   A\bAl\bli\bia\bas\bs
-              returns  true unless a _\bn_\ba_\bm_\be is given for which no alias has been
+              For each _\bn_\ba_\bm_\be in the argument list for which no  _\bv_\ba_\bl_\bu_\be  is  sup-
+              plied,  the  name  and  value  of  the  alias is printed.  A\bAl\bli\bia\bas\bs
+              returns true unless a _\bn_\ba_\bm_\be is given for which no alias has  been
               defined.
 
        b\bbg\bg [_\bj_\bo_\bb_\bs_\bp_\be_\bc ...]
-              Resume each suspended job _\bj_\bo_\bb_\bs_\bp_\be_\bc in the background,  as  if  it
+              Resume  each  suspended  job _\bj_\bo_\bb_\bs_\bp_\be_\bc in the background, as if it
               had been started with &\b&.  If _\bj_\bo_\bb_\bs_\bp_\be_\bc is not present, the shell's
-              notion of the _\bc_\bu_\br_\br_\be_\bn_\bt _\bj_\bo_\bb is used.  b\bbg\bg _\bj_\bo_\bb_\bs_\bp_\be_\bc returns 0  unless
-              run  when  job control is disabled or, when run with job control
-              enabled, any specified _\bj_\bo_\bb_\bs_\bp_\be_\bc was  not  found  or  was  started
+              notion  of the _\bc_\bu_\br_\br_\be_\bn_\bt _\bj_\bo_\bb is used.  b\bbg\bg _\bj_\bo_\bb_\bs_\bp_\be_\bc returns 0 unless
+              run when job control is disabled or, when run with  job  control
+              enabled,  any  specified  _\bj_\bo_\bb_\bs_\bp_\be_\bc  was  not found or was started
               without job control.
 
        b\bbi\bin\bnd\bd [-\b-m\bm _\bk_\be_\by_\bm_\ba_\bp] [-\b-l\blp\bps\bsv\bvP\bPS\bSV\bVX\bX]
@@ -3986,28 +4018,28 @@ S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS
        b\bbi\bin\bnd\bd [-\b-m\bm _\bk_\be_\by_\bm_\ba_\bp] -\b-x\bx _\bk_\be_\by_\bs_\be_\bq:_\bs_\bh_\be_\bl_\bl_\b-_\bc_\bo_\bm_\bm_\ba_\bn_\bd
        b\bbi\bin\bnd\bd [-\b-m\bm _\bk_\be_\by_\bm_\ba_\bp] _\bk_\be_\by_\bs_\be_\bq:_\bf_\bu_\bn_\bc_\bt_\bi_\bo_\bn_\b-_\bn_\ba_\bm_\be
        b\bbi\bin\bnd\bd [-\b-m\bm _\bk_\be_\by_\bm_\ba_\bp] _\bk_\be_\by_\bs_\be_\bq:_\br_\be_\ba_\bd_\bl_\bi_\bn_\be_\b-_\bc_\bo_\bm_\bm_\ba_\bn_\bd
-              Display  current  r\bre\bea\bad\bdl\bli\bin\bne\be key and function bindings, bind a key
-              sequence to a r\bre\bea\bad\bdl\bli\bin\bne\be function or  macro,  or  set  a  r\bre\bea\bad\bdl\bli\bin\bne\be
-              variable.   Each  non-option  argument  is a command as it would
-              appear in _\b._\bi_\bn_\bp_\bu_\bt_\br_\bc, but each binding or command must  be  passed
-              as  a  separate argument; e.g., '"\C-x\C-r": re-read-init-file'.
+              Display current r\bre\bea\bad\bdl\bli\bin\bne\be key and function bindings, bind  a  key
+              sequence  to  a  r\bre\bea\bad\bdl\bli\bin\bne\be  function  or macro, or set a r\bre\bea\bad\bdl\bli\bin\bne\be
+              variable.  Each non-option argument is a  command  as  it  would
+              appear  in  _\b._\bi_\bn_\bp_\bu_\bt_\br_\bc, but each binding or command must be passed
+              as a separate argument; e.g.,  '"\C-x\C-r":  re-read-init-file'.
               Options, if supplied, have the following meanings:
               -\b-m\bm _\bk_\be_\by_\bm_\ba_\bp
                      Use _\bk_\be_\by_\bm_\ba_\bp as the keymap to be affected by the subsequent
                      bindings.  Acceptable _\bk_\be_\by_\bm_\ba_\bp names are _\be_\bm_\ba_\bc_\bs_\b, _\be_\bm_\ba_\bc_\bs_\b-_\bs_\bt_\ba_\bn_\b-
-                     _\bd_\ba_\br_\bd_\b_\be_\bm_\ba_\bc_\bs_\b-_\bm_\be_\bt_\ba_\b, _\be_\bm_\ba_\bc_\bs_\b-_\bc_\bt_\bl_\bx_\b,  _\bv_\bi_\b,  _\bv_\bi_\b-_\bm_\bo_\bv_\be_\b _\bv_\bi_\b-_\bc_\bo_\bm_\bm_\ba_\bn_\bd,
-                     and  _\bv_\bi_\b-_\bi_\bn_\bs_\be_\br_\bt.  _\bv_\bi is equivalent to _\bv_\bi_\b-_\bc_\bo_\bm_\bm_\ba_\bn_\bd; _\be_\bm_\ba_\bc_\bs is
+                     _\bd_\ba_\br_\bd_\b _\be_\bm_\ba_\bc_\bs_\b-_\bm_\be_\bt_\ba_\b,  _\be_\bm_\ba_\bc_\bs_\b-_\bc_\bt_\bl_\bx_\b,  _\bv_\bi_\b, _\bv_\bi_\b-_\bm_\bo_\bv_\be_\b, _\bv_\bi_\b-_\bc_\bo_\bm_\bm_\ba_\bn_\bd,
+                     and _\bv_\bi_\b-_\bi_\bn_\bs_\be_\br_\bt.  _\bv_\bi is equivalent to _\bv_\bi_\b-_\bc_\bo_\bm_\bm_\ba_\bn_\bd; _\be_\bm_\ba_\bc_\b is
                      equivalent to _\be_\bm_\ba_\bc_\bs_\b-_\bs_\bt_\ba_\bn_\bd_\ba_\br_\bd.
               -\b-l\bl     List the names of all r\bre\bea\bad\bdl\bli\bin\bne\be functions.
-              -\b-p\bp     Display r\bre\bea\bad\bdl\bli\bin\bne\be function names and bindings  in  such  a
+              -\b-p\bp     Display  r\bre\bea\bad\bdl\bli\bin\bne\be  function  names and bindings in such a
                      way that they can be re-read.
               -\b-P\bP     List current r\bre\bea\bad\bdl\bli\bin\bne\be function names and bindings.
-              -\b-s\bs     Display  r\bre\bea\bad\bdl\bli\bin\bne\be  key  sequences bound to macros and the
-                     strings they output in such a way that they  can  be  re-
+              -\b-s\bs     Display r\bre\bea\bad\bdl\bli\bin\bne\be key sequences bound to  macros  and  the
+                     strings  they  output  in such a way that they can be re-
                      read.
-              -\b-S\bS     Display  r\bre\bea\bad\bdl\bli\bin\bne\be  key  sequences bound to macros and the
+              -\b-S\bS     Display r\bre\bea\bad\bdl\bli\bin\bne\be key sequences bound to  macros  and  the
                      strings they output.
-              -\b-v\bv     Display r\bre\bea\bad\bdl\bli\bin\bne\be variable names and values in such a  way
+              -\b-v\bv     Display  r\bre\bea\bad\bdl\bli\bin\bne\be variable names and values in such a way
                      that they can be re-read.
               -\b-V\bV     List current r\bre\bea\bad\bdl\bli\bin\bne\be variable names and values.
               -\b-f\bf _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be
@@ -4019,172 +4051,172 @@ S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS
               -\b-r\br _\bk_\be_\by_\bs_\be_\bq
                      Remove any current binding for _\bk_\be_\by_\bs_\be_\bq.
               -\b-x\bx _\bk_\be_\by_\bs_\be_\bq:\b:_\bs_\bh_\be_\bl_\bl_\b-_\bc_\bo_\bm_\bm_\ba_\bn_\bd
-                     Cause  _\bs_\bh_\be_\bl_\bl_\b-_\bc_\bo_\bm_\bm_\ba_\bn_\bd  to  be  executed whenever _\bk_\be_\by_\bs_\be_\bq is
-                     entered.  When _\bs_\bh_\be_\bl_\bl_\b-_\bc_\bo_\bm_\bm_\ba_\bn_\bd is executed, the shell  sets
-                     the  R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE_\b_L\bLI\bIN\bNE\bE  variable to the contents of the r\bre\bea\bad\bd-\b-
-                     l\bli\bin\bne\bline buffer and the R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE_\b_P\bPO\bOI\bIN\bNT\bT variable  to  the
+                     Cause _\bs_\bh_\be_\bl_\bl_\b-_\bc_\bo_\bm_\bm_\ba_\bn_\bd to be  executed  whenever  _\bk_\be_\by_\bs_\be_\b is
+                     entered.   When _\bs_\bh_\be_\bl_\bl_\b-_\bc_\bo_\bm_\bm_\ba_\bn_\bd is executed, the shell sets
+                     the R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE_\b_L\bLI\bIN\bNE\bE variable to the contents of  the  r\bre\bea\bad\bd-\b-
+                     l\bli\bin\bne\b line  buffer and the R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE_\b_P\bPO\bOI\bIN\bNT\bT variable to the
                      current location of the insertion point.  If the executed
-                     command changes  the  value  of  R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE_\b_L\bLI\bIN\bNE\bE  or  R\bRE\bEA\bAD\bD-\b-
-                     L\bLI\bIN\bNE\bE_\b_P\bPO\bOI\bIN\bNT\bT,  those  new  values  will be reflected in the
+                     command  changes  the  value  of  R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE_\b_L\bLI\bIN\bNE\bE  or R\bRE\bEA\bAD\bD-\b-
+                     L\bLI\bIN\bNE\bE_\b_P\bPO\bOI\bIN\bNT\bT, those new values will  be  reflected  in  the
                      editing state.
-              -\b-X\bX     List all key sequences bound to shell  commands  and  the
-                     associated  commands  in  a  format that can be reused as
+              -\b-X\bX     List  all  key  sequences bound to shell commands and the
+                     associated commands in a format that  can  be  reused  as
                      input.
 
-              The return value is 0 unless an unrecognized option is given  or
+              The  return value is 0 unless an unrecognized option is given or
               an error occurred.
 
        b\bbr\bre\bea\bak\bk [_\bn]
-              Exit  from  within a f\bfo\bor\br, w\bwh\bhi\bil\ble\be, u\bun\bnt\bti\bil\bl, or s\bse\bel\ble\bec\bct\bt loop.  If _\bn is
-              specified, break _\bn levels.  _\bn must be >= 1.   If  _\bn  is  greater
-              than  the  number  of  enclosing  loops, all enclosing loops are
-              exited.  The return value is 0 unless _\bn is not greater  than  or
+              Exit from within a f\bfo\bor\br, w\bwh\bhi\bil\ble\be, u\bun\bnt\bti\bil\bl, or s\bse\bel\ble\bec\bct\bt loop.  If  _\b is
+              specified,  break  _\bn  levels.   _\bn must be >= 1.  If _\bn is greater
+              than the number of enclosing  loops,  all  enclosing  loops  are
+              exited.   The  return value is 0 unless _\bn is not greater than or
               equal to 1.
 
        b\bbu\bui\bil\blt\bti\bin\bn _\bs_\bh_\be_\bl_\bl_\b-_\bb_\bu_\bi_\bl_\bt_\bi_\bn [_\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs]
-              Execute  the  specified shell builtin, passing it _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs, and
+              Execute the specified shell builtin, passing it  _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs,  and
               return its exit status.  This is useful when defining a function
-              whose  name  is the same as a shell builtin, retaining the func-
+              whose name is the same as a shell builtin, retaining  the  func-
               tionality of the builtin within the function.  The c\bcd\bd builtin is
-              commonly  redefined  this  way.   The  return status is false if
+              commonly redefined this way.  The  return  status  is  false  if
               _\bs_\bh_\be_\bl_\bl_\b-_\bb_\bu_\bi_\bl_\bt_\bi_\bn is not a shell builtin command.
 
        c\bca\bal\bll\ble\ber\br [_\be_\bx_\bp_\br]
               Returns the context of any active subroutine call (a shell func-
               tion or a script executed with the .\b. or s\bso\bou\bur\brc\bce\be builtins).  With-
               out _\be_\bx_\bp_\br, c\bca\bal\bll\ble\ber\br displays the line number and source filename of
-              the  current subroutine call.  If a non-negative integer is sup-
+              the current subroutine call.  If a non-negative integer is  sup-
               plied as _\be_\bx_\bp_\br, c\bca\bal\bll\ble\ber\br displays the line number, subroutine name,
-              and  source  file  corresponding to that position in the current
-              execution call stack.  This extra information may be  used,  for
-              example,  to print a stack trace.  The current frame is frame 0.
-              The return value is 0 unless the shell is not executing  a  sub-
-              routine  call or _\be_\bx_\bp_\br does not correspond to a valid position in
+              and source file corresponding to that position  in  the  current
+              execution  call  stack.  This extra information may be used, for
+              example, to print a stack trace.  The current frame is frame  0.
+              The  return  value is 0 unless the shell is not executing a sub-
+              routine call or _\be_\bx_\bp_\br does not correspond to a valid position  in
               the call stack.
 
        c\bcd\bd [-\b-L\bL|[-\b-P\bP [-\b-e\be]] [-@]] [_\bd_\bi_\br]
-              Change the current directory to _\bd_\bi_\br.  if _\bd_\bi_\br  is  not  supplied,
-              the  value of the H\bHO\bOM\bME\bE shell variable is the default.  Any addi-
+              Change  the  current  directory to _\bd_\bi_\br.  if _\bd_\bi_\br is not supplied,
+              the value of the H\bHO\bOM\bME\bE shell variable is the default.  Any  addi-
               tional arguments following _\bd_\bi_\br are ignored.  The variable C\bCD\bDP\bPA\bAT\bTH\bH
-              defines  the  search path for the directory containing _\bd_\bi_\br: each
-              directory name in  C\bCD\bDP\bPA\bAT\bTH\bH  is  searched  for  _\bd_\bi_\br.   Alternative
-              directory  names in C\bCD\bDP\bPA\bAT\bTH\bH are separated by a colon (:).  A null
-              directory name in C\bCD\bDP\bPA\bAT\bTH\bH is the same as the  current  directory,
+              defines the search path for the directory containing  _\bd_\bi_\br:  each
+              directory  name  in  C\bCD\bDP\bPA\bAT\bTH\bH  is  searched  for _\bd_\bi_\br.  Alternative
+              directory names in C\bCD\bDP\bPA\bAT\bTH\bH are separated by a colon (:).  A  null
+              directory  name  in C\bCD\bDP\bPA\bAT\bTH\bH is the same as the current directory,
               i.e., ``.\b.''.  If _\bd_\bi_\br begins with a slash (/), then C\bCD\bDP\bPA\bAT\bTH\bH is not
-              used.  The -\b-P\bP option causes c\bcd\bd to  use  the  physical  directory
-              structure  by  resolving symbolic links while traversing _\bd_\bi_\br and
+              used.   The  -\b-P\bP  option  causes c\bcd\bd to use the physical directory
+              structure by resolving symbolic links while traversing  _\bd_\bi_\b and
               before processing instances of _\b._\b. in _\bd_\bi_\br (see also the -\b-P\bP option
               to the s\bse\bet\bt builtin command); the -\b-L\bL option forces symbolic links
-              to be followed by resolving the link after processing  instances
+              to  be followed by resolving the link after processing instances
               of _\b._\b. in _\bd_\bi_\br.  If _\b._\b. appears in _\bd_\bi_\br, it is processed by removing
-              the immediately previous pathname component from _\bd_\bi_\br, back to  a
-              slash  or  the  beginning  of _\bd_\bi_\br.  If the -\b-e\be option is supplied
-              with -\b-P\bP, and the current working directory  cannot  be  success-
-              fully  determined  after  a successful directory change, c\bcd\bd will
-              return an unsuccessful status.  On systems that support it,  the
-              -\b-@\b option  presents  the  extended attributes associated with a
-              file as a directory.  An argument of -\b- is converted  to  $\b$O\bOL\bLD\bDP\bPW\bWD\bD
+              the  immediately previous pathname component from _\bd_\bi_\br, back to a
+              slash or the beginning of _\bd_\bi_\br.  If the  -\b-e\be  option  is  supplied
+              with  -\b-P\bP,  and  the current working directory cannot be success-
+              fully determined after a successful directory  change,  c\bcd\b will
+              return  an unsuccessful status.  On systems that support it, the
+              -\b-@\boption presents the extended  attributes  associated  with  a
+              file  as  a directory.  An argument of -\b- is converted to $\b$O\bOL\bLD\bDP\bPW\bWD\bD
               before the directory change is attempted.  If a non-empty direc-
-              tory name from C\bCD\bDP\bPA\bAT\bTH\bH is used, or if -\b- is  the  first  argument,
+              tory  name  from  C\bCD\bDP\bPA\bAT\bTH\bH is used, or if -\b- is the first argument,
               and the directory change is successful, the absolute pathname of
-              the new working directory is written  to  the  standard  output.
-              The  return  value  is  true  if  the directory was successfully
+              the  new  working  directory  is written to the standard output.
+              The return value is  true  if  the  directory  was  successfully
               changed; false otherwise.
 
        c\bco\bom\bmm\bma\ban\bnd\bd [-\b-p\bpV\bVv\bv] _\bc_\bo_\bm_\bm_\ba_\bn_\bd [_\ba_\br_\bg ...]
-              Run _\bc_\bo_\bm_\bm_\ba_\bn_\bd with _\ba_\br_\bg_\bs  suppressing  the  normal  shell  function
+              Run  _\bc_\bo_\bm_\bm_\ba_\bn_\bd  with  _\ba_\br_\bg_\bs  suppressing  the normal shell function
               lookup.  Only builtin commands or commands found in the P\bPA\bAT\bTH\bH are
-              executed.  If the -\b-p\bp option is given, the search for _\bc_\bo_\bm_\bm_\ba_\bn_\b is
-              performed  using  a default value for P\bPA\bAT\bTH\bH that is guaranteed to
-              find all of the standard utilities.  If  either  the  -\b-V\bV  or  -\b-v\bv
+              executed.   If the -\b-p\bp option is given, the search for _\bc_\bo_\bm_\bm_\ba_\bn_\bd is
+              performed using a default value for P\bPA\bAT\bTH\bH that is  guaranteed  to
+              find  all  of  the  standard  utilities.  If either the -\b-V\bV or -\b-v\bv
               option is supplied, a description of _\bc_\bo_\bm_\bm_\ba_\bn_\bd is printed.  The -\b-v\bv
-              option causes a single word indicating the command  or  filename
+              option  causes  a single word indicating the command or filename
               used to invoke _\bc_\bo_\bm_\bm_\ba_\bn_\bd to be displayed; the -\b-V\bV option produces a
-              more verbose description.  If the -\b-V\bV or -\b-v\bv option  is  supplied,
-              the  exit  status  is  0 if _\bc_\bo_\bm_\bm_\ba_\bn_\bd was found, and 1 if not.  If
+              more  verbose  description.  If the -\b-V\bV or -\b-v\bv option is supplied,
+              the exit status is 0 if _\bc_\bo_\bm_\bm_\ba_\bn_\bd was found, and  1  if  not.   If
               neither option is supplied and an error occurred or _\bc_\bo_\bm_\bm_\ba_\bn_\bd can-
-              not  be found, the exit status is 127.  Otherwise, the exit sta-
+              not be found, the exit status is 127.  Otherwise, the exit  sta-
               tus of the c\bco\bom\bmm\bma\ban\bnd\bd builtin is the exit status of _\bc_\bo_\bm_\bm_\ba_\bn_\bd.
 
        c\bco\bom\bmp\bpg\bge\ben\bn [_\bo_\bp_\bt_\bi_\bo_\bn] [_\bw_\bo_\br_\bd]
-              Generate possible completion matches for _\bw_\bo_\br_\bd according  to  the
-              _\bo_\bp_\bt_\bi_\bo_\bns,  which  may  be  any  option  accepted  by the c\bco\bom\bmp\bpl\ble\bet\bte\be
-              builtin with the exception of -\b-p\bp and -\b-r\br, and write  the  matches
-              to  the  standard  output.  When using the -\b-F\bF or -\b-C\bC options, the
-              various shell  variables  set  by  the  programmable  completion
+              Generate  possible  completion matches for _\bw_\bo_\br_\bd according to the
+              _\bo_\bp_\bt_\bi_\bo_\bns, which may  be  any  option  accepted  by  the  c\bco\bom\bmp\bpl\ble\bet\bte\be
+              builtin  with  the exception of -\b-p\bp and -\b-r\br, and write the matches
+              to the standard output.  When using the -\b-F\bF or  -\b-C\bC  options,  the
+              various  shell  variables  set  by  the  programmable completion
               facilities, while available, will not have useful values.
 
               The matches will be generated in the same way as if the program-
               mable completion code had generated them directly from a comple-
-              tion  specification  with the same flags.  If _\bw_\bo_\br_\bd is specified,
+              tion specification with the same flags.  If _\bw_\bo_\br_\bd  is  specified,
               only those completions matching _\bw_\bo_\br_\bd will be displayed.
 
-              The return value is true unless an invalid option  is  supplied,
+              The  return  value is true unless an invalid option is supplied,
               or no matches were generated.
 
-       c\bco\bom\bmp\bpl\ble\bet\bte\b [-\b-a\bab\bbc\bcd\bde\bef\bfg\bgj\bjk\bks\bsu\buv\bv]  [-\b-o\bo _\bc_\bo_\bm_\bp_\b-_\bo_\bp_\bt_\bi_\bo_\bn] [-\b-D\bDE\bE] [-\b-A\bA _\ba_\bc_\bt_\bi_\bo_\bn] [-\b-G\bG _\bg_\bl_\bo_\bb_\b-
+       c\bco\bom\bmp\bpl\ble\bet\bte\b[-\b-a\bab\bbc\bcd\bde\bef\bfg\bgj\bjk\bks\bsu\buv\bv] [-\b-o\bo _\bc_\bo_\bm_\bp_\b-_\bo_\bp_\bt_\bi_\bo_\bn] [-\b-D\bDE\bE] [-\b-A\bA _\ba_\bc_\bt_\bi_\bo_\bn]  [-\b-G\b _\bg_\bl_\bo_\bb_\b-
        _\bp_\ba_\bt] [-\b-W\bW _\bw_\bo_\br_\bd_\bl_\bi_\bs_\bt] [-\b-F\bF _\bf_\bu_\bn_\bc_\bt_\bi_\bo_\bn] [-\b-C\bC _\bc_\bo_\bm_\bm_\ba_\bn_\bd]
               [-\b-X\bX _\bf_\bi_\bl_\bt_\be_\br_\bp_\ba_\bt] [-\b-P\bP _\bp_\br_\be_\bf_\bi_\bx] [-\b-S\bS _\bs_\bu_\bf_\bf_\bi_\bx] _\bn_\ba_\bm_\be [_\bn_\ba_\bm_\be _\b._\b._\b.]
        c\bco\bom\bmp\bpl\ble\bet\bte\be -\b-p\bpr\br [-\b-D\bDE\bE] [_\bn_\ba_\bm_\be ...]
-              Specify how arguments to each _\bn_\ba_\bm_\be should be completed.  If  the
-              -\b-p\b option  is supplied, or if no options are supplied, existing
-              completion specifications are printed in a way that allows  them
+              Specify  how arguments to each _\bn_\ba_\bm_\be should be completed.  If the
+              -\b-p\boption is supplied, or if no options are  supplied,  existing
+              completion  specifications are printed in a way that allows them
               to be reused as input.  The -\b-r\br option removes a completion spec-
-              ification for each _\bn_\ba_\bm_\be, or, if no _\bn_\ba_\bm_\bes are supplied, all  com-
+              ification  for each _\bn_\ba_\bm_\be, or, if no _\bn_\ba_\bm_\bes are supplied, all com-
               pletion  specifications.   The  -\b-D\bD  option  indicates  that  the
-              remaining options and actions should apply  to  the  ``default''
-              command  completion;  that is, completion attempted on a command
-              for which no completion has previously  been  defined.   The  -\b-E\bE
-              option  indicates  that the remaining options and actions should
-              apply to  ``empty''  command  completion;  that  is,  completion
+              remaining  options  and  actions should apply to the ``default''
+              command completion; that is, completion attempted on  a  command
+              for  which  no  completion  has previously been defined.  The -\b-E\bE
+              option indicates that the remaining options and  actions  should
+              apply  to  ``empty''  command  completion;  that  is, completion
               attempted on a blank line.
 
-              The  process  of  applying  these completion specifications when
-              word completion is attempted is described above  under  P\bPr\bro\bog\bgr\bra\bam\bm-\b-
+              The process of applying  these  completion  specifications  when
+              word  completion  is attempted is described above under P\bPr\bro\bog\bgr\bra\bam\bm-\b-
               m\bma\bab\bbl\ble\be C\bCo\bom\bmp\bpl\ble\bet\bti\bio\bon\bn.
 
-              Other  options,  if specified, have the following meanings.  The
-              arguments to the -\b-G\bG, -\b-W\bW, and -\b-X\bX options (and, if necessary,  the
-              -\b-P\b and -\b-S\bS options) should be quoted to protect them from expan-
+              Other options, if specified, have the following  meanings.   The
+              arguments  to the -\b-G\bG, -\b-W\bW, and -\b-X\bX options (and, if necessary, the
+              -\b-P\band -\b-S\bS options) should be quoted to protect them from  expan-
               sion before the c\bco\bom\bmp\bpl\ble\bet\bte\be builtin is invoked.
               -\b-o\bo _\bc_\bo_\bm_\bp_\b-_\bo_\bp_\bt_\bi_\bo_\bn
-                      The _\bc_\bo_\bm_\bp_\b-_\bo_\bp_\bt_\bi_\bo_\bn controls several aspects  of  the  comp-
-                      spec's  behavior beyond the simple generation of comple-
+                      The  _\bc_\bo_\bm_\bp_\b-_\bo_\bp_\bt_\bi_\bo_\bn  controls  several aspects of the comp-
+                      spec's behavior beyond the simple generation of  comple-
                       tions.  _\bc_\bo_\bm_\bp_\b-_\bo_\bp_\bt_\bi_\bo_\bn may be one of:
                       b\bba\bas\bsh\bhd\bde\bef\bfa\bau\bul\blt\bt
                               Perform the rest of the default b\bba\bas\bsh\bh completions
                               if the compspec generates no matches.
-                      d\bde\bef\bfa\bau\bul\blt\bt Use  readline's  default  filename completion if
+                      d\bde\bef\bfa\bau\bul\blt\bt Use readline's default  filename  completion  if
                               the compspec generates no matches.
                       d\bdi\bir\brn\bna\bam\bme\bes\bs
-                              Perform directory name completion if  the  comp-
+                              Perform  directory  name completion if the comp-
                               spec generates no matches.
                       f\bfi\bil\ble\ben\bna\bam\bme\bes\bs
-                              Tell  readline that the compspec generates file-
-                              names, so it can perform  any  filename-specific
-                              processing  (like  adding  a  slash to directory
-                              names, quoting special characters, or  suppress-
-                              ing  trailing spaces).  Intended to be used with
+                              Tell readline that the compspec generates  file-
+                              names,  so  it can perform any filename-specific
+                              processing (like adding  a  slash  to  directory
+                              names,  quoting special characters, or suppress-
+                              ing trailing spaces).  Intended to be used  with
                               shell functions.
-                      n\bno\boq\bqu\buo\bot\bte\be Tell readline not to quote the  completed  words
-                              if  they are filenames (quoting filenames is the
+                      n\bno\boq\bqu\buo\bot\bte\be Tell  readline  not to quote the completed words
+                              if they are filenames (quoting filenames is  the
                               default).
-                      n\bno\bos\bsp\bpa\bac\bce\be Tell  readline  not  to  append  a  space   (the
-                              default)  to  words  completed at the end of the
+                      n\bno\bos\bsp\bpa\bac\bce\be Tell   readline  not  to  append  a  space  (the
+                              default) to words completed at the  end  of  the
                               line.
                       p\bpl\blu\bus\bsd\bdi\bir\brs\bs
-                              After any matches defined by  the  compspec  are
-                              generated,    directory   name   completion   is
-                              attempted and  any  matches  are  added  to  the
+                              After  any  matches  defined by the compspec are
+                              generated,   directory   name   completion    is
+                              attempted  and  any  matches  are  added  to the
                               results of the other actions.
               -\b-A\bA _\ba_\bc_\bt_\bi_\bo_\bn
-                      The  _\ba_\bc_\bt_\bi_\bo_\bn  may  be  one of the following to generate a
+                      The _\ba_\bc_\bt_\bi_\bo_\bn may be one of the  following  to  generate  a
                       list of possible completions:
                       a\bal\bli\bia\bas\bs   Alias names.  May also be specified as -\b-a\ba.
                       a\bar\brr\bra\bay\byv\bva\bar\br
                               Array variable names.
                       b\bbi\bin\bnd\bdi\bin\bng\bg R\bRe\bea\bad\bdl\bli\bin\bne\be key binding names.
-                      b\bbu\bui\bil\blt\bti\bin\bn Names of shell builtin commands.   May  also  be
+                      b\bbu\bui\bil\blt\bti\bin\bn Names  of  shell  builtin commands.  May also be
                               specified as -\b-b\bb.
                       c\bco\bom\bmm\bma\ban\bnd\bd Command names.  May also be specified as -\b-c\bc.
                       d\bdi\bir\bre\bec\bct\bto\bor\bry\by
@@ -4192,7 +4224,7 @@ S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS
                       d\bdi\bis\bsa\bab\bbl\ble\bed\bd
                               Names of disabled shell builtins.
                       e\ben\bna\bab\bbl\ble\bed\bd Names of enabled shell builtins.
-                      e\bex\bxp\bpo\bor\brt\bt  Names  of exported shell variables.  May also be
+                      e\bex\bxp\bpo\bor\brt\bt  Names of exported shell variables.  May also  be
                               specified as -\b-e\be.
                       f\bfi\bil\ble\be    File names.  May also be specified as -\b-f\bf.
                       f\bfu\bun\bnc\bct\bti\bio\bon\bn
@@ -4201,17 +4233,17 @@ S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS
                       h\bhe\bel\blp\bpt\bto\bop\bpi\bic\bc
                               Help topics as accepted by the h\bhe\bel\blp\bp builtin.
                       h\bho\bos\bst\btn\bna\bam\bme\be
-                              Hostnames, as taken from the file  specified  by
+                              Hostnames,  as  taken from the file specified by
                               the H\bHO\bOS\bST\bTF\bFI\bIL\bLE\bE shell variable.
-                      j\bjo\bob\bb     Job  names,  if job control is active.  May also
+                      j\bjo\bob\bb     Job names, if job control is active.   May  also
                               be specified as -\b-j\bj.
-                      k\bke\bey\byw\bwo\bor\brd\bd Shell reserved words.  May also be specified  as
+                      k\bke\bey\byw\bwo\bor\brd\bd Shell  reserved words.  May also be specified as
                               -\b-k\bk.
                       r\bru\bun\bnn\bni\bin\bng\bg Names of running jobs, if job control is active.
                       s\bse\ber\brv\bvi\bic\bce\be Service names.  May also be specified as -\b-s\bs.
-                      s\bse\bet\bto\bop\bpt\bt  Valid  arguments  for  the  -\b-o\bo option to the s\bse\bet\bt
+                      s\bse\bet\bto\bop\bpt\bt  Valid arguments for the -\b-o\bo  option  to  the  s\bse\bet\bt
                               builtin.
-                      s\bsh\bho\bop\bpt\bt   Shell option names  as  accepted  by  the  s\bsh\bho\bop\bpt\bt
+                      s\bsh\bho\bop\bpt\bt   Shell  option  names  as  accepted  by the s\bsh\bho\bop\bpt\bt
                               builtin.
                       s\bsi\big\bgn\bna\bal\bl  Signal names.
                       s\bst\bto\bop\bpp\bpe\bed\bd Names of stopped jobs, if job control is active.
@@ -4220,187 +4252,187 @@ S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS
                               Names of all shell variables.  May also be spec-
                               ified as -\b-v\bv.
               -\b-C\bC _\bc_\bo_\bm_\bm_\ba_\bn_\bd
-                      _\bc_\bo_\bm_\bm_\ba_\bn_\bis executed in a subshell environment,  and  its
+                      _\bc_\bo_\bm_\bm_\ba_\bn_\b is  executed in a subshell environment, and its
                       output is used as the possible completions.
               -\b-F\bF _\bf_\bu_\bn_\bc_\bt_\bi_\bo_\bn
-                      The  shell  function _\bf_\bu_\bn_\bc_\bt_\bi_\bo_\bn is executed in the current
-                      shell environment.  When the function is  executed,  the
-                      first  argument  ($\b$1\b1)  is  the name of the command whose
-                      arguments are being completed, the second argument  ($\b$2\b2)
+                      The shell function _\bf_\bu_\bn_\bc_\bt_\bi_\bo_\bn is executed in  the  current
+                      shell  environment.   When the function is executed, the
+                      first argument ($\b$1\b1) is the name  of  the  command  whose
+                      arguments  are being completed, the second argument ($\b$2\b2)
                       is the word being completed, and the third argument ($\b$3\b3)
-                      is the word preceding the word being  completed  on  the
-                      current  command  line.   When it finishes, the possible
-                      completions are retrieved from the value of the  C\bCO\bOM\bMP\bPR\bRE\bE-\b-
+                      is  the  word  preceding the word being completed on the
+                      current command line.  When it  finishes,  the  possible
+                      completions  are retrieved from the value of the C\bCO\bOM\bMP\bPR\bRE\bE-\b-
                       P\bPL\bLY\bY array variable.
               -\b-G\bG _\bg_\bl_\bo_\bb_\bp_\ba_\bt
-                      The  pathname  expansion  pattern _\bg_\bl_\bo_\bb_\bp_\ba_\bt is expanded to
+                      The pathname expansion pattern _\bg_\bl_\bo_\bb_\bp_\ba_\bt  is  expanded  to
                       generate the possible completions.
               -\b-P\bP _\bp_\br_\be_\bf_\bi_\bx
-                      _\bp_\br_\be_\bf_\bi_\bis added at the beginning of each  possible  com-
+                      _\bp_\br_\be_\bf_\bi_\b is  added at the beginning of each possible com-
                       pletion after all other options have been applied.
               -\b-S\bS _\bs_\bu_\bf_\bf_\bi_\bx
                       _\bs_\bu_\bf_\bf_\bi_\bx is appended to each possible completion after all
                       other options have been applied.
               -\b-W\bW _\bw_\bo_\br_\bd_\bl_\bi_\bs_\bt
-                      The _\bw_\bo_\br_\bd_\bl_\bi_\bs_\bt is split using the characters  in  the  I\bIF\bFS\bS
-                      special  variable as delimiters, and each resultant word
-                      is expanded.  The possible completions are  the  members
-                      of  the  resultant  list which match the word being com-
+                      The  _\bw_\bo_\br_\bd_\bl_\bi_\bs_\bt  is  split using the characters in the I\bIF\bFS\bS
+                      special variable as delimiters, and each resultant  word
+                      is  expanded.   The possible completions are the members
+                      of the resultant list which match the  word  being  com-
                       pleted.
               -\b-X\bX _\bf_\bi_\bl_\bt_\be_\br_\bp_\ba_\bt
-                      _\bf_\bi_\bl_\bt_\be_\br_\bp_\ba_\bis a pattern as used for  pathname  expansion.
+                      _\bf_\bi_\bl_\bt_\be_\br_\bp_\ba_\b is  a pattern as used for pathname expansion.
                       It is applied to the list of possible completions gener-
-                      ated by the preceding options and  arguments,  and  each
-                      completion  matching _\bf_\bi_\bl_\bt_\be_\br_\bp_\ba_\bt is removed from the list.
-                      A leading !\b! in _\bf_\bi_\bl_\bt_\be_\br_\bp_\ba_\bt negates the  pattern;  in  this
+                      ated  by  the  preceding options and arguments, and each
+                      completion matching _\bf_\bi_\bl_\bt_\be_\br_\bp_\ba_\bt is removed from the  list.
+                      A  leading  !\b!  in _\bf_\bi_\bl_\bt_\be_\br_\bp_\ba_\bt negates the pattern; in this
                       case, any completion not matching _\bf_\bi_\bl_\bt_\be_\br_\bp_\ba_\bt is removed.
 
-              The  return  value is true unless an invalid option is supplied,
-              an option other than -\b-p\bp or -\b-r\br is supplied without a  _\bn_\ba_\bm_\b argu-
-              ment,  an  attempt  is made to remove a completion specification
+              The return value is true unless an invalid option  is  supplied,
+              an  option  other than -\b-p\bp or -\b-r\br is supplied without a _\bn_\ba_\bm_\be argu-
+              ment, an attempt is made to remove  a  completion  specification
               for a _\bn_\ba_\bm_\be for which no specification exists, or an error occurs
               adding a completion specification.
 
        c\bco\bom\bmp\bpo\bop\bpt\bt [-\b-o\bo _\bo_\bp_\bt_\bi_\bo_\bn] [-\b-D\bDE\bE] [+\b+o\bo _\bo_\bp_\bt_\bi_\bo_\bn] [_\bn_\ba_\bm_\be]
               Modify  completion  options  for  each  _\bn_\ba_\bm_\be  according  to  the
-              _\bo_\bp_\bt_\bi_\bo_\bns, or for the currently-executing completion if  no  _\bn_\ba_\bm_\bes
-              are  supplied.   If no _\bo_\bp_\bt_\bi_\bo_\bns are given, display the completion
-              options for each _\bn_\ba_\bm_\be or the current completion.   The  possible
-              values  of  _\bo_\bp_\bt_\bi_\bo_\bn  are  those  valid  for  the c\bco\bom\bmp\bpl\ble\bet\bte\be builtin
-              described above.  The -\b-D\bD option  indicates  that  the  remaining
+              _\bo_\bp_\bt_\bi_\bo_\bns,  or  for the currently-executing completion if no _\bn_\ba_\bm_\bes
+              are supplied.  If no _\bo_\bp_\bt_\bi_\bo_\bns are given, display  the  completion
+              options  for  each _\bn_\ba_\bm_\be or the current completion.  The possible
+              values of _\bo_\bp_\bt_\bi_\bo_\bn  are  those  valid  for  the  c\bco\bom\bmp\bpl\ble\bet\bte\b builtin
+              described  above.   The  -\b-D\bD  option indicates that the remaining
               options should apply to the ``default'' command completion; that
-              is, completion attempted on a command for  which  no  completion
-              has  previously  been defined.  The -\b-E\bE option indicates that the
-              remaining options should apply to ``empty'' command  completion;
+              is,  completion  attempted  on a command for which no completion
+              has previously been defined.  The -\b-E\bE option indicates  that  the
+              remaining  options should apply to ``empty'' command completion;
               that is, completion attempted on a blank line.
 
-              The  return  value is true unless an invalid option is supplied,
+              The return value is true unless an invalid option  is  supplied,
               an attempt is made to modify the options for a _\bn_\ba_\bm_\be for which no
               completion specification exists, or an output error occurs.
 
        c\bco\bon\bnt\bti\bin\bnu\bue\be [_\bn]
               Resume the next iteration of the enclosing f\bfo\bor\br, w\bwh\bhi\bil\ble\be, u\bun\bnt\bti\bil\bl, or
-              s\bse\bel\ble\bec\bct\bloop.  If _\bn is specified, resume  at  the  _\bnth  enclosing
-              loop.   _\bn  must  be  >=  1.   If _\bn is greater than the number of
-              enclosing loops, the  last  enclosing  loop  (the  ``top-level''
+              s\bse\bel\ble\bec\bct\b loop.   If  _\bn  is specified, resume at the _\bnth enclosing
+              loop.  _\bn must be >= 1.  If _\bn  is  greater  than  the  number  of
+              enclosing  loops,  the  last  enclosing  loop (the ``top-level''
               loop) is resumed.  The return value is 0 unless _\bn is not greater
               than or equal to 1.
 
        d\bde\bec\bcl\bla\bar\bre\be [-\b-a\baA\bAf\bfF\bFg\bgi\bil\bln\bnr\brt\btu\bux\bx] [-\b-p\bp] [_\bn_\ba_\bm_\be[=_\bv_\ba_\bl_\bu_\be] ...]
        t\bty\byp\bpe\bes\bse\bet\bt [-\b-a\baA\bAf\bfF\bFg\bgi\bil\bln\bnr\brt\btu\bux\bx] [-\b-p\bp] [_\bn_\ba_\bm_\be[=_\bv_\ba_\bl_\bu_\be] ...]
-              Declare variables and/or give them attributes.  If no _\bn_\ba_\bm_\bes  are
-              given  then display the values of variables.  The -\b-p\bp option will
+              Declare  variables and/or give them attributes.  If no _\bn_\ba_\bm_\bes are
+              given then display the values of variables.  The -\b-p\bp option  will
               display the attributes and values of each _\bn_\ba_\bm_\be.  When -\b-p\bp is used
-              with  _\bn_\ba_\bm_\be  arguments, additional options, other than -\b-f\bf and -\b-F\bF,
-              are ignored.  When -\b-p\bp is supplied  without  _\bn_\ba_\bm_\be  arguments,  it
-              will  display  the attributes and values of all variables having
+              with _\bn_\ba_\bm_\be arguments, additional options, other than -\b-f\bf  and  -\b-F\bF,
+              are  ignored.   When  -\b-p\bp  is supplied without _\bn_\ba_\bm_\be arguments, it
+              will display the attributes and values of all  variables  having
               the attributes specified by the additional options.  If no other
-              options   are   supplied  with  -\b-p\bp,  d\bde\bec\bcl\bla\bar\bre\be  will  display  the
-              attributes and values of all shell  variables.   The  -\b-f\b option
-              will  restrict  the  display  to shell functions.  The -\b-F\bF option
-              inhibits the display of function definitions; only the  function
-              name  and  attributes are printed.  If the e\bex\bxt\btd\bde\beb\bbu\bug\bg shell option
-              is enabled using s\bsh\bho\bop\bpt\bt, the source file  name  and  line  number
-              where  the  function  is  defined are displayed as well.  The -\b-F\bF
+              options  are  supplied  with  -\b-p\bp,  d\bde\bec\bcl\bla\bar\bre\be  will   display   the
+              attributes  and  values  of  all shell variables.  The -\b-f\bf option
+              will restrict the display to shell  functions.   The  -\b-F\b option
+              inhibits  the display of function definitions; only the function
+              name and attributes are printed.  If the e\bex\bxt\btd\bde\beb\bbu\bug\bg  shell  option
+              is  enabled  using  s\bsh\bho\bop\bpt\bt,  the source file name and line number
+              where the function is defined are displayed  as  well.   The  -\b-F\bF
               option implies -\b-f\bf.  The -\b-g\bg option forces variables to be created
-              or  modified  at the global scope, even when d\bde\bec\bcl\bla\bar\bre\be is executed
-              in a shell function.  It is ignored in  all  other  cases.   The
-              following  options  can  be used to restrict output to variables
+              or modified at the global scope, even when d\bde\bec\bcl\bla\bar\bre\be  is  executed
+              in  a  shell  function.   It is ignored in all other cases.  The
+              following options can be used to restrict  output  to  variables
               with the specified attribute or to give variables attributes:
-              -\b-a\ba     Each _\bn_\ba_\bm_\be  is  an  indexed  array  variable  (see  A\bAr\brr\bra\bay\bys\bs
+              -\b-a\ba     Each  _\bn_\ba_\bm_\be  is  an  indexed  array  variable  (see A\bAr\brr\bra\bay\bys\bs
                      above).
-              -\b-A\bA     Each  _\bn_\ba_\bm_\be  is  an associative array variable (see A\bAr\brr\bra\bay\bys\bs
+              -\b-A\bA     Each _\bn_\ba_\bm_\be is an associative array  variable  (see  A\bAr\brr\bra\bay\bys\bs
                      above).
               -\b-f\bf     Use function names only.
               -\b-i\bi     The variable is treated as an integer; arithmetic evalua-
-                     tion  (see A\bAR\bRI\bIT\bTH\bHM\bME\bET\bTI\bIC\bC E\bEV\bVA\bAL\bLU\bUA\bAT\bTI\bIO\bON\bN above) is performed when
+                     tion (see A\bAR\bRI\bIT\bTH\bHM\bME\bET\bTI\bIC\bC E\bEV\bVA\bAL\bLU\bUA\bAT\bTI\bIO\bON\bN above) is performed  when
                      the variable is assigned a value.
-              -\b-l\bl     When the variable is assigned  a  value,  all  upper-case
-                     characters  are  converted to lower-case.  The upper-case
+              -\b-l\bl     When  the  variable  is  assigned a value, all upper-case
+                     characters are converted to lower-case.   The  upper-case
                      attribute is disabled.
-              -\b-n\bn     Give each _\bn_\ba_\bm_\be the _\bn_\ba_\bm_\be_\br_\be_\bf attribute, making  it  a  name
-                     reference  to  another  variable.  That other variable is
-                     defined by the value of _\bn_\ba_\bm_\be.   All  references,  assign-
-                     ments,  and  attribute  modifications to _\bn_\ba_\bm_\be, except for
-                     changing the -\b-n\bn attribute itself, are  performed  on  the
-                     variable   referenced   by  _\bn_\ba_\bm_\be's  value.   The  nameref
+              -\b-n\bn     Give  each  _\bn_\ba_\bm_\be  the _\bn_\ba_\bm_\be_\br_\be_\bf attribute, making it a name
+                     reference to another variable.  That  other  variable  is
+                     defined  by  the  value of _\bn_\ba_\bm_\be.  All references, assign-
+                     ments, and attribute modifications to  _\bn_\ba_\bm_\be,  except  for
+                     changing  the  -\b-n\bn  attribute itself, are performed on the
+                     variable  referenced  by  _\bn_\ba_\bm_\be's  value.    The   nameref
                      attribute cannot be applied to array variables.
               -\b-r\br     Make _\bn_\ba_\bm_\bes readonly.  These names cannot then be assigned
                      values by subsequent assignment statements or unset.
-              -\b-t\bt     Give  each  _\bn_\ba_\bm_\be  the  _\bt_\br_\ba_\bc_\be attribute.  Traced functions
-                     inherit the D\bDE\bEB\bBU\bUG\bG  and  R\bRE\bET\bTU\bUR\bRN\bN  traps  from  the  calling
-                     shell.   The  trace  attribute has no special meaning for
+              -\b-t\bt     Give each _\bn_\ba_\bm_\be the  _\bt_\br_\ba_\bc_\be  attribute.   Traced  functions
+                     inherit  the  D\bDE\bEB\bBU\bUG\bG  and  R\bRE\bET\bTU\bUR\bRN\bN  traps  from the calling
+                     shell.  The trace attribute has no  special  meaning  for
                      variables.
-              -\b-u\bu     When the variable is assigned  a  value,  all  lower-case
-                     characters  are  converted to upper-case.  The lower-case
+              -\b-u\bu     When  the  variable  is  assigned a value, all lower-case
+                     characters are converted to upper-case.   The  lower-case
                      attribute is disabled.
-              -\b-x\bx     Mark _\bn_\ba_\bm_\bes for export  to  subsequent  commands  via  the
+              -\b-x\bx     Mark  _\bn_\ba_\bm_\bes  for  export  to  subsequent commands via the
                      environment.
 
-              Using  `+'  instead of `-' turns off the attribute instead, with
+              Using `+' instead of `-' turns off the attribute  instead,  with
               the exceptions that +\b+a\ba may not be used to destroy an array vari-
-              able  and  +\b+r\br will not remove the readonly attribute.  When used
+              able and +\b+r\br will not remove the readonly attribute.   When  used
               in a function, d\bde\bec\bcl\bla\bar\bre\be and t\bty\byp\bpe\bes\bse\bet\bt make each _\bn_\ba_\bm_\be local, as with
               the l\blo\boc\bca\bal\bl command, unless the -\b-g\bg option is supplied.  If a vari-
-              able name is followed by =_\bv_\ba_\bl_\bu_\be, the value of  the  variable  is
-              set  to  _\bv_\ba_\bl_\bu_\be.  When using -\b-a\ba or -\b-A\bA and the compound assignment
-              syntax to create array variables, additional attributes  do  not
+              able  name  is  followed by =_\bv_\ba_\bl_\bu_\be, the value of the variable is
+              set to _\bv_\ba_\bl_\bu_\be.  When using -\b-a\ba or -\b-A\bA and the  compound  assignment
+              syntax  to  create array variables, additional attributes do not
               take effect until subsequent assignments.  The return value is 0
-              unless an invalid option is encountered, an attempt is  made  to
-              define  a  function  using ``-f foo=bar'', an attempt is made to
-              assign a value to a readonly variable, an  attempt  is  made  to
-              assign  a  value to an array variable without using the compound
-              assignment syntax (see A\bAr\brr\bra\bay\bys\bs above), one of the _\bn_\ba_\bm_\be_\bs is not  a
-              valid  shell variable name, an attempt is made to turn off read-
-              only status for a readonly variable, an attempt is made to  turn
+              unless  an  invalid option is encountered, an attempt is made to
+              define a function using ``-f foo=bar'', an attempt  is  made  to
+              assign  a  value  to  a readonly variable, an attempt is made to
+              assign a value to an array variable without using  the  compound
+              assignment  syntax (see A\bAr\brr\bra\bay\bys\bs above), one of the _\bn_\ba_\bm_\be_\bs is not a
+              valid shell variable name, an attempt is made to turn off  read-
+              only  status for a readonly variable, an attempt is made to turn
               off array status for an array variable, or an attempt is made to
               display a non-existent function with -\b-f\bf.
 
        d\bdi\bir\brs\bs [\b[-\b-c\bcl\blp\bpv\bv]\b] [\b[+\b+_\bn]\b] [\b[-\b-_\bn]\b]
-              Without options,  displays  the  list  of  currently  remembered
-              directories.   The  default  display  is  on  a single line with
-              directory names separated by spaces.  Directories are  added  to
-              the  list  with  the  p\bpu\bus\bsh\bhd\bd  command;  the  p\bpo\bop\bpd\bd command removes
+              Without  options,  displays  the  list  of  currently remembered
+              directories.  The default display  is  on  a  single  line  with
+              directory  names  separated by spaces.  Directories are added to
+              the list with  the  p\bpu\bus\bsh\bhd\bd  command;  the  p\bpo\bop\bpd\bd  command  removes
               entries from the list.
               -\b-c\bc     Clears  the  directory  stack  by  deleting  all  of  the
                      entries.
-              -\b-l\bl     Produces  a  listing  using  full  pathnames; the default
+              -\b-l\bl     Produces a listing  using  full  pathnames;  the  default
                      listing format uses a tilde to denote the home directory.
               -\b-p\bp     Print the directory stack with one entry per line.
-              -\b-v\bv     Print the directory stack with one entry per  line,  pre-
+              -\b-v\bv     Print  the  directory stack with one entry per line, pre-
                      fixing each entry with its index in the stack.
               +\b+_\bn     Displays the _\bnth entry counting from the left of the list
                      shown by d\bdi\bir\brs\bs when invoked without options, starting with
                      zero.
-              -\b-_\bn     Displays  the  _\bnth  entry  counting from the right of the
+              -\b-_\bn     Displays the _\bnth entry counting from  the  right  of  the
                      list shown by d\bdi\bir\brs\bs when invoked without options, starting
                      with zero.
 
-              The  return value is 0 unless an invalid option is supplied or _\bn
+              The return value is 0 unless an invalid option is supplied or  _\bn
               indexes beyond the end of the directory stack.
 
        d\bdi\bis\bso\bow\bwn\bn [-\b-a\bar\br] [-\b-h\bh] [_\bj_\bo_\bb_\bs_\bp_\be_\bc ...]
-              Without options, remove each _\bj_\bo_\bb_\bs_\bp_\be_\bc from the  table  of  active
-              jobs.   If _\bj_\bo_\bb_\bs_\bp_\be_\bc is not present, and neither the -\b-a\ba nor the -\b-r\br
-              option is supplied, the _\bc_\bu_\br_\br_\be_\bn_\bt _\bj_\bo_\bb is used.  If the  -\b-h\b option
-              is  given,  each  _\bj_\bo_\bb_\bs_\bp_\be_\bc  is not removed from the table, but is
-              marked so that S\bSI\bIG\bGH\bHU\bUP\bP is not  sent  to  the  job  if  the  shell
-              receives  a  S\bSI\bIG\bGH\bHU\bUP\bP.   If  no _\bj_\bo_\bb_\bs_\bp_\be_\bc is supplied, the -\b-a\ba option
-              means to remove or mark all jobs; the -\b-r\br option without  a  _\bj_\bo_\bb_\b-
-              _\bs_\bp_\be_\b argument  restricts operation to running jobs.  The return
+              Without  options,  remove  each _\bj_\bo_\bb_\bs_\bp_\be_\bc from the table of active
+              jobs.  If _\bj_\bo_\bb_\bs_\bp_\be_\bc is not present, and neither the -\b-a\ba nor the  -\b-r\br
+              option  is  supplied, the _\bc_\bu_\br_\br_\be_\bn_\bt _\bj_\bo_\bb is used.  If the -\b-h\bh option
+              is given, each _\bj_\bo_\bb_\bs_\bp_\be_\bc is not removed from  the  table,  but  is
+              marked  so  that  S\bSI\bIG\bGH\bHU\bUP\bP  is  not  sent  to the job if the shell
+              receives a S\bSI\bIG\bGH\bHU\bUP\bP.  If no _\bj_\bo_\bb_\bs_\bp_\be_\bc is  supplied,  the  -\b-a\b option
+              means  to  remove or mark all jobs; the -\b-r\br option without a _\bj_\bo_\bb_\b-
+              _\bs_\bp_\be_\bargument restricts operation to running jobs.   The  return
               value is 0 unless a _\bj_\bo_\bb_\bs_\bp_\be_\bc does not specify a valid job.
 
        e\bec\bch\bho\bo [-\b-n\bne\beE\bE] [_\ba_\br_\bg ...]
-              Output the _\ba_\br_\bgs, separated by spaces,  followed  by  a  newline.
-              The  return  status  is 0 unless a write error occurs.  If -\b-n\bn is
+              Output  the  _\ba_\br_\bgs,  separated  by spaces, followed by a newline.
+              The return status is 0 unless a write error occurs.   If  -\b-n\b is
               specified, the trailing newline is suppressed.  If the -\b-e\be option
-              is  given,  interpretation  of  the  following backslash-escaped
-              characters is enabled.  The -\b-E\bE option disables  the  interpreta-
-              tion  of these escape characters, even on systems where they are
-              interpreted by default.  The x\bxp\bpg\bg_\b_e\bec\bch\bho\bo shell option may  be  used
-              to  dynamically  determine  whether  or  not  e\bec\bch\bho\bo expands these
-              escape characters by default.  e\bec\bch\bho\bo does  not  interpret  -\b--\b to
-              mean  the  end of options.  e\bec\bch\bho\bo interprets the following escape
+              is given,  interpretation  of  the  following  backslash-escaped
+              characters  is  enabled.  The -\b-E\bE option disables the interpreta-
+              tion of these escape characters, even on systems where they  are
+              interpreted  by  default.  The x\bxp\bpg\bg_\b_e\bec\bch\bho\bo shell option may be used
+              to dynamically determine  whether  or  not  e\bec\bch\bho\bo  expands  these
+              escape  characters  by  default.   e\bec\bch\bho\bo does not interpret -\b--\b- to
+              mean the end of options.  e\bec\bch\bho\bo interprets the  following  escape
               sequences:
               \\b\a\ba     alert (bell)
               \\b\b\bb     backspace
@@ -4413,189 +4445,189 @@ S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS
               \\b\t\bt     horizontal tab
               \\b\v\bv     vertical tab
               \\b\\\b\     backslash
-              \\b\0\b0_\bn_\bn_\bn  the eight-bit character whose value is  the  octal  value
+              \\b\0\b0_\bn_\bn_\bn  the  eight-bit  character  whose value is the octal value
                      _\bn_\bn_\bn (zero to three octal digits)
-              \\b\x\bx_\bH_\bH   the  eight-bit  character  whose value is the hexadecimal
+              \\b\x\bx_\bH_\bH   the eight-bit character whose value  is  the  hexadecimal
                      value _\bH_\bH (one or two hex digits)
-              \\b\u\bu_\bH_\bH_\bH_\bH the Unicode (ISO/IEC 10646) character whose value is  the
+              \\b\u\bu_\bH_\bH_\bH_\bH the  Unicode (ISO/IEC 10646) character whose value is the
                      hexadecimal value _\bH_\bH_\bH_\bH (one to four hex digits)
               \\b\U\bU_\bH_\bH_\bH_\bH_\bH_\bH_\bH_\bH
-                     the  Unicode (ISO/IEC 10646) character whose value is the
+                     the Unicode (ISO/IEC 10646) character whose value is  the
                      hexadecimal value _\bH_\bH_\bH_\bH_\bH_\bH_\bH_\bH (one to eight hex digits)
 
        e\ben\bna\bab\bbl\ble\be [-\b-a\ba] [-\b-d\bdn\bnp\bps\bs] [-\b-f\bf _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be] [_\bn_\ba_\bm_\be ...]
-              Enable and disable builtin shell commands.  Disabling a  builtin
+              Enable  and disable builtin shell commands.  Disabling a builtin
               allows a disk command which has the same name as a shell builtin
-              to be executed without specifying a full pathname,  even  though
-              the  shell  normally searches for builtins before disk commands.
-              If -\b-n\bn is used, each  _\bn_\ba_\bm_\be  is  disabled;  otherwise,  _\bn_\ba_\bm_\be_\b are
+              to  be  executed without specifying a full pathname, even though
+              the shell normally searches for builtins before  disk  commands.
+              If  -\b-n\bn  is  used,  each  _\bn_\ba_\bm_\be  is disabled; otherwise, _\bn_\ba_\bm_\be_\bs are
               enabled.  For example, to use the t\bte\bes\bst\bt binary found via the P\bPA\bAT\bTH\bH
-              instead of the shell builtin version, run  ``enable  -n  test''.
-              The  -\b-f\bf  option  means to load the new builtin command _\bn_\ba_\bm_\be from
+              instead  of  the  shell builtin version, run ``enable -n test''.
+              The -\b-f\bf option means to load the new builtin  command  _\bn_\ba_\bm_\b from
               shared object _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be, on systems that support dynamic loading.
-              The  -\b-d\bd  option will delete a builtin previously loaded with -\b-f\bf.
+              The -\b-d\bd option will delete a builtin previously loaded  with  -\b-f\bf.
               If no _\bn_\ba_\bm_\be arguments are given, or if the -\b-p\bp option is supplied,
               a list of shell builtins is printed.  With no other option argu-
-              ments, the list consists of all enabled shell builtins.   If  -\b-n\bn
-              is  supplied, only disabled builtins are printed.  If -\b-a\ba is sup-
-              plied, the list printed includes all builtins, with  an  indica-
-              tion  of whether or not each is enabled.  If -\b-s\bs is supplied, the
-              output is restricted to the POSIX _\bs_\bp_\be_\bc_\bi_\ba_\bl builtins.  The  return
-              value  is  0 unless a _\bn_\ba_\bm_\be is not a shell builtin or there is an
+              ments,  the  list consists of all enabled shell builtins.  If -\b-n\bn
+              is supplied, only disabled builtins are printed.  If -\b-a\ba is  sup-
+              plied,  the  list printed includes all builtins, with an indica-
+              tion of whether or not each is enabled.  If -\b-s\bs is supplied,  the
+              output  is restricted to the POSIX _\bs_\bp_\be_\bc_\bi_\ba_\bl builtins.  The return
+              value is 0 unless a _\bn_\ba_\bm_\be is not a shell builtin or there  is  an
               error loading a new builtin from a shared object.
 
        e\bev\bva\bal\bl [_\ba_\br_\bg ...]
-              The _\ba_\br_\bgs are read and concatenated together into a  single  com-
-              mand.   This command is then read and executed by the shell, and
-              its exit status is returned as the value of e\bev\bva\bal\bl.  If there  are
+              The  _\ba_\br_\bgs  are read and concatenated together into a single com-
+              mand.  This command is then read and executed by the shell,  and
+              its  exit status is returned as the value of e\bev\bva\bal\bl.  If there are
               no _\ba_\br_\bg_\bs, or only null arguments, e\bev\bva\bal\bl returns 0.
 
        e\bex\bxe\bec\bc [-\b-c\bcl\bl] [-\b-a\ba _\bn_\ba_\bm_\be] [_\bc_\bo_\bm_\bm_\ba_\bn_\bd [_\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs]]
-              If  _\bc_\bo_\bm_\bm_\ba_\bn_\bd is specified, it replaces the shell.  No new process
-              is created.  The _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs become the arguments to _\bc_\bo_\bm_\bm_\ba_\bn_\bd.   If
+              If _\bc_\bo_\bm_\bm_\ba_\bn_\bd is specified, it replaces the shell.  No new  process
+              is  created.  The _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs become the arguments to _\bc_\bo_\bm_\bm_\ba_\bn_\bd.  If
               the -\b-l\bl option is supplied, the shell places a dash at the begin-
-              ning of the zeroth argument passed to  _\bc_\bo_\bm_\bm_\ba_\bn_\bd.   This  is  what
+              ning  of  the  zeroth  argument passed to _\bc_\bo_\bm_\bm_\ba_\bn_\bd.  This is what
               _\bl_\bo_\bg_\bi_\bn(1) does.  The -\b-c\bc option causes _\bc_\bo_\bm_\bm_\ba_\bn_\bd to be executed with
-              an empty environment.  If -\b-a\ba is supplied, the shell passes  _\bn_\ba_\bm_\be
+              an  empty environment.  If -\b-a\ba is supplied, the shell passes _\bn_\ba_\bm_\be
               as the zeroth argument to the executed command.  If _\bc_\bo_\bm_\bm_\ba_\bn_\bd can-
-              not be executed for some reason, a non-interactive shell  exits,
-              unless  the  e\bex\bxe\bec\bcf\bfa\bai\bil\bl shell option is enabled.  In that case, it
-              returns failure.  An interactive shell returns  failure  if  the
+              not  be executed for some reason, a non-interactive shell exits,
+              unless the e\bex\bxe\bec\bcf\bfa\bai\bil\bl shell option is enabled.  In that  case,  it
+              returns  failure.   An  interactive shell returns failure if the
               file cannot be executed.  If _\bc_\bo_\bm_\bm_\ba_\bn_\bd is not specified, any redi-
               rections take effect in the current shell, and the return status
               is 0.  If there is a redirection error, the return status is 1.
 
        e\bex\bxi\bit\bt [_\bn]
-              Cause  the  shell  to exit with a status of _\bn.  If _\bn is omitted,
+              Cause the shell to exit with a status of _\bn.  If  _\bn  is  omitted,
               the exit status is that of the last command executed.  A trap on
               E\bEX\bXI\bIT\bT is executed before the shell terminates.
 
        e\bex\bxp\bpo\bor\brt\bt [-\b-f\bfn\bn] [_\bn_\ba_\bm_\be[=_\bw_\bo_\br_\bd]] ...
        e\bex\bxp\bpo\bor\brt\bt -\b-p\bp
-              The  supplied _\bn_\ba_\bm_\be_\bs are marked for automatic export to the envi-
-              ronment of subsequently executed commands.  If the -\b-f\bf option  is
-              given,  the _\bn_\ba_\bm_\be_\bs refer to functions.  If no _\bn_\ba_\bm_\be_\bs are given, or
-              if the -\b-p\bp option is supplied, a list of names  of  all  exported
-              variables  is printed.  The -\b-n\bn option causes the export property
+              The supplied _\bn_\ba_\bm_\be_\bs are marked for automatic export to the  envi-
+              ronment  of subsequently executed commands.  If the -\b-f\bf option is
+              given, the _\bn_\ba_\bm_\be_\bs refer to functions.  If no _\bn_\ba_\bm_\be_\bs are given,  or
+              if  the  -\b-p\bp  option is supplied, a list of names of all exported
+              variables is printed.  The -\b-n\bn option causes the export  property
               to be removed from each _\bn_\ba_\bm_\be.  If a variable name is followed by
               =_\bw_\bo_\br_\bd, the value of the variable is set to _\bw_\bo_\br_\bd.  e\bex\bxp\bpo\bor\brt\bt returns
               an exit status of 0 unless an invalid option is encountered, one
-              of  the  _\bn_\ba_\bm_\be_\bs is not a valid shell variable name, or -\b-f\bf is sup-
+              of the _\bn_\ba_\bm_\be_\bs is not a valid shell variable name, or -\b-f\bf  is  sup-
               plied with a _\bn_\ba_\bm_\be that is not a function.
 
        f\bfc\bc [-\b-e\be _\be_\bn_\ba_\bm_\be] [-\b-l\bln\bnr\br] [_\bf_\bi_\br_\bs_\bt] [_\bl_\ba_\bs_\bt]
        f\bfc\bc -\b-s\bs [_\bp_\ba_\bt=_\br_\be_\bp] [_\bc_\bm_\bd]
-              The first form selects a range of commands from  _\bf_\bi_\br_\bs_\bt  to  _\bl_\ba_\bs_\bt
-              from  the  history  list  and  displays or edits and re-executes
-              them.  _\bF_\bi_\br_\bs_\bt and _\bl_\ba_\bs_\bt may be specified as a  string  (to  locate
-              the  last command beginning with that string) or as a number (an
-              index into the history list, where a negative number is used  as
-              an  offset  from  the  current  command number).  If _\bl_\ba_\bs_\bt is not
-              specified it is set to the current command for listing (so  that
-              ``fc  -l  -10'' prints the last 10 commands) and to _\bf_\bi_\br_\bs_\bt other-
-              wise.  If _\bf_\bi_\br_\bs_\bt is not specified it is set to the previous  com-
+              The  first  form  selects a range of commands from _\bf_\bi_\br_\bs_\bt to _\bl_\ba_\bs_\bt
+              from the history list and  displays  or  edits  and  re-executes
+              them.   _\bF_\bi_\br_\bs_\bt  and  _\bl_\ba_\bs_\bt may be specified as a string (to locate
+              the last command beginning with that string) or as a number  (an
+              index  into the history list, where a negative number is used as
+              an offset from the current command  number).   If  _\bl_\ba_\bs_\bt  is  not
+              specified  it is set to the current command for listing (so that
+              ``fc -l -10'' prints the last 10 commands) and to  _\bf_\bi_\br_\bs_\b other-
+              wise.   If _\bf_\bi_\br_\bs_\bt is not specified it is set to the previous com-
               mand for editing and -16 for listing.
 
-              The  -\b-n\bn option suppresses the command numbers when listing.  The
-              -\b-r\boption reverses the order of the commands.  If the -\b-l\b option
-              is  given,  the  commands are listed on standard output.  Other-
-              wise, the editor given by _\be_\bn_\ba_\bm_\be is invoked on a file  containing
-              those  commands.  If _\be_\bn_\ba_\bm_\be is not given, the value of the F\bFC\bCE\bED\bDI\bIT\bT
-              variable is used, and the value of E\bED\bDI\bIT\bTO\bOR\bR if F\bFC\bCE\bED\bDI\bIT\bT is not  set.
-              If  neither  variable  is set, _\bv_\bi is used.  When editing is com-
+              The -\b-n\bn option suppresses the command numbers when listing.   The
+              -\b-r\b option reverses the order of the commands.  If the -\b-l\bl option
+              is given, the commands are listed on  standard  output.   Other-
+              wise,  the editor given by _\be_\bn_\ba_\bm_\be is invoked on a file containing
+              those commands.  If _\be_\bn_\ba_\bm_\be is not given, the value of the  F\bFC\bCE\bED\bDI\bIT\bT
+              variable  is used, and the value of E\bED\bDI\bIT\bTO\bOR\bR if F\bFC\bCE\bED\bDI\bIT\bT is not set.
+              If neither variable is set, _\bv_\bi is used.  When  editing  is  com-
               plete, the edited commands are echoed and executed.
 
-              In the second form, _\bc_\bo_\bm_\bm_\ba_\bn_\bd is re-executed after  each  instance
-              of  _\bp_\ba_\bt  is  replaced by _\br_\be_\bp.  _\bC_\bo_\bm_\bm_\ba_\bn_\bd is intepreted the same as
-              _\bf_\bi_\br_\bs_\babove.  A useful alias to use with this is ``r="fc  -s"'',
-              so  that  typing  ``r  cc'' runs the last command beginning with
+              In  the  second form, _\bc_\bo_\bm_\bm_\ba_\bn_\bd is re-executed after each instance
+              of _\bp_\ba_\bt is replaced by _\br_\be_\bp.  _\bC_\bo_\bm_\bm_\ba_\bn_\bd is intepreted  the  same  as
+              _\bf_\bi_\br_\bs_\b above.  A useful alias to use with this is ``r="fc -s"'',
+              so that typing ``r cc'' runs the  last  command  beginning  with
               ``cc'' and typing ``r'' re-executes the last command.
 
-              If the first form is used, the  return  value  is  0  unless  an
-              invalid  option  is encountered or _\bf_\bi_\br_\bs_\bt or _\bl_\ba_\bs_\bt specify history
-              lines out of range.  If the -\b-e\be option is  supplied,  the  return
+              If  the  first  form  is  used,  the return value is 0 unless an
+              invalid option is encountered or _\bf_\bi_\br_\bs_\bt or _\bl_\ba_\bs_\bt  specify  history
+              lines  out  of  range.  If the -\b-e\be option is supplied, the return
               value is the value of the last command executed or failure if an
               error occurs with the temporary file of commands.  If the second
-              form  is  used, the return status is that of the command re-exe-
-              cuted, unless _\bc_\bm_\bd does not specify  a  valid  history  line,  in
+              form is used, the return status is that of the  command  re-exe-
+              cuted,  unless  _\bc_\bm_\bd  does  not  specify a valid history line, in
               which case f\bfc\bc returns failure.
 
        f\bfg\bg [_\bj_\bo_\bb_\bs_\bp_\be_\bc]
-              Resume  _\bj_\bo_\bb_\bs_\bp_\be_\bc  in the foreground, and make it the current job.
+              Resume _\bj_\bo_\bb_\bs_\bp_\be_\bc in the foreground, and make it the  current  job.
               If _\bj_\bo_\bb_\bs_\bp_\be_\bc is not present, the shell's notion of the _\bc_\bu_\br_\br_\be_\bn_\bt _\bj_\bo_\bb
-              is  used.   The  return value is that of the command placed into
-              the foreground, or failure if run when job control  is  disabled
+              is used.  The return value is that of the  command  placed  into
+              the  foreground,  or failure if run when job control is disabled
               or, when run with job control enabled, if _\bj_\bo_\bb_\bs_\bp_\be_\bc does not spec-
-              ify a valid job or _\bj_\bo_\bb_\bs_\bp_\be_\bc specifies  a  job  that  was  started
+              ify  a  valid  job  or  _\bj_\bo_\bb_\bs_\bp_\be_\bc specifies a job that was started
               without job control.
 
        g\bge\bet\bto\bop\bpt\bts\bs _\bo_\bp_\bt_\bs_\bt_\br_\bi_\bn_\bg _\bn_\ba_\bm_\be [_\ba_\br_\bg_\bs]
-              g\bge\bet\bto\bop\bpt\bts\b is used by shell procedures to parse positional parame-
-              ters.  _\bo_\bp_\bt_\bs_\bt_\br_\bi_\bn_\bg contains the option  characters  to  be  recog-
-              nized;  if  a  character  is  followed by a colon, the option is
-              expected to have an argument, which should be separated from  it
-              by  white space.  The colon and question mark characters may not
-              be used as option characters.  Each time it is invoked,  g\bge\bet\bto\bop\bpt\bts\bs
-              places  the next option in the shell variable _\bn_\ba_\bm_\be, initializing
+              g\bge\bet\bto\bop\bpt\bts\bis used by shell procedures to parse positional  parame-
+              ters.   _\bo_\bp_\bt_\bs_\bt_\br_\bi_\bn_\bg  contains  the  option characters to be recog-
+              nized; if a character is followed by  a  colon,  the  option  is
+              expected  to have an argument, which should be separated from it
+              by white space.  The colon and question mark characters may  not
+              be  used as option characters.  Each time it is invoked, g\bge\bet\bto\bop\bpt\bts\bs
+              places the next option in the shell variable _\bn_\ba_\bm_\be,  initializing
               _\bn_\ba_\bm_\be if it does not exist, and the index of the next argument to
               be processed into the variable O\bOP\bPT\bTI\bIN\bND\bD.  O\bOP\bPT\bTI\bIN\bND\bD is initialized to
-              1 each time the shell or a shell script  is  invoked.   When  an
-              option  requires  an argument, g\bge\bet\bto\bop\bpt\bts\bs places that argument into
-              the variable O\bOP\bPT\bTA\bAR\bRG\bG.  The shell does not reset O\bOP\bPT\bTI\bIN\bND\b automati-
-              cally;  it  must  be  manually  reset  between multiple calls to
+              1  each  time  the  shell or a shell script is invoked.  When an
+              option requires an argument, g\bge\bet\bto\bop\bpt\bts\bs places that  argument  into
+              the  variable O\bOP\bPT\bTA\bAR\bRG\bG.  The shell does not reset O\bOP\bPT\bTI\bIN\bND\bD automati-
+              cally; it must be  manually  reset  between  multiple  calls  to
               g\bge\bet\bto\bop\bpt\bts\bs within the same shell invocation if a new set of parame-
               ters is to be used.
 
-              When  the  end  of  options is encountered, g\bge\bet\bto\bop\bpt\bts\bs exits with a
-              return value greater than zero.  O\bOP\bPT\bTI\bIN\bND\bD is set to the  index  of
+              When the end of options is encountered,  g\bge\bet\bto\bop\bpt\bts\bs  exits  with  a
+              return  value  greater than zero.  O\bOP\bPT\bTI\bIN\bND\bD is set to the index of
               the first non-option argument, and _\bn_\ba_\bm_\be is set to ?.
 
-              g\bge\bet\bto\bop\bpt\bts\b normally  parses the positional parameters, but if more
+              g\bge\bet\bto\bop\bpt\bts\bnormally parses the positional parameters, but  if  more
               arguments are given in _\ba_\br_\bg_\bs, g\bge\bet\bto\bop\bpt\bts\bs parses those instead.
 
-              g\bge\bet\bto\bop\bpt\bts\bcan report errors in two ways.  If the  first  character
-              of  _\bo_\bp_\bt_\bs_\bt_\br_\bi_\bn_\bg  is  a  colon, _\bs_\bi_\bl_\be_\bn_\bt error reporting is used.  In
-              normal operation, diagnostic messages are printed  when  invalid
-              options  or  missing  option  arguments are encountered.  If the
-              variable O\bOP\bPT\bTE\bER\bRR\bR is set to 0, no  error  messages  will  be  dis-
+              g\bge\bet\bto\bop\bpt\bts\b can  report errors in two ways.  If the first character
+              of _\bo_\bp_\bt_\bs_\bt_\br_\bi_\bn_\bg is a colon, _\bs_\bi_\bl_\be_\bn_\bt error  reporting  is  used.   In
+              normal  operation,  diagnostic messages are printed when invalid
+              options or missing option arguments  are  encountered.   If  the
+              variable  O\bOP\bPT\bTE\bER\bRR\bR  is  set  to  0, no error messages will be dis-
               played, even if the first character of _\bo_\bp_\bt_\bs_\bt_\br_\bi_\bn_\bg is not a colon.
 
               If an invalid option is seen, g\bge\bet\bto\bop\bpt\bts\bs places ? into _\bn_\ba_\bm_\be and, if
-              not silent, prints an  error  message  and  unsets  O\bOP\bPT\bTA\bAR\bRG\bG.   If
-              g\bge\bet\bto\bop\bpt\bts\b is  silent,  the  option  character  found is placed in
+              not  silent,  prints  an  error  message  and unsets O\bOP\bPT\bTA\bAR\bRG\bG.  If
+              g\bge\bet\bto\bop\bpt\bts\bis silent, the  option  character  found  is  placed  in
               O\bOP\bPT\bTA\bAR\bRG\bG and no diagnostic message is printed.
 
-              If a required argument is not found, and g\bge\bet\bto\bop\bpt\bts\bs is not  silent,
-              a  question  mark  (?\b?) is placed in _\bn_\ba_\bm_\be, O\bOP\bPT\bTA\bAR\bRG\bG is unset, and a
-              diagnostic message is printed.  If g\bge\bet\bto\bop\bpt\bts\bs  is  silent,  then  a
-              colon  (:\b:)  is  placed  in  _\bn_\ba_\bm_\be and O\bOP\bPT\bTA\bAR\bRG\bG is set to the option
+              If  a required argument is not found, and g\bge\bet\bto\bop\bpt\bts\bs is not silent,
+              a question mark (?\b?) is placed in _\bn_\ba_\bm_\be, O\bOP\bPT\bTA\bAR\bRG\bG is  unset,  and  a
+              diagnostic  message  is  printed.   If g\bge\bet\bto\bop\bpt\bts\bs is silent, then a
+              colon (:\b:) is placed in _\bn_\ba_\bm_\be and O\bOP\bPT\bTA\bAR\bRG\bG  is  set  to  the  option
               character found.
 
-              g\bge\bet\bto\bop\bpt\bts\breturns true if an option, specified or unspecified,  is
+              g\bge\bet\bto\bop\bpt\bts\b returns true if an option, specified or unspecified, is
               found.  It returns false if the end of options is encountered or
               an error occurs.
 
        h\bha\bas\bsh\bh [-\b-l\blr\br] [-\b-p\bp _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be] [-\b-d\bdt\bt] [_\bn_\ba_\bm_\be]
               Each time h\bha\bas\bsh\bh is invoked, the full pathname of the command _\bn_\ba_\bm_\be
-              is  determined  by searching the directories in $\b$P\bPA\bAT\bTH\bH and remem-
+              is determined by searching the directories in $\b$P\bPA\bAT\bTH\bH  and  remem-
               bered.  Any previously-remembered pathname is discarded.  If the
               -\b-p\bp option is supplied, no path search is performed, and _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be
-              is used as the full filename of  the  command.   The  -\b-r\b option
-              causes  the  shell  to  forget all remembered locations.  The -\b-d\bd
-              option causes the shell to forget  the  remembered  location  of
-              each  _\bn_\ba_\bm_\be.   If the -\b-t\bt option is supplied, the full pathname to
-              which each _\bn_\ba_\bm_\be corresponds is printed.  If multiple _\bn_\ba_\bm_\b argu-
-              ments  are  supplied  with  -\b-t\bt,  the  _\bn_\ba_\bm_\be is printed before the
-              hashed full pathname.  The -\b-l\bl option causes output  to  be  dis-
+              is  used  as  the  full  filename of the command.  The -\b-r\br option
+              causes the shell to forget all  remembered  locations.   The  -\b-d\bd
+              option  causes  the  shell  to forget the remembered location of
+              each _\bn_\ba_\bm_\be.  If the -\b-t\bt option is supplied, the full  pathname  to
+              which  each _\bn_\ba_\bm_\be corresponds is printed.  If multiple _\bn_\ba_\bm_\be argu-
+              ments are supplied with -\b-t\bt,  the  _\bn_\ba_\bm_\be  is  printed  before  the
+              hashed  full  pathname.   The -\b-l\bl option causes output to be dis-
               played in a format that may be reused as input.  If no arguments
-              are given, or if only -\b-l\bl is supplied, information  about  remem-
-              bered  commands  is printed.  The return status is true unless a
+              are  given,  or if only -\b-l\bl is supplied, information about remem-
+              bered commands is printed.  The return status is true  unless  a
               _\bn_\ba_\bm_\be is not found or an invalid option is supplied.
 
        h\bhe\bel\blp\bp [-\b-d\bdm\bms\bs] [_\bp_\ba_\bt_\bt_\be_\br_\bn]
-              Display helpful information about builtin commands.  If  _\bp_\ba_\bt_\bt_\be_\br_\bn
-              is  specified, h\bhe\bel\blp\bp gives detailed help on all commands matching
-              _\bp_\ba_\bt_\bt_\be_\br_\bn; otherwise help for all the builtins and  shell  control
+              Display  helpful information about builtin commands.  If _\bp_\ba_\bt_\bt_\be_\br_\bn
+              is specified, h\bhe\bel\blp\bp gives detailed help on all commands  matching
+              _\bp_\ba_\bt_\bt_\be_\br_\bn;  otherwise  help for all the builtins and shell control
               structures is printed.
               -\b-d\bd     Display a short description of each _\bp_\ba_\bt_\bt_\be_\br_\bn
               -\b-m\bm     Display the description of each _\bp_\ba_\bt_\bt_\be_\br_\bn in a manpage-like
@@ -4612,44 +4644,44 @@ S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS
        h\bhi\bis\bst\bto\bor\bry\by -\b-s\bs _\ba_\br_\bg [_\ba_\br_\bg _\b._\b._\b.]
               With no options, display the command history list with line num-
               bers.  Lines listed with a *\b* have been modified.  An argument of
-              _\blists only the last _\bn lines.  If the shell variable  H\bHI\bIS\bST\bTT\bTI\bIM\bME\bE-\b-
-              F\bFO\bOR\bRM\bMA\bAT\b is  set  and not null, it is used as a format string for
-              _\bs_\bt_\br_\bf_\bt_\bi_\bm_\be(3) to display the time stamp associated with each  dis-
-              played  history  entry.  No intervening blank is printed between
-              the formatted time stamp and the history line.  If  _\bf_\bi_\bl_\be_\bn_\ba_\bm_\b is
-              supplied,  it  is  used as the name of the history file; if not,
-              the value of H\bHI\bIS\bST\bTF\bFI\bIL\bLE\bE is used.  Options, if supplied,  have  the
+              _\b lists only the last _\bn lines.  If the shell variable H\bHI\bIS\bST\bTT\bTI\bIM\bME\bE-\b-
+              F\bFO\bOR\bRM\bMA\bAT\bis set and not null, it is used as a  format  string  for
+              _\bs_\bt_\br_\bf_\bt_\bi_\bm_\be(3)  to display the time stamp associated with each dis-
+              played history entry.  No intervening blank is  printed  between
+              the  formatted  time stamp and the history line.  If _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be is
+              supplied, it is used as the name of the history  file;  if  not,
+              the  value  of H\bHI\bIS\bST\bTF\bFI\bIL\bLE\bE is used.  Options, if supplied, have the
               following meanings:
               -\b-c\bc     Clear the history list by deleting all the entries.
               -\b-d\bd _\bo_\bf_\bf_\bs_\be_\bt
                      Delete the history entry at position _\bo_\bf_\bf_\bs_\be_\bt.
-              -\b-a\ba     Append  the  ``new'' history lines (history lines entered
-                     since the beginning of the current b\bba\bas\bsh\bh session)  to  the
+              -\b-a\ba     Append the ``new'' history lines (history  lines  entered
+                     since  the  beginning of the current b\bba\bas\bsh\bh session) to the
                      history file.
-              -\b-n\bn     Read  the history lines not already read from the history
-                     file into the current  history  list.   These  are  lines
-                     appended  to  the history file since the beginning of the
+              -\b-n\bn     Read the history lines not already read from the  history
+                     file  into  the  current  history  list.  These are lines
+                     appended to the history file since the beginning  of  the
                      current b\bba\bas\bsh\bh session.
-              -\b-r\br     Read the contents of the history file and append them  to
+              -\b-r\br     Read  the contents of the history file and append them to
                      the current history list.
               -\b-w\bw     Write the current history list to the history file, over-
                      writing the history file's contents.
-              -\b-p\bp     Perform history substitution on the  following  _\ba_\br_\bg_\b and
-                     display  the  result  on  the  standard output.  Does not
-                     store the results in the history list.  Each _\ba_\br_\bg must  be
+              -\b-p\bp     Perform  history  substitution  on the following _\ba_\br_\bg_\bs and
+                     display the result on  the  standard  output.   Does  not
+                     store  the results in the history list.  Each _\ba_\br_\bg must be
                      quoted to disable normal history expansion.
-              -\b-s\bs     Store  the  _\ba_\br_\bg_\bs  in  the history list as a single entry.
-                     The last command in the history list  is  removed  before
+              -\b-s\bs     Store the _\ba_\br_\bg_\bs in the history list  as  a  single  entry.
+                     The  last  command  in the history list is removed before
                      the _\ba_\br_\bg_\bs are added.
 
-              If  the  H\bHI\bIS\bST\bTT\bTI\bIM\bME\bEF\bFO\bOR\bRM\bMA\bAT\bT variable is set, the time stamp informa-
-              tion associated with each history entry is written to  the  his-
-              tory  file, marked with the history comment character.  When the
-              history file is read, lines beginning with the  history  comment
-              character  followed  immediately  by  a digit are interpreted as
+              If the H\bHI\bIS\bST\bTT\bTI\bIM\bME\bEF\bFO\bOR\bRM\bMA\bAT\bT variable is set, the time  stamp  informa-
+              tion  associated  with each history entry is written to the his-
+              tory file, marked with the history comment character.  When  the
+              history  file  is read, lines beginning with the history comment
+              character followed immediately by a  digit  are  interpreted  as
               timestamps for the previous history line.  The return value is 0
-              unless  an  invalid option is encountered, an error occurs while
-              reading or writing the history file, an invalid _\bo_\bf_\bf_\bs_\be_\bt  is  sup-
+              unless an invalid option is encountered, an error  occurs  while
+              reading  or  writing the history file, an invalid _\bo_\bf_\bf_\bs_\be_\bt is sup-
               plied as an argument to -\b-d\bd, or the history expansion supplied as
               an argument to -\b-p\bp fails.
 
@@ -4658,201 +4690,201 @@ S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS
               The first form lists the active jobs.  The options have the fol-
               lowing meanings:
               -\b-l\bl     List process IDs in addition to the normal information.
-              -\b-n\bn     Display  information  only  about  jobs that have changed
+              -\b-n\bn     Display information only about  jobs  that  have  changed
                      status since the user was last notified of their status.
-              -\b-p\bp     List only the process  ID  of  the  job's  process  group
+              -\b-p\bp     List  only  the  process  ID  of  the job's process group
                      leader.
               -\b-r\br     Display only running jobs.
               -\b-s\bs     Display only stopped jobs.
 
-              If  _\bj_\bo_\bb_\bs_\bp_\be_\bc  is given, output is restricted to information about
-              that job.  The return status is 0 unless an  invalid  option  is
+              If _\bj_\bo_\bb_\bs_\bp_\be_\bc is given, output is restricted to  information  about
+              that  job.   The  return status is 0 unless an invalid option is
               encountered or an invalid _\bj_\bo_\bb_\bs_\bp_\be_\bc is supplied.
 
               If the -\b-x\bx option is supplied, j\bjo\bob\bbs\bs replaces any _\bj_\bo_\bb_\bs_\bp_\be_\bc found in
-              _\bc_\bo_\bm_\bm_\ba_\bn_\bor _\ba_\br_\bg_\bs with the corresponding  process  group  ID,  and
+              _\bc_\bo_\bm_\bm_\ba_\bn_\b or  _\ba_\br_\bg_\bs  with  the corresponding process group ID, and
               executes _\bc_\bo_\bm_\bm_\ba_\bn_\bd passing it _\ba_\br_\bg_\bs, returning its exit status.
 
        k\bki\bil\bll\bl [-\b-s\bs _\bs_\bi_\bg_\bs_\bp_\be_\bc | -\b-n\bn _\bs_\bi_\bg_\bn_\bu_\bm | -\b-_\bs_\bi_\bg_\bs_\bp_\be_\bc] [_\bp_\bi_\bd | _\bj_\bo_\bb_\bs_\bp_\be_\bc] ...
        k\bki\bil\bll\bl -\b-l\bl [_\bs_\bi_\bg_\bs_\bp_\be_\bc | _\be_\bx_\bi_\bt_\b__\bs_\bt_\ba_\bt_\bu_\bs]
-              Send  the  signal  named  by  _\bs_\bi_\bg_\bs_\bp_\be_\bc or _\bs_\bi_\bg_\bn_\bu_\bm to the processes
-              named by _\bp_\bi_\bd or _\bj_\bo_\bb_\bs_\bp_\be_\bc.  _\bs_\bi_\bg_\bs_\bp_\be_\bc is either  a  case-insensitive
-              signal  name such as S\bSI\bIG\bGK\bKI\bIL\bLL\bL (with or without the S\bSI\bIG\bG prefix) or
-              a signal number; _\bs_\bi_\bg_\bn_\bu_\bm is a signal number.  If _\bs_\bi_\bg_\bs_\bp_\be_\bc  is  not
-              present,  then  S\bSI\bIG\bGT\bTE\bER\bRM\bM is assumed.  An argument of -\b-l\bl lists the
-              signal names.  If any arguments are supplied when -\b-l\bl  is  given,
-              the  names  of  the  signals  corresponding to the arguments are
+              Send the signal named by _\bs_\bi_\bg_\bs_\bp_\be_\bc  or  _\bs_\bi_\bg_\bn_\bu_\bm  to  the  processes
+              named  by  _\bp_\bi_\bd or _\bj_\bo_\bb_\bs_\bp_\be_\bc.  _\bs_\bi_\bg_\bs_\bp_\be_\bc is either a case-insensitive
+              signal name such as S\bSI\bIG\bGK\bKI\bIL\bLL\bL (with or without the S\bSI\bIG\bG prefix)  or
+              a  signal  number; _\bs_\bi_\bg_\bn_\bu_\bm is a signal number.  If _\bs_\bi_\bg_\bs_\bp_\be_\bc is not
+              present, then S\bSI\bIG\bGT\bTE\bER\bRM\bM is assumed.  An argument of -\b-l\bl  lists  the
+              signal  names.   If any arguments are supplied when -\b-l\bl is given,
+              the names of the signals  corresponding  to  the  arguments  are
               listed, and the return status is 0.  The _\be_\bx_\bi_\bt_\b__\bs_\bt_\ba_\bt_\bu_\bs argument to
-              -\b-l\b is  a  number  specifying either a signal number or the exit
-              status of a process terminated by a signal.  k\bki\bil\bll\bl  returns  true
-              if  at  least  one  signal was successfully sent, or false if an
+              -\b-l\bis a number specifying either a signal  number  or  the  exit
+              status  of  a process terminated by a signal.  k\bki\bil\bll\bl returns true
+              if at least one signal was successfully sent,  or  false  if  an
               error occurs or an invalid option is encountered.
 
        l\ble\bet\bt _\ba_\br_\bg [_\ba_\br_\bg ...]
               Each _\ba_\br_\bg is an arithmetic expression to be evaluated (see A\bAR\bRI\bIT\bTH\bH-\b-
-              M\bME\bET\bTI\bIC\b E\bEV\bVA\bAL\bLU\bUA\bAT\bTI\bIO\bON\bN  above).   If the last _\ba_\br_\bg evaluates to 0, l\ble\bet\bt
+              M\bME\bET\bTI\bIC\bE\bEV\bVA\bAL\bLU\bUA\bAT\bTI\bIO\bON\bN above).  If the last _\ba_\br_\bg evaluates  to  0,  l\ble\bet\bt
               returns 1; 0 is returned otherwise.
 
        l\blo\boc\bca\bal\bl [_\bo_\bp_\bt_\bi_\bo_\bn] [_\bn_\ba_\bm_\be[=_\bv_\ba_\bl_\bu_\be] ...]
-              For each argument, a local variable named _\bn_\ba_\bm_\be is  created,  and
-              assigned  _\bv_\ba_\bl_\bu_\be.   The _\bo_\bp_\bt_\bi_\bo_\bn can be any of the options accepted
+              For  each  argument, a local variable named _\bn_\ba_\bm_\be is created, and
+              assigned _\bv_\ba_\bl_\bu_\be.  The _\bo_\bp_\bt_\bi_\bo_\bn can be any of the  options  accepted
               by d\bde\bec\bcl\bla\bar\bre\be.  When l\blo\boc\bca\bal\bl is used within a function, it causes the
-              variable  _\bn_\ba_\bm_\be  to have a visible scope restricted to that func-
+              variable _\bn_\ba_\bm_\be to have a visible scope restricted to  that  func-
               tion and its children.  With no operands, l\blo\boc\bca\bal\bl writes a list of
-              local  variables  to the standard output.  It is an error to use
+              local variables to the standard output.  It is an error  to  use
               l\blo\boc\bca\bal\bl when not within a function.  The return status is 0 unless
-              l\blo\boc\bca\bal\b is  used outside a function, an invalid _\bn_\ba_\bm_\be is supplied,
+              l\blo\boc\bca\bal\bis used outside a function, an invalid _\bn_\ba_\bm_\be  is  supplied,
               or _\bn_\ba_\bm_\be is a readonly variable.
 
        l\blo\bog\bgo\bou\but\bt Exit a login shell.
 
-       m\bma\bap\bpf\bfi\bil\ble\b[-\b-d\bd _\bd_\be_\bl_\bi_\bm] [-\b-n\bn _\bc_\bo_\bu_\bn_\bt] [-\b-O\bO _\bo_\br_\bi_\bg_\bi_\bn] [-\b-s\bs _\bc_\bo_\bu_\bn_\bt] [-\b-t\bt] [-\b-u\bu  _\bf_\bd]  [-\b-C\bC
+       m\bma\bap\bpf\bfi\bil\ble\b [-\b-d\bd  _\bd_\be_\bl_\bi_\bm] [-\b-n\bn _\bc_\bo_\bu_\bn_\bt] [-\b-O\bO _\bo_\br_\bi_\bg_\bi_\bn] [-\b-s\bs _\bc_\bo_\bu_\bn_\bt] [-\b-t\bt] [-\b-u\bu _\bf_\bd] [-\b-C\bC
        _\bc_\ba_\bl_\bl_\bb_\ba_\bc_\bk] [-\b-c\bc _\bq_\bu_\ba_\bn_\bt_\bu_\bm] [_\ba_\br_\br_\ba_\by]
        r\bre\bea\bad\bda\bar\brr\bra\bay\by [-\b-d\bd _\bd_\be_\bl_\bi_\bm] [-\b-n\bn _\bc_\bo_\bu_\bn_\bt] [-\b-O\bO _\bo_\br_\bi_\bg_\bi_\bn] [-\b-s\bs _\bc_\bo_\bu_\bn_\bt] [-\b-t\bt] [-\b-u\bu _\bf_\bd] [-\b-C\bC
        _\bc_\ba_\bl_\bl_\bb_\ba_\bc_\bk] [-\b-c\bc _\bq_\bu_\ba_\bn_\bt_\bu_\bm] [_\ba_\br_\br_\ba_\by]
-              Read lines from the standard input into the indexed array  vari-
-              able  _\ba_\br_\br_\ba_\by, or from file descriptor _\bf_\bd if the -\b-u\bu option is sup-
-              plied.  The variable M\bMA\bAP\bPF\bFI\bIL\bLE\bE is the default _\ba_\br_\br_\ba_\by.  Options,  if
+              Read  lines from the standard input into the indexed array vari-
+              able _\ba_\br_\br_\ba_\by, or from file descriptor _\bf_\bd if the -\b-u\bu option is  sup-
+              plied.   The variable M\bMA\bAP\bPF\bFI\bIL\bLE\bE is the default _\ba_\br_\br_\ba_\by.  Options, if
               supplied, have the following meanings:
-              -\b-d\bd     The  first  character  of _\bd_\be_\bl_\bi_\bm is used to terminate each
+              -\b-d\bd     The first character of _\bd_\be_\bl_\bi_\bm is used  to  terminate  each
                      input line, rather than newline.
-              -\b-n\bn     Copy at most _\bc_\bo_\bu_\bn_\bt lines.  If _\bc_\bo_\bu_\bn_\bt is 0, all  lines  are
+              -\b-n\bn     Copy  at  most _\bc_\bo_\bu_\bn_\bt lines.  If _\bc_\bo_\bu_\bn_\bt is 0, all lines are
                      copied.
-              -\b-O\bO     Begin  assigning  to  _\ba_\br_\br_\ba_\by at index _\bo_\br_\bi_\bg_\bi_\bn.  The default
+              -\b-O\bO     Begin assigning to _\ba_\br_\br_\ba_\by at index  _\bo_\br_\bi_\bg_\bi_\bn.   The  default
                      index is 0.
               -\b-s\bs     Discard the first _\bc_\bo_\bu_\bn_\bt lines read.
               -\b-t\bt     Remove a trailing newline from each line read.
-              -\b-u\bu     Read lines from file descriptor _\bf_\bd instead of  the  stan-
+              -\b-u\bu     Read  lines  from file descriptor _\bf_\bd instead of the stan-
                      dard input.
-              -\b-C\bC     Evaluate  _\bc_\ba_\bl_\bl_\bb_\ba_\bc_\bk each time _\bq_\bu_\ba_\bn_\bt_\bu_\bm lines are read.  The
+              -\b-C\bC     Evaluate _\bc_\ba_\bl_\bl_\bb_\ba_\bc_\bk each time _\bq_\bu_\ba_\bn_\bt_\bu_\bm lines are read.   The
                      -\b-c\bc option specifies _\bq_\bu_\ba_\bn_\bt_\bu_\bm.
-              -\b-c\bc     Specify the number of lines read  between  each  call  to
+              -\b-c\bc     Specify  the  number  of  lines read between each call to
                      _\bc_\ba_\bl_\bl_\bb_\ba_\bc_\bk.
 
-              If  -\b-C\bC  is  specified  without  -\b-c\bc, the default quantum is 5000.
+              If -\b-C\bC is specified without -\b-c\bc,  the  default  quantum  is  5000.
               When _\bc_\ba_\bl_\bl_\bb_\ba_\bc_\bk is evaluated, it is supplied the index of the next
               array element to be assigned and the line to be assigned to that
-              element as additional arguments.  _\bc_\ba_\bl_\bl_\bb_\ba_\bc_\bk  is  evaluated  after
+              element  as  additional  arguments.  _\bc_\ba_\bl_\bl_\bb_\ba_\bc_\bk is evaluated after
               the line is read but before the array element is assigned.
 
-              If  not  supplied  with  an  explicit origin, m\bma\bap\bpf\bfi\bil\ble\be will clear
+              If not supplied with an  explicit  origin,  m\bma\bap\bpf\bfi\bil\ble\be  will  clear
               _\ba_\br_\br_\ba_\by before assigning to it.
 
-              m\bma\bap\bpf\bfi\bil\ble\breturns successfully unless an invalid option or  option
-              argument  is  supplied,  _\ba_\br_\br_\ba_\by is invalid or unassignable, or if
+              m\bma\bap\bpf\bfi\bil\ble\b returns successfully unless an invalid option or option
+              argument is supplied, _\ba_\br_\br_\ba_\by is invalid or  unassignable,  or  if
               _\ba_\br_\br_\ba_\by is not an indexed array.
 
        p\bpo\bop\bpd\bd [-n\bn] [+_\bn] [-_\bn]
-              Removes entries from the directory stack.   With  no  arguments,
-              removes  the  top directory from the stack, and performs a c\bcd\bd to
+              Removes  entries  from  the directory stack.  With no arguments,
+              removes the top directory from the stack, and performs a  c\bcd\b to
               the new top directory.  Arguments, if supplied, have the follow-
               ing meanings:
-              -\b-n\bn     Suppresses  the  normal change of directory when removing
-                     directories from the stack, so that  only  the  stack  is
+              -\b-n\bn     Suppresses the normal change of directory  when  removing
+                     directories  from  the  stack,  so that only the stack is
                      manipulated.
-              +\b+_\bn     Removes  the _\bnth entry counting from the left of the list
-                     shown by d\bdi\bir\brs\bs, starting with zero.  For  example:  ``popd
+              +\b+_\bn     Removes the _\bnth entry counting from the left of the  list
+                     shown  by  d\bdi\bir\brs\bs, starting with zero.  For example: ``popd
                      +0'' removes the first directory, ``popd +1'' the second.
               -\b-_\bn     Removes the _\bnth entry counting from the right of the list
-                     shown by d\bdi\bir\brs\bs, starting with zero.  For  example:  ``popd
-                     -0''  removes the last directory, ``popd -1'' the next to
+                     shown  by  d\bdi\bir\brs\bs, starting with zero.  For example: ``popd
+                     -0'' removes the last directory, ``popd -1'' the next  to
                      last.
 
-              If the p\bpo\bop\bpd\bd command is successful, a d\bdi\bir\brs\bs is performed as  well,
-              and  the  return  status is 0.  p\bpo\bop\bpd\bd returns false if an invalid
+              If  the p\bpo\bop\bpd\bd command is successful, a d\bdi\bir\brs\bs is performed as well,
+              and the return status is 0.  p\bpo\bop\bpd\bd returns false  if  an  invalid
               option is encountered, the directory stack is empty, a non-exis-
               tent directory stack entry is specified, or the directory change
               fails.
 
        p\bpr\bri\bin\bnt\btf\bf [-\b-v\bv _\bv_\ba_\br] _\bf_\bo_\br_\bm_\ba_\bt [_\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs]
-              Write the formatted _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs to the standard output  under  the
-              control  of  the  _\bf_\bo_\br_\bm_\ba_\bt.  The -\b-v\bv option causes the output to be
-              assigned to the variable _\bv_\ba_\br rather than being  printed  to  the
+              Write  the  formatted _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs to the standard output under the
+              control of the _\bf_\bo_\br_\bm_\ba_\bt.  The -\b-v\bv option causes the  output  to  be
+              assigned  to  the  variable _\bv_\ba_\br rather than being printed to the
               standard output.
 
-              The  _\bf_\bo_\br_\bm_\ba_\bt  is a character string which contains three types of
-              objects: plain characters, which are simply copied  to  standard
-              output,  character  escape  sequences,  which  are converted and
-              copied to the standard output, and format  specifications,  each
-              of  which  causes  printing of the next successive _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt.  In
+              The _\bf_\bo_\br_\bm_\ba_\bt is a character string which contains three  types  of
+              objects:  plain  characters, which are simply copied to standard
+              output, character escape  sequences,  which  are  converted  and
+              copied  to  the standard output, and format specifications, each
+              of which causes printing of the next  successive  _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt.   In
               addition to the standard _\bp_\br_\bi_\bn_\bt_\bf(1) format specifications, p\bpr\bri\bin\bnt\btf\bf
               interprets the following extensions:
               %\b%b\bb     causes p\bpr\bri\bin\bnt\btf\bf to expand backslash escape sequences in the
                      corresponding _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt (except that \\b\c\bc terminates output,
-                     backslashes  in \\b\'\b', \\b\"\b", and \\b\?\b? are not removed, and octal
+                     backslashes in \\b\'\b', \\b\"\b", and \\b\?\b? are not removed, and  octal
                      escapes beginning with \\b\0\b0 may contain up to four digits).
-              %\b%q\bq     causes p\bpr\bri\bin\bnt\btf\bf to output the corresponding _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt  in  a
+              %\b%q\bq     causes  p\bpr\bri\bin\bnt\btf\bf  to output the corresponding _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt in a
                      format that can be reused as shell input.
               %\b%(\b(_\bd_\ba_\bt_\be_\bf_\bm_\bt)\b)T\bT
-                     causes  p\bpr\bri\bin\bnt\btf\bf  to  output the date-time string resulting
-                     from using _\bd_\ba_\bt_\be_\bf_\bm_\bt as a format  string  for  _\bs_\bt_\br_\bf_\bt_\bi_\bm_\be(3).
+                     causes p\bpr\bri\bin\bnt\btf\bf to output the  date-time  string  resulting
+                     from  using  _\bd_\ba_\bt_\be_\bf_\bm_\bt  as a format string for _\bs_\bt_\br_\bf_\bt_\bi_\bm_\be(3).
                      The corresponding _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt is an integer representing the
-                     number of seconds since the epoch.  Two special  argument
-                     values  may  be used: -1 represents the current time, and
-                     -2 represents the time the  shell  was  invoked.   If  no
-                     argument  is  specified,  conversion behaves as if -1 had
-                     been given.  This is an exception  to  the  usual  p\bpr\bri\bin\bnt\btf\bf
+                     number  of seconds since the epoch.  Two special argument
+                     values may be used: -1 represents the current  time,  and
+                     -2  represents  the  time  the  shell was invoked.  If no
+                     argument is specified, conversion behaves as  if  -1  had
+                     been  given.   This  is  an exception to the usual p\bpr\bri\bin\bnt\btf\bf
                      behavior.
 
-              Arguments  to non-string format specifiers are treated as C con-
+              Arguments to non-string format specifiers are treated as C  con-
               stants, except that a leading plus or minus sign is allowed, and
-              if  the leading character is a single or double quote, the value
+              if the leading character is a single or double quote, the  value
               is the ASCII value of the following character.
 
-              The _\bf_\bo_\br_\bm_\ba_\bt is reused as necessary to consume all  of  the  _\ba_\br_\bg_\bu_\b-
+              The  _\bf_\bo_\br_\bm_\ba_\bt  is  reused as necessary to consume all of the _\ba_\br_\bg_\bu_\b-
               _\bm_\be_\bn_\bt_\bs.  If the _\bf_\bo_\br_\bm_\ba_\bt requires more _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs than are supplied,
-              the extra format specifications behave as if  a  zero  value  or
-              null  string,  as  appropriate,  had  been supplied.  The return
+              the  extra  format  specifications  behave as if a zero value or
+              null string, as appropriate,  had  been  supplied.   The  return
               value is zero on success, non-zero on failure.
 
        p\bpu\bus\bsh\bhd\bd [-\b-n\bn] [+_\bn] [-_\bn]
        p\bpu\bus\bsh\bhd\bd [-\b-n\bn] [_\bd_\bi_\br]
-              Adds a directory to the top of the directory stack,  or  rotates
-              the  stack,  making the new top of the stack the current working
+              Adds  a  directory to the top of the directory stack, or rotates
+              the stack, making the new top of the stack the  current  working
               directory.  With no arguments, exchanges the top two directories
-              and  returns 0, unless the directory stack is empty.  Arguments,
+              and returns 0, unless the directory stack is empty.   Arguments,
               if supplied, have the following meanings:
-              -\b-n\bn     Suppresses the normal change  of  directory  when  adding
-                     directories  to  the  stack,  so  that  only the stack is
+              -\b-n\bn     Suppresses  the  normal  change  of directory when adding
+                     directories to the stack,  so  that  only  the  stack  is
                      manipulated.
-              +\b+_\bn     Rotates the stack so that  the  _\bnth  directory  (counting
-                     from  the  left  of the list shown by d\bdi\bir\brs\bs, starting with
+              +\b+_\bn     Rotates  the  stack  so  that the _\bnth directory (counting
+                     from the left of the list shown by  d\bdi\bir\brs\bs,  starting  with
                      zero) is at the top.
-              -\b-_\bn     Rotates the stack so that  the  _\bnth  directory  (counting
-                     from  the  right of the list shown by d\bdi\bir\brs\bs, starting with
+              -\b-_\bn     Rotates  the  stack  so  that the _\bnth directory (counting
+                     from the right of the list shown by d\bdi\bir\brs\bs,  starting  with
                      zero) is at the top.
               _\bd_\bi_\br    Adds _\bd_\bi_\br to the directory stack at the top, making it the
-                     new  current working directory as if it had been supplied
+                     new current working directory as if it had been  supplied
                      as the argument to the c\bcd\bd builtin.
 
               If the p\bpu\bus\bsh\bhd\bd command is successful, a d\bdi\bir\brs\bs is performed as well.
-              If  the first form is used, p\bpu\bus\bsh\bhd\bd returns 0 unless the cd to _\bd_\bi_\br
-              fails.  With the second form, p\bpu\bus\bsh\bhd\bd returns 0 unless the  direc-
-              tory  stack  is empty, a non-existent directory stack element is
-              specified, or the directory change to the specified new  current
+              If the first form is used, p\bpu\bus\bsh\bhd\bd returns 0 unless the cd to  _\bd_\bi_\br
+              fails.   With the second form, p\bpu\bus\bsh\bhd\bd returns 0 unless the direc-
+              tory stack is empty, a non-existent directory stack  element  is
+              specified,  or the directory change to the specified new current
               directory fails.
 
        p\bpw\bwd\bd [-\b-L\bLP\bP]
-              Print  the  absolute  pathname of the current working directory.
+              Print the absolute pathname of the  current  working  directory.
               The pathname printed contains no symbolic links if the -\b-P\bP option
               is supplied or the -\b-o\bo p\bph\bhy\bys\bsi\bic\bca\bal\bl option to the s\bse\bet\bt builtin command
-              is enabled.  If the -\b-L\bL option is used, the pathname printed  may
-              contain  symbolic links.  The return status is 0 unless an error
-              occurs while reading the name of the  current  directory  or  an
+              is  enabled.  If the -\b-L\bL option is used, the pathname printed may
+              contain symbolic links.  The return status is 0 unless an  error
+              occurs  while  reading  the  name of the current directory or an
               invalid option is supplied.
 
        r\bre\bea\bad\bd [-\b-e\ber\brs\bs] [-\b-a\ba _\ba_\bn_\ba_\bm_\be] [-\b-d\bd _\bd_\be_\bl_\bi_\bm] [-\b-i\bi _\bt_\be_\bx_\bt] [-\b-n\bn _\bn_\bc_\bh_\ba_\br_\bs] [-\b-N\bN _\bn_\bc_\bh_\ba_\br_\bs] [-\b-p\bp
        _\bp_\br_\bo_\bm_\bp_\bt] [-\b-t\bt _\bt_\bi_\bm_\be_\bo_\bu_\bt] [-\b-u\bu _\bf_\bd] [_\bn_\ba_\bm_\be ...]
-              One line is read from the  standard  input,  or  from  the  file
-              descriptor  _\bf_\bd supplied as an argument to the -\b-u\bu option, and the
+              One  line  is  read  from  the  standard input, or from the file
+              descriptor _\bf_\bd supplied as an argument to the -\b-u\bu option, and  the
               first word is assigned to the first _\bn_\ba_\bm_\be, the second word to the
-              second  _\bn_\ba_\bm_\be, and so on, with leftover words and their interven-
-              ing separators assigned to the last _\bn_\ba_\bm_\be.  If  there  are  fewer
+              second _\bn_\ba_\bm_\be, and so on, with leftover words and their  interven-
+              ing  separators  assigned  to the last _\bn_\ba_\bm_\be.  If there are fewer
               words read from the input stream than names, the remaining names
-              are assigned empty values.  The characters in I\bIF\bFS\bS  are  used  to
-              split  the  line  into words using the same rules the shell uses
+              are  assigned  empty  values.  The characters in I\bIF\bFS\bS are used to
+              split the line into words using the same rules  the  shell  uses
               for expansion (described above under W\bWo\bor\brd\bd S\bSp\bpl\bli\bit\btt\bti\bin\bng\bg).  The back-
-              slash  character  (\\b\)  may be used to remove any special meaning
+              slash character (\\b\) may be used to remove  any  special  meaning
               for the next character read and for line continuation.  Options,
               if supplied, have the following meanings:
               -\b-a\ba _\ba_\bn_\ba_\bm_\be
@@ -4861,157 +4893,157 @@ S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS
                      new  values  are  assigned.   Other  _\bn_\ba_\bm_\be  arguments  are
                      ignored.
               -\b-d\bd _\bd_\be_\bl_\bi_\bm
-                     The first character of _\bd_\be_\bl_\bi_\bm is  used  to  terminate  the
+                     The  first  character  of  _\bd_\be_\bl_\bi_\bm is used to terminate the
                      input line, rather than newline.
               -\b-e\be     If the standard input is coming from a terminal, r\bre\bea\bad\bdl\bli\bin\bne\be
-                     (see R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE above) is used to obtain the  line.   Read-
-                     line  uses  the  current (or default, if line editing was
+                     (see  R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE  above) is used to obtain the line.  Read-
+                     line uses the current (or default, if  line  editing  was
                      not previously active) editing settings.
               -\b-i\bi _\bt_\be_\bx_\bt
-                     If r\bre\bea\bad\bdl\bli\bin\bne\be is being used  to  read  the  line,  _\bt_\be_\bx_\b is
+                     If  r\bre\bea\bad\bdl\bli\bin\bne\be  is  being  used  to  read the line, _\bt_\be_\bx_\bt is
                      placed into the editing buffer before editing begins.
               -\b-n\bn _\bn_\bc_\bh_\ba_\br_\bs
-                     r\bre\bea\bad\b returns after reading _\bn_\bc_\bh_\ba_\br_\bs characters rather than
-                     waiting for a complete line of input, but honor a  delim-
-                     iter  if fewer than _\bn_\bc_\bh_\ba_\br_\bs characters are read before the
+                     r\bre\bea\bad\breturns after reading _\bn_\bc_\bh_\ba_\br_\bs characters rather  than
+                     waiting  for a complete line of input, but honor a delim-
+                     iter if fewer than _\bn_\bc_\bh_\ba_\br_\bs characters are read before  the
                      delimiter.
               -\b-N\bN _\bn_\bc_\bh_\ba_\br_\bs
-                     r\bre\bea\bad\breturns  after  reading  exactly  _\bn_\bc_\bh_\ba_\br_\b characters
-                     rather  than waiting for a complete line of input, unless
-                     EOF is encountered or r\bre\bea\bad\bd times out.  Delimiter  charac-
-                     ters  encountered  in the input are not treated specially
-                     and do not cause r\bre\bea\bad\bd to return until  _\bn_\bc_\bh_\ba_\br_\b characters
+                     r\bre\bea\bad\b returns  after  reading  exactly  _\bn_\bc_\bh_\ba_\br_\bs characters
+                     rather than waiting for a complete line of input,  unless
+                     EOF  is encountered or r\bre\bea\bad\bd times out.  Delimiter charac-
+                     ters encountered in the input are not  treated  specially
+                     and  do  not cause r\bre\bea\bad\bd to return until _\bn_\bc_\bh_\ba_\br_\bs characters
                      are read.
               -\b-p\bp _\bp_\br_\bo_\bm_\bp_\bt
                      Display _\bp_\br_\bo_\bm_\bp_\bt on standard error, without a trailing new-
                      line, before attempting to read any input.  The prompt is
                      displayed only if input is coming from a terminal.
               -\b-r\br     Backslash does not act as an escape character.  The back-
-                     slash is considered to be part of the line.  In  particu-
-                     lar,  a  backslash-newline pair may not be used as a line
+                     slash  is considered to be part of the line.  In particu-
+                     lar, a backslash-newline pair may not be used as  a  line
                      continuation.
               -\b-s\bs     Silent mode.  If input is coming from a terminal, charac-
                      ters are not echoed.
               -\b-t\bt _\bt_\bi_\bm_\be_\bo_\bu_\bt
-                     Cause  r\bre\bea\bad\bd  to time out and return failure if a complete
-                     line of input (or a specified number  of  characters)  is
-                     not  read within _\bt_\bi_\bm_\be_\bo_\bu_\bt seconds.  _\bt_\bi_\bm_\be_\bo_\bu_\bt may be a deci-
-                     mal number with a fractional portion following the  deci-
-                     mal  point.   This  option  is  only effective if r\bre\bea\bad\bd is
-                     reading input from a terminal,  pipe,  or  other  special
-                     file;  it  has no effect when reading from regular files.
+                     Cause r\bre\bea\bad\bd to time out and return failure if  a  complete
+                     line  of  input  (or a specified number of characters) is
+                     not read within _\bt_\bi_\bm_\be_\bo_\bu_\bt seconds.  _\bt_\bi_\bm_\be_\bo_\bu_\bt may be a  deci-
+                     mal  number with a fractional portion following the deci-
+                     mal point.  This option is  only  effective  if  r\bre\bea\bad\b is
+                     reading  input  from  a  terminal, pipe, or other special
+                     file; it has no effect when reading from  regular  files.
                      If r\bre\bea\bad\bd times out, r\bre\bea\bad\bd saves any partial input read into
-                     the  specified  variable  _\bn_\ba_\bm_\be.   If  _\bt_\bi_\bm_\be_\bo_\bu_\bt  is 0, r\bre\bea\bad\bd
-                     returns immediately, without trying  to  read  any  data.
-                     The  exit status is 0 if input is available on the speci-
-                     fied file descriptor, non-zero otherwise.  The exit  sta-
+                     the specified variable  _\bn_\ba_\bm_\be.   If  _\bt_\bi_\bm_\be_\bo_\bu_\bt  is  0,  r\bre\bea\bad\bd
+                     returns  immediately,  without  trying  to read any data.
+                     The exit status is 0 if input is available on the  speci-
+                     fied  file descriptor, non-zero otherwise.  The exit sta-
                      tus is greater than 128 if the timeout is exceeded.
               -\b-u\bu _\bf_\bd  Read input from file descriptor _\bf_\bd.
 
               If no _\bn_\ba_\bm_\be_\bs are supplied, the line read is assigned to the vari-
-              able R\bRE\bEP\bPL\bLY\bY.  The return code  is  zero,  unless  end-of-file  is
-              encountered,  r\bre\bea\bad\bd  times  out (in which case the return code is
-              greater than 128), a variable assignment error (such as  assign-
-              ing  to a readonly variable) occurs, or an invalid file descrip-
+              able  R\bRE\bEP\bPL\bLY\bY.   The  return  code  is zero, unless end-of-file is
+              encountered, r\bre\bea\bad\bd times out (in which case the  return  code  is
+              greater  than 128), a variable assignment error (such as assign-
+              ing to a readonly variable) occurs, or an invalid file  descrip-
               tor is supplied as the argument to -\b-u\bu.
 
        r\bre\bea\bad\bdo\bon\bnl\bly\by [-\b-a\baA\bAf\bf] [-\b-p\bp] [_\bn_\ba_\bm_\be[=_\bw_\bo_\br_\bd] ...]
-              The given _\bn_\ba_\bm_\be_\bs are marked readonly; the values of  these  _\bn_\ba_\bm_\be_\bs
-              may  not  be changed by subsequent assignment.  If the -\b-f\bf option
-              is supplied, the functions corresponding to  the  _\bn_\ba_\bm_\be_\bs  are  so
-              marked.   The  -\b-a\ba  option  restricts  the  variables  to indexed
-              arrays; the -\b-A\bA option restricts  the  variables  to  associative
-              arrays.   If both options are supplied, -\b-A\bA takes precedence.  If
-              no _\bn_\ba_\bm_\be arguments are given, or if the -\b-p\bp option is supplied,  a
+              The  given  _\bn_\ba_\bm_\be_\bs are marked readonly; the values of these _\bn_\ba_\bm_\be_\bs
+              may not be changed by subsequent assignment.  If the  -\b-f\b option
+              is  supplied,  the  functions  corresponding to the _\bn_\ba_\bm_\be_\bs are so
+              marked.  The  -\b-a\ba  option  restricts  the  variables  to  indexed
+              arrays;  the  -\b-A\bA  option  restricts the variables to associative
+              arrays.  If both options are supplied, -\b-A\bA takes precedence.   If
+              no  _\bn_\ba_\bm_\be arguments are given, or if the -\b-p\bp option is supplied, a
               list of all readonly names is printed.  The other options may be
-              used to restrict the output to a subset of the set  of  readonly
-              names.   The -\b-p\bp option causes output to be displayed in a format
-              that may be reused as input.  If a variable name is followed  by
-              =_\bw_\bo_\br_\bd,  the  value  of  the variable is set to _\bw_\bo_\br_\bd.  The return
-              status is 0 unless an invalid option is encountered, one of  the
+              used  to  restrict the output to a subset of the set of readonly
+              names.  The -\b-p\bp option causes output to be displayed in a  format
+              that  may be reused as input.  If a variable name is followed by
+              =_\bw_\bo_\br_\bd, the value of the variable is set  to  _\bw_\bo_\br_\bd.   The  return
+              status  is 0 unless an invalid option is encountered, one of the
               _\bn_\ba_\bm_\be_\bs is not a valid shell variable name, or -\b-f\bf is supplied with
               a _\bn_\ba_\bm_\be that is not a function.
 
        r\bre\bet\btu\bur\brn\bn [_\bn]
-              Causes a function to stop executing and return the value  speci-
-              fied  by _\bn to its caller.  If _\bn is omitted, the return status is
-              that of the last command executed  in  the  function  body.   If
-              r\bre\bet\btu\bur\brn\b is  executed by a trap handler, the last command used to
-              determine the status is the last  command  executed  before  the
-              trap  handler.   if  r\bre\bet\btu\bur\brn\bn is executed during a D\bDE\bEB\bBU\bUG\bG trap, the
-              last command used to determine the status is  the  last  command
-              executed  by  the  trap  handler  before r\bre\bet\btu\bur\brn\bn was invoked.  If
-              r\bre\bet\btu\bur\brn\bis used outside a function, but  during  execution  of  a
-              script  by  the .\b.  (s\bso\bou\bur\brc\bce\be) command, it causes the shell to stop
-              executing that script and return either _\bn or the exit status  of
-              the  last  command executed within the script as the exit status
-              of the script.  If _\bn is supplied, the return value is its  least
-              significant  8 bits.  The return status is non-zero if r\bre\bet\btu\bur\brn\bn is
-              supplied a non-numeric argument, or is used outside  a  function
-              and  not  during execution of a script by .\b. or s\bso\bou\bur\brc\bce\be.  Any com-
-              mand associated with the R\bRE\bET\bTU\bUR\bRN\bN trap is executed  before  execu-
+              Causes  a function to stop executing and return the value speci-
+              fied by _\bn to its caller.  If _\bn is omitted, the return status  is
+              that  of  the  last  command  executed in the function body.  If
+              r\bre\bet\btu\bur\brn\bis executed by a trap handler, the last command  used  to
+              determine  the  status  is  the last command executed before the
+              trap handler.  if r\bre\bet\btu\bur\brn\bn is executed during a  D\bDE\bEB\bBU\bUG\bG  trap,  the
+              last  command  used  to determine the status is the last command
+              executed by the trap handler  before  r\bre\bet\btu\bur\brn\bn  was  invoked.   If
+              r\bre\bet\btu\bur\brn\b is  used  outside  a function, but during execution of a
+              script by the .\b.  (s\bso\bou\bur\brc\bce\be) command, it causes the shell  to  stop
+              executing  that script and return either _\bn or the exit status of
+              the last command executed within the script as the  exit  status
+              of  the script.  If _\bn is supplied, the return value is its least
+              significant 8 bits.  The return status is non-zero if r\bre\bet\btu\bur\brn\b is
+              supplied  a  non-numeric argument, or is used outside a function
+              and not during execution of a script by .\b. or s\bso\bou\bur\brc\bce\be.   Any  com-
+              mand  associated  with the R\bRE\bET\bTU\bUR\bRN\bN trap is executed before execu-
               tion resumes after the function or script.
 
        s\bse\bet\bt [-\b--\b-a\bab\bbe\bef\bfh\bhk\bkm\bmn\bnp\bpt\btu\buv\bvx\bxB\bBC\bCE\bEH\bHP\bPT\bT] [-\b-o\bo _\bo_\bp_\bt_\bi_\bo_\bn_\b-_\bn_\ba_\bm_\be] [_\ba_\br_\bg ...]
        s\bse\bet\bt [+\b+a\bab\bbe\bef\bfh\bhk\bkm\bmn\bnp\bpt\btu\buv\bvx\bxB\bBC\bCE\bEH\bHP\bPT\bT] [+\b+o\bo _\bo_\bp_\bt_\bi_\bo_\bn_\b-_\bn_\ba_\bm_\be] [_\ba_\br_\bg ...]
-              Without  options,  the name and value of each shell variable are
+              Without options, the name and value of each shell  variable  are
               displayed in a format that can be reused as input for setting or
               resetting the currently-set variables.  Read-only variables can-
-              not be reset.  In _\bp_\bo_\bs_\bi_\bx mode, only shell variables  are  listed.
-              The  output  is  sorted  according  to the current locale.  When
-              options are specified, they set or unset shell attributes.   Any
-              arguments  remaining after option processing are treated as val-
+              not  be  reset.  In _\bp_\bo_\bs_\bi_\bx mode, only shell variables are listed.
+              The output is sorted according  to  the  current  locale.   When
+              options  are specified, they set or unset shell attributes.  Any
+              arguments remaining after option processing are treated as  val-
               ues for the positional parameters and are assigned, in order, to
-              $\b$1\b1,  $\b$2\b2,  .\b..\b..\b.   $\b$_\bn.   Options,  if specified, have the following
+              $\b$1\b1, $\b$2\b2, .\b..\b..\b.  $\b$_\bn.  Options,  if  specified,  have  the  following
               meanings:
-              -\b-a\ba      Automatically mark variables  and  functions  which  are
-                      modified  or  created  for  export to the environment of
+              -\b-a\ba      Automatically  mark  variables  and  functions which are
+                      modified or created for export  to  the  environment  of
                       subsequent commands.
-              -\b-b\bb      Report the status of terminated background jobs  immedi-
+              -\b-b\bb      Report  the status of terminated background jobs immedi-
                       ately, rather than before the next primary prompt.  This
                       is effective only when job control is enabled.
-              -\b-e\be      Exit immediately if a _\bp_\bi_\bp_\be_\bl_\bi_\bn_\be (which may consist  of  a
-                      single  _\bs_\bi_\bm_\bp_\bl_\be  _\bc_\bo_\bm_\bm_\ba_\bn_\bd),  a _\bl_\bi_\bs_\bt, or a _\bc_\bo_\bm_\bp_\bo_\bu_\bn_\bd _\bc_\bo_\bm_\bm_\ba_\bn_\bd
+              -\b-e\be      Exit  immediately  if a _\bp_\bi_\bp_\be_\bl_\bi_\bn_\be (which may consist of a
+                      single _\bs_\bi_\bm_\bp_\bl_\be _\bc_\bo_\bm_\bm_\ba_\bn_\bd), a _\bl_\bi_\bs_\bt, or  a  _\bc_\bo_\bm_\bp_\bo_\bu_\bn_\b _\bc_\bo_\bm_\bm_\ba_\bn_\bd
                       (see S\bSH\bHE\bEL\bLL\bL G\bGR\bRA\bAM\bMM\bMA\bAR\bR above), exits with a non-zero status.
-                      The  shell  does  not  exit if the command that fails is
-                      part of the command list immediately following  a  w\bwh\bhi\bil\ble\be
-                      or  u\bun\bnt\bti\bil\bl  keyword, part of the test following the i\bif\bf or
-                      e\bel\bli\bif\breserved words, part of any command executed  in  a
-                      &\b&&\b or |\b||\b| list except the command following the final &\b&&\b&
+                      The shell does not exit if the  command  that  fails  is
+                      part  of  the command list immediately following a w\bwh\bhi\bil\ble\be
+                      or u\bun\bnt\bti\bil\bl keyword, part of the test following the  i\bif\b or
+                      e\bel\bli\bif\b reserved  words, part of any command executed in a
+                      &\b&&\bor |\b||\b| list except the command following the final  &\b&&\b&
                       or |\b||\b|, any command in a pipeline but the last, or if the
-                      command's  return  value is being inverted with !\b!.  If a
-                      compound command other than a subshell  returns  a  non-
-                      zero  status because a command failed while -\b-e\be was being
-                      ignored, the shell does not exit.  A  trap  on  E\bER\bRR\bR,  if
-                      set,  is  executed  before the shell exits.  This option
+                      command's return value is being inverted with !\b!.   If  a
+                      compound  command  other  than a subshell returns a non-
+                      zero status because a command failed while -\b-e\be was  being
+                      ignored,  the  shell  does  not exit.  A trap on E\bER\bRR\bR, if
+                      set, is executed before the shell  exits.   This  option
                       applies to the shell environment and each subshell envi-
-                      ronment  separately  (see  C\bCO\bOM\bMM\bMA\bAN\bND\bD E\bEX\bXE\bEC\bCU\bUT\bTI\bIO\bON\bN E\bEN\bNV\bVI\bIR\bRO\bON\bNM\bME\bEN\bNT\bT
+                      ronment separately (see  C\bCO\bOM\bMM\bMA\bAN\bND\bD  E\bEX\bXE\bEC\bCU\bUT\bTI\bIO\bON\b E\bEN\bNV\bVI\bIR\bRO\bON\bNM\bME\bEN\bNT\bT
                       above), and may cause subshells to exit before executing
                       all the commands in the subshell.
 
-                      If  a  compound  command or shell function executes in a
-                      context where -\b-e\be is being ignored, none of the  commands
-                      executed  within  the  compound command or function body
-                      will be affected by the -\b-e\be setting, even if  -\b-e\be  is  set
-                      and  a  command returns a failure status.  If a compound
-                      command or shell function sets -\b-e\be while executing  in  a
-                      context  where -\b-e\be is ignored, that setting will not have
-                      any effect until the compound  command  or  the  command
+                      If a compound command or shell function  executes  in  a
+                      context  where -\b-e\be is being ignored, none of the commands
+                      executed within the compound command  or  function  body
+                      will  be  affected  by the -\b-e\be setting, even if -\b-e\be is set
+                      and a command returns a failure status.  If  a  compound
+                      command  or  shell function sets -\b-e\be while executing in a
+                      context where -\b-e\be is ignored, that setting will not  have
+                      any  effect  until  the  compound command or the command
                       containing the function call completes.
               -\b-f\bf      Disable pathname expansion.
-              -\b-h\bh      Remember  the location of commands as they are looked up
+              -\b-h\bh      Remember the location of commands as they are looked  up
                       for execution.  This is enabled by default.
-              -\b-k\bk      All arguments in the form of assignment  statements  are
-                      placed  in the environment for a command, not just those
+              -\b-k\bk      All  arguments  in the form of assignment statements are
+                      placed in the environment for a command, not just  those
                       that precede the command name.
-              -\b-m\bm      Monitor mode.  Job control is enabled.  This  option  is
-                      on  by  default  for  interactive shells on systems that
-                      support it (see J\bJO\bOB\bB C\bCO\bON\bNT\bTR\bRO\bOL\bL above).  All  processes  run
+              -\b-m\bm      Monitor  mode.   Job control is enabled.  This option is
+                      on by default for interactive  shells  on  systems  that
+                      support  it  (see J\bJO\bOB\bB C\bCO\bON\bNT\bTR\bRO\bOL\bL above).  All processes run
                       in a separate process group.  When a background job com-
                       pletes, the shell prints a line containing its exit sta-
                       tus.
               -\b-n\bn      Read commands but do not execute them.  This may be used
-                      to check a shell script  for  syntax  errors.   This  is
+                      to  check  a  shell  script  for syntax errors.  This is
                       ignored by interactive shells.
               -\b-o\bo _\bo_\bp_\bt_\bi_\bo_\bn_\b-_\bn_\ba_\bm_\be
                       The _\bo_\bp_\bt_\bi_\bo_\bn_\b-_\bn_\ba_\bm_\be can be one of the following:
@@ -5019,10 +5051,10 @@ S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS
                               Same as -\b-a\ba.
                       b\bbr\bra\bac\bce\bee\bex\bxp\bpa\ban\bnd\bd
                               Same as -\b-B\bB.
-                      e\bem\bma\bac\bcs\bs   Use  an  emacs-style command line editing inter-
+                      e\bem\bma\bac\bcs\bs   Use an emacs-style command line  editing  inter-
                               face.  This is enabled by default when the shell
                               is interactive, unless the shell is started with
-                              the -\b--\b-n\bno\boe\bed\bdi\bit\bti\bin\bng\bg option.  This also  affects  the
+                              the  -\b--\b-n\bno\boe\bed\bdi\bit\bti\bin\bng\bg  option.  This also affects the
                               editing interface used for r\bre\bea\bad\bd -\b-e\be.
                       e\ber\brr\bre\bex\bxi\bit\bt Same as -\b-e\be.
                       e\ber\brr\brt\btr\bra\bac\bce\be
@@ -5036,8 +5068,8 @@ S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS
                               H\bHI\bIS\bST\bTO\bOR\bRY\bY.  This option is on by default in inter-
                               active shells.
                       i\big\bgn\bno\bor\bre\bee\beo\bof\bf
-                              The   effect   is   as   if  the  shell  command
-                              ``IGNOREEOF=10'' had been  executed  (see  S\bSh\bhe\bel\bll\bl
+                              The  effect  is  as   if   the   shell   command
+                              ``IGNOREEOF=10''  had  been  executed (see S\bSh\bhe\bel\bll\bl
                               V\bVa\bar\bri\bia\bab\bbl\ble\bes\bs above).
                       k\bke\bey\byw\bwo\bor\brd\bd Same as -\b-k\bk.
                       m\bmo\bon\bni\bit\bto\bor\br Same as -\b-m\bm.
@@ -5052,340 +5084,341 @@ S\bSH\bHE\bEL\bLL\bL B\bBU\bUI\bIL\bLT\bTI\bIN\bN C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS
                       p\bph\bhy\bys\bsi\bic\bca\bal\bl
                               Same as -\b-P\bP.
                       p\bpi\bip\bpe\bef\bfa\bai\bil\bl
-                              If  set,  the  return value of a pipeline is the
-                              value of the last (rightmost)  command  to  exit
-                              with  a non-zero status, or zero if all commands
-                              in the pipeline exit successfully.  This  option
+                              If set, the return value of a  pipeline  is  the
+                              value  of  the  last (rightmost) command to exit
+                              with a non-zero status, or zero if all  commands
+                              in  the pipeline exit successfully.  This option
                               is disabled by default.
-                      p\bpo\bos\bsi\bix\bx   Change  the  behavior  of b\bba\bas\bsh\bh where the default
-                              operation differs from  the  POSIX  standard  to
-                              match  the  standard (_\bp_\bo_\bs_\bi_\bx _\bm_\bo_\bd_\be).  See S\bSE\bEE\bE A\bAL\bLS\bSO\bO
+                      p\bpo\bos\bsi\bix\bx   Change the behavior of b\bba\bas\bsh\bh  where  the  default
+                              operation  differs  from  the  POSIX standard to
+                              match the standard (_\bp_\bo_\bs_\bi_\bx _\bm_\bo_\bd_\be).  See  S\bSE\bEE\b A\bAL\bLS\bSO\bO
                               below for a reference to a document that details
                               how posix mode affects bash's behavior.
                       p\bpr\bri\biv\bvi\bil\ble\beg\bge\bed\bd
                               Same as -\b-p\bp.
                       v\bve\ber\brb\bbo\bos\bse\be Same as -\b-v\bv.
-                      v\bvi\bi      Use  a  vi-style command line editing interface.
+                      v\bvi\bi      Use a vi-style command line  editing  interface.
                               This also affects the editing interface used for
                               r\bre\bea\bad\bd -\b-e\be.
                       x\bxt\btr\bra\bac\bce\be  Same as -\b-x\bx.
                       If -\b-o\bo is supplied with no _\bo_\bp_\bt_\bi_\bo_\bn_\b-_\bn_\ba_\bm_\be, the values of the
-                      current options are printed.  If +\b+o\bo is supplied with  no
-                      _\bo_\bp_\bt_\bi_\bo_\bn_\b-_\bn_\ba_\bm_\be,  a  series  of s\bse\bet\bt commands to recreate the
-                      current option settings is  displayed  on  the  standard
+                      current  options are printed.  If +\b+o\bo is supplied with no
+                      _\bo_\bp_\bt_\bi_\bo_\bn_\b-_\bn_\ba_\bm_\be, a series of s\bse\bet\bt commands  to  recreate  the
+                      current  option  settings  is  displayed on the standard
                       output.
-              -\b-p\bp      Turn  on  _\bp_\br_\bi_\bv_\bi_\bl_\be_\bg_\be_\bd  mode.   In this mode, the $\b$E\bEN\bNV\bV and
-                      $\b$B\bBA\bAS\bSH\bH_\b_E\bEN\bNV\bfiles are not processed, shell  functions  are
-                      not  inherited  from the environment, and the S\bSH\bHE\bEL\bLL\bLO\bOP\bPT\bTS\bS,
-                      B\bBA\bAS\bSH\bHO\bOP\bPT\bTS\bS, C\bCD\bDP\bPA\bAT\bTH\bH,  and  G\bGL\bLO\bOB\bBI\bIG\bGN\bNO\bOR\bRE\bE  variables,  if  they
+              -\b-p\bp      Turn on _\bp_\br_\bi_\bv_\bi_\bl_\be_\bg_\be_\bd mode.  In this  mode,  the  $\b$E\bEN\bNV\b and
+                      $\b$B\bBA\bAS\bSH\bH_\b_E\bEN\bNV\b files  are not processed, shell functions are
+                      not inherited from the environment, and  the  S\bSH\bHE\bEL\bLL\bLO\bOP\bPT\bTS\bS,
+                      B\bBA\bAS\bSH\bHO\bOP\bPT\bTS\bS,  C\bCD\bDP\bPA\bAT\bTH\bH,  and  G\bGL\bLO\bOB\bBI\bIG\bGN\bNO\bOR\bRE\bE  variables,  if they
                       appear in the environment, are ignored.  If the shell is
-                      started with the effective user (group) id not equal  to
-                      the  real user (group) id, and the -\b-p\bp option is not sup-
+                      started  with the effective user (group) id not equal to
+                      the real user (group) id, and the -\b-p\bp option is not  sup-
                       plied, these actions are taken and the effective user id
-                      is  set  to  the real user id.  If the -\b-p\bp option is sup-
-                      plied at startup, the effective user id  is  not  reset.
-                      Turning  this  option  off causes the effective user and
+                      is set to the real user id.  If the -\b-p\bp  option  is  sup-
+                      plied  at  startup,  the effective user id is not reset.
+                      Turning this option off causes the  effective  user  and
                       group ids to be set to the real user and group ids.
               -\b-t\bt      Exit after reading and executing one command.
               -\b-u\bu      Treat unset variables and parameters other than the spe-
-                      cial  parameters "@" and "*" as an error when performing
-                      parameter expansion.  If expansion is  attempted  on  an
-                      unset  variable  or parameter, the shell prints an error
-                      message, and, if not interactive, exits with a  non-zero
+                      cial parameters "@" and "*" as an error when  performing
+                      parameter  expansion.   If  expansion is attempted on an
+                      unset variable or parameter, the shell prints  an  error
+                      message,  and, if not interactive, exits with a non-zero
                       status.
               -\b-v\bv      Print shell input lines as they are read.
-              -\b-x\bx      After  expanding  each _\bs_\bi_\bm_\bp_\bl_\be _\bc_\bo_\bm_\bm_\ba_\bn_\bd, f\bfo\bor\br command, c\bca\bas\bse\be
+              -\b-x\bx      After expanding each _\bs_\bi_\bm_\bp_\bl_\be _\bc_\bo_\bm_\bm_\ba_\bn_\bd, f\bfo\bor\br  command,  c\bca\bas\bse\be
                       command, s\bse\bel\ble\bec\bct\bt command, or arithmetic f\bfo\bor\br command, dis-
-                      play  the expanded value of P\bPS\bS4\b4, followed by the command
+                      play the expanded value of P\bPS\bS4\b4, followed by the  command
                       and its expanded arguments or associated word list.
-              -\b-B\bB      The shell performs brace expansion (see B\bBr\bra\bac\bce\b E\bEx\bxp\bpa\ban\bns\bsi\bio\bon\bn
+              -\b-B\bB      The  shell performs brace expansion (see B\bBr\bra\bac\bce\be E\bEx\bxp\bpa\ban\bns\bsi\bio\bon\bn
                       above).  This is on by default.
-              -\b-C\bC      If  set,  b\bba\bas\bsh\bh  does not overwrite an existing file with
-                      the >\b>, >\b>&\b&, and <\b<>\b> redirection operators.   This  may  be
+              -\b-C\bC      If set, b\bba\bas\bsh\bh does not overwrite an  existing  file  with
+                      the  >\b>,  >\b>&\b&,  and <\b<>\b> redirection operators.  This may be
                       overridden when creating output files by using the redi-
                       rection operator >\b>|\b| instead of >\b>.
               -\b-E\bE      If set, any trap on E\bER\bRR\bR is inherited by shell functions,
-                      command  substitutions,  and commands executed in a sub-
-                      shell environment.  The E\bER\bRR\bR trap is normally not  inher-
+                      command substitutions, and commands executed in  a  sub-
+                      shell  environment.  The E\bER\bRR\bR trap is normally not inher-
                       ited in such cases.
               -\b-H\bH      Enable !\b!  style history substitution.  This option is on
                       by default when the shell is interactive.
-              -\b-P\bP      If set, the shell does not resolve symbolic  links  when
-                      executing  commands  such  as c\bcd\bd that change the current
+              -\b-P\bP      If  set,  the shell does not resolve symbolic links when
+                      executing commands such as c\bcd\bd that  change  the  current
                       working  directory.   It  uses  the  physical  directory
                       structure instead.  By default, b\bba\bas\bsh\bh follows the logical
-                      chain of  directories  when  performing  commands  which
+                      chain  of  directories  when  performing  commands which
                       change the current directory.
-              -\b-T\bT      If  set,  any traps on D\bDE\bEB\bBU\bUG\bG and R\bRE\bET\bTU\bUR\bRN\bN are inherited by
-                      shell functions,  command  substitutions,  and  commands
-                      executed  in  a  subshell  environment.   The  D\bDE\bEB\bBU\bUG\bG and
+              -\b-T\bT      If set, any traps on D\bDE\bEB\bBU\bUG\bG and R\bRE\bET\bTU\bUR\bRN\bN are  inherited  by
+                      shell  functions,  command  substitutions,  and commands
+                      executed in  a  subshell  environment.   The  D\bDE\bEB\bBU\bUG\b and
                       R\bRE\bET\bTU\bUR\bRN\bN traps are normally not inherited in such cases.
-              -\b--\b-      If no arguments follow this option, then the  positional
+              -\b--\b-      If  no arguments follow this option, then the positional
                       parameters are unset.  Otherwise, the positional parame-
-                      ters are set to the _\ba_\br_\bgs, even if  some  of  them  begin
+                      ters  are  set  to  the _\ba_\br_\bgs, even if some of them begin
                       with a -\b-.
-              -\b-       Signal  the  end of options, cause all remaining _\ba_\br_\bgs to
+              -\b-       Signal the end of options, cause all remaining  _\ba_\br_\bgs  to
                       be assigned to the positional parameters.  The -\b-x\bx and -\b-v\bv
                       options are turned off.  If there are no _\ba_\br_\bgs, the posi-
                       tional parameters remain unchanged.
 
-              The options are off by default unless otherwise noted.  Using  +
-              rather  than  -  causes  these  options  to  be turned off.  The
-              options can also be specified as arguments to an  invocation  of
-              the  shell.  The current set of options may be found in $\b$-\b-.  The
+              The  options are off by default unless otherwise noted.  Using +
+              rather than - causes  these  options  to  be  turned  off.   The
+              options  can  also be specified as arguments to an invocation of
+              the shell.  The current set of options may be found in $\b$-\b-.   The
               return status is always true unless an invalid option is encoun-
               tered.
 
        s\bsh\bhi\bif\bft\bt [_\bn]
-              The  positional  parameters  from _\bn+1 ... are renamed to $\b$1\b1 .\b..\b..\b..\b.
-              Parameters represented by the numbers  $\b$#\b#  down  to  $\b$#\b#-_\bn+1  are
-              unset.   _\bn  must  be a non-negative number less than or equal to
-              $\b$#\b#.  If _\bn is 0, no parameters are changed.  If _\bn is  not  given,
-              it  is assumed to be 1.  If _\bn is greater than $\b$#\b#, the positional
-              parameters are not changed.  The return status is  greater  than
+              The positional parameters from _\bn+1 ... are renamed  to  $\b$1\b .\b..\b..\b..\b.
+              Parameters  represented  by  the  numbers  $\b$#\b# down to $\b$#\b#-_\bn+1 are
+              unset.  _\bn must be a non-negative number less than  or  equal  to
+              $\b$#\b#.   If  _\bn is 0, no parameters are changed.  If _\bn is not given,
+              it is assumed to be 1.  If _\bn is greater than $\b$#\b#, the  positional
+              parameters  are  not changed.  The return status is greater than
               zero if _\bn is greater than $\b$#\b# or less than zero; otherwise 0.
 
        s\bsh\bho\bop\bpt\bt [-\b-p\bpq\bqs\bsu\bu] [-\b-o\bo] [_\bo_\bp_\bt_\bn_\ba_\bm_\be ...]
-              Toggle  the values of settings controlling optional shell behav-
-              ior.  The settings can be either those listed below, or, if  the
+              Toggle the values of settings controlling optional shell  behav-
+              ior.   The settings can be either those listed below, or, if the
               -\b-o\bo option is used, those available with the -\b-o\bo option to the s\bse\bet\bt
               builtin command.  With no options, or with the -\b-p\bp option, a list
-              of  all  settable  options  is  displayed, with an indication of
-              whether or not each is set.  The -\b-p\bp option causes output  to  be
-              displayed  in a form that may be reused as input.  Other options
+              of all settable options is  displayed,  with  an  indication  of
+              whether  or  not each is set.  The -\b-p\bp option causes output to be
+              displayed in a form that may be reused as input.  Other  options
               have the following meanings:
               -\b-s\bs     Enable (set) each _\bo_\bp_\bt_\bn_\ba_\bm_\be.
               -\b-u\bu     Disable (unset) each _\bo_\bp_\bt_\bn_\ba_\bm_\be.
-              -\b-q\bq     Suppresses normal output (quiet mode); the return  status
+              -\b-q\bq     Suppresses  normal output (quiet mode); the return status
                      indicates whether the _\bo_\bp_\bt_\bn_\ba_\bm_\be is set or unset.  If multi-
-                     ple _\bo_\bp_\bt_\bn_\ba_\bm_\be arguments are given with -\b-q\bq, the return  sta-
-                     tus  is zero if all _\bo_\bp_\bt_\bn_\ba_\bm_\be_\bs are enabled; non-zero other-
+                     ple  _\bo_\bp_\bt_\bn_\ba_\bm_\be arguments are given with -\b-q\bq, the return sta-
+                     tus is zero if all _\bo_\bp_\bt_\bn_\ba_\bm_\be_\bs are enabled; non-zero  other-
                      wise.
-              -\b-o\bo     Restricts the values of _\bo_\bp_\bt_\bn_\ba_\bm_\be to be those  defined  for
+              -\b-o\bo     Restricts  the  values of _\bo_\bp_\bt_\bn_\ba_\bm_\be to be those defined for
                      the -\b-o\bo option to the s\bse\bet\bt builtin.
 
-              If  either  -\b-s\bs  or  -\b-u\bu  is used with no _\bo_\bp_\bt_\bn_\ba_\bm_\be arguments, s\bsh\bho\bop\bpt\bt
-              shows only those options which are set or  unset,  respectively.
-              Unless  otherwise  noted, the s\bsh\bho\bop\bpt\bt options are disabled (unset)
+              If either -\b-s\bs or -\b-u\bu is used  with  no  _\bo_\bp_\bt_\bn_\ba_\bm_\be  arguments,  s\bsh\bho\bop\bpt\bt
+              shows  only  those options which are set or unset, respectively.
+              Unless otherwise noted, the s\bsh\bho\bop\bpt\bt options are  disabled  (unset)
               by default.
 
-              The return status when listing options is zero if  all  _\bo_\bp_\bt_\bn_\ba_\bm_\be_\bs
-              are  enabled,  non-zero  otherwise.   When  setting or unsetting
-              options, the return status is zero unless an _\bo_\bp_\bt_\bn_\ba_\bm_\be  is  not  a
+              The  return  status when listing options is zero if all _\bo_\bp_\bt_\bn_\ba_\bm_\be_\bs
+              are enabled, non-zero  otherwise.   When  setting  or  unsetting
+              options,  the  return  status is zero unless an _\bo_\bp_\bt_\bn_\ba_\bm_\be is not a
               valid shell option.
 
               The list of s\bsh\bho\bop\bpt\bt options is:
 
-              a\bau\but\bto\boc\bcd\bd  If  set,  a command name that is the name of a directory
-                      is executed as if it were the argument to  the  c\bcd\b com-
+              a\bau\but\bto\boc\bcd\bd  If set, a command name that is the name of  a  directory
+                      is  executed  as  if it were the argument to the c\bcd\bd com-
                       mand.  This option is only used by interactive shells.
               c\bcd\bda\bab\bbl\ble\be_\b_v\bva\bar\brs\bs
-                      If  set,  an  argument to the c\bcd\bd builtin command that is
-                      not a directory is assumed to be the name of a  variable
+                      If set, an argument to the c\bcd\bd builtin  command  that  is
+                      not  a directory is assumed to be the name of a variable
                       whose value is the directory to change to.
               c\bcd\bds\bsp\bpe\bel\bll\bl If set, minor errors in the spelling of a directory com-
-                      ponent in a c\bcd\bd command will be  corrected.   The  errors
+                      ponent  in  a  c\bcd\bd command will be corrected.  The errors
                       checked for are transposed characters, a missing charac-
-                      ter, and one character too many.   If  a  correction  is
-                      found,  the  corrected filename is printed, and the com-
-                      mand proceeds.  This option is only used by  interactive
+                      ter,  and  one  character  too many.  If a correction is
+                      found, the corrected filename is printed, and  the  com-
+                      mand  proceeds.  This option is only used by interactive
                       shells.
               c\bch\bhe\bec\bck\bkh\bha\bas\bsh\bh
                       If set, b\bba\bas\bsh\bh checks that a command found in the hash ta-
-                      ble exists before trying to execute  it.   If  a  hashed
-                      command  no  longer exists, a normal path search is per-
+                      ble  exists  before  trying  to execute it.  If a hashed
+                      command no longer exists, a normal path search  is  per-
                       formed.
               c\bch\bhe\bec\bck\bkj\bjo\bob\bbs\bs
                       If set, b\bba\bas\bsh\bh lists the status of any stopped and running
-                      jobs  before  exiting an interactive shell.  If any jobs
+                      jobs before exiting an interactive shell.  If  any  jobs
                       are running, this causes the exit to be deferred until a
-                      second  exit is attempted without an intervening command
-                      (see J\bJO\bOB\bB C\bCO\bON\bNT\bTR\bRO\bOL\bL above).   The  shell  always  postpones
+                      second exit is attempted without an intervening  command
+                      (see  J\bJO\bOB\bB  C\bCO\bON\bNT\bTR\bRO\bOL\bL  above).   The shell always postpones
                       exiting if any jobs are stopped.
               c\bch\bhe\bec\bck\bkw\bwi\bin\bns\bsi\biz\bze\be
-                      If  set,  b\bba\bas\bsh\bh checks the window size after each command
-                      and, if necessary, updates the values of L\bLI\bIN\bNE\bES\bS and  C\bCO\bOL\bL-\b-
+                      If set, b\bba\bas\bsh\bh checks the window size after  each  command
+                      and,  if necessary, updates the values of L\bLI\bIN\bNE\bES\bS and C\bCO\bOL\bL-\b-
                       U\bUM\bMN\bNS\bS.
-              c\bcm\bmd\bdh\bhi\bis\bst\bt If  set,  b\bba\bas\bsh\bh attempts to save all lines of a multiple-
-                      line command in the same  history  entry.   This  allows
+              c\bcm\bmd\bdh\bhi\bis\bst\bt If set, b\bba\bas\bsh\bh attempts to save all lines of  a  multiple-
+                      line  command  in  the  same history entry.  This allows
                       easy re-editing of multi-line commands.
               c\bco\bom\bmp\bpa\bat\bt3\b31\b1
                       If set, b\bba\bas\bsh\bh changes its behavior to that of version 3.1
-                      with respect to quoted arguments to the  [\b[[\b conditional
+                      with  respect  to quoted arguments to the [\b[[\b[ conditional
                       command's =\b=~\b~ operator and locale-specific string compar-
-                      ison when using the [\b[[\b[ conditional  command's  <\b<  and  >\b>
-                      operators.   Bash  versions  prior to bash-4.1 use ASCII
+                      ison  when  using  the  [\b[[\b[ conditional command's <\b< and >\b>
+                      operators.  Bash versions prior to  bash-4.1  use  ASCII
                       collation and _\bs_\bt_\br_\bc_\bm_\bp(3); bash-4.1 and later use the cur-
                       rent locale's collation sequence and _\bs_\bt_\br_\bc_\bo_\bl_\bl(3).
               c\bco\bom\bmp\bpa\bat\bt3\b32\b2
                       If set, b\bba\bas\bsh\bh changes its behavior to that of version 3.2
-                      with respect to locale-specific string  comparison  when
-                      using  the  [\b[[\b[  conditional  command's <\b< and >\b> operators
+                      with  respect  to locale-specific string comparison when
+                      using the [\b[[\b[ conditional command's  <\b<  and  >\b operators
                       (see previous item).
               c\bco\bom\bmp\bpa\bat\bt4\b40\b0
                       If set, b\bba\bas\bsh\bh changes its behavior to that of version 4.0
-                      with  respect  to locale-specific string comparison when
-                      using the [\b[[\b[ conditional command's  <\b<  and  >\b operators
-                      (see  description  of c\bco\bom\bmp\bpa\bat\bt3\b31\b1) and the effect of inter-
-                      rupting a command list.  Bash  versions  4.0  and  later
-                      interrupt  the  list as if the shell received the inter-
-                      rupt; previous versions continue with the  next  command
+                      with respect to locale-specific string  comparison  when
+                      using  the  [\b[[\b[  conditional  command's <\b< and >\b> operators
+                      (see description of c\bco\bom\bmp\bpa\bat\bt3\b31\b1) and the effect  of  inter-
+                      rupting  a  command  list.   Bash versions 4.0 and later
+                      interrupt the list as if the shell received  the  inter-
+                      rupt;  previous  versions continue with the next command
                       in the list.
               c\bco\bom\bmp\bpa\bat\bt4\b41\b1
-                      If  set, b\bba\bas\bsh\bh, when in _\bp_\bo_\bs_\bi_\bx mode, treats a single quote
-                      in a double-quoted  parameter  expansion  as  a  special
-                      character.   The  single quotes must match (an even num-
-                      ber) and the characters between the  single  quotes  are
-                      considered  quoted.   This is the behavior of posix mode
-                      through version 4.1.  The default bash behavior  remains
+                      If set, b\bba\bas\bsh\bh, when in _\bp_\bo_\bs_\bi_\bx mode, treats a single  quote
+                      in  a  double-quoted  parameter  expansion  as a special
+                      character.  The single quotes must match (an  even  num-
+                      ber)  and  the  characters between the single quotes are
+                      considered quoted.  This is the behavior of  posix  mode
+                      through  version 4.1.  The default bash behavior remains
                       as in previous versions.
               c\bco\bom\bmp\bpa\bat\bt4\b42\b2
-                      If  set, b\bba\bas\bsh\bh does not process the replacement string in
-                      the pattern  substitution  word  expansion  using  quote
+                      If set, b\bba\bas\bsh\bh does not process the replacement string  in
+                      the  pattern  substitution  word  expansion  using quote
                       removal.
               c\bco\bom\bmp\bpl\ble\bet\bte\be_\b_f\bfu\bul\bll\blq\bqu\buo\bot\bte\be
-                      If  set,  b\bba\bas\bsh\bh  quotes all shell metacharacters in file-
-                      names and directory names  when  performing  completion.
+                      If set, b\bba\bas\bsh\bh quotes all shell  metacharacters  in  file-
+                      names  and  directory  names when performing completion.
                       If not set, b\bba\bas\bsh\bh removes metacharacters such as the dol-
-                      lar sign from the set of characters that will be  quoted
-                      in  completed filenames when these metacharacters appear
-                      in shell variable references in words to  be  completed.
-                      This  means  that  dollar  signs  in variable names that
-                      expand to directories will not be quoted;  however,  any
-                      dollar  signs appearing in filenames will not be quoted,
-                      either.  This is active only when bash  is  using  back-
-                      slashes  to quote completed filenames.  This variable is
-                      set by default, which is the default  bash  behavior  in
+                      lar  sign from the set of characters that will be quoted
+                      in completed filenames when these metacharacters  appear
+                      in  shell  variable references in words to be completed.
+                      This means that dollar  signs  in  variable  names  that
+                      expand  to  directories will not be quoted; however, any
+                      dollar signs appearing in filenames will not be  quoted,
+                      either.   This  is  active only when bash is using back-
+                      slashes to quote completed filenames.  This variable  is
+                      set  by  default,  which is the default bash behavior in
                       versions through 4.2.
               d\bdi\bir\bre\bex\bxp\bpa\ban\bnd\bd
-                      If  set,  b\bba\bas\bsh\bh replaces directory names with the results
-                      of word expansion when performing  filename  completion.
-                      This  changes  the contents of the readline editing buf-
-                      fer.  If not set, b\bba\bas\bsh\bh attempts  to  preserve  what  the
+                      If set, b\bba\bas\bsh\bh replaces directory names with  the  results
+                      of  word  expansion when performing filename completion.
+                      This changes the contents of the readline  editing  buf-
+                      fer.   If  not  set,  b\bba\bas\bsh\bh attempts to preserve what the
                       user typed.
               d\bdi\bir\brs\bsp\bpe\bel\bll\bl
-                      If  set,  b\bba\bas\bsh\bh attempts spelling correction on directory
-                      names during word completion if the directory name  ini-
+                      If set, b\bba\bas\bsh\bh attempts spelling correction  on  directory
+                      names  during word completion if the directory name ini-
                       tially supplied does not exist.
-              d\bdo\bot\btg\bgl\blo\bob\bb If  set, b\bba\bas\bsh\bh includes filenames beginning with a `.' in
+              d\bdo\bot\btg\bgl\blo\bob\bb If set, b\bba\bas\bsh\bh includes filenames beginning with a `.'  in
                       the results of pathname expansion.
               e\bex\bxe\bec\bcf\bfa\bai\bil\bl
                       If set, a non-interactive shell will not exit if it can-
-                      not  execute  the  file  specified as an argument to the
-                      e\bex\bxe\bec\bbuiltin command.  An  interactive  shell  does  not
+                      not execute the file specified as  an  argument  to  the
+                      e\bex\bxe\bec\b builtin  command.   An  interactive shell does not
                       exit if e\bex\bxe\bec\bc fails.
               e\bex\bxp\bpa\ban\bnd\bd_\b_a\bal\bli\bia\bas\bse\bes\bs
-                      If  set,  aliases  are expanded as described above under
+                      If set, aliases are expanded as  described  above  under
                       A\bAL\bLI\bIA\bAS\bSE\bES\bS.  This option is enabled by default for interac-
                       tive shells.
               e\bex\bxt\btd\bde\beb\bbu\bug\bg
-                      If  set,  behavior  intended  for  use  by  debuggers is
+                      If set,  behavior  intended  for  use  by  debuggers  is
                       enabled:
                       1\b1.\b.     The -\b-F\bF option to the d\bde\bec\bcl\bla\bar\bre\be builtin displays the
                              source file name and line number corresponding to
                              each function name supplied as an argument.
-                      2\b2.\b.     If the command run by the D\bDE\bEB\bBU\bUG\bG  trap  returns  a
-                             non-zero  value,  the next command is skipped and
+                      2\b2.\b.     If  the  command  run by the D\bDE\bEB\bBU\bUG\bG trap returns a
+                             non-zero value, the next command is  skipped  and
                              not executed.
-                      3\b3.\b.     If the command run by the D\bDE\bEB\bBU\bUG\bG  trap  returns  a
-                             value  of 2, and the shell is executing in a sub-
-                             routine (a shell function or a shell script  exe-
-                             cuted  by  the  .\b.  or s\bso\bou\bur\brc\bce\be builtins), the shell
+                      3\b3.\b.     If  the  command  run by the D\bDE\bEB\bBU\bUG\bG trap returns a
+                             value of 2, and the shell is executing in a  sub-
+                             routine  (a shell function or a shell script exe-
+                             cuted by the .\b. or  s\bso\bou\bur\brc\bce\be  builtins),  the  shell
                              simulates a call to r\bre\bet\btu\bur\brn\bn.
-                      4\b4.\b.     B\bBA\bAS\bSH\bH_\b_A\bAR\bRG\bGC\band B\bBA\bAS\bSH\bH_\b_A\bAR\bRG\bGV\bV are updated as  described
+                      4\b4.\b.     B\bBA\bAS\bSH\bH_\b_A\bAR\bRG\bGC\b and B\bBA\bAS\bSH\bH_\b_A\bAR\bRG\bGV\bV are updated as described
                              in their descriptions above.
-                      5\b5.\b.     Function  tracing  is  enabled: command substitu-
+                      5\b5.\b.     Function tracing is  enabled:  command  substitu-
                              tion, shell functions, and subshells invoked with
                              (\b( _\bc_\bo_\bm_\bm_\ba_\bn_\bd )\b) inherit the D\bDE\bEB\bBU\bUG\bG and R\bRE\bET\bTU\bUR\bRN\bN traps.
-                      6\b6.\b.     Error  tracing  is enabled: command substitution,
-                             shell functions, and  subshells  invoked  with  (\b(
+                      6\b6.\b.     Error tracing is enabled:  command  substitution,
+                             shell  functions,  and  subshells  invoked with (\b(
                              _\bc_\bo_\bm_\bm_\ba_\bn_\bd )\b) inherit the E\bER\bRR\bR trap.
               e\bex\bxt\btg\bgl\blo\bob\bb If set, the extended pattern matching features described
                       above under P\bPa\bat\bth\bhn\bna\bam\bme\be E\bEx\bxp\bpa\ban\bns\bsi\bio\bon\bn are enabled.
               e\bex\bxt\btq\bqu\buo\bot\bte\be
-                      If set, $\b$'_\bs_\bt_\br_\bi_\bn_\bg' and  $\b$"_\bs_\bt_\br_\bi_\bn_\bg"  quoting  is  performed
-                      within   $\b${\b{_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br}\b}   expansions  enclosed  in  double
+                      If  set,  $\b$'_\bs_\bt_\br_\bi_\bn_\bg'  and  $\b$"_\bs_\bt_\br_\bi_\bn_\bg" quoting is performed
+                      within  $\b${\b{_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br}\b}  expansions  enclosed   in   double
                       quotes.  This option is enabled by default.
               f\bfa\bai\bil\blg\bgl\blo\bob\bb
-                      If set, patterns which fail to  match  filenames  during
+                      If  set,  patterns  which fail to match filenames during
                       pathname expansion result in an expansion error.
               f\bfo\bor\brc\bce\be_\b_f\bfi\big\bgn\bno\bor\bre\be
-                      If  set,  the  suffixes  specified  by the F\bFI\bIG\bGN\bNO\bOR\bRE\bE shell
-                      variable cause words to be ignored when performing  word
+                      If set, the suffixes  specified  by  the  F\bFI\bIG\bGN\bNO\bOR\bRE\b shell
+                      variable  cause words to be ignored when performing word
                       completion even if the ignored words are the only possi-
                       ble  completions.   See  S\bSH\bHE\bEL\bLL\bL  V\bVA\bAR\bRI\bIA\bAB\bBL\bLE\bES\bS  above  for  a
-                      description  of  F\bFI\bIG\bGN\bNO\bOR\bRE\bE.   This  option  is  enabled by
+                      description of  F\bFI\bIG\bGN\bNO\bOR\bRE\bE.   This  option  is  enabled  by
                       default.
               g\bgl\blo\bob\bba\bas\bsc\bci\bii\bir\bra\ban\bng\bge\bes\bs
-                      If set,  range  expressions  used  in  pattern  matching
-                      bracket  expressions (see P\bPa\bat\btt\bte\ber\brn\bn M\bMa\bat\btc\bch\bhi\bin\bng\bg above) behave
-                      as if in the traditional C locale when  performing  com-
+                      If  set,  range  expressions  used  in  pattern matching
+                      bracket expressions (see P\bPa\bat\btt\bte\ber\brn\bn M\bMa\bat\btc\bch\bhi\bin\bng\bg above)  behave
+                      as  if  in the traditional C locale when performing com-
                       parisons.   That  is,  the  current  locale's  collating
-                      sequence is not taken into account, so b\bb will  not  col-
-                      late  between  A\bA  and  B\bB,  and upper-case and lower-case
+                      sequence  is  not taken into account, so b\bb will not col-
+                      late between A\bA and  B\bB,  and  upper-case  and  lower-case
                       ASCII characters will collate together.
               g\bgl\blo\bob\bbs\bst\bta\bar\br
                       If set, the pattern *\b**\b* used in a pathname expansion con-
-                      text  will  match all files and zero or more directories
-                      and subdirectories.  If the pattern is followed by a  /\b/,
+                      text will match all files and zero or  more  directories
+                      and  subdirectories.  If the pattern is followed by a /\b/,
                       only directories and subdirectories match.
               g\bgn\bnu\bu_\b_e\ber\brr\brf\bfm\bmt\bt
                       If set, shell error messages are written in the standard
                       GNU error message format.
               h\bhi\bis\bst\bta\bap\bpp\bpe\ben\bnd\bd
-                      If set, the history list is appended to the  file  named
-                      by  the  value  of  the H\bHI\bIS\bST\bTF\bFI\bIL\bLE\bE variable when the shell
+                      If  set,  the history list is appended to the file named
+                      by the value of the H\bHI\bIS\bST\bTF\bFI\bIL\bLE\bE  variable  when  the  shell
                       exits, rather than overwriting the file.
               h\bhi\bis\bst\btr\bre\bee\bed\bdi\bit\bt
-                      If set, and r\bre\bea\bad\bdl\bli\bin\bne\be is being used, a user is given  the
+                      If  set, and r\bre\bea\bad\bdl\bli\bin\bne\be is being used, a user is given the
                       opportunity to re-edit a failed history substitution.
               h\bhi\bis\bst\btv\bve\ber\bri\bif\bfy\by
-                      If  set, and r\bre\bea\bad\bdl\bli\bin\bne\be is being used, the results of his-
-                      tory substitution are  not  immediately  passed  to  the
-                      shell  parser.   Instead,  the  resulting line is loaded
+                      If set, and r\bre\bea\bad\bdl\bli\bin\bne\be is being used, the results of  his-
+                      tory  substitution  are  not  immediately  passed to the
+                      shell parser.  Instead, the  resulting  line  is  loaded
                       into the r\bre\bea\bad\bdl\bli\bin\bne\be editing buffer, allowing further modi-
                       fication.
               h\bho\bos\bst\btc\bco\bom\bmp\bpl\ble\bet\bte\be
                       If set, and r\bre\bea\bad\bdl\bli\bin\bne\be is being used, b\bba\bas\bsh\bh will attempt to
-                      perform hostname completion when a word containing  a  @\b@
-                      is   being  completed  (see  C\bCo\bom\bmp\bpl\ble\bet\bti\bin\bng\bg  under  R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE
+                      perform  hostname  completion when a word containing a @\b@
+                      is  being  completed  (see  C\bCo\bom\bmp\bpl\ble\bet\bti\bin\bng\bg  under   R\bRE\bEA\bAD\bDL\bLI\bIN\bNE\bE
                       above).  This is enabled by default.
               h\bhu\bup\bpo\bon\bne\bex\bxi\bit\bt
                       If set, b\bba\bas\bsh\bh will send S\bSI\bIG\bGH\bHU\bUP\bP to all jobs when an inter-
                       active login shell exits.
               i\bin\bnt\bte\ber\bra\bac\bct\bti\biv\bve\be_\b_c\bco\bom\bmm\bme\ben\bnt\bts\bs
                       If set, allow a word beginning with #\b# to cause that word
-                      and all remaining characters on that line to be  ignored
-                      in  an  interactive  shell  (see  C\bCO\bOM\bMM\bME\bEN\bNT\bTS\bS above).  This
+                      and  all remaining characters on that line to be ignored
+                      in an interactive  shell  (see  C\bCO\bOM\bMM\bME\bEN\bNT\bTS\bS  above).   This
                       option is enabled by default.
               l\bla\bas\bst\btp\bpi\bip\bpe\be
-                      If set, and job control is not active,  the  shell  runs
+                      If  set,  and  job control is not active, the shell runs
                       the last command of a pipeline not executed in the back-
                       ground in the current shell environment.
-              l\bli\bit\bth\bhi\bis\bst\bt If set, and the c\bcm\bmd\bdh\bhi\bis\bst\bt option  is  enabled,  multi-line
+              l\bli\bit\bth\bhi\bis\bst\bt If  set,  and  the c\bcm\bmd\bdh\bhi\bis\bst\bt option is enabled, multi-line
                       commands are saved to the history with embedded newlines
                       rather than using semicolon separators where possible.
               l\blo\bog\bgi\bin\bn_\b_s\bsh\bhe\bel\bll\bl
-                      The shell sets this option if it is started as  a  login
-                      shell  (see  I\bIN\bNV\bVO\bOC\bCA\bAT\bTI\bIO\bON\bN  above).   The  value may not be
+                      The  shell  sets this option if it is started as a login
+                      shell (see I\bIN\bNV\bVO\bOC\bCA\bAT\bTI\bIO\bON\bN above).   The  value  may  not  be
                       changed.
               m\bma\bai\bil\blw\bwa\bar\brn\bn
-                      If set, and a file that b\bba\bas\bsh\bh is checking  for  mail  has
-                      been  accessed  since  the last time it was checked, the
-                      message ``The mail in _\bm_\ba_\bi_\bl_\bf_\bi_\bl_\be has been read''  is  dis-
+                      If  set,  and  a file that b\bba\bas\bsh\bh is checking for mail has
+                      been accessed since the last time it  was  checked,  the
+                      message  ``The  mail in _\bm_\ba_\bi_\bl_\bf_\bi_\bl_\be has been read'' is dis-
                       played.
               n\bno\bo_\b_e\bem\bmp\bpt\bty\by_\b_c\bcm\bmd\bd_\b_c\bco\bom\bmp\bpl\ble\bet\bti\bio\bon\bn
-                      If  set,  and  r\bre\bea\bad\bdl\bli\bin\bne\be  is  being  used,  b\bba\bas\bsh\bh will not
+                      If set, and  r\bre\bea\bad\bdl\bli\bin\bne\be  is  being  used,  b\bba\bas\bsh\bh  will  not
                       attempt to search the P\bPA\bAT\bTH\bH for possible completions when
                       completion is attempted on an empty line.
               n\bno\boc\bca\bas\bse\beg\bgl\blo\bob\bb
-                      If  set,  b\bba\bas\bsh\bh  matches  filenames in a case-insensitive
+                      If set, b\bba\bas\bsh\bh matches  filenames  in  a  case-insensitive
                       fashion when performing pathname expansion (see P\bPa\bat\bth\bhn\bna\bam\bme\be
                       E\bEx\bxp\bpa\ban\bns\bsi\bio\bon\bn above).
               n\bno\boc\bca\bas\bse\bem\bma\bat\btc\bch\bh
-                      If  set,  b\bba\bas\bsh\bh  matches  patterns  in a case-insensitive
+                      If set, b\bba\bas\bsh\bh  matches  patterns  in  a  case-insensitive
                       fashion when performing matching while executing c\bca\bas\bse\be or
-                      [\b[[\b[ conditional commands, or when filtering possible com-
+                      [\b[[\b[ conditional commands, when performing pattern substi-
+                      tution  word expansions, or when filtering possible com-
                       pletions as part of programmable completion.
               n\bnu\bul\bll\blg\bgl\blo\bob\bb
                       If set, b\bba\bas\bsh\bh allows patterns which match no  files  (see
@@ -5785,4 +5818,4 @@ B\bBU\bUG\bGS\bS
 
 
 
-GNU Bash 4.3                   2014 November 21                        BASH(1)
+GNU Bash 4.3                   2014 November 28                        BASH(1)
diff --git a/examples/loadables/Makefile.in.save b/examples/loadables/Makefile.in.save
new file mode 100644 (file)
index 0000000..f6208f5
--- /dev/null
@@ -0,0 +1,238 @@
+#
+# Simple makefile for the sample loadable builtins
+#
+# Copyright (C) 1996 Free Software Foundation, Inc.     
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
+
+# Include some boilerplate Gnu makefile definitions.
+prefix = @prefix@
+
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+libdir = @libdir@
+infodir = @infodir@
+includedir = @includedir@
+
+topdir = @top_srcdir@
+BUILD_DIR = @BUILD_DIR@
+srcdir = @srcdir@
+VPATH = .:@srcdir@
+
+@SET_MAKE@
+CC = @CC@
+RM = rm -f
+
+SHELL = @MAKE_SHELL@
+
+host_os = @host_os@
+host_cpu = @host_cpu@
+host_vendor = @host_vendor@
+
+CFLAGS = @CFLAGS@
+LOCAL_CFLAGS = @LOCAL_CFLAGS@
+DEFS = @DEFS@
+LOCAL_DEFS = @LOCAL_DEFS@
+
+CPPFLAGS = @CPPFLAGS@
+
+BASHINCDIR = ${topdir}/include
+
+LIBBUILD = ${BUILD_DIR}/lib
+
+INTL_LIBSRC = ${topdir}/lib/intl
+INTL_BUILDDIR = ${LIBBUILD}/intl
+INTL_INC = @INTL_INC@
+LIBINTL_H = @LIBINTL_H@
+
+CCFLAGS = $(DEFS) $(LOCAL_DEFS) $(LOCAL_CFLAGS) $(CFLAGS)
+
+#
+# These values are generated for configure by ${topdir}/support/shobj-conf.
+# If your system is not supported by that script, but includes facilities for
+# dynamic loading of shared objects, please update the script and send the
+# changes to bash-maintainers@gnu.org.
+#
+SHOBJ_CC = @SHOBJ_CC@
+SHOBJ_CFLAGS = @SHOBJ_CFLAGS@
+SHOBJ_LD = @SHOBJ_LD@
+SHOBJ_LDFLAGS = @SHOBJ_LDFLAGS@
+SHOBJ_XLDFLAGS = @SHOBJ_XLDFLAGS@
+SHOBJ_LIBS = @SHOBJ_LIBS@
+SHOBJ_STATUS = @SHOBJ_STATUS@
+
+INC = -I. -I.. -I$(topdir) -I$(topdir)/lib -I$(topdir)/builtins \
+      -I$(BASHINCDIR) -I$(BUILD_DIR) -I$(LIBBUILD) \
+      -I$(BUILD_DIR)/builtins $(INTL_INC)
+
+.c.o:
+       $(SHOBJ_CC) $(SHOBJ_CFLAGS) $(CCFLAGS) $(INC) -c -o $@ $<
+
+
+ALLPROG = print truefalse sleep pushd finfo logname basename dirname \
+         tty pathchk tee head mkdir rmdir printenv id whoami \
+         uname sync push ln unlink cut realpath getconf strftime
+OTHERPROG = necho hello cat
+
+all:   $(SHOBJ_STATUS)
+
+supported:     $(ALLPROG)
+others:                $(OTHERPROG)
+
+unsupported:
+       @echo "Your system (${host_os}) is not supported by the"
+       @echo "${topdir}/support/shobj-conf script."
+       @echo "If your operating system provides facilities for dynamic"
+       @echo "loading of shared objects using the dlopen(3) interface,"
+       @echo "please update the script and re-run configure.
+       @echo "Please send the changes you made to bash-maintainers@gnu.org"
+       @echo "for inclusion in future bash releases."
+
+everything: supported others
+
+print: print.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ print.o $(SHOBJ_LIBS)
+
+necho: necho.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ necho.o $(SHOBJ_LIBS)
+
+getconf: getconf.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ getconf.o $(SHOBJ_LIBS)
+
+hello: hello.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ hello.o $(SHOBJ_LIBS)
+
+truefalse: truefalse.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ truefalse.o $(SHOBJ_LIBS)
+
+sleep: sleep.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ sleep.o $(SHOBJ_LIBS)
+
+finfo: finfo.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ finfo.o $(SHOBJ_LIBS)
+
+cat:   cat.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ cat.o $(SHOBJ_LIBS)
+
+logname:       logname.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ logname.o $(SHOBJ_LIBS)
+
+basename:      basename.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ basename.o $(SHOBJ_LIBS)
+
+dirname:       dirname.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ dirname.o $(SHOBJ_LIBS)
+
+tty:   tty.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ tty.o $(SHOBJ_LIBS)
+
+pathchk:       pathchk.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ pathchk.o $(SHOBJ_LIBS)
+
+tee:   tee.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ tee.o $(SHOBJ_LIBS)
+
+mkdir: mkdir.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ mkdir.o $(SHOBJ_LIBS)
+
+rmdir: rmdir.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ rmdir.o $(SHOBJ_LIBS)
+
+head:  head.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ head.o $(SHOBJ_LIBS)
+
+printenv:      printenv.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ printenv.o $(SHOBJ_LIBS)
+
+id:    id.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ id.o $(SHOBJ_LIBS)
+
+whoami:        whoami.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ whoami.o $(SHOBJ_LIBS)
+
+uname: uname.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ uname.o $(SHOBJ_LIBS)
+
+sync:  sync.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ sync.o $(SHOBJ_LIBS)
+
+push:  push.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ push.o $(SHOBJ_LIBS)
+
+ln:    ln.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ ln.o $(SHOBJ_LIBS)
+
+unlink:        unlink.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ unlink.o $(SHOBJ_LIBS)
+
+cut:   cut.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ cut.o $(SHOBJ_LIBS)
+
+realpath:      realpath.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ realpath.o $(SHOBJ_LIBS)
+
+strftime:      strftime.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ strftime.o $(SHOBJ_LIBS)
+
+# pushd is a special case.  We use the same source that the builtin version
+# uses, with special compilation options.
+#
+pushd.c:       ${topdir}/builtins/pushd.def
+       $(RM) $@
+       ${BUILD_DIR}/builtins/mkbuiltins -D ${topdir}/builtins ${topdir}/builtins/pushd.def
+
+pushd.o:       pushd.c
+       $(RM) $@
+       $(SHOBJ_CC) -DHAVE_CONFIG_H -DPUSHD_AND_POPD -DLOADABLE_BUILTIN $(SHOBJ_CFLAGS) $(CFLAGS) $(CPPFLAGS) $(INC) -c -o $@ $<
+
+pushd: pushd.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ pushd.o $(SHOBJ_LIBS)
+
+clean:
+       $(RM) $(ALLPROG) $(OTHERPROG) *.o
+       -( cd perl && ${MAKE} ${MFLAGS} $@ )
+
+mostlyclean:   clean
+       -( cd perl && ${MAKE} ${MFLAGS} $@ )
+
+distclean maintainer-clean: clean
+       $(RM) Makefile pushd.c
+       -( cd perl && ${MAKE} ${MFLAGS} $@ )
+
+print.o: print.c
+truefalse.o: truefalse.c
+sleep.o: sleep.c
+finfo.o: finfo.c
+logname.o: logname.c
+basename.o: basename.c
+dirname.o: dirname.c
+tty.o: tty.c
+pathchk.o: pathchk.c
+tee.o: tee.c
+head.o: head.c
+rmdir.o: rmdir.c
+necho.o: necho.c
+getconf.o: getconf.c
+hello.o: hello.c
+cat.o: cat.c
+printenv.o: printenv.c
+id.o: id.c
+whoami.o: whoami.c
+uname.o: uname.c
+sync.o: sync.c
+push.o: push.c
+mkdir.o: mkdir.c
+realpath.o: realpath.c
+strftime.o: strftime.c
index 3b51cee3d20743cc531861ebdb218664ffcb8f54..5864d1da8f20bb8ce2b9c6e9dfb8aee669022263 100644 (file)
@@ -4504,7 +4504,7 @@ execute_function (var, words, flags, fds_to_close, async, subshell)
   COMMAND *tc, *fc, *save_current;
   char *debug_trap, *error_trap, *return_trap;
 #if defined (ARRAY_VARS)
-  SHELL_VAR *funcname_v, *nfv, *bash_source_v, *bash_lineno_v;
+  SHELL_VAR *funcname_v, *bash_source_v, *bash_lineno_v;
   ARRAY *funcname_a;
   volatile ARRAY *bash_source_a;
   volatile ARRAY *bash_lineno_a;
@@ -4513,6 +4513,7 @@ execute_function (var, words, flags, fds_to_close, async, subshell)
   FUNCTION_DEF *shell_fn;
   char *sfile, *t;
   sh_getopt_state_t *gs;
+  SHELL_VAR *gv;
 
   USE_VAR(fc);
 
@@ -4706,8 +4707,8 @@ execute_function (var, words, flags, fds_to_close, async, subshell)
     pop_args ();
 
   /* If we have a local copy of OPTIND, note it in the saved getopts state. */
-  nfv = find_variable ("OPTIND");
-  if (nfv && nfv->context == variable_context)
+  gv = find_variable ("OPTIND");
+  if (gv && gv->context == variable_context)
     gs->gs_flags |= 1;
 
   if (subshell == 0)
diff --git a/jobs.c b/jobs.c
index f4d986bb89c3a187e66cb8d21a14f2de1fc8b71b..681ec5bfe982480efa1dc0d37dcb452700ec86a9 100644 (file)
--- a/jobs.c
+++ b/jobs.c
@@ -1754,6 +1754,7 @@ make_child (command, async_p)
   while ((pid = fork ()) < 0 && errno == EAGAIN && forksleep < FORKSLEEP_MAX)
     {
       /* bash-4.2 */
+      sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
       /* If we can't create any children, try to reap some dead ones. */
       waitchld (-1, 0);
 
@@ -1763,6 +1764,10 @@ make_child (command, async_p)
       if (sleep (forksleep) != 0)
        break;
       forksleep <<= 1;
+
+      if (interrupt_state)
+       break;
+      sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
     }
 
   if (pid != 0)
@@ -2590,12 +2595,12 @@ itrace("wait_for: blocking wait for %d returns %d child = %p", (int)pid, r, chil
      of the last child in the pipeline is the significant one.  If the command
      or job was terminated by a signal, note that value also. */
   termination_state = (job != NO_JOB) ? job_exit_status (job)
-                                     : process_exit_status (child->status);
+                                     : (child ? process_exit_status (child->status) : EXECUTION_SUCCESS);
   last_command_exit_signal = (job != NO_JOB) ? job_exit_signal (job)
-                                            : process_exit_signal (child->status);
+                                            : (child ? process_exit_signal (child->status) : 0);
 
   /* XXX */
-  if ((job != NO_JOB && JOBSTATE (job) == JSTOPPED) || WIFSTOPPED (child->status))
+  if ((job != NO_JOB && JOBSTATE (job) == JSTOPPED) || (child && WIFSTOPPED (child->status)))
     termination_state = 128 + WSTOPSIG (child->status);
 
   if (job == NO_JOB || IS_JOBCONTROL (job))
diff --git a/jobs.c~ b/jobs.c~
new file mode 100644 (file)
index 0000000..928c880
--- /dev/null
+++ b/jobs.c~
@@ -0,0 +1,4545 @@
+/* jobs.c - functions that make children, remember them, and handle their termination. */
+
+/* This file works with both POSIX and BSD systems.  It implements job
+   control. */
+
+/* Copyright (C) 1989-2013 Free Software Foundation, Inc.
+
+   This file is part of GNU Bash, the Bourne Again SHell.
+
+   Bash is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   Bash is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with Bash.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "config.h"
+
+#include "bashtypes.h"
+#include "trap.h"
+#include <stdio.h>
+#include <signal.h>
+#include <errno.h>
+
+#if defined (HAVE_UNISTD_H)
+#  include <unistd.h>
+#endif
+
+#include "posixtime.h"
+
+#if defined (HAVE_SYS_RESOURCE_H) && defined (HAVE_WAIT3) && !defined (_POSIX_VERSION) && !defined (RLIMTYPE)
+#  include <sys/resource.h>
+#endif /* !_POSIX_VERSION && HAVE_SYS_RESOURCE_H && HAVE_WAIT3 && !RLIMTYPE */
+
+#if defined (HAVE_SYS_FILE_H)
+#  include <sys/file.h>
+#endif
+
+#include "filecntl.h"
+#include <sys/ioctl.h>
+#if defined (HAVE_SYS_PARAM_H)
+#include <sys/param.h>
+#endif
+
+#if defined (BUFFERED_INPUT)
+#  include "input.h"
+#endif
+
+/* Need to include this up here for *_TTY_DRIVER definitions. */
+#include "shtty.h"
+
+/* Define this if your output is getting swallowed.  It's a no-op on
+   machines with the termio or termios tty drivers. */
+/* #define DRAIN_OUTPUT */
+
+/* For the TIOCGPGRP and TIOCSPGRP ioctl parameters on HP-UX */
+#if defined (hpux) && !defined (TERMIOS_TTY_DRIVER)
+#  include <bsdtty.h>
+#endif /* hpux && !TERMIOS_TTY_DRIVER */
+
+#include "bashansi.h"
+#include "bashintl.h"
+#include "shell.h"
+#include "jobs.h"
+#include "execute_cmd.h"
+#include "flags.h"
+
+#include "builtins/builtext.h"
+#include "builtins/common.h"
+
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+#if !defined (HAVE_KILLPG)
+extern int killpg __P((pid_t, int));
+#endif
+
+#if !DEFAULT_CHILD_MAX
+#  define DEFAULT_CHILD_MAX 32
+#endif
+
+#if !MAX_CHILD_MAX
+#  define MAX_CHILD_MAX 8192
+#endif
+
+#if !defined (DEBUG)
+#define MAX_JOBS_IN_ARRAY 4096         /* production */
+#else
+#define MAX_JOBS_IN_ARRAY 128          /* testing */
+#endif
+
+/* Flag values for second argument to delete_job */
+#define DEL_WARNSTOPPED                1       /* warn about deleting stopped jobs */
+#define DEL_NOBGPID            2       /* don't add pgrp leader to bgpids */
+
+/* Take care of system dependencies that must be handled when waiting for
+   children.  The arguments to the WAITPID macro match those to the Posix.1
+   waitpid() function. */
+
+#if defined (ultrix) && defined (mips) && defined (_POSIX_VERSION)
+#  define WAITPID(pid, statusp, options) \
+       wait3 ((union wait *)statusp, options, (struct rusage *)0)
+#else
+#  if defined (_POSIX_VERSION) || defined (HAVE_WAITPID)
+#    define WAITPID(pid, statusp, options) \
+       waitpid ((pid_t)pid, statusp, options)
+#  else
+#    if defined (HAVE_WAIT3)
+#      define WAITPID(pid, statusp, options) \
+       wait3 (statusp, options, (struct rusage *)0)
+#    else
+#      define WAITPID(pid, statusp, options) \
+       wait3 (statusp, options, (int *)0)
+#    endif /* HAVE_WAIT3 */
+#  endif /* !_POSIX_VERSION && !HAVE_WAITPID*/
+#endif /* !(Ultrix && mips && _POSIX_VERSION) */
+
+/* getpgrp () varies between systems.  Even systems that claim to be
+   Posix.1 compatible lie sometimes (Ultrix, SunOS4, apollo). */
+#if defined (GETPGRP_VOID)
+#  define getpgid(p) getpgrp ()
+#else
+#  define getpgid(p) getpgrp (p)
+#endif /* !GETPGRP_VOID */
+
+/* If the system needs it, REINSTALL_SIGCHLD_HANDLER will reinstall the
+   handler for SIGCHLD. */
+#if defined (MUST_REINSTALL_SIGHANDLERS)
+#  define REINSTALL_SIGCHLD_HANDLER signal (SIGCHLD, sigchld_handler)
+#else
+#  define REINSTALL_SIGCHLD_HANDLER
+#endif /* !MUST_REINSTALL_SIGHANDLERS */
+
+/* Some systems let waitpid(2) tell callers about stopped children. */
+#if !defined (WCONTINUED) || defined (WCONTINUED_BROKEN)
+#  undef WCONTINUED
+#  define WCONTINUED 0
+#endif
+#if !defined (WIFCONTINUED)
+#  define WIFCONTINUED(s)      (0)
+#endif
+
+/* The number of additional slots to allocate when we run out. */
+#define JOB_SLOTS 8
+
+typedef int sh_job_map_func_t __P((JOB *, int, int, int));
+
+/* Variables used here but defined in other files. */
+extern int subshell_environment, line_number;
+extern int posixly_correct, shell_level;
+extern int last_command_exit_value, last_command_exit_signal;
+extern int loop_level, breaking;
+extern int executing_list;
+extern int sourcelevel;
+extern int running_trap;
+extern sh_builtin_func_t *this_shell_builtin;
+extern char *shell_name, *this_command_name;
+extern sigset_t top_level_mask;
+extern procenv_t wait_intr_buf;
+extern int wait_signal_received;
+extern WORD_LIST *subst_assign_varlist;
+
+static struct jobstats zerojs = { -1L, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NO_JOB, NO_JOB, 0, 0 };
+struct jobstats js = { -1L, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NO_JOB, NO_JOB, 0, 0 };
+
+struct bgpids bgpids = { 0, 0, 0 };
+
+/* The array of known jobs. */
+JOB **jobs = (JOB **)NULL;
+
+#if 0
+/* The number of slots currently allocated to JOBS. */
+int job_slots = 0;
+#endif
+
+/* The controlling tty for this shell. */
+int shell_tty = -1;
+
+/* The shell's process group. */
+pid_t shell_pgrp = NO_PID;
+
+/* The terminal's process group. */
+pid_t terminal_pgrp = NO_PID;
+
+/* The process group of the shell's parent. */
+pid_t original_pgrp = NO_PID;
+
+/* The process group of the pipeline currently being made. */
+pid_t pipeline_pgrp = (pid_t)0;
+
+#if defined (PGRP_PIPE)
+/* Pipes which each shell uses to communicate with the process group leader
+   until all of the processes in a pipeline have been started.  Then the
+   process leader is allowed to continue. */
+int pgrp_pipe[2] = { -1, -1 };
+#endif
+
+#if 0
+/* The job which is current; i.e. the one that `%+' stands for. */
+int current_job = NO_JOB;
+
+/* The previous job; i.e. the one that `%-' stands for. */
+int previous_job = NO_JOB;
+#endif
+
+/* Last child made by the shell.  */
+volatile pid_t last_made_pid = NO_PID;
+
+/* Pid of the last asynchronous child. */
+volatile pid_t last_asynchronous_pid = NO_PID;
+
+/* The pipeline currently being built. */
+PROCESS *the_pipeline = (PROCESS *)NULL;
+
+/* If this is non-zero, do job control. */
+int job_control = 1;
+
+/* Are we running in background? (terminal_pgrp != shell_pgrp) */
+int running_in_background = 0;
+
+/* Call this when you start making children. */
+int already_making_children = 0;
+
+/* If this is non-zero, $LINES and $COLUMNS are reset after every process
+   exits from get_tty_state(). */
+int check_window_size = CHECKWINSIZE_DEFAULT;
+
+/* Functions local to this file. */
+
+static sighandler wait_sigint_handler __P((int));
+static sighandler sigchld_handler __P((int));
+static sighandler sigcont_sighandler __P((int));
+static sighandler sigstop_sighandler __P((int));
+
+static int waitchld __P((pid_t, int));
+
+static PROCESS *find_pipeline __P((pid_t, int, int *));
+static PROCESS *find_process __P((pid_t, int, int *));
+
+static char *current_working_directory __P((void));
+static char *job_working_directory __P((void));
+static char *j_strsignal __P((int));
+static char *printable_job_status __P((int, PROCESS *, int));
+
+static PROCESS *find_last_proc __P((int, int));
+static pid_t find_last_pid __P((int, int));
+
+static int set_new_line_discipline __P((int));
+static int map_over_jobs __P((sh_job_map_func_t *, int, int));
+static int job_last_stopped __P((int));
+static int job_last_running __P((int));
+static int most_recent_job_in_state __P((int, JOB_STATE));
+static int find_job __P((pid_t, int, PROCESS **));
+static int print_job __P((JOB *, int, int, int));
+static int process_exit_status __P((WAIT));
+static int process_exit_signal __P((WAIT));
+static int set_job_status_and_cleanup __P((int));
+
+static WAIT job_signal_status __P((int));
+static WAIT raw_job_exit_status __P((int));
+
+static void notify_of_job_status __P((void));
+static void reset_job_indices __P((void));
+static void cleanup_dead_jobs __P((void));
+static int processes_in_job __P((int));
+static void realloc_jobs_list __P((void));
+static int compact_jobs_list __P((int));
+static int discard_pipeline __P((PROCESS *));
+static void add_process __P((char *, pid_t));
+static void print_pipeline __P((PROCESS *, int, int, FILE *));
+static void pretty_print_job __P((int, int, FILE *));
+static void set_current_job __P((int));
+static void reset_current __P((void));
+static void set_job_running __P((int));
+static void setjstatus __P((int));
+static int maybe_give_terminal_to __P((pid_t, pid_t, int));
+static void mark_all_jobs_as_dead __P((void));
+static void mark_dead_jobs_as_notified __P((int));
+static void restore_sigint_handler __P((void));
+#if defined (PGRP_PIPE)
+static void pipe_read __P((int *));
+#endif
+
+static struct pidstat *bgp_alloc __P((pid_t, int));
+static struct pidstat *bgp_add __P((pid_t, int));
+static int bgp_delete __P((pid_t));
+static void bgp_clear __P((void));
+static int bgp_search __P((pid_t));
+static void bgp_prune __P((void));
+
+#if defined (ARRAY_VARS)
+static int *pstatuses;         /* list of pipeline statuses */
+static int statsize;
+#endif
+
+/* Used to synchronize between wait_for and other functions and the SIGCHLD
+   signal handler. */
+static int sigchld;
+static int queue_sigchld;
+
+#define QUEUE_SIGCHLD(os)      (os) = sigchld, queue_sigchld++
+
+#define UNQUEUE_SIGCHLD(os) \
+       do { \
+         queue_sigchld--; \
+         if (queue_sigchld == 0 && os != sigchld) \
+           waitchld (-1, 0); \
+       } while (0)
+
+static SigHandler *old_tstp, *old_ttou, *old_ttin;
+static SigHandler *old_cont = (SigHandler *)SIG_DFL;
+
+/* A place to temporarily save the current pipeline. */
+static PROCESS *saved_pipeline;
+static int saved_already_making_children;
+
+/* Set this to non-zero whenever you don't want the jobs list to change at
+   all: no jobs deleted and no status change notifications.  This is used,
+   for example, when executing SIGCHLD traps, which may run arbitrary
+   commands. */
+static int jobs_list_frozen;
+
+static char retcode_name_buffer[64];
+
+#if !defined (_POSIX_VERSION)
+
+/* These are definitions to map POSIX 1003.1 functions onto existing BSD
+   library functions and system calls. */
+#define setpgid(pid, pgrp)     setpgrp (pid, pgrp)
+#define tcsetpgrp(fd, pgrp)    ioctl ((fd), TIOCSPGRP, &(pgrp))
+
+pid_t
+tcgetpgrp (fd)
+     int fd;
+{
+  pid_t pgrp;
+
+  /* ioctl will handle setting errno correctly. */
+  if (ioctl (fd, TIOCGPGRP, &pgrp) < 0)
+    return (-1);
+  return (pgrp);
+}
+
+#endif /* !_POSIX_VERSION */
+
+/* Initialize the global job stats structure and other bookkeeping variables */
+void
+init_job_stats ()
+{
+  js = zerojs;
+}
+
+/* Return the working directory for the current process.  Unlike
+   job_working_directory, this does not call malloc (), nor do any
+   of the functions it calls.  This is so that it can safely be called
+   from a signal handler. */
+static char *
+current_working_directory ()
+{
+  char *dir;
+  static char d[PATH_MAX];
+
+  dir = get_string_value ("PWD");
+
+  if (dir == 0 && the_current_working_directory && no_symbolic_links)
+    dir = the_current_working_directory;
+
+  if (dir == 0)
+    {
+      dir = getcwd (d, sizeof(d));
+      if (dir)
+       dir = d;
+    }
+
+  return (dir == 0) ? "<unknown>" : dir;
+}
+
+/* Return the working directory for the current process. */
+static char *
+job_working_directory ()
+{
+  char *dir;
+
+  dir = get_string_value ("PWD");
+  if (dir)
+    return (savestring (dir));
+
+  dir = get_working_directory ("job-working-directory");
+  if (dir)
+    return (dir);
+
+  return (savestring ("<unknown>"));
+}
+
+void
+making_children ()
+{
+  if (already_making_children)
+    return;
+
+  already_making_children = 1;
+  start_pipeline ();
+}
+
+void
+stop_making_children ()
+{
+  already_making_children = 0;
+}
+
+void
+cleanup_the_pipeline ()
+{
+  PROCESS *disposer;
+  sigset_t set, oset;
+
+  BLOCK_CHILD (set, oset);
+  disposer = the_pipeline;
+  the_pipeline = (PROCESS *)NULL;
+  UNBLOCK_CHILD (oset);
+
+  if (disposer)
+    discard_pipeline (disposer);
+}
+
+void
+save_pipeline (clear)
+     int clear;
+{
+  saved_pipeline = the_pipeline;
+  if (clear)
+    the_pipeline = (PROCESS *)NULL;
+  saved_already_making_children = already_making_children;
+}
+
+void
+restore_pipeline (discard)
+     int discard;
+{
+  PROCESS *old_pipeline;
+
+  old_pipeline = the_pipeline;
+  the_pipeline = saved_pipeline;
+  already_making_children = saved_already_making_children;
+  if (discard && old_pipeline)
+    discard_pipeline (old_pipeline);
+}
+
+/* Start building a pipeline.  */
+void
+start_pipeline ()
+{
+  if (the_pipeline)
+    {
+      cleanup_the_pipeline ();
+      pipeline_pgrp = 0;
+#if defined (PGRP_PIPE)
+      sh_closepipe (pgrp_pipe);
+#endif
+    }
+
+#if defined (PGRP_PIPE)
+  if (job_control)
+    {
+      if (pipe (pgrp_pipe) == -1)
+       sys_error (_("start_pipeline: pgrp pipe"));
+    }
+#endif
+}
+
+/* Stop building a pipeline.  Install the process list in the job array.
+   This returns the index of the newly installed job.
+   DEFERRED is a command structure to be executed upon satisfactory
+   execution exit of this pipeline. */
+int
+stop_pipeline (async, deferred)
+     int async;
+     COMMAND *deferred;
+{
+  register int i, j;
+  JOB *newjob;
+  sigset_t set, oset;
+
+  BLOCK_CHILD (set, oset);
+
+#if defined (PGRP_PIPE)
+  /* The parent closes the process group synchronization pipe. */
+  sh_closepipe (pgrp_pipe);
+#endif
+
+  cleanup_dead_jobs ();
+
+  if (js.j_jobslots == 0)
+    {
+      js.j_jobslots = JOB_SLOTS;
+      jobs = (JOB **)xmalloc (js.j_jobslots * sizeof (JOB *));
+
+      /* Now blank out these new entries. */
+      for (i = 0; i < js.j_jobslots; i++)
+       jobs[i] = (JOB *)NULL;
+
+      js.j_firstj = js.j_lastj = js.j_njobs = 0;
+    }
+
+  /* Scan from the last slot backward, looking for the next free one. */
+  /* XXX - revisit this interactive assumption */
+  /* XXX - this way for now */
+  if (interactive)
+    {
+      for (i = js.j_jobslots; i; i--)
+       if (jobs[i - 1])
+         break;
+    }
+  else
+    {
+#if 0
+      /* This wraps around, but makes it inconvenient to extend the array */
+      for (i = js.j_lastj+1; i != js.j_lastj; i++)
+       {
+         if (i >= js.j_jobslots)
+           i = 0;
+         if (jobs[i] == 0)
+           break;
+       }       
+      if (i == js.j_lastj)
+        i = js.j_jobslots;
+#else
+      /* This doesn't wrap around yet. */
+      for (i = js.j_lastj ? js.j_lastj + 1 : js.j_lastj; i < js.j_jobslots; i++)
+       if (jobs[i] == 0)
+         break;
+#endif
+    }
+
+  /* Do we need more room? */
+
+  /* First try compaction */
+  if ((interactive_shell == 0 || subshell_environment) && i == js.j_jobslots && js.j_jobslots >= MAX_JOBS_IN_ARRAY)
+    i = compact_jobs_list (0);
+
+  /* If we can't compact, reallocate */
+  if (i == js.j_jobslots)
+    {
+      js.j_jobslots += JOB_SLOTS;
+      jobs = (JOB **)xrealloc (jobs, (js.j_jobslots * sizeof (JOB *)));
+
+      for (j = i; j < js.j_jobslots; j++)
+       jobs[j] = (JOB *)NULL;
+    }
+
+  /* Add the current pipeline to the job list. */
+  if (the_pipeline)
+    {
+      register PROCESS *p;
+      int any_running, any_stopped, n;
+
+      newjob = (JOB *)xmalloc (sizeof (JOB));
+
+      for (n = 1, p = the_pipeline; p->next != the_pipeline; n++, p = p->next)
+       ;
+      p->next = (PROCESS *)NULL;
+      newjob->pipe = REVERSE_LIST (the_pipeline, PROCESS *);
+      for (p = newjob->pipe; p->next; p = p->next)
+       ;
+      p->next = newjob->pipe;
+
+      the_pipeline = (PROCESS *)NULL;
+      newjob->pgrp = pipeline_pgrp;
+      pipeline_pgrp = 0;
+
+      newjob->flags = 0;
+
+      /* Flag to see if in another pgrp. */
+      if (job_control)
+       newjob->flags |= J_JOBCONTROL;
+
+      /* Set the state of this pipeline. */
+      p = newjob->pipe;
+      any_running = any_stopped = 0;
+      do
+       {
+         any_running |= PRUNNING (p);
+         any_stopped |= PSTOPPED (p);
+         p = p->next;
+       }
+      while (p != newjob->pipe);
+
+      newjob->state = any_running ? JRUNNING : (any_stopped ? JSTOPPED : JDEAD);
+      newjob->wd = job_working_directory ();
+      newjob->deferred = deferred;
+
+      newjob->j_cleanup = (sh_vptrfunc_t *)NULL;
+      newjob->cleanarg = (PTR_T) NULL;
+
+      jobs[i] = newjob;
+      if (newjob->state == JDEAD && (newjob->flags & J_FOREGROUND))
+       setjstatus (i);
+      if (newjob->state == JDEAD)
+       {
+         js.c_reaped += n;     /* wouldn't have been done since this was not part of a job */
+         js.j_ndead++;
+       }
+      js.c_injobs += n;
+
+      js.j_lastj = i;
+      js.j_njobs++;
+    }
+  else
+    newjob = (JOB *)NULL;
+
+  if (newjob)
+    js.j_lastmade = newjob;
+
+  if (async)
+    {
+      if (newjob)
+       {
+         newjob->flags &= ~J_FOREGROUND;
+         newjob->flags |= J_ASYNC;
+         js.j_lastasync = newjob;
+       }
+      reset_current ();
+    }
+  else
+    {
+      if (newjob)
+       {
+         newjob->flags |= J_FOREGROUND;
+         /*
+          *            !!!!! NOTE !!!!!  (chet@ins.cwru.edu)
+          *
+          * The currently-accepted job control wisdom says to set the
+          * terminal's process group n+1 times in an n-step pipeline:
+          * once in the parent and once in each child.  This is where
+          * the parent gives it away.
+          *
+          * Don't give the terminal away if this shell is an asynchronous
+          * subshell or if we're a (presumably non-interactive) shell running
+          * in the background.
+          *
+          */
+         if (job_control && newjob->pgrp && (subshell_environment&SUBSHELL_ASYNC) == 0 && running_in_background == 0)
+           maybe_give_terminal_to (shell_pgrp, newjob->pgrp, 0);
+       }
+    }
+
+  stop_making_children ();
+  UNBLOCK_CHILD (oset);
+  return (newjob ? i : js.j_current);
+}
+
+/* Functions to manage the list of exited background pids whose status has
+   been saved. */
+
+static struct pidstat *
+bgp_alloc (pid, status)
+     pid_t pid;
+     int status;
+{
+  struct pidstat *ps;
+
+  ps = (struct pidstat *)xmalloc (sizeof (struct pidstat));
+  ps->pid = pid;
+  ps->status = status;
+  ps->next = (struct pidstat *)0;
+  return ps;
+}
+
+static struct pidstat *
+bgp_add (pid, status)
+     pid_t pid;
+     int status;
+{
+  struct pidstat *ps;
+
+  ps = bgp_alloc (pid, status);
+
+  if (bgpids.list == 0)
+    {
+      bgpids.list = bgpids.end = ps;
+      bgpids.npid = 0;                 /* just to make sure */
+    }
+  else
+    {
+      bgpids.end->next = ps;
+      bgpids.end = ps;
+    }
+  bgpids.npid++;
+
+  if (bgpids.npid > js.c_childmax)
+    bgp_prune ();
+
+  return ps;
+}
+
+static int
+bgp_delete (pid)
+     pid_t pid;
+{
+  struct pidstat *prev, *p;
+
+  for (prev = p = bgpids.list; p; prev = p, p = p->next)
+    if (p->pid == pid)
+      {
+       prev->next = p->next;   /* remove from list */
+       break;
+      }
+
+  if (p == 0)
+    return 0;          /* not found */
+
+#if defined (DEBUG)
+  itrace("bgp_delete: deleting %d", pid);
+#endif
+
+  /* Housekeeping in the border cases. */
+  if (p == bgpids.list)
+    bgpids.list = bgpids.list->next;
+  else if (p == bgpids.end)
+    bgpids.end = prev;
+
+  bgpids.npid--;
+  if (bgpids.npid == 0)
+    bgpids.list = bgpids.end = 0;
+  else if (bgpids.npid == 1)
+    bgpids.end = bgpids.list;          /* just to make sure */
+
+  free (p);
+  return 1;
+}
+
+/* Clear out the list of saved statuses */
+static void
+bgp_clear ()
+{
+  struct pidstat *ps, *p;
+
+  for (ps = bgpids.list; ps; )
+    {
+      p = ps;
+      ps = ps->next;
+      free (p);
+    }
+  bgpids.list = bgpids.end = 0;
+  bgpids.npid = 0;
+}
+
+/* Search for PID in the list of saved background pids; return its status if
+   found.  If not found, return -1. */
+static int
+bgp_search (pid)
+     pid_t pid;
+{
+  struct pidstat *ps;
+
+  for (ps = bgpids.list ; ps; ps = ps->next)
+    if (ps->pid == pid)
+      return ps->status;
+  return -1;
+}
+
+static void
+bgp_prune ()
+{
+  struct pidstat *ps;
+
+  if (bgpids.npid == 0 || bgpids.list == 0)
+    return;            /* just paranoia */
+
+  while (bgpids.npid > js.c_childmax)
+    {
+      ps = bgpids.list;
+      bgpids.list = bgpids.list->next;
+      free (ps);
+      bgpids.npid--;
+    }
+}
+
+/* Reset the values of js.j_lastj and js.j_firstj after one or both have
+   been deleted.  The caller should check whether js.j_njobs is 0 before
+   calling this.  This wraps around, but the rest of the code does not.  At
+   this point, it should not matter. */
+static void
+reset_job_indices ()
+{
+  int old;
+
+  if (jobs[js.j_firstj] == 0)
+    {
+      old = js.j_firstj++;
+      if (old >= js.j_jobslots)
+       old = js.j_jobslots - 1;
+      while (js.j_firstj != old)
+       {
+         if (js.j_firstj >= js.j_jobslots)
+           js.j_firstj = 0;
+         if (jobs[js.j_firstj] || js.j_firstj == old)  /* needed if old == 0 */
+           break;
+         js.j_firstj++;
+       }
+      if (js.j_firstj == old)
+        js.j_firstj = js.j_lastj = js.j_njobs = 0;
+    }
+  if (jobs[js.j_lastj] == 0)
+    {
+      old = js.j_lastj--;
+      if (old < 0)
+       old = 0;
+      while (js.j_lastj != old)
+       {
+         if (js.j_lastj < 0)
+           js.j_lastj = js.j_jobslots - 1;
+         if (jobs[js.j_lastj] || js.j_lastj == old)    /* needed if old == js.j_jobslots */
+           break;
+         js.j_lastj--;
+       }
+      if (js.j_lastj == old)
+        js.j_firstj = js.j_lastj = js.j_njobs = 0;
+    }
+}
+      
+/* Delete all DEAD jobs that the user had received notification about. */
+static void
+cleanup_dead_jobs ()
+{
+  register int i;
+  int os;
+
+  if (js.j_jobslots == 0 || jobs_list_frozen)
+    return;
+
+  QUEUE_SIGCHLD(os);
+
+  /* XXX could use js.j_firstj and js.j_lastj here */
+  for (i = 0; i < js.j_jobslots; i++)
+    {
+#if defined (DEBUG)
+      if (i < js.j_firstj && jobs[i])
+       itrace("cleanup_dead_jobs: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);
+      if (i > js.j_lastj && jobs[i])
+       itrace("cleanup_dead_jobs: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);
+#endif
+
+      if (jobs[i] && DEADJOB (i) && IS_NOTIFIED (i))
+       delete_job (i, 0);
+    }
+
+#if defined (COPROCESS_SUPPORT)
+  coproc_reap ();
+#endif
+
+  UNQUEUE_SIGCHLD(os);
+}
+
+static int
+processes_in_job (job)
+     int job;
+{
+  int nproc;
+  register PROCESS *p;
+
+  nproc = 0;
+  p = jobs[job]->pipe;
+  do
+    {
+      p = p->next;
+      nproc++;
+    }
+  while (p != jobs[job]->pipe);
+
+  return nproc;
+}
+
+static void
+delete_old_job (pid)
+     pid_t pid;
+{
+  PROCESS *p;
+  int job;
+
+  job = find_job (pid, 0, &p);
+  if (job != NO_JOB)
+    {
+#ifdef DEBUG
+      itrace ("delete_old_job: found pid %d in job %d with state %d", pid, job, jobs[job]->state);
+#endif
+      if (JOBSTATE (job) == JDEAD)
+       delete_job (job, DEL_NOBGPID);
+      else
+       {
+#ifdef DEBUG
+         internal_warning (_("forked pid %d appears in running job %d"), pid, job+1);
+#endif
+         if (p)
+           p->pid = 0;
+       }
+    }
+}
+
+/* Reallocate and compress the jobs list.  This returns with a jobs array
+   whose size is a multiple of JOB_SLOTS and can hold the current number of
+   jobs.  Heuristics are used to minimize the number of new reallocs. */
+static void
+realloc_jobs_list ()
+{
+  sigset_t set, oset;
+  int nsize, i, j, ncur, nprev;
+  JOB **nlist;
+
+  ncur = nprev = NO_JOB;
+  nsize = ((js.j_njobs + JOB_SLOTS - 1) / JOB_SLOTS);
+  nsize *= JOB_SLOTS;
+  i = js.j_njobs % JOB_SLOTS;
+  if (i == 0 || i > (JOB_SLOTS >> 1))
+    nsize += JOB_SLOTS;
+
+  BLOCK_CHILD (set, oset);
+  nlist = (js.j_jobslots == nsize) ? jobs : (JOB **) xmalloc (nsize * sizeof (JOB *));
+
+  js.c_reaped = js.j_ndead = 0;
+  for (i = j = 0; i < js.j_jobslots; i++)
+    if (jobs[i])
+      {
+       if (i == js.j_current)
+         ncur = j;
+       if (i == js.j_previous)
+         nprev = j;
+       nlist[j++] = jobs[i];
+       if (jobs[i]->state == JDEAD)
+         {
+           js.j_ndead++;
+           js.c_reaped += processes_in_job (i);
+         }
+      }
+
+#if 0
+  itrace ("realloc_jobs_list: resize jobs list from %d to %d", js.j_jobslots, nsize);
+  itrace ("realloc_jobs_list: j_lastj changed from %d to %d", js.j_lastj, (j > 0) ? j - 1 : 0);
+  itrace ("realloc_jobs_list: j_njobs changed from %d to %d", js.j_njobs, j);
+  itrace ("realloc_jobs_list: js.j_ndead %d js.c_reaped %d", js.j_ndead, js.c_reaped);
+#endif
+
+  js.j_firstj = 0;
+  js.j_lastj = (j > 0) ? j - 1 : 0;
+  js.j_njobs = j;
+  js.j_jobslots = nsize;
+
+  /* Zero out remaining slots in new jobs list */
+  for ( ; j < nsize; j++)
+    nlist[j] = (JOB *)NULL;
+
+  if (jobs != nlist)
+    {
+      free (jobs);
+      jobs = nlist;
+    }
+
+  if (ncur != NO_JOB)
+    js.j_current = ncur;
+  if (nprev != NO_JOB)
+    js.j_previous = nprev;
+
+  /* Need to reset these */
+  if (js.j_current == NO_JOB || js.j_previous == NO_JOB || js.j_current > js.j_lastj || js.j_previous > js.j_lastj)
+    reset_current ();
+
+#if 0
+  itrace ("realloc_jobs_list: reset js.j_current (%d) and js.j_previous (%d)", js.j_current, js.j_previous);
+#endif
+
+  UNBLOCK_CHILD (oset);
+}
+
+/* Compact the jobs list by removing dead jobs.  Assume that we have filled
+   the jobs array to some predefined maximum.  Called when the shell is not
+   the foreground process (subshell_environment != 0).  Returns the first
+   available slot in the compacted list.  If that value is js.j_jobslots, then
+   the list needs to be reallocated.  The jobs array may be in new memory if
+   this returns > 0 and < js.j_jobslots.  FLAGS is reserved for future use. */
+static int
+compact_jobs_list (flags)
+     int flags;
+{
+  if (js.j_jobslots == 0 || jobs_list_frozen)
+    return js.j_jobslots;
+
+  reap_dead_jobs ();
+  realloc_jobs_list ();
+
+#if 0
+  itrace("compact_jobs_list: returning %d", (js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0);
+#endif
+
+  return ((js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0);
+}
+
+/* Delete the job at INDEX from the job list.  Must be called
+   with SIGCHLD blocked. */
+void
+delete_job (job_index, dflags)
+     int job_index, dflags;
+{
+  register JOB *temp;
+  PROCESS *proc;
+  int ndel;
+
+  if (js.j_jobslots == 0 || jobs_list_frozen)
+    return;
+
+  if ((dflags & DEL_WARNSTOPPED) && subshell_environment == 0 && STOPPED (job_index))
+    internal_warning (_("deleting stopped job %d with process group %ld"), job_index+1, (long)jobs[job_index]->pgrp);
+  temp = jobs[job_index];
+  if (temp == 0)
+    return;
+
+  if ((dflags & DEL_NOBGPID) == 0)
+    {
+      proc = find_last_proc (job_index, 0);
+      /* Could do this just for J_ASYNC jobs, but we save all. */
+      if (proc)
+       bgp_add (proc->pid, process_exit_status (proc->status));
+    }
+
+  jobs[job_index] = (JOB *)NULL;
+  if (temp == js.j_lastmade)
+    js.j_lastmade = 0;
+  else if (temp == js.j_lastasync)
+    js.j_lastasync = 0;
+
+  free (temp->wd);
+  ndel = discard_pipeline (temp->pipe);
+
+  js.c_injobs -= ndel;
+  if (temp->state == JDEAD)
+    {
+      js.c_reaped -= ndel;
+      js.j_ndead--;
+      if (js.c_reaped < 0)
+       {
+#ifdef DEBUG
+         itrace("delete_job (%d pgrp %d): js.c_reaped (%d) < 0 ndel = %d js.j_ndead = %d", job_index, temp->pgrp, js.c_reaped, ndel, js.j_ndead);
+#endif
+         js.c_reaped = 0;
+       }
+    }
+
+  if (temp->deferred)
+    dispose_command (temp->deferred);
+
+  free (temp);
+
+  js.j_njobs--;
+  if (js.j_njobs == 0)
+    js.j_firstj = js.j_lastj = 0;
+  else if (jobs[js.j_firstj] == 0 || jobs[js.j_lastj] == 0)
+    reset_job_indices ();
+
+  if (job_index == js.j_current || job_index == js.j_previous)
+    reset_current ();
+}
+
+/* Must be called with SIGCHLD blocked. */
+void
+nohup_job (job_index)
+     int job_index;
+{
+  register JOB *temp;
+
+  if (js.j_jobslots == 0)
+    return;
+
+  if (temp = jobs[job_index])
+    temp->flags |= J_NOHUP;
+}
+
+/* Get rid of the data structure associated with a process chain. */
+static int
+discard_pipeline (chain)
+     register PROCESS *chain;
+{
+  register PROCESS *this, *next;
+  int n;
+
+  this = chain;
+  n = 0;
+  do
+    {
+      next = this->next;
+      FREE (this->command);
+      free (this);
+      n++;
+      this = next;
+    }
+  while (this != chain);
+
+  return n;
+}
+
+/* Add this process to the chain being built in the_pipeline.
+   NAME is the command string that will be exec'ed later.
+   PID is the process id of the child. */
+static void
+add_process (name, pid)
+     char *name;
+     pid_t pid;
+{
+  PROCESS *t, *p;
+
+#if defined (RECYCLES_PIDS)
+  int j;
+  p = find_process (pid, 0, &j);
+  if (p)
+    {
+#  ifdef DEBUG
+      if (j == NO_JOB)
+       internal_warning (_("add_process: process %5ld (%s) in the_pipeline"), (long)p->pid, p->command);
+#  endif
+      if (PALIVE (p))
+        internal_warning (_("add_process: pid %5ld (%s) marked as still alive"), (long)p->pid, p->command);
+      p->running = PS_RECYCLED;                /* mark as recycled */
+    }
+#endif
+
+  t = (PROCESS *)xmalloc (sizeof (PROCESS));
+  t->next = the_pipeline;
+  t->pid = pid;
+  WSTATUS (t->status) = 0;
+  t->running = PS_RUNNING;
+  t->command = name;
+  the_pipeline = t;
+
+  if (t->next == 0)
+    t->next = t;
+  else
+    {
+      p = t->next;
+      while (p->next != t->next)
+       p = p->next;
+      p->next = t;
+    }
+}
+
+/* Create a (dummy) PROCESS with NAME, PID, and STATUS, and make it the last
+   process in jobs[JID]->pipe.  Used by the lastpipe code. */
+void
+append_process (name, pid, status, jid)
+     char *name;
+     pid_t pid;
+     int status;
+     int jid;
+{
+  PROCESS *t, *p;
+
+  t = (PROCESS *)xmalloc (sizeof (PROCESS));
+  t->next = (PROCESS *)NULL;
+  t->pid = pid;
+  /* set process exit status using offset discovered by configure */
+  t->status = (status & 0xff) << WEXITSTATUS_OFFSET;
+  t->running = PS_DONE;
+  t->command = name;
+
+  js.c_reaped++;       /* XXX */
+
+  for (p = jobs[jid]->pipe; p->next != jobs[jid]->pipe; p = p->next)
+    ;
+  p->next = t;
+  t->next = jobs[jid]->pipe;
+}
+
+#if 0
+/* Take the last job and make it the first job.  Must be called with
+   SIGCHLD blocked. */
+int
+rotate_the_pipeline ()
+{
+  PROCESS *p;
+
+  if (the_pipeline->next == the_pipeline)
+    return;
+  for (p = the_pipeline; p->next != the_pipeline; p = p->next)
+    ;
+  the_pipeline = p;
+}
+
+/* Reverse the order of the processes in the_pipeline.  Must be called with
+   SIGCHLD blocked. */
+int
+reverse_the_pipeline ()
+{
+  PROCESS *p, *n;
+
+  if (the_pipeline->next == the_pipeline)
+    return;
+
+  for (p = the_pipeline; p->next != the_pipeline; p = p->next)
+    ;
+  p->next = (PROCESS *)NULL;
+
+  n = REVERSE_LIST (the_pipeline, PROCESS *);
+
+  the_pipeline = n;
+  for (p = the_pipeline; p->next; p = p->next)
+    ;
+  p->next = the_pipeline;
+}
+#endif
+
+/* Map FUNC over the list of jobs.  If FUNC returns non-zero,
+   then it is time to stop mapping, and that is the return value
+   for map_over_jobs.  FUNC is called with a JOB, arg1, arg2,
+   and INDEX. */
+static int
+map_over_jobs (func, arg1, arg2)
+     sh_job_map_func_t *func;
+     int arg1, arg2;
+{
+  register int i;
+  int result;
+  sigset_t set, oset;
+
+  if (js.j_jobslots == 0)
+    return 0;
+
+  BLOCK_CHILD (set, oset);
+
+  /* XXX could use js.j_firstj here */
+  for (i = result = 0; i < js.j_jobslots; i++)
+    {
+#if defined (DEBUG)
+      if (i < js.j_firstj && jobs[i])
+       itrace("map_over_jobs: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);
+      if (i > js.j_lastj && jobs[i])
+       itrace("map_over_jobs: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);
+#endif
+      if (jobs[i])
+       {
+         result = (*func)(jobs[i], arg1, arg2, i);
+         if (result)
+           break;
+       }
+    }
+
+  UNBLOCK_CHILD (oset);
+
+  return (result);
+}
+
+/* Cause all the jobs in the current pipeline to exit. */
+void
+terminate_current_pipeline ()
+{
+  if (pipeline_pgrp && pipeline_pgrp != shell_pgrp)
+    {
+      killpg (pipeline_pgrp, SIGTERM);
+      killpg (pipeline_pgrp, SIGCONT);
+    }
+}
+
+/* Cause all stopped jobs to exit. */
+void
+terminate_stopped_jobs ()
+{
+  register int i;
+
+  /* XXX could use js.j_firstj here */
+  for (i = 0; i < js.j_jobslots; i++)
+    {
+      if (jobs[i] && STOPPED (i))
+       {
+         killpg (jobs[i]->pgrp, SIGTERM);
+         killpg (jobs[i]->pgrp, SIGCONT);
+       }
+    }
+}
+
+/* Cause all jobs, running or stopped, to receive a hangup signal.  If
+   a job is marked J_NOHUP, don't send the SIGHUP. */
+void
+hangup_all_jobs ()
+{
+  register int i;
+
+  /* XXX could use js.j_firstj here */
+  for (i = 0; i < js.j_jobslots; i++)
+    {
+      if (jobs[i])
+       {
+         if  (jobs[i]->flags & J_NOHUP)
+           continue;
+         killpg (jobs[i]->pgrp, SIGHUP);
+         if (STOPPED (i))
+           killpg (jobs[i]->pgrp, SIGCONT);
+       }
+    }
+}
+
+void
+kill_current_pipeline ()
+{
+  stop_making_children ();
+  start_pipeline ();
+}
+
+/* Return the pipeline that PID belongs to.  Note that the pipeline
+   doesn't have to belong to a job.  Must be called with SIGCHLD blocked.
+   If JOBP is non-null, return the index of the job containing PID.  */
+static PROCESS *
+find_pipeline (pid, alive_only, jobp)
+     pid_t pid;
+     int alive_only;
+     int *jobp;                /* index into jobs list or NO_JOB */
+{
+  int job;
+  PROCESS *p;
+
+  /* See if this process is in the pipeline that we are building. */
+  if (jobp)
+    *jobp = NO_JOB;
+  if (the_pipeline)
+    {
+      p = the_pipeline;
+      do
+       {
+         /* Return it if we found it.  Don't ever return a recycled pid. */
+         if (p->pid == pid && ((alive_only == 0 && PRECYCLED(p) == 0) || PALIVE(p)))
+           return (p);
+
+         p = p->next;
+       }
+      while (p != the_pipeline);
+    }
+
+  job = find_job (pid, alive_only, &p);
+  if (jobp)
+    *jobp = job;
+  return (job == NO_JOB) ? (PROCESS *)NULL : jobs[job]->pipe;
+}
+
+/* Return the PROCESS * describing PID.  If JOBP is non-null return the index
+   into the jobs array of the job containing PID.  Must be called with
+   SIGCHLD blocked. */
+static PROCESS *
+find_process (pid, alive_only, jobp)
+     pid_t pid;
+     int alive_only;
+     int *jobp;                /* index into jobs list or NO_JOB */
+{
+  PROCESS *p;
+
+  p = find_pipeline (pid, alive_only, jobp);
+  while (p && p->pid != pid)
+    p = p->next;
+  return p;
+}
+
+/* Return the job index that PID belongs to, or NO_JOB if it doesn't
+   belong to any job.  Must be called with SIGCHLD blocked. */
+static int
+find_job (pid, alive_only, procp)
+     pid_t pid;
+     int alive_only;
+     PROCESS **procp;
+{
+  register int i;
+  PROCESS *p;
+
+  /* XXX could use js.j_firstj here, and should check js.j_lastj */
+  for (i = 0; i < js.j_jobslots; i++)
+    {
+#if defined (DEBUG)
+      if (i < js.j_firstj && jobs[i])
+       itrace("find_job: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);
+      if (i > js.j_lastj && jobs[i])
+       itrace("find_job: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);
+#endif
+      if (jobs[i])
+       {
+         p = jobs[i]->pipe;
+
+         do
+           {
+             if (p->pid == pid && ((alive_only == 0 && PRECYCLED(p) == 0) || PALIVE(p)))
+               {
+                 if (procp)
+                   *procp = p;
+                 return (i);
+               }
+
+             p = p->next;
+           }
+         while (p != jobs[i]->pipe);
+       }
+    }
+
+  return (NO_JOB);
+}
+
+/* Find a job given a PID.  If BLOCK is non-zero, block SIGCHLD as
+   required by find_job. */
+int
+get_job_by_pid (pid, block)
+     pid_t pid;
+     int block;
+{
+  int job;
+  sigset_t set, oset;
+
+  if (block)
+    BLOCK_CHILD (set, oset);
+
+  job = find_job (pid, 0, NULL);
+
+  if (block)
+    UNBLOCK_CHILD (oset);
+
+  return job;
+}
+
+/* Print descriptive information about the job with leader pid PID. */
+void
+describe_pid (pid)
+     pid_t pid;
+{
+  int job;
+  sigset_t set, oset;
+
+  BLOCK_CHILD (set, oset);
+
+  job = find_job (pid, 0, NULL);
+
+  if (job != NO_JOB)
+    fprintf (stderr, "[%d] %ld\n", job + 1, (long)pid);
+  else
+    programming_error (_("describe_pid: %ld: no such pid"), (long)pid);
+
+  UNBLOCK_CHILD (oset);
+}
+
+static char *
+j_strsignal (s)
+     int s;
+{
+  char *x;
+
+  x = strsignal (s);
+  if (x == 0)
+    {
+      x = retcode_name_buffer;
+      sprintf (x, _("Signal %d"), s);
+    }
+  return x;
+}
+
+static char *
+printable_job_status (j, p, format)
+     int j;
+     PROCESS *p;
+     int format;
+{
+  static char *temp;
+  int es;
+
+  temp = _("Done");
+
+  if (STOPPED (j) && format == 0)
+    {
+      if (posixly_correct == 0 || p == 0 || (WIFSTOPPED (p->status) == 0))
+       temp = _("Stopped");
+      else
+       {
+         temp = retcode_name_buffer;
+         sprintf (temp, _("Stopped(%s)"), signal_name (WSTOPSIG (p->status)));
+       }
+    }
+  else if (RUNNING (j))
+    temp = _("Running");
+  else
+    {
+      if (WIFSTOPPED (p->status))
+       temp = j_strsignal (WSTOPSIG (p->status));
+      else if (WIFSIGNALED (p->status))
+       temp = j_strsignal (WTERMSIG (p->status));
+      else if (WIFEXITED (p->status))
+       {
+         temp = retcode_name_buffer;
+         es = WEXITSTATUS (p->status);
+         if (es == 0)
+           strcpy (temp, _("Done"));
+         else if (posixly_correct)
+           sprintf (temp, _("Done(%d)"), es);
+         else
+           sprintf (temp, _("Exit %d"), es);
+       }
+      else
+       temp = _("Unknown status");
+    }
+
+  return temp;
+}
+
+/* This is the way to print out information on a job if you
+   know the index.  FORMAT is:
+
+    JLIST_NORMAL)   [1]+ Running          emacs
+    JLIST_LONG  )   [1]+ 2378 Running      emacs
+    -1   )   [1]+ 2378       emacs
+
+    JLIST_NORMAL)   [1]+ Stopped          ls | more
+    JLIST_LONG  )   [1]+ 2369 Stopped      ls
+                        2367       | more
+    JLIST_PID_ONLY)
+       Just list the pid of the process group leader (really
+       the process group).
+    JLIST_CHANGED_ONLY)
+       Use format JLIST_NORMAL, but list only jobs about which
+       the user has not been notified. */
+
+/* Print status for pipeline P.  If JOB_INDEX is >= 0, it is the index into
+   the JOBS array corresponding to this pipeline.  FORMAT is as described
+   above.  Must be called with SIGCHLD blocked.
+
+   If you're printing a pipeline that's not in the jobs array, like the
+   current pipeline as it's being created, pass -1 for JOB_INDEX */
+static void
+print_pipeline (p, job_index, format, stream)
+     PROCESS *p;
+     int job_index, format;
+     FILE *stream;
+{
+  PROCESS *first, *last, *show;
+  int es, name_padding;
+  char *temp;
+
+  if (p == 0)
+    return;
+
+  first = last = p;
+  while (last->next != first)
+    last = last->next;
+
+  for (;;)
+    {
+      if (p != first)
+       fprintf (stream, format ? "     " : " |");
+
+      if (format != JLIST_STANDARD)
+       fprintf (stream, "%5ld", (long)p->pid);
+
+      fprintf (stream, " ");
+
+      if (format > -1 && job_index >= 0)
+       {
+         show = format ? p : last;
+         temp = printable_job_status (job_index, show, format);
+
+         if (p != first)
+           {
+             if (format)
+               {
+                 if (show->running == first->running &&
+                     WSTATUS (show->status) == WSTATUS (first->status))
+                   temp = "";
+               }
+             else
+               temp = (char *)NULL;
+           }
+
+         if (temp)
+           {
+             fprintf (stream, "%s", temp);
+
+             es = STRLEN (temp);
+             if (es == 0)
+               es = 2; /* strlen ("| ") */
+             name_padding = LONGEST_SIGNAL_DESC - es;
+
+             fprintf (stream, "%*s", name_padding, "");
+
+             if ((WIFSTOPPED (show->status) == 0) &&
+                 (WIFCONTINUED (show->status) == 0) &&
+                 WIFCORED (show->status))
+               fprintf (stream, _("(core dumped) "));
+           }
+       }
+
+      if (p != first && format)
+       fprintf (stream, "| ");
+
+      if (p->command)
+       fprintf (stream, "%s", p->command);
+
+      if (p == last && job_index >= 0)
+       {
+         temp = current_working_directory ();
+
+         if (RUNNING (job_index) && (IS_FOREGROUND (job_index) == 0))
+           fprintf (stream, " &");
+
+         if (strcmp (temp, jobs[job_index]->wd) != 0)
+           fprintf (stream,
+             _("  (wd: %s)"), polite_directory_format (jobs[job_index]->wd));
+       }
+
+      if (format || (p == last))
+       {
+         /* We need to add a CR only if this is an interactive shell, and
+            we're reporting the status of a completed job asynchronously.
+            We can't really check whether this particular job is being
+            reported asynchronously, so just add the CR if the shell is
+            currently interactive and asynchronous notification is enabled. */
+         if (asynchronous_notification && interactive)
+           fprintf (stream, "\r\n");
+         else
+           fprintf (stream, "\n");
+       }
+
+      if (p == last)
+       break;
+      p = p->next;
+    }
+  fflush (stream);
+}
+
+/* Print information to STREAM about jobs[JOB_INDEX] according to FORMAT.
+   Must be called with SIGCHLD blocked or queued with queue_sigchld */
+static void
+pretty_print_job (job_index, format, stream)
+     int job_index, format;
+     FILE *stream;
+{
+  register PROCESS *p;
+
+  /* Format only pid information about the process group leader? */
+  if (format == JLIST_PID_ONLY)
+    {
+      fprintf (stream, "%ld\n", (long)jobs[job_index]->pipe->pid);
+      return;
+    }
+
+  if (format == JLIST_CHANGED_ONLY)
+    {
+      if (IS_NOTIFIED (job_index))
+       return;
+      format = JLIST_STANDARD;
+    }
+
+  if (format != JLIST_NONINTERACTIVE)
+    fprintf (stream, "[%d]%c ", job_index + 1,
+             (job_index == js.j_current) ? '+':
+               (job_index == js.j_previous) ? '-' : ' ');
+
+  if (format == JLIST_NONINTERACTIVE)
+    format = JLIST_LONG;
+
+  p = jobs[job_index]->pipe;
+
+  print_pipeline (p, job_index, format, stream);
+
+  /* We have printed information about this job.  When the job's
+     status changes, waitchld () sets the notification flag to 0. */
+  jobs[job_index]->flags |= J_NOTIFIED;
+}
+
+static int
+print_job (job, format, state, job_index)
+     JOB *job;
+     int format, state, job_index;
+{
+  if (state == -1 || (JOB_STATE)state == job->state)
+    pretty_print_job (job_index, format, stdout);
+  return (0);
+}
+
+void
+list_one_job (job, format, ignore, job_index)
+     JOB *job;
+     int format, ignore, job_index;
+{
+  pretty_print_job (job_index, format, stdout);
+}
+
+void
+list_stopped_jobs (format)
+     int format;
+{
+  cleanup_dead_jobs ();
+  map_over_jobs (print_job, format, (int)JSTOPPED);
+}
+
+void
+list_running_jobs (format)
+     int format;
+{
+  cleanup_dead_jobs ();
+  map_over_jobs (print_job, format, (int)JRUNNING);
+}
+
+/* List jobs.  If FORMAT is non-zero, then the long form of the information
+   is printed, else just a short version. */
+void
+list_all_jobs (format)
+     int format;
+{
+  cleanup_dead_jobs ();
+  map_over_jobs (print_job, format, -1);
+}
+
+/* Fork, handling errors.  Returns the pid of the newly made child, or 0.
+   COMMAND is just for remembering the name of the command; we don't do
+   anything else with it.  ASYNC_P says what to do with the tty.  If
+   non-zero, then don't give it away. */
+pid_t
+make_child (command, async_p)
+     char *command;
+     int async_p;
+{
+  int forksleep;
+  sigset_t set, oset;
+  pid_t pid;
+
+  /* XXX - block SIGTERM here and unblock in child after fork resets the
+     set of pending signals? */
+  sigemptyset (&set);
+  sigaddset (&set, SIGCHLD);
+  sigaddset (&set, SIGINT);
+  sigemptyset (&oset);
+  sigprocmask (SIG_BLOCK, &set, &oset);
+
+  making_children ();
+
+  forksleep = 1;
+
+#if defined (BUFFERED_INPUT)
+  /* If default_buffered_input is active, we are reading a script.  If
+     the command is asynchronous, we have already duplicated /dev/null
+     as fd 0, but have not changed the buffered stream corresponding to
+     the old fd 0.  We don't want to sync the stream in this case. */
+  if (default_buffered_input != -1 &&
+      (!async_p || default_buffered_input > 0))
+    sync_buffered_stream (default_buffered_input);
+#endif /* BUFFERED_INPUT */
+
+  RESET_SIGTERM;
+
+  /* Create the child, handle severe errors.  Retry on EAGAIN. */
+  while ((pid = fork ()) < 0 && errno == EAGAIN && forksleep < FORKSLEEP_MAX)
+    {
+      /* bash-4.2 */
+      sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
+      /* If we can't create any children, try to reap some dead ones. */
+      waitchld (-1, 0);
+
+      sys_error ("fork: retry");
+      RESET_SIGTERM;
+
+      if (sleep (forksleep) != 0)
+       break;
+      forksleep <<= 1;
+
+      if (interrupt_state)
+       break;
+      sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
+    }
+
+  if (pid != 0)
+    RESET_SIGTERM;
+
+  if (pid < 0)
+    {
+      sys_error ("fork");
+
+      /* Kill all of the processes in the current pipeline. */
+      terminate_current_pipeline ();
+
+      /* Discard the current pipeline, if any. */
+      if (the_pipeline)
+       kill_current_pipeline ();
+
+      last_command_exit_value = EX_NOEXEC;
+      throw_to_top_level ();   /* Reset signals, etc. */
+    }
+
+  if (pid == 0)
+    {
+      /* In the child.  Give this child the right process group, set the
+        signals to the default state for a new process. */
+      pid_t mypid;
+
+      mypid = getpid ();
+#if defined (BUFFERED_INPUT)
+      /* Close default_buffered_input if it's > 0.  We don't close it if it's
+        0 because that's the file descriptor used when redirecting input,
+        and it's wrong to close the file in that case. */
+      unset_bash_input (0);
+#endif /* BUFFERED_INPUT */
+
+      /* Restore top-level signal mask. */
+      sigprocmask (SIG_SETMASK, &top_level_mask, (sigset_t *)NULL);
+
+      if (job_control)
+       {
+         /* All processes in this pipeline belong in the same
+            process group. */
+
+         if (pipeline_pgrp == 0)       /* This is the first child. */
+           pipeline_pgrp = mypid;
+
+         /* Check for running command in backquotes. */
+         if (pipeline_pgrp == shell_pgrp)
+           ignore_tty_job_signals ();
+         else
+           default_tty_job_signals ();
+
+         /* Set the process group before trying to mess with the terminal's
+            process group.  This is mandated by POSIX. */
+         /* This is in accordance with the Posix 1003.1 standard,
+            section B.7.2.4, which says that trying to set the terminal
+            process group with tcsetpgrp() to an unused pgrp value (like
+            this would have for the first child) is an error.  Section
+            B.4.3.3, p. 237 also covers this, in the context of job control
+            shells. */
+         if (setpgid (mypid, pipeline_pgrp) < 0)
+           sys_error (_("child setpgid (%ld to %ld)"), (long)mypid, (long)pipeline_pgrp);
+
+         /* By convention (and assumption above), if
+            pipeline_pgrp == shell_pgrp, we are making a child for
+            command substitution.
+            In this case, we don't want to give the terminal to the
+            shell's process group (we could be in the middle of a
+            pipeline, for example). */
+         if (async_p == 0 && pipeline_pgrp != shell_pgrp && ((subshell_environment&SUBSHELL_ASYNC) == 0) && running_in_background == 0)
+           give_terminal_to (pipeline_pgrp, 0);
+
+#if defined (PGRP_PIPE)
+         if (pipeline_pgrp == mypid)
+           pipe_read (pgrp_pipe);
+#endif
+       }
+      else                     /* Without job control... */
+       {
+         if (pipeline_pgrp == 0)
+           pipeline_pgrp = shell_pgrp;
+
+         /* If these signals are set to SIG_DFL, we encounter the curious
+            situation of an interactive ^Z to a running process *working*
+            and stopping the process, but being unable to do anything with
+            that process to change its state.  On the other hand, if they
+            are set to SIG_IGN, jobs started from scripts do not stop when
+            the shell running the script gets a SIGTSTP and stops. */
+
+         default_tty_job_signals ();
+       }
+
+#if defined (PGRP_PIPE)
+      /* Release the process group pipe, since our call to setpgid ()
+        is done.  The last call to sh_closepipe is done in stop_pipeline. */
+      sh_closepipe (pgrp_pipe);
+#endif /* PGRP_PIPE */
+
+#if 0
+      /* Don't set last_asynchronous_pid in the child */
+      if (async_p)
+       last_asynchronous_pid = mypid;          /* XXX */
+      else
+#endif
+#if defined (RECYCLES_PIDS)
+      if (last_asynchronous_pid == mypid)
+        /* Avoid pid aliasing.  1 seems like a safe, unusual pid value. */
+       last_asynchronous_pid = 1;
+#endif
+    }
+  else
+    {
+      /* In the parent.  Remember the pid of the child just created
+        as the proper pgrp if this is the first child. */
+
+      if (job_control)
+       {
+         if (pipeline_pgrp == 0)
+           {
+             pipeline_pgrp = pid;
+             /* Don't twiddle terminal pgrps in the parent!  This is the bug,
+                not the good thing of twiddling them in the child! */
+             /* give_terminal_to (pipeline_pgrp, 0); */
+           }
+         /* This is done on the recommendation of the Rationale section of
+            the POSIX 1003.1 standard, where it discusses job control and
+            shells.  It is done to avoid possible race conditions. (Ref.
+            1003.1 Rationale, section B.4.3.3, page 236). */
+         setpgid (pid, pipeline_pgrp);
+       }
+      else
+       {
+         if (pipeline_pgrp == 0)
+           pipeline_pgrp = shell_pgrp;
+       }
+
+      /* Place all processes into the jobs array regardless of the
+        state of job_control. */
+      add_process (command, pid);
+
+      if (async_p)
+       last_asynchronous_pid = pid;
+#if defined (RECYCLES_PIDS)
+      else if (last_asynchronous_pid == pid)
+        /* Avoid pid aliasing.  1 seems like a safe, unusual pid value. */
+       last_asynchronous_pid = 1;
+#endif
+
+      /* Delete the saved status for any job containing this PID in case it's
+        been reused. */
+      delete_old_job (pid);
+
+      /* Perform the check for pid reuse unconditionally.  Some systems reuse
+         PIDs before giving a process CHILD_MAX/_SC_CHILD_MAX unique ones. */
+      bgp_delete (pid);                /* new process, discard any saved status */
+
+      last_made_pid = pid;
+
+      /* keep stats */
+      js.c_totforked++;
+      js.c_living++;
+
+      /* Unblock SIGINT and SIGCHLD unless creating a pipeline, in which case
+        SIGCHLD remains blocked until all commands in the pipeline have been
+        created. */
+      sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
+    }
+
+  return (pid);
+}
+
+/* These two functions are called only in child processes. */
+void
+ignore_tty_job_signals ()
+{
+  set_signal_handler (SIGTSTP, SIG_IGN);
+  set_signal_handler (SIGTTIN, SIG_IGN);
+  set_signal_handler (SIGTTOU, SIG_IGN);
+}
+
+/* Reset the tty-generated job control signals to SIG_DFL unless that signal
+   was ignored at entry to the shell, in which case we need to set it to
+   SIG_IGN in the child.  We can't rely on resetting traps, since the hard
+   ignored signals can't be trapped. */
+void
+default_tty_job_signals ()
+{
+  if (signal_is_trapped (SIGTSTP) == 0 && signal_is_hard_ignored (SIGTSTP))
+    set_signal_handler (SIGTSTP, SIG_IGN);
+  else
+    set_signal_handler (SIGTSTP, SIG_DFL);
+
+  if (signal_is_trapped (SIGTTIN) == 0 && signal_is_hard_ignored (SIGTTIN))
+    set_signal_handler (SIGTTIN, SIG_IGN);
+  else
+    set_signal_handler (SIGTTIN, SIG_DFL);
+
+  if (signal_is_trapped (SIGTTOU) == 0 && signal_is_hard_ignored (SIGTTOU))
+    set_signal_handler (SIGTTOU, SIG_IGN);
+  else
+    set_signal_handler (SIGTTOU, SIG_DFL);
+}
+
+/* Called once in a parent process. */
+void
+get_original_tty_job_signals ()
+{
+  static int fetched = 0;
+
+  if (fetched == 0)
+    {
+      get_original_signal (SIGTSTP);
+      get_original_signal (SIGTTIN);
+      get_original_signal (SIGTTOU);
+      fetched = 1;
+    }
+}
+
+/* When we end a job abnormally, or if we stop a job, we set the tty to the
+   state kept in here.  When a job ends normally, we set the state in here
+   to the state of the tty. */
+
+static TTYSTRUCT shell_tty_info;
+
+#if defined (NEW_TTY_DRIVER)
+static struct tchars shell_tchars;
+static struct ltchars shell_ltchars;
+#endif /* NEW_TTY_DRIVER */
+
+#if defined (NEW_TTY_DRIVER) && defined (DRAIN_OUTPUT)
+/* Since the BSD tty driver does not allow us to change the tty modes
+   while simultaneously waiting for output to drain and preserving
+   typeahead, we have to drain the output ourselves before calling
+   ioctl.  We cheat by finding the length of the output queue, and
+   using select to wait for an appropriate length of time.  This is
+   a hack, and should be labeled as such (it's a hastily-adapted
+   mutation of a `usleep' implementation).  It's only reason for
+   existing is the flaw in the BSD tty driver. */
+
+static int ttspeeds[] =
+{
+  0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
+  1800, 2400, 4800, 9600, 19200, 38400
+};
+
+static void
+draino (fd, ospeed)
+     int fd, ospeed;
+{
+  register int delay = ttspeeds[ospeed];
+  int n;
+
+  if (!delay)
+    return;
+
+  while ((ioctl (fd, TIOCOUTQ, &n) == 0) && n)
+    {
+      if (n > (delay / 100))
+       {
+         struct timeval tv;
+
+         n *= 10;              /* 2 bits more for conservativeness. */
+         tv.tv_sec = n / delay;
+         tv.tv_usec = ((n % delay) * 1000000) / delay;
+         select (fd, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv);
+       }
+      else
+       break;
+    }
+}
+#endif /* NEW_TTY_DRIVER && DRAIN_OUTPUT */
+
+/* Return the fd from which we are actually getting input. */
+#define input_tty() (shell_tty != -1) ? shell_tty : fileno (stderr)
+
+/* Fill the contents of shell_tty_info with the current tty info. */
+int
+get_tty_state ()
+{
+  int tty;
+
+  tty = input_tty ();
+  if (tty != -1)
+    {
+#if defined (NEW_TTY_DRIVER)
+      ioctl (tty, TIOCGETP, &shell_tty_info);
+      ioctl (tty, TIOCGETC, &shell_tchars);
+      ioctl (tty, TIOCGLTC, &shell_ltchars);
+#endif /* NEW_TTY_DRIVER */
+
+#if defined (TERMIO_TTY_DRIVER)
+      ioctl (tty, TCGETA, &shell_tty_info);
+#endif /* TERMIO_TTY_DRIVER */
+
+#if defined (TERMIOS_TTY_DRIVER)
+      if (tcgetattr (tty, &shell_tty_info) < 0)
+       {
+#if 0
+         /* Only print an error message if we're really interactive at
+            this time. */
+         if (interactive)
+           sys_error ("[%ld: %d (%d)] tcgetattr", (long)getpid (), shell_level, tty);
+#endif
+         return -1;
+       }
+#endif /* TERMIOS_TTY_DRIVER */
+      if (check_window_size)
+       get_new_window_size (0, (int *)0, (int *)0);
+    }
+  return 0;
+}
+
+/* Make the current tty use the state in shell_tty_info. */
+int
+set_tty_state ()
+{
+  int tty;
+
+  tty = input_tty ();
+  if (tty != -1)
+    {
+#if defined (NEW_TTY_DRIVER)
+#  if defined (DRAIN_OUTPUT)
+      draino (tty, shell_tty_info.sg_ospeed);
+#  endif /* DRAIN_OUTPUT */
+      ioctl (tty, TIOCSETN, &shell_tty_info);
+      ioctl (tty, TIOCSETC, &shell_tchars);
+      ioctl (tty, TIOCSLTC, &shell_ltchars);
+#endif /* NEW_TTY_DRIVER */
+
+#if defined (TERMIO_TTY_DRIVER)
+      ioctl (tty, TCSETAW, &shell_tty_info);
+#endif /* TERMIO_TTY_DRIVER */
+
+#if defined (TERMIOS_TTY_DRIVER)
+      if (tcsetattr (tty, TCSADRAIN, &shell_tty_info) < 0)
+       {
+         /* Only print an error message if we're really interactive at
+            this time. */
+         if (interactive)
+           sys_error ("[%ld: %d (%d)] tcsetattr", (long)getpid (), shell_level, tty);
+         return -1;
+       }
+#endif /* TERMIOS_TTY_DRIVER */
+    }
+  return 0;
+}
+
+/* Given an index into the jobs array JOB, return the PROCESS struct of the last
+   process in that job's pipeline.  This is the one whose exit status
+   counts.  Must be called with SIGCHLD blocked or queued. */
+static PROCESS *
+find_last_proc (job, block)
+     int job;
+     int block;
+{
+  register PROCESS *p;
+  sigset_t set, oset;
+
+  if (block)
+    BLOCK_CHILD (set, oset);
+
+  p = jobs[job]->pipe;
+  while (p && p->next != jobs[job]->pipe)
+    p = p->next;
+
+  if (block)
+    UNBLOCK_CHILD (oset);
+
+  return (p);
+}
+
+static pid_t
+find_last_pid (job, block)
+     int job;
+     int block;
+{
+  PROCESS *p;
+
+  p = find_last_proc (job, block);
+  /* Possible race condition here. */
+  return p->pid;
+}     
+
+/* Wait for a particular child of the shell to finish executing.
+   This low-level function prints an error message if PID is not
+   a child of this shell.  It returns -1 if it fails, or whatever
+   wait_for returns otherwise.  If the child is not found in the
+   jobs table, it returns 127. */
+int
+wait_for_single_pid (pid)
+     pid_t pid;
+{
+  register PROCESS *child;
+  sigset_t set, oset;
+  int r, job;
+
+  BLOCK_CHILD (set, oset);
+  child = find_pipeline (pid, 0, (int *)NULL);
+  UNBLOCK_CHILD (oset);
+
+  if (child == 0)
+    {
+      r = bgp_search (pid);
+      if (r >= 0)
+       return r;
+    }
+
+  if (child == 0)
+    {
+      internal_error (_("wait: pid %ld is not a child of this shell"), (long)pid);
+      return (127);
+    }
+
+  r = wait_for (pid);
+
+  /* POSIX.2: if we just waited for a job, we can remove it from the jobs
+     table. */
+  BLOCK_CHILD (set, oset);
+  job = find_job (pid, 0, NULL);
+  if (job != NO_JOB && jobs[job] && DEADJOB (job))
+    jobs[job]->flags |= J_NOTIFIED;
+  UNBLOCK_CHILD (oset);
+
+  /* If running in posix mode, remove the job from the jobs table immediately */
+  if (posixly_correct)
+    {
+      cleanup_dead_jobs ();
+      bgp_delete (pid);
+    }
+
+  return r;
+}
+
+/* Wait for all of the background processes started by this shell to finish. */
+void
+wait_for_background_pids ()
+{
+  register int i, r, waited_for;
+  sigset_t set, oset;
+  pid_t pid;
+
+  for (waited_for = 0;;)
+    {
+      BLOCK_CHILD (set, oset);
+
+      /* find first running job; if none running in foreground, break */
+      /* XXX could use js.j_firstj and js.j_lastj here */
+      for (i = 0; i < js.j_jobslots; i++)
+       {
+#if defined (DEBUG)
+         if (i < js.j_firstj && jobs[i])
+           itrace("wait_for_background_pids: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);
+         if (i > js.j_lastj && jobs[i])
+           itrace("wait_for_background_pids: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);
+#endif
+         if (jobs[i] && RUNNING (i) && IS_FOREGROUND (i) == 0)
+           break;
+       }
+      if (i == js.j_jobslots)
+       {
+         UNBLOCK_CHILD (oset);
+         break;
+       }
+
+      /* now wait for the last pid in that job. */
+      pid = find_last_pid (i, 0);
+      UNBLOCK_CHILD (oset);
+      QUIT;
+      errno = 0;               /* XXX */
+      r = wait_for_single_pid (pid);
+      if (r == -1)
+       {
+         /* If we're mistaken about job state, compensate. */
+         if (errno == ECHILD)
+           mark_all_jobs_as_dead ();
+       }
+      else
+       waited_for++;
+    }
+
+  /* POSIX.2 says the shell can discard the statuses of all completed jobs if
+     `wait' is called with no arguments. */
+  mark_dead_jobs_as_notified (1);
+  cleanup_dead_jobs ();
+  bgp_clear ();
+}
+
+/* Make OLD_SIGINT_HANDLER the SIGINT signal handler. */
+#define INVALID_SIGNAL_HANDLER (SigHandler *)wait_for_background_pids
+static SigHandler *old_sigint_handler = INVALID_SIGNAL_HANDLER;
+
+static int wait_sigint_received;
+static int child_caught_sigint;
+static int waiting_for_child;
+
+static void
+restore_sigint_handler ()
+{
+  if (old_sigint_handler != INVALID_SIGNAL_HANDLER)
+    {
+      set_signal_handler (SIGINT, old_sigint_handler);
+      old_sigint_handler = INVALID_SIGNAL_HANDLER;
+      waiting_for_child = 0;
+    }
+}
+
+/* Handle SIGINT while we are waiting for children in a script to exit.
+   The `wait' builtin should be interruptible, but all others should be
+   effectively ignored (i.e. not cause the shell to exit). */
+static sighandler
+wait_sigint_handler (sig)
+     int sig;
+{
+  SigHandler *sigint_handler;
+
+  if (interrupt_immediately ||
+      (this_shell_builtin && this_shell_builtin == wait_builtin))
+    {
+      last_command_exit_value = 128+SIGINT;
+      restore_sigint_handler ();
+      /* If we got a SIGINT while in `wait', and SIGINT is trapped, do
+        what POSIX.2 says (see builtins/wait.def for more info). */
+      if (this_shell_builtin && this_shell_builtin == wait_builtin &&
+         signal_is_trapped (SIGINT) &&
+         ((sigint_handler = trap_to_sighandler (SIGINT)) == trap_handler))
+       {
+         trap_handler (SIGINT);        /* set pending_traps[SIGINT] */
+         wait_signal_received = SIGINT;
+         if (interrupt_immediately)
+           {
+             interrupt_immediately = 0;
+             longjmp (wait_intr_buf, 1);
+           }
+         else
+           /* Let CHECK_WAIT_INTR handle it in wait_for/waitchld */
+           SIGRETURN (0);
+       }
+      else if (interrupt_immediately)
+       {
+         ADDINTERRUPT;
+         QUIT;
+       }
+      else /* wait_builtin but signal not trapped, treat as interrupt */
+       kill (getpid (), SIGINT);
+    }
+
+  /* XXX - should this be interrupt_state?  If it is, the shell will act
+     as if it got the SIGINT interrupt. */
+  if (waiting_for_child)
+    wait_sigint_received = 1;
+  else
+    {
+      last_command_exit_value = 128+SIGINT;
+      restore_sigint_handler ();
+      kill (getpid (), SIGINT);
+    }
+
+  /* Otherwise effectively ignore the SIGINT and allow the running job to
+     be killed. */
+  SIGRETURN (0);
+}
+
+static int
+process_exit_signal (status)
+     WAIT status;
+{
+  return (WIFSIGNALED (status) ? WTERMSIG (status) : 0);
+}
+
+static int
+process_exit_status (status)
+     WAIT status;
+{
+  if (WIFSIGNALED (status))
+    return (128 + WTERMSIG (status));
+  else if (WIFSTOPPED (status) == 0)
+    return (WEXITSTATUS (status));
+  else
+    return (EXECUTION_SUCCESS);
+}
+
+static WAIT
+job_signal_status (job)
+     int job;
+{
+  register PROCESS *p;
+  WAIT s;
+
+  p = jobs[job]->pipe;
+  do
+    {
+      s = p->status;
+      if (WIFSIGNALED(s) || WIFSTOPPED(s))
+       break;
+      p = p->next;
+    }
+  while (p != jobs[job]->pipe);
+
+  return s;
+}
+  
+/* Return the exit status of the last process in the pipeline for job JOB.
+   This is the exit status of the entire job. */
+static WAIT
+raw_job_exit_status (job)
+     int job;
+{
+  register PROCESS *p;
+  int fail;
+  WAIT ret;
+
+  if (pipefail_opt)
+    {
+      fail = 0;
+      p = jobs[job]->pipe;
+      do
+       {
+         if (WSTATUS (p->status) != EXECUTION_SUCCESS)
+           fail = WSTATUS(p->status);
+         p = p->next;
+       }
+      while (p != jobs[job]->pipe);
+      WSTATUS (ret) = fail;
+      return ret;
+    }
+
+  for (p = jobs[job]->pipe; p->next != jobs[job]->pipe; p = p->next)
+    ;
+  return (p->status);
+}
+
+/* Return the exit status of job JOB.  This is the exit status of the last
+   (rightmost) process in the job's pipeline, modified if the job was killed
+   by a signal or stopped. */
+int
+job_exit_status (job)
+     int job;
+{
+  return (process_exit_status (raw_job_exit_status (job)));
+}
+
+int
+job_exit_signal (job)
+     int job;
+{
+  return (process_exit_signal (raw_job_exit_status (job)));
+}
+
+#define FIND_CHILD(pid, child) \
+  do \
+    { \
+      child = find_pipeline (pid, 0, (int *)NULL); \
+      if (child == 0) \
+       { \
+         give_terminal_to (shell_pgrp, 0); \
+         UNBLOCK_CHILD (oset); \
+         internal_error (_("wait_for: No record of process %ld"), (long)pid); \
+         restore_sigint_handler (); \
+         return (termination_state = 127); \
+       } \
+    } \
+  while (0)
+
+/* Wait for pid (one of our children) to terminate, then
+   return the termination state.  Returns 127 if PID is not found in
+   the jobs table.  Returns -1 if waitchld() returns -1, indicating
+   that there are no unwaited-for child processes. */
+int
+wait_for (pid)
+     pid_t pid;
+{
+  int job, termination_state, r;
+  WAIT s;
+  register PROCESS *child;
+  sigset_t set, oset;
+
+  /* In the case that this code is interrupted, and we longjmp () out of it,
+     we are relying on the code in throw_to_top_level () to restore the
+     top-level signal mask. */
+  child = 0;
+  BLOCK_CHILD (set, oset);
+
+  /* Ignore interrupts while waiting for a job run without job control
+     to finish.  We don't want the shell to exit if an interrupt is
+     received, only if one of the jobs run is killed via SIGINT.  If
+     job control is not set, the job will be run in the same pgrp as
+     the shell, and the shell will see any signals the job gets.  In
+     fact, we want this set every time the waiting shell and the waited-
+     for process are in the same process group, including command
+     substitution. */
+
+  /* This is possibly a race condition -- should it go in stop_pipeline? */
+  wait_sigint_received = child_caught_sigint = 0;
+  if (job_control == 0 || (subshell_environment&SUBSHELL_COMSUB))
+    {
+      old_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler);
+      waiting_for_child = 0;
+      if (old_sigint_handler == SIG_IGN)
+       set_signal_handler (SIGINT, old_sigint_handler);
+    }
+
+  termination_state = last_command_exit_value;
+
+  if (interactive && job_control == 0)
+    QUIT;
+  /* Check for terminating signals and exit the shell if we receive one */
+  CHECK_TERMSIG;
+
+  /* Check for a trapped signal interrupting the wait builtin and jump out */
+  CHECK_WAIT_INTR;
+
+  /* If we say wait_for (), then we have a record of this child somewhere.
+     If it and none of its peers are running, don't call waitchld(). */
+
+  job = NO_JOB;
+  do
+    {
+      if (pid != ANY_PID)
+       FIND_CHILD (pid, child);
+
+      /* If this child is part of a job, then we are really waiting for the
+        job to finish.  Otherwise, we are waiting for the child to finish.
+        We check for JDEAD in case the job state has been set by waitchld
+        after receipt of a SIGCHLD. */
+      if (job == NO_JOB)
+       job = find_job (pid, 0, NULL);
+
+      /* waitchld() takes care of setting the state of the job.  If the job
+        has already exited before this is called, sigchld_handler will have
+        called waitchld and the state will be set to JDEAD. */
+
+      if (pid == ANY_PID || PRUNNING(child) || (job != NO_JOB && RUNNING (job)))
+       {
+#if defined (WAITPID_BROKEN)    /* SCOv4 */
+         sigset_t suspend_set;
+         sigemptyset (&suspend_set);
+         sigsuspend (&suspend_set);
+#else /* !WAITPID_BROKEN */
+#  if defined (MUST_UNBLOCK_CHLD)
+         struct sigaction act, oact;
+         sigset_t nullset, chldset;
+
+         sigemptyset (&nullset);
+         sigemptyset (&chldset);
+         sigprocmask (SIG_SETMASK, &nullset, &chldset);
+         act.sa_handler = SIG_DFL;
+         sigemptyset (&act.sa_mask);
+         sigemptyset (&oact.sa_mask);
+         act.sa_flags = 0;
+#  if defined (SA_RESTART)
+         act.sa_flags |= SA_RESTART;
+#  endif
+         sigaction (SIGCHLD, &act, &oact);
+#  endif /* MUST_UNBLOCK_CHLD */
+         queue_sigchld = 1;
+         waiting_for_child++;
+         r = waitchld (pid, 1);        /* XXX */
+         waiting_for_child--;
+#if 0
+itrace("wait_for: blocking wait for %d returns %d child = %p", (int)pid, r, child);
+#endif
+#  if defined (MUST_UNBLOCK_CHLD)
+         sigaction (SIGCHLD, &oact, (struct sigaction *)NULL);
+         sigprocmask (SIG_SETMASK, &chldset, (sigset_t *)NULL);
+#  endif
+         queue_sigchld = 0;
+         if (r == -1 && errno == ECHILD && this_shell_builtin == wait_builtin)
+           {
+             termination_state = -1;
+             /* XXX - restore sigint handler here? */
+             goto wait_for_return;
+           }
+
+         /* If child is marked as running, but waitpid() returns -1/ECHILD,
+            there is something wrong.  Somewhere, wait should have returned
+            that child's pid.  Mark the child as not running and the job,
+            if it exists, as JDEAD. */
+         if (r == -1 && errno == ECHILD)
+           {
+             if (child)
+               {
+                 child->running = PS_DONE;
+                 WSTATUS (child->status) = 0;  /* XXX -- can't find true status */
+               }
+             js.c_living = 0;          /* no living child processes */
+             if (job != NO_JOB)
+               {
+                 jobs[job]->state = JDEAD;
+                 js.c_reaped++;
+                 js.j_ndead++;
+               }
+             if (pid == ANY_PID)
+               {
+                 termination_state = -1;
+                 break;
+               }
+           }
+#endif /* WAITPID_BROKEN */
+       }
+
+      /* If the shell is interactive, and job control is disabled, see
+        if the foreground process has died due to SIGINT and jump out
+        of the wait loop if it has.  waitchld has already restored the
+        old SIGINT signal handler. */
+      if (interactive && job_control == 0)
+       QUIT;
+      /* Check for terminating signals and exit the shell if we receive one */
+      CHECK_TERMSIG;
+
+      /* Check for a trapped signal interrupting the wait builtin and jump out */
+      CHECK_WAIT_INTR;
+
+      if (pid == ANY_PID)
+        /* XXX - could set child but we don't have a handle on what waitchld
+          reaps.  Leave termination_state alone. */
+       goto wait_for_return;
+    }
+  while (PRUNNING (child) || (job != NO_JOB && RUNNING (job)));
+
+  /* Restore the original SIGINT signal handler before we return. */
+  restore_sigint_handler ();
+
+  /* The exit state of the command is either the termination state of the
+     child, or the termination state of the job.  If a job, the status
+     of the last child in the pipeline is the significant one.  If the command
+     or job was terminated by a signal, note that value also. */
+  termination_state = (job != NO_JOB) ? job_exit_status (job)
+                                     : (child ? process_exit_status (child->status) : EXECUTION_SUCCESS);
+  last_command_exit_signal = (job != NO_JOB) ? job_exit_signal (job)
+                                            : (child ? process_exit_signal (child->status) : 0);
+
+  /* XXX */
+  if ((job != NO_JOB && JOBSTATE (job) == JSTOPPED) || WIFSTOPPED (child->status))
+    termination_state = 128 + WSTOPSIG (child->status);
+
+  if (job == NO_JOB || IS_JOBCONTROL (job))
+    {
+      /* XXX - under what circumstances is a job not present in the jobs
+        table (job == NO_JOB)?
+               1.  command substitution
+
+        In the case of command substitution, at least, it's probably not
+        the right thing to give the terminal to the shell's process group,
+        even though there is code in subst.c:command_substitute to work
+        around it.
+
+        Things that don't:
+               $PROMPT_COMMAND execution
+               process substitution
+       */
+#if 0
+if (job == NO_JOB)
+  itrace("wait_for: job == NO_JOB, giving the terminal to shell_pgrp (%ld)", (long)shell_pgrp);
+#endif
+      /* Don't modify terminal pgrp if we are running in the background */
+      if (running_in_background == 0)
+       give_terminal_to (shell_pgrp, 0);
+    }
+
+  /* If the command did not exit cleanly, or the job is just
+     being stopped, then reset the tty state back to what it
+     was before this command.  Reset the tty state and notify
+     the user of the job termination only if the shell is
+     interactive.  Clean up any dead jobs in either case. */
+  if (job != NO_JOB)
+    {
+      if (interactive_shell && subshell_environment == 0)
+       {
+         /* This used to use `child->status'.  That's wrong, however, for
+            pipelines.  `child' is the first process in the pipeline.  It's
+            likely that the process we want to check for abnormal termination
+            or stopping is the last process in the pipeline, especially if
+            it's long-lived and the first process is short-lived.  Since we
+            know we have a job here, we can check all the processes in this
+            job's pipeline and see if one of them stopped or terminated due
+            to a signal.  We might want to change this later to just check
+            the last process in the pipeline.  If no process exits due to a
+            signal, S is left as the status of the last job in the pipeline. */
+         s = job_signal_status (job);
+
+         if (WIFSIGNALED (s) || WIFSTOPPED (s))
+           {
+             set_tty_state ();
+
+             /* If the current job was stopped or killed by a signal, and
+                the user has requested it, get a possibly new window size */
+             if (check_window_size && (job == js.j_current || IS_FOREGROUND (job)))
+               get_new_window_size (0, (int *)0, (int *)0);
+           }
+         else
+           get_tty_state ();
+
+         /* If job control is enabled, the job was started with job
+            control, the job was the foreground job, and it was killed
+            by SIGINT, then print a newline to compensate for the kernel
+            printing the ^C without a trailing newline. */
+         if (job_control && IS_JOBCONTROL (job) && IS_FOREGROUND (job) &&
+               WIFSIGNALED (s) && WTERMSIG (s) == SIGINT)
+           {
+             /* If SIGINT is not trapped and the shell is in a for, while,
+                or until loop, act as if the shell received SIGINT as
+                well, so the loop can be broken.  This doesn't call the
+                SIGINT signal handler; maybe it should. */
+             if (signal_is_trapped (SIGINT) == 0 && (loop_level || (shell_compatibility_level > 32 && executing_list)))
+               ADDINTERRUPT;
+             else
+               {
+                 putchar ('\n');
+                 fflush (stdout);
+               }
+           }
+       }
+      else if ((subshell_environment & (SUBSHELL_COMSUB|SUBSHELL_PIPE)) && wait_sigint_received)
+       {
+         /* If waiting for a job in a subshell started to do command
+            substitution or to run a pipeline element that consists of
+            something like a while loop or a for loop, simulate getting
+            and being killed by the SIGINT to pass the status back to our
+            parent. */
+         s = job_signal_status (job);
+
+         if (child_caught_sigint == 0 && signal_is_trapped (SIGINT) == 0)
+           {
+             UNBLOCK_CHILD (oset);
+             old_sigint_handler = set_signal_handler (SIGINT, SIG_DFL);
+             if (old_sigint_handler == SIG_IGN)
+               restore_sigint_handler ();
+             else
+               kill (getpid (), SIGINT);
+           }
+       }
+      else if (interactive_shell == 0 && IS_FOREGROUND (job) && check_window_size)
+       get_new_window_size (0, (int *)0, (int *)0);
+
+      /* Moved here from set_job_status_and_cleanup, which is in the SIGCHLD
+         signal handler path */
+      if (DEADJOB (job) && IS_FOREGROUND (job) /*&& subshell_environment == 0*/)
+       setjstatus (job);
+
+      /* If this job is dead, notify the user of the status.  If the shell
+        is interactive, this will display a message on the terminal.  If
+        the shell is not interactive, make sure we turn on the notify bit
+        so we don't get an unwanted message about the job's termination,
+        and so delete_job really clears the slot in the jobs table. */
+      notify_and_cleanup ();
+    }
+
+wait_for_return:
+
+  UNBLOCK_CHILD (oset);
+
+  return (termination_state);
+}
+
+/* Wait for the last process in the pipeline for JOB.  Returns whatever
+   wait_for returns: the last process's termination state or -1 if there
+   are no unwaited-for child processes or an error occurs. */
+int
+wait_for_job (job)
+     int job;
+{
+  pid_t pid;
+  int r;
+  sigset_t set, oset;
+
+  BLOCK_CHILD(set, oset);
+  if (JOBSTATE (job) == JSTOPPED)
+    internal_warning (_("wait_for_job: job %d is stopped"), job+1);
+
+  pid = find_last_pid (job, 0);
+  UNBLOCK_CHILD(oset);
+  r = wait_for (pid);
+
+  /* POSIX.2: we can remove the job from the jobs table if we just waited
+     for it. */
+  BLOCK_CHILD (set, oset);
+  if (job != NO_JOB && jobs[job] && DEADJOB (job))
+    jobs[job]->flags |= J_NOTIFIED;
+  UNBLOCK_CHILD (oset);
+
+  return r;
+}
+
+/* Wait for any background job started by this shell to finish.  Very
+   similar to wait_for_background_pids().  Returns the exit status of
+   the next exiting job, -1 if there are no background jobs.  The caller
+   is responsible for translating -1 into the right return value. */
+int
+wait_for_any_job ()
+{
+  pid_t pid;
+  int i, r, waited_for;
+  sigset_t set, oset;
+
+  if (jobs_list_frozen)
+    return -1;
+
+  /* First see if there are any unnotified dead jobs that we can report on */
+  BLOCK_CHILD (set, oset);
+  for (i = 0; i < js.j_jobslots; i++)
+    {
+      if (jobs[i] && DEADJOB (i) && IS_NOTIFIED (i) == 0)
+       {
+return_job:
+         r = job_exit_status (i);
+         notify_of_job_status ();              /* XXX */
+         delete_job (i, 0);
+#if defined (COPROCESS_SUPPORT)
+         coproc_reap ();
+#endif
+         UNBLOCK_CHILD (oset);
+         return r;
+       }
+    }
+  UNBLOCK_CHILD (oset);
+
+  /* At this point, we have no dead jobs in the jobs table.  Wait until we
+     get one, even if it takes multiple pids exiting. */
+  for (waited_for = 0;;)
+    {
+      /* Make sure there is a background job to wait for */
+      BLOCK_CHILD (set, oset);
+      for (i = 0; i < js.j_jobslots; i++)
+        if (jobs[i] && RUNNING (i) && IS_FOREGROUND (i) == 0)
+          break;
+      if (i == js.j_jobslots)
+       {
+         UNBLOCK_CHILD (oset);
+         return -1;
+       }
+
+      UNBLOCK_CHILD (oset);
+
+      QUIT;
+      CHECK_TERMSIG;
+      CHECK_WAIT_INTR;
+
+      errno = 0;
+      r = wait_for (ANY_PID);  /* special sentinel value for wait_for */
+      if (r == -1 && errno == ECHILD)
+       mark_all_jobs_as_dead ();
+       
+      /* Now we see if we have any dead jobs and return the first one */
+      BLOCK_CHILD (set, oset);
+      for (i = 0; i < js.j_jobslots; i++)
+       if (jobs[i] && DEADJOB (i))
+         goto return_job;
+      UNBLOCK_CHILD (oset);
+    }
+
+  return -1;
+}
+
+/* Print info about dead jobs, and then delete them from the list
+   of known jobs.  This does not actually delete jobs when the
+   shell is not interactive, because the dead jobs are not marked
+   as notified. */
+void
+notify_and_cleanup ()
+{
+  if (jobs_list_frozen)
+    return;
+
+  if (interactive || interactive_shell == 0 || sourcelevel)
+    notify_of_job_status ();
+
+  cleanup_dead_jobs ();
+}
+
+/* Make dead jobs disappear from the jobs array without notification.
+   This is used when the shell is not interactive. */
+void
+reap_dead_jobs ()
+{
+  mark_dead_jobs_as_notified (0);
+  cleanup_dead_jobs ();
+}
+
+/* Return the next closest (chronologically) job to JOB which is in
+   STATE.  STATE can be JSTOPPED, JRUNNING.  NO_JOB is returned if
+   there is no next recent job. */
+static int
+most_recent_job_in_state (job, state)
+     int job;
+     JOB_STATE state;
+{
+  register int i, result;
+  sigset_t set, oset;
+
+  BLOCK_CHILD (set, oset);
+
+  for (result = NO_JOB, i = job - 1; i >= 0; i--)
+    {
+      if (jobs[i] && (JOBSTATE (i) == state))
+       {
+         result = i;
+         break;
+       }
+    }
+
+  UNBLOCK_CHILD (oset);
+
+  return (result);
+}
+
+/* Return the newest *stopped* job older than JOB, or NO_JOB if not
+   found. */
+static int
+job_last_stopped (job)
+     int job;
+{
+  return (most_recent_job_in_state (job, JSTOPPED));
+}
+
+/* Return the newest *running* job older than JOB, or NO_JOB if not
+   found. */
+static int
+job_last_running (job)
+     int job;
+{
+  return (most_recent_job_in_state (job, JRUNNING));
+}
+
+/* Make JOB be the current job, and make previous be useful.  Must be
+   called with SIGCHLD blocked. */
+static void
+set_current_job (job)
+     int job;
+{
+  int candidate;
+
+  if (js.j_current != job)
+    {
+      js.j_previous = js.j_current;
+      js.j_current = job;
+    }
+
+  /* First choice for previous job is the old current job. */
+  if (js.j_previous != js.j_current &&
+      js.j_previous != NO_JOB &&
+      jobs[js.j_previous] &&
+      STOPPED (js.j_previous))
+    return;
+
+  /* Second choice:  Newest stopped job that is older than
+     the current job. */
+  candidate = NO_JOB;
+  if (STOPPED (js.j_current))
+    {
+      candidate = job_last_stopped (js.j_current);
+
+      if (candidate != NO_JOB)
+       {
+         js.j_previous = candidate;
+         return;
+       }
+    }
+
+  /* If we get here, there is either only one stopped job, in which case it is
+     the current job and the previous job should be set to the newest running
+     job, or there are only running jobs and the previous job should be set to
+     the newest running job older than the current job.  We decide on which
+     alternative to use based on whether or not JOBSTATE(js.j_current) is
+     JSTOPPED. */
+
+  candidate = RUNNING (js.j_current) ? job_last_running (js.j_current)
+                                   : job_last_running (js.j_jobslots);
+
+  if (candidate != NO_JOB)
+    {
+      js.j_previous = candidate;
+      return;
+    }
+
+  /* There is only a single job, and it is both `+' and `-'. */
+  js.j_previous = js.j_current;
+}
+
+/* Make current_job be something useful, if it isn't already. */
+
+/* Here's the deal:  The newest non-running job should be `+', and the
+   next-newest non-running job should be `-'.  If there is only a single
+   stopped job, the js.j_previous is the newest non-running job.  If there
+   are only running jobs, the newest running job is `+' and the
+   next-newest running job is `-'.  Must be called with SIGCHLD blocked. */
+
+static void
+reset_current ()
+{
+  int candidate;
+
+  if (js.j_jobslots && js.j_current != NO_JOB && jobs[js.j_current] && STOPPED (js.j_current))
+    candidate = js.j_current;
+  else
+    {
+      candidate = NO_JOB;
+
+      /* First choice: the previous job. */
+      if (js.j_previous != NO_JOB && jobs[js.j_previous] && STOPPED (js.j_previous))
+       candidate = js.j_previous;
+
+      /* Second choice: the most recently stopped job. */
+      if (candidate == NO_JOB)
+       candidate = job_last_stopped (js.j_jobslots);
+
+      /* Third choice: the newest running job. */
+      if (candidate == NO_JOB)
+       candidate = job_last_running (js.j_jobslots);
+    }
+
+  /* If we found a job to use, then use it.  Otherwise, there
+     are no jobs period. */
+  if (candidate != NO_JOB)
+    set_current_job (candidate);
+  else
+    js.j_current = js.j_previous = NO_JOB;
+}
+
+/* Set up the job structures so we know the job and its processes are
+   all running. */
+static void
+set_job_running (job)
+     int job;
+{
+  register PROCESS *p;
+
+  /* Each member of the pipeline is now running. */
+  p = jobs[job]->pipe;
+
+  do
+    {
+      if (WIFSTOPPED (p->status))
+       p->running = PS_RUNNING;        /* XXX - could be PS_STOPPED */
+      p = p->next;
+    }
+  while (p != jobs[job]->pipe);
+
+  /* This means that the job is running. */
+  JOBSTATE (job) = JRUNNING;
+}
+
+/* Start a job.  FOREGROUND if non-zero says to do that.  Otherwise,
+   start the job in the background.  JOB is a zero-based index into
+   JOBS.  Returns -1 if it is unable to start a job, and the return
+   status of the job otherwise. */
+int
+start_job (job, foreground)
+     int job, foreground;
+{
+  register PROCESS *p;
+  int already_running;
+  sigset_t set, oset;
+  char *wd, *s;
+  static TTYSTRUCT save_stty;
+
+  BLOCK_CHILD (set, oset);
+
+  if (DEADJOB (job))
+    {
+      internal_error (_("%s: job has terminated"), this_command_name);
+      UNBLOCK_CHILD (oset);
+      return (-1);
+    }
+
+  already_running = RUNNING (job);
+
+  if (foreground == 0 && already_running)
+    {
+      internal_error (_("%s: job %d already in background"), this_command_name, job + 1);
+      UNBLOCK_CHILD (oset);
+      return (0);              /* XPG6/SUSv3 says this is not an error */
+    }
+
+  wd = current_working_directory ();
+
+  /* You don't know about the state of this job.  Do you? */
+  jobs[job]->flags &= ~J_NOTIFIED;
+
+  if (foreground)
+    {
+      set_current_job (job);
+      jobs[job]->flags |= J_FOREGROUND;
+    }
+
+  /* Tell the outside world what we're doing. */
+  p = jobs[job]->pipe;
+
+  if (foreground == 0)
+    {
+      /* POSIX.2 says `bg' doesn't give any indication about current or
+        previous job. */
+      if (posixly_correct == 0)
+       s = (job == js.j_current) ? "+ ": ((job == js.j_previous) ? "- " : " ");       
+      else
+       s = " ";
+      printf ("[%d]%s", job + 1, s);
+    }
+
+  do
+    {
+      printf ("%s%s",
+              p->command ? p->command : "",
+              p->next != jobs[job]->pipe? " | " : "");
+      p = p->next;
+    }
+  while (p != jobs[job]->pipe);
+
+  if (foreground == 0)
+    printf (" &");
+
+  if (strcmp (wd, jobs[job]->wd) != 0)
+    printf ("  (wd: %s)", polite_directory_format (jobs[job]->wd));
+
+  printf ("\n");
+
+  /* Run the job. */
+  if (already_running == 0)
+    set_job_running (job);
+
+  /* Save the tty settings before we start the job in the foreground. */
+  if (foreground)
+    {
+      get_tty_state ();
+      save_stty = shell_tty_info;
+      /* Give the terminal to this job. */
+      if (IS_JOBCONTROL (job))
+       give_terminal_to (jobs[job]->pgrp, 0);
+    }
+  else
+    jobs[job]->flags &= ~J_FOREGROUND;
+
+  /* If the job is already running, then don't bother jump-starting it. */
+  if (already_running == 0)
+    {
+      jobs[job]->flags |= J_NOTIFIED;
+      killpg (jobs[job]->pgrp, SIGCONT);
+    }
+
+  if (foreground)
+    {
+      pid_t pid;
+      int st;
+
+      pid = find_last_pid (job, 0);
+      UNBLOCK_CHILD (oset);
+      st = wait_for (pid);
+      shell_tty_info = save_stty;
+      set_tty_state ();
+      return (st);
+    }
+  else
+    {
+      reset_current ();
+      UNBLOCK_CHILD (oset);
+      return (0);
+    }
+}
+
+/* Give PID SIGNAL.  This determines what job the pid belongs to (if any).
+   If PID does belong to a job, and the job is stopped, then CONTinue the
+   job after giving it SIGNAL.  Returns -1 on failure.  If GROUP is non-null,
+   then kill the process group associated with PID. */
+int
+kill_pid (pid, sig, group)
+     pid_t pid;
+     int sig, group;
+{
+  register PROCESS *p;
+  int job, result, negative;
+  sigset_t set, oset;
+
+  if (pid < -1)
+    {
+      pid = -pid;
+      group = negative = 1;
+    }
+  else
+    negative = 0;
+
+  result = EXECUTION_SUCCESS;
+  if (group)
+    {
+      BLOCK_CHILD (set, oset);
+      p = find_pipeline (pid, 0, &job);
+
+      if (job != NO_JOB)
+       {
+         jobs[job]->flags &= ~J_NOTIFIED;
+
+         /* Kill process in backquotes or one started without job control? */
+
+         /* If we're passed a pid < -1, just call killpg and see what happens  */
+         if (negative && jobs[job]->pgrp == shell_pgrp)
+           result = killpg (pid, sig);
+         /* If we're killing using job control notification, for example,
+            without job control active, we have to do things ourselves. */
+         else if (jobs[job]->pgrp == shell_pgrp)
+           {
+             p = jobs[job]->pipe;
+             do
+               {
+                 if (PALIVE (p) == 0)
+                   continue;           /* avoid pid recycling problem */
+                 kill (p->pid, sig);
+                 if (PEXITED (p) && (sig == SIGTERM || sig == SIGHUP))
+                   kill (p->pid, SIGCONT);
+                 p = p->next;
+               }
+             while  (p != jobs[job]->pipe);
+           }
+         else
+           {
+             result = killpg (jobs[job]->pgrp, sig);
+             if (p && STOPPED (job) && (sig == SIGTERM || sig == SIGHUP))
+               killpg (jobs[job]->pgrp, SIGCONT);
+             /* If we're continuing a stopped job via kill rather than bg or
+                fg, emulate the `bg' behavior. */
+             if (p && STOPPED (job) && (sig == SIGCONT))
+               {
+                 set_job_running (job);
+                 jobs[job]->flags &= ~J_FOREGROUND;
+                 jobs[job]->flags |= J_NOTIFIED;
+               }
+           }
+       }
+      else
+       result = killpg (pid, sig);
+
+      UNBLOCK_CHILD (oset);
+    }
+  else
+    result = kill (pid, sig);
+
+  return (result);
+}
+
+/* sigchld_handler () flushes at least one of the children that we are
+   waiting for.  It gets run when we have gotten a SIGCHLD signal. */
+static sighandler
+sigchld_handler (sig)
+     int sig;
+{
+  int n, oerrno;
+
+  oerrno = errno;
+  REINSTALL_SIGCHLD_HANDLER;
+  sigchld++;
+  n = 0;
+  if (queue_sigchld == 0)
+    n = waitchld (-1, 0);
+  errno = oerrno;
+  SIGRETURN (n);
+}
+
+/* waitchld() reaps dead or stopped children.  It's called by wait_for and
+   sigchld_handler, and runs until there aren't any children terminating any
+   more.
+   If BLOCK is 1, this is to be a blocking wait for a single child, although
+   an arriving SIGCHLD could cause the wait to be non-blocking.  It returns
+   the number of children reaped, or -1 if there are no unwaited-for child
+   processes. */
+static int
+waitchld (wpid, block)
+     pid_t wpid;
+     int block;
+{
+  WAIT status;
+  PROCESS *child;
+  pid_t pid;
+
+  int call_set_current, last_stopped_job, job, children_exited, waitpid_flags;
+  static int wcontinued = WCONTINUED;  /* run-time fix for glibc problem */
+
+  call_set_current = children_exited = 0;
+  last_stopped_job = NO_JOB;
+
+  do
+    {
+      /* We don't want to be notified about jobs stopping if job control
+        is not active.  XXX - was interactive_shell instead of job_control */
+      waitpid_flags = (job_control && subshell_environment == 0)
+                       ? (WUNTRACED|wcontinued)
+                       : 0;
+      if (sigchld || block == 0)
+       waitpid_flags |= WNOHANG;
+
+      /* Check for terminating signals and exit the shell if we receive one */
+      CHECK_TERMSIG;
+      /* Check for a trapped signal interrupting the wait builtin and jump out */
+      CHECK_WAIT_INTR;
+
+      if (block == 1 && queue_sigchld == 0 && (waitpid_flags & WNOHANG) == 0)
+       {
+         internal_warning (_("waitchld: turning on WNOHANG to avoid indefinite block"));
+         waitpid_flags |= WNOHANG;
+       }
+
+      pid = WAITPID (-1, &status, waitpid_flags);
+
+#if 0
+if (wpid != -1 && block)
+  itrace("waitchld: blocking waitpid returns %d", pid);
+#endif
+      /* WCONTINUED may be rejected by waitpid as invalid even when defined */
+      if (wcontinued && pid < 0 && errno == EINVAL)
+       {
+         wcontinued = 0;
+         continue;     /* jump back to the test and retry without WCONTINUED */
+       }
+
+      /* The check for WNOHANG is to make sure we decrement sigchld only
+        if it was non-zero before we called waitpid. */
+      if (sigchld > 0 && (waitpid_flags & WNOHANG))
+       sigchld--;
+
+      /* If waitpid returns -1 with errno == ECHILD, there are no more
+        unwaited-for child processes of this shell. */
+      if (pid < 0 && errno == ECHILD)
+       {
+         if (children_exited == 0)
+           return -1;
+         else
+           break;
+       }
+
+#if 0
+itrace("waitchld: waitpid returns %d block = %d children_exited = %d", pid, block, children_exited);
+#endif
+      /* If waitpid returns 0, there are running children.  If it returns -1,
+        the only other error POSIX says it can return is EINTR. */
+      CHECK_TERMSIG;
+      CHECK_WAIT_INTR;
+
+      /* If waitpid returns -1/EINTR and the shell saw a SIGINT, then we
+        assume the child has blocked or handled SIGINT.  In that case, we
+        require the child to actually die due to SIGINT to act on the
+        SIGINT we received; otherwise we assume the child handled it and
+        let it go. */
+      if (pid < 0 && errno == EINTR && wait_sigint_received)
+       child_caught_sigint = 1;
+
+      if (pid <= 0)
+       continue;       /* jumps right to the test */
+
+      /* If the child process did die due to SIGINT, forget our assumption
+        that it caught or otherwise handled it. */
+      if (WIFSIGNALED (status) && WTERMSIG (status) == SIGINT)
+        child_caught_sigint = 0;
+
+      /* children_exited is used to run traps on SIGCHLD.  We don't want to
+         run the trap if a process is just being continued. */
+      if (WIFCONTINUED(status) == 0)
+       {
+         children_exited++;
+         js.c_living--;
+       }
+
+      /* Locate our PROCESS for this pid. */
+      child = find_process (pid, 1, &job);     /* want living procs only */
+
+#if defined (COPROCESS_SUPPORT)
+      coproc_pidchk (pid, WSTATUS(status));
+#endif
+
+      /* It is not an error to have a child terminate that we did
+        not have a record of.  This child could have been part of
+        a pipeline in backquote substitution.  Even so, I'm not
+        sure child is ever non-zero. */
+      if (child == 0)
+       {
+         if (WIFEXITED (status) || WIFSIGNALED (status))
+           js.c_reaped++;
+         continue;
+       }
+
+      /* Remember status, and whether or not the process is running. */
+      child->status = status;
+      child->running = WIFCONTINUED(status) ? PS_RUNNING : PS_DONE;
+
+      if (PEXITED (child))
+       {
+         js.c_totreaped++;
+         if (job != NO_JOB)
+           js.c_reaped++;
+       }
+        
+      if (job == NO_JOB)
+       continue;
+
+      call_set_current += set_job_status_and_cleanup (job);
+
+      if (STOPPED (job))
+       last_stopped_job = job;
+      else if (DEADJOB (job) && last_stopped_job == job)
+       last_stopped_job = NO_JOB;
+    }
+  while ((sigchld || block == 0) && pid > (pid_t)0);
+
+  /* If a job was running and became stopped, then set the current
+     job.  Otherwise, don't change a thing. */
+  if (call_set_current)
+    {
+      if (last_stopped_job != NO_JOB)
+       set_current_job (last_stopped_job);
+      else
+       reset_current ();
+    }
+
+  /* Call a SIGCHLD trap handler for each child that exits, if one is set. */
+  if (job_control && signal_is_trapped (SIGCHLD) && children_exited &&
+      trap_list[SIGCHLD] != (char *)IGNORE_SIG)
+    {
+      if (posixly_correct && this_shell_builtin && this_shell_builtin == wait_builtin)
+       {
+         interrupt_immediately = 0;
+         /* This was trap_handler (SIGCHLD) but that can lose traps if
+            children_exited > 1 */
+         queue_sigchld_trap (children_exited);
+         wait_signal_received = SIGCHLD;
+         /* If we're in a signal handler, let CHECK_WAIT_INTR pick it up;
+            run_pending_traps will call run_sigchld_trap later  */
+         if (sigchld == 0)
+           longjmp (wait_intr_buf, 1);
+       }
+      /* If not in posix mode and not executing the wait builtin, queue the
+        signal for later handling.  Run the trap immediately if we are
+        executing the wait builtin, but don't break out of `wait'. */
+      else if (sigchld)        /* called from signal handler */
+       queue_sigchld_trap (children_exited);
+      else if (running_trap)
+       queue_sigchld_trap (children_exited);
+      else if (this_shell_builtin == wait_builtin)
+       run_sigchld_trap (children_exited);     /* XXX */
+      else
+       queue_sigchld_trap (children_exited);
+    }
+
+  /* We have successfully recorded the useful information about this process
+     that has just changed state.  If we notify asynchronously, and the job
+     that this process belongs to is no longer running, then notify the user
+     of that fact now. */
+  if (asynchronous_notification && interactive)
+    notify_of_job_status ();
+
+  return (children_exited);
+}
+
+/* Set the status of JOB and perform any necessary cleanup if the job is
+   marked as JDEAD.
+
+   Currently, the cleanup activity is restricted to handling any SIGINT
+   received while waiting for a foreground job to finish. */
+static int
+set_job_status_and_cleanup (job)
+     int job;
+{
+  PROCESS *child;
+  int tstatus, job_state, any_stopped, any_tstped, call_set_current;
+  SigHandler *temp_handler;
+
+  child = jobs[job]->pipe;
+  jobs[job]->flags &= ~J_NOTIFIED;
+
+  call_set_current = 0;
+
+  /*
+   * COMPUTE JOB STATUS
+   */
+
+  /* If all children are not running, but any of them is  stopped, then
+     the job is stopped, not dead. */
+  job_state = any_stopped = any_tstped = 0;
+  do
+    {
+      job_state |= PRUNNING (child);
+#if 0
+      if (PEXITED (child) && (WIFSTOPPED (child->status)))
+#else
+      /* Only checking for WIFSTOPPED now, not for PS_DONE */
+      if (PSTOPPED (child))
+#endif
+       {
+         any_stopped = 1;
+         any_tstped |= job_control && (WSTOPSIG (child->status) == SIGTSTP);
+       }
+      child = child->next;
+    }
+  while (child != jobs[job]->pipe);
+
+  /* If job_state != 0, the job is still running, so don't bother with
+     setting the process exit status and job state unless we're
+     transitioning from stopped to running. */
+  if (job_state != 0 && JOBSTATE(job) != JSTOPPED)
+    return 0;
+
+  /*
+   * SET JOB STATUS
+   */
+
+  /* The job is either stopped or dead.  Set the state of the job accordingly. */
+  if (any_stopped)
+    {
+      jobs[job]->state = JSTOPPED;
+      jobs[job]->flags &= ~J_FOREGROUND;
+      call_set_current++;
+      /* Suspending a job with SIGTSTP breaks all active loops. */
+      if (any_tstped && loop_level)
+       breaking = loop_level;
+    }
+  else if (job_state != 0)     /* was stopped, now running */
+    {
+      jobs[job]->state = JRUNNING;
+      call_set_current++;
+    }
+  else
+    {
+      jobs[job]->state = JDEAD;
+      js.j_ndead++;
+
+#if 0
+      if (IS_FOREGROUND (job))
+       setjstatus (job);
+#endif
+
+      /* If this job has a cleanup function associated with it, call it
+        with `cleanarg' as the single argument, then set the function
+        pointer to NULL so it is not inadvertently called twice.  The
+        cleanup function is responsible for deallocating cleanarg. */
+      if (jobs[job]->j_cleanup)
+       {
+         (*jobs[job]->j_cleanup) (jobs[job]->cleanarg);
+         jobs[job]->j_cleanup = (sh_vptrfunc_t *)NULL;
+       }
+    }
+
+  /*
+   * CLEANUP
+   *
+   * Currently, we just do special things if we got a SIGINT while waiting
+   * for a foreground job to complete
+   */
+
+  if (JOBSTATE (job) == JDEAD)
+    {
+      /* If we're running a shell script and we get a SIGINT with a
+        SIGINT trap handler, but the foreground job handles it and
+        does not exit due to SIGINT, run the trap handler but do not
+        otherwise act as if we got the interrupt. */
+      if (wait_sigint_received && interactive_shell == 0 &&
+         child_caught_sigint && IS_FOREGROUND (job) &&
+         signal_is_trapped (SIGINT))
+       {
+         int old_frozen;
+         wait_sigint_received = 0;
+         last_command_exit_value = process_exit_status (child->status);
+
+         old_frozen = jobs_list_frozen;
+         jobs_list_frozen = 1;
+         tstatus = maybe_call_trap_handler (SIGINT);
+         jobs_list_frozen = old_frozen;
+       }
+
+      /* If the foreground job is killed by SIGINT when job control is not
+        active, we need to perform some special handling.
+
+        The check of wait_sigint_received is a way to determine if the
+        SIGINT came from the keyboard (in which case the shell has already
+        seen it, and wait_sigint_received is non-zero, because keyboard
+        signals are sent to process groups) or via kill(2) to the foreground
+        process by another process (or itself).  If the shell did receive the
+        SIGINT, it needs to perform normal SIGINT processing. */
+      else if (wait_sigint_received &&
+             child_caught_sigint == 0 &&
+             IS_FOREGROUND (job) && IS_JOBCONTROL (job) == 0)
+       {
+         int old_frozen;
+
+         wait_sigint_received = 0;
+
+         /* If SIGINT is trapped, set the exit status so that the trap
+            handler can see it. */
+         if (signal_is_trapped (SIGINT))
+           last_command_exit_value = process_exit_status (child->status);
+
+         /* If the signal is trapped, let the trap handler get it no matter
+            what and simply return if the trap handler returns.
+           maybe_call_trap_handler() may cause dead jobs to be removed from
+           the job table because of a call to execute_command.  We work
+           around this by setting JOBS_LIST_FROZEN. */
+         old_frozen = jobs_list_frozen;
+         jobs_list_frozen = 1;
+         tstatus = maybe_call_trap_handler (SIGINT);
+         jobs_list_frozen = old_frozen;
+         if (tstatus == 0 && old_sigint_handler != INVALID_SIGNAL_HANDLER)
+           {
+             /* wait_sigint_handler () has already seen SIGINT and
+                allowed the wait builtin to jump out.  We need to
+                call the original SIGINT handler, if necessary.  If
+                the original handler is SIG_DFL, we need to resend
+                the signal to ourselves. */
+
+             temp_handler = old_sigint_handler;
+
+             /* Bogus.  If we've reset the signal handler as the result
+                of a trap caught on SIGINT, then old_sigint_handler
+                will point to trap_handler, which now knows nothing about
+                SIGINT (if we reset the sighandler to the default).
+                In this case, we have to fix things up.  What a crock. */
+             if (temp_handler == trap_handler && signal_is_trapped (SIGINT) == 0)
+                 temp_handler = trap_to_sighandler (SIGINT);
+               restore_sigint_handler ();
+             if (temp_handler == SIG_DFL)
+               termsig_handler (SIGINT);       /* XXX */
+             else if (temp_handler != SIG_IGN)
+               (*temp_handler) (SIGINT);
+           }
+       }
+    }
+
+  return call_set_current;
+}
+
+/* Build the array of values for the $PIPESTATUS variable from the set of
+   exit statuses of all processes in the job J. */
+static void
+setjstatus (j)
+     int j;
+{
+#if defined (ARRAY_VARS)
+  register int i;
+  register PROCESS *p;
+
+  for (i = 1, p = jobs[j]->pipe; p->next != jobs[j]->pipe; p = p->next, i++)
+    ;
+  i++;
+  if (statsize < i)
+    {
+      pstatuses = (int *)xrealloc (pstatuses, i * sizeof (int));
+      statsize = i;
+    }
+  i = 0;
+  p = jobs[j]->pipe;
+  do
+    {
+      pstatuses[i++] = process_exit_status (p->status);
+      p = p->next;
+    }
+  while (p != jobs[j]->pipe);
+
+  pstatuses[i] = -1;   /* sentinel */
+  set_pipestatus_array (pstatuses, i);
+#endif
+}
+
+void
+run_sigchld_trap (nchild)
+     int nchild;
+{
+  char *trap_command;
+  int i;
+
+  /* Turn off the trap list during the call to parse_and_execute ()
+     to avoid potentially infinite recursive calls.  Preserve the
+     values of last_command_exit_value, last_made_pid, and the_pipeline
+     around the execution of the trap commands. */
+  trap_command = savestring (trap_list[SIGCHLD]);
+
+  begin_unwind_frame ("SIGCHLD trap");
+  unwind_protect_int (last_command_exit_value);
+  unwind_protect_int (last_command_exit_signal);
+  unwind_protect_var (last_made_pid);
+  unwind_protect_int (interrupt_immediately);
+  unwind_protect_int (jobs_list_frozen);
+  unwind_protect_pointer (the_pipeline);
+  unwind_protect_pointer (subst_assign_varlist);
+  unwind_protect_pointer (this_shell_builtin);
+
+  /* We have to add the commands this way because they will be run
+     in reverse order of adding.  We don't want maybe_set_sigchld_trap ()
+     to reference freed memory. */
+  add_unwind_protect (xfree, trap_command);
+  add_unwind_protect (maybe_set_sigchld_trap, trap_command);
+
+  subst_assign_varlist = (WORD_LIST *)NULL;
+  the_pipeline = (PROCESS *)NULL;
+
+  running_trap = SIGCHLD + 1;
+
+  set_impossible_sigchld_trap ();
+  jobs_list_frozen = 1;
+  for (i = 0; i < nchild; i++)
+    {
+#if 0
+      interrupt_immediately = 1;
+#endif
+      parse_and_execute (savestring (trap_command), "trap", SEVAL_NOHIST|SEVAL_RESETLINE);
+    }
+
+  run_unwind_frame ("SIGCHLD trap");
+  running_trap = 0;
+}
+
+/* Function to call when you want to notify people of changes
+   in job status.  This prints out all jobs which are pending
+   notification to stderr, and marks those printed as already
+   notified, thus making them candidates for cleanup. */
+static void
+notify_of_job_status ()
+{
+  register int job, termsig;
+  char *dir;
+  sigset_t set, oset;
+  WAIT s;
+
+  if (jobs == 0 || js.j_jobslots == 0)
+    return;
+
+  if (old_ttou != 0)
+    {
+      sigemptyset (&set);
+      sigaddset (&set, SIGCHLD);
+      sigaddset (&set, SIGTTOU);
+      sigemptyset (&oset);
+      sigprocmask (SIG_BLOCK, &set, &oset);
+    }
+  else
+    queue_sigchld++;
+
+  /* XXX could use js.j_firstj here */
+  for (job = 0, dir = (char *)NULL; job < js.j_jobslots; job++)
+    {
+      if (jobs[job] && IS_NOTIFIED (job) == 0)
+       {
+         s = raw_job_exit_status (job);
+         termsig = WTERMSIG (s);
+
+         /* POSIX.2 says we have to hang onto the statuses of at most the
+            last CHILD_MAX background processes if the shell is running a
+            script.  If the shell is running a script, either from a file
+            or standard input, don't print anything unless the job was
+            killed by a signal. */
+         if (startup_state == 0 && WIFSIGNALED (s) == 0 &&
+               ((DEADJOB (job) && IS_FOREGROUND (job) == 0) || STOPPED (job)))
+           continue;
+         
+#if 0
+         /* If job control is disabled, don't print the status messages.
+            Mark dead jobs as notified so that they get cleaned up.  If
+            startup_state == 2, we were started to run `-c command', so
+            don't print anything. */
+         if ((job_control == 0 && interactive_shell) || startup_state == 2)
+#else
+         /* If job control is disabled, don't print the status messages.
+            Mark dead jobs as notified so that they get cleaned up.  If
+            startup_state == 2 and subshell_environment has the
+            SUBSHELL_COMSUB bit turned on, we were started to run a command
+            substitution, so don't print anything. */
+         if ((job_control == 0 && interactive_shell) ||
+             (startup_state == 2 && (subshell_environment & SUBSHELL_COMSUB)))
+#endif
+           {
+             /* POSIX.2 compatibility:  if the shell is not interactive,
+                hang onto the job corresponding to the last asynchronous
+                pid until the user has been notified of its status or does
+                a `wait'. */
+             if (DEADJOB (job) && (interactive_shell || (find_last_pid (job, 0) != last_asynchronous_pid)))
+               jobs[job]->flags |= J_NOTIFIED;
+             continue;
+           }
+
+         /* Print info on jobs that are running in the background,
+            and on foreground jobs that were killed by anything
+            except SIGINT (and possibly SIGPIPE). */
+         switch (JOBSTATE (job))
+           {
+           case JDEAD:
+             if (interactive_shell == 0 && termsig && WIFSIGNALED (s) &&
+                 termsig != SIGINT &&
+#if defined (DONT_REPORT_SIGTERM)
+                 termsig != SIGTERM &&
+#endif
+#if defined (DONT_REPORT_SIGPIPE)
+                 termsig != SIGPIPE &&
+#endif
+                 signal_is_trapped (termsig) == 0)
+               {
+                 /* Don't print `0' for a line number. */
+                 fprintf (stderr, _("%s: line %d: "), get_name_for_error (), (line_number == 0) ? 1 : line_number);
+                 pretty_print_job (job, JLIST_NONINTERACTIVE, stderr);
+               }
+             else if (IS_FOREGROUND (job))
+               {
+#if !defined (DONT_REPORT_SIGPIPE)
+                 if (termsig && WIFSIGNALED (s) && termsig != SIGINT)
+#else
+                 if (termsig && WIFSIGNALED (s) && termsig != SIGINT && termsig != SIGPIPE)
+#endif
+                   {
+                     fprintf (stderr, "%s", j_strsignal (termsig));
+
+                     if (WIFCORED (s))
+                       fprintf (stderr, _(" (core dumped)"));
+
+                     fprintf (stderr, "\n");
+                   }
+               }
+             else if (job_control)     /* XXX job control test added */
+               {
+                 if (dir == 0)
+                   dir = current_working_directory ();
+                 pretty_print_job (job, JLIST_STANDARD, stderr);
+                 if (dir && strcmp (dir, jobs[job]->wd) != 0)
+                   fprintf (stderr,
+                            _("(wd now: %s)\n"), polite_directory_format (dir));
+               }
+
+             jobs[job]->flags |= J_NOTIFIED;
+             break;
+
+           case JSTOPPED:
+             fprintf (stderr, "\n");
+             if (dir == 0)
+               dir = current_working_directory ();
+             pretty_print_job (job, JLIST_STANDARD, stderr);
+             if (dir && (strcmp (dir, jobs[job]->wd) != 0))
+               fprintf (stderr,
+                        _("(wd now: %s)\n"), polite_directory_format (dir));
+             jobs[job]->flags |= J_NOTIFIED;
+             break;
+
+           case JRUNNING:
+           case JMIXED:
+             break;
+
+           default:
+             programming_error ("notify_of_job_status");
+           }
+       }
+    }
+  if (old_ttou != 0)
+    sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
+  else
+    queue_sigchld--;
+}
+
+/* Initialize the job control mechanism, and set up the tty stuff. */
+int
+initialize_job_control (force)
+     int force;
+{
+  pid_t t;
+  int t_errno;
+
+  t_errno = -1;
+  shell_pgrp = getpgid (0);
+
+  if (shell_pgrp == -1)
+    {
+      sys_error (_("initialize_job_control: getpgrp failed"));
+      exit (1);
+    }
+
+  /* We can only have job control if we are interactive unless we force it. */
+  if (interactive == 0 && force == 0)
+    {
+      job_control = 0;
+      original_pgrp = NO_PID;
+      shell_tty = fileno (stderr);
+      terminal_pgrp = tcgetpgrp (shell_tty);   /* for checking later */
+    }
+  else
+    {
+      shell_tty = -1;
+
+      /* If forced_interactive is set, we skip the normal check that stderr
+        is attached to a tty, so we need to check here.  If it's not, we
+        need to see whether we have a controlling tty by opening /dev/tty,
+        since trying to use job control tty pgrp manipulations on a non-tty
+        is going to fail. */
+      if (forced_interactive && isatty (fileno (stderr)) == 0)
+       shell_tty = open ("/dev/tty", O_RDWR|O_NONBLOCK);
+
+      /* Get our controlling terminal.  If job_control is set, or
+        interactive is set, then this is an interactive shell no
+        matter where fd 2 is directed. */
+      if (shell_tty == -1)
+       shell_tty = dup (fileno (stderr));      /* fd 2 */
+
+      if (shell_tty != -1)
+       shell_tty = move_to_high_fd (shell_tty, 1, -1);
+
+      /* Compensate for a bug in systems that compiled the BSD
+        rlogind with DEBUG defined, like NeXT and Alliant. */
+      if (shell_pgrp == 0)
+       {
+         shell_pgrp = getpid ();
+         setpgid (0, shell_pgrp);
+         if (shell_tty != -1)
+           tcsetpgrp (shell_tty, shell_pgrp);
+       }
+
+      while ((terminal_pgrp = tcgetpgrp (shell_tty)) != -1)
+       {
+         if (shell_pgrp != terminal_pgrp)
+           {
+             SigHandler *ottin;
+
+             ottin = set_signal_handler (SIGTTIN, SIG_DFL);
+             kill (0, SIGTTIN);
+             set_signal_handler (SIGTTIN, ottin);
+             continue;
+           }
+         break;
+       }
+
+      if (terminal_pgrp == -1)
+       t_errno = errno;
+
+      /* Make sure that we are using the new line discipline. */
+      if (set_new_line_discipline (shell_tty) < 0)
+       {
+         sys_error (_("initialize_job_control: line discipline"));
+         job_control = 0;
+       }
+      else
+       {
+         original_pgrp = shell_pgrp;
+         shell_pgrp = getpid ();
+
+         if ((original_pgrp != shell_pgrp) && (setpgid (0, shell_pgrp) < 0))
+           {
+             sys_error (_("initialize_job_control: setpgid"));
+             shell_pgrp = original_pgrp;
+           }
+
+         job_control = 1;
+
+         /* If (and only if) we just set our process group to our pid,
+            thereby becoming a process group leader, and the terminal
+            is not in the same process group as our (new) process group,
+            then set the terminal's process group to our (new) process
+            group.  If that fails, set our process group back to what it
+            was originally (so we can still read from the terminal) and
+            turn off job control.  */
+         if (shell_pgrp != original_pgrp && shell_pgrp != terminal_pgrp)
+           {
+             if (give_terminal_to (shell_pgrp, 0) < 0)
+               {
+                 t_errno = errno;
+                 setpgid (0, original_pgrp);
+                 shell_pgrp = original_pgrp;
+                 errno = t_errno;
+                 sys_error (_("cannot set terminal process group (%d)"), shell_pgrp);
+                 job_control = 0;
+               }
+           }
+
+         if (job_control && ((t = tcgetpgrp (shell_tty)) == -1 || t != shell_pgrp))
+           {
+             if (t_errno != -1)
+               errno = t_errno;
+             sys_error (_("cannot set terminal process group (%d)"), t);
+             job_control = 0;
+           }
+       }
+      if (job_control == 0)
+       internal_error (_("no job control in this shell"));
+    }
+
+  running_in_background = terminal_pgrp != shell_pgrp;
+
+  if (shell_tty != fileno (stderr))
+    SET_CLOSE_ON_EXEC (shell_tty);
+
+  set_signal_handler (SIGCHLD, sigchld_handler);
+
+  change_flag ('m', job_control ? '-' : '+');
+
+  if (interactive)
+    get_tty_state ();
+
+  if (js.c_childmax < 0)
+    js.c_childmax = getmaxchild ();
+  if (js.c_childmax < 0)
+    js.c_childmax = DEFAULT_CHILD_MAX;
+
+  return job_control;
+}
+
+#ifdef DEBUG
+void
+debug_print_pgrps ()
+{
+  itrace("original_pgrp = %ld shell_pgrp = %ld terminal_pgrp = %ld",
+        (long)original_pgrp, (long)shell_pgrp, (long)terminal_pgrp);
+  itrace("tcgetpgrp(%d) -> %ld, getpgid(0) -> %ld",
+        shell_tty, (long)tcgetpgrp (shell_tty), (long)getpgid(0));
+}
+#endif
+
+/* Set the line discipline to the best this system has to offer.
+   Return -1 if this is not possible. */
+static int
+set_new_line_discipline (tty)
+     int tty;
+{
+#if defined (NEW_TTY_DRIVER)
+  int ldisc;
+
+  if (ioctl (tty, TIOCGETD, &ldisc) < 0)
+    return (-1);
+
+  if (ldisc != NTTYDISC)
+    {
+      ldisc = NTTYDISC;
+
+      if (ioctl (tty, TIOCSETD, &ldisc) < 0)
+       return (-1);
+    }
+  return (0);
+#endif /* NEW_TTY_DRIVER */
+
+#if defined (TERMIO_TTY_DRIVER)
+#  if defined (TERMIO_LDISC) && (NTTYDISC)
+  if (ioctl (tty, TCGETA, &shell_tty_info) < 0)
+    return (-1);
+
+  if (shell_tty_info.c_line != NTTYDISC)
+    {
+      shell_tty_info.c_line = NTTYDISC;
+      if (ioctl (tty, TCSETAW, &shell_tty_info) < 0)
+       return (-1);
+    }
+#  endif /* TERMIO_LDISC && NTTYDISC */
+  return (0);
+#endif /* TERMIO_TTY_DRIVER */
+
+#if defined (TERMIOS_TTY_DRIVER)
+#  if defined (TERMIOS_LDISC) && defined (NTTYDISC)
+  if (tcgetattr (tty, &shell_tty_info) < 0)
+    return (-1);
+
+  if (shell_tty_info.c_line != NTTYDISC)
+    {
+      shell_tty_info.c_line = NTTYDISC;
+      if (tcsetattr (tty, TCSADRAIN, &shell_tty_info) < 0)
+       return (-1);
+    }
+#  endif /* TERMIOS_LDISC && NTTYDISC */
+  return (0);
+#endif /* TERMIOS_TTY_DRIVER */
+
+#if !defined (NEW_TTY_DRIVER) && !defined (TERMIO_TTY_DRIVER) && !defined (TERMIOS_TTY_DRIVER)
+  return (-1);
+#endif
+}
+
+/* Setup this shell to handle C-C, etc. */
+void
+initialize_job_signals ()
+{
+  if (interactive)
+    {
+      set_signal_handler (SIGINT, sigint_sighandler);
+      set_signal_handler (SIGTSTP, SIG_IGN);
+      set_signal_handler (SIGTTOU, SIG_IGN);
+      set_signal_handler (SIGTTIN, SIG_IGN);
+    }
+  else if (job_control)
+    {
+      old_tstp = set_signal_handler (SIGTSTP, sigstop_sighandler);
+      old_ttin = set_signal_handler (SIGTTIN, sigstop_sighandler);
+      old_ttou = set_signal_handler (SIGTTOU, sigstop_sighandler);
+    }
+  /* Leave disposition unmodified for non-interactive shells without job
+     control. */
+}
+
+/* Here we handle CONT signals. */
+static sighandler
+sigcont_sighandler (sig)
+     int sig;
+{
+  initialize_job_signals ();
+  set_signal_handler (SIGCONT, old_cont);
+  kill (getpid (), SIGCONT);
+
+  SIGRETURN (0);
+}
+
+/* Here we handle stop signals while we are running not as a login shell. */
+static sighandler
+sigstop_sighandler (sig)
+     int sig;
+{
+  set_signal_handler (SIGTSTP, old_tstp);
+  set_signal_handler (SIGTTOU, old_ttou);
+  set_signal_handler (SIGTTIN, old_ttin);
+
+  old_cont = set_signal_handler (SIGCONT, sigcont_sighandler);
+
+  give_terminal_to (shell_pgrp, 0);
+
+  kill (getpid (), sig);
+
+  SIGRETURN (0);
+}
+
+/* Give the terminal to PGRP.  */
+int
+give_terminal_to (pgrp, force)
+     pid_t pgrp;
+     int force;
+{
+  sigset_t set, oset;
+  int r, e;
+
+  r = 0;
+  if (job_control || force)
+    {
+      sigemptyset (&set);
+      sigaddset (&set, SIGTTOU);
+      sigaddset (&set, SIGTTIN);
+      sigaddset (&set, SIGTSTP);
+      sigaddset (&set, SIGCHLD);
+      sigemptyset (&oset);
+      sigprocmask (SIG_BLOCK, &set, &oset);
+
+      if (tcsetpgrp (shell_tty, pgrp) < 0)
+       {
+         /* Maybe we should print an error message? */
+#if 0
+         sys_error ("tcsetpgrp(%d) failed: pid %ld to pgrp %ld",
+           shell_tty, (long)getpid(), (long)pgrp);
+#endif
+         r = -1;
+         e = errno;
+       }
+      else
+       terminal_pgrp = pgrp;
+      sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
+    }
+
+  if (r == -1)
+    errno = e;
+
+  return r;
+}
+
+/* Give terminal to NPGRP iff it's currently owned by OPGRP.  FLAGS are the
+   flags to pass to give_terminal_to(). */
+static int
+maybe_give_terminal_to (opgrp, npgrp, flags)
+     pid_t opgrp, npgrp;
+     int flags;
+{
+  int tpgrp;
+
+  tpgrp = tcgetpgrp (shell_tty);
+  if (tpgrp < 0 && errno == ENOTTY)
+    return -1;
+  if (tpgrp == npgrp)
+    {
+      terminal_pgrp = npgrp;
+      return 0;
+    }
+  else if (tpgrp != opgrp)
+    {
+#if defined (DEBUG)
+      internal_warning ("%d: maybe_give_terminal_to: terminal pgrp == %d shell pgrp = %d new pgrp = %d in_background = %d", (int)getpid(), tpgrp, opgrp, npgrp, running_in_background);
+#endif
+      return -1;
+    }
+  else
+    return (give_terminal_to (npgrp, flags));     
+}
+
+/* Clear out any jobs in the job array.  This is intended to be used by
+   children of the shell, who should not have any job structures as baggage
+   when they start executing (forking subshells for parenthesized execution
+   and functions with pipes are the two that spring to mind).  If RUNNING_ONLY
+   is nonzero, only running jobs are removed from the table. */
+void
+delete_all_jobs (running_only)
+     int running_only;
+{
+  register int i;
+  sigset_t set, oset;
+
+  BLOCK_CHILD (set, oset);
+
+  /* XXX - need to set j_lastj, j_firstj appropriately if running_only != 0. */
+  if (js.j_jobslots)
+    {
+      js.j_current = js.j_previous = NO_JOB;
+
+      /* XXX could use js.j_firstj here */
+      for (i = 0; i < js.j_jobslots; i++)
+       {
+#if defined (DEBUG)
+         if (i < js.j_firstj && jobs[i])
+           itrace("delete_all_jobs: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);
+         if (i > js.j_lastj && jobs[i])
+           itrace("delete_all_jobs: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);
+#endif
+         if (jobs[i] && (running_only == 0 || (running_only && RUNNING(i))))
+           delete_job (i, DEL_WARNSTOPPED);
+       }
+      if (running_only == 0)
+       {
+         free ((char *)jobs);
+         js.j_jobslots = 0;
+         js.j_firstj = js.j_lastj = js.j_njobs = 0;
+       }
+    }
+
+  if (running_only == 0)
+    bgp_clear ();
+
+  UNBLOCK_CHILD (oset);
+}
+
+/* Mark all jobs in the job array so that they don't get a SIGHUP when the
+   shell gets one.  If RUNNING_ONLY is nonzero, mark only running jobs. */
+void
+nohup_all_jobs (running_only)
+     int running_only;
+{
+  register int i;
+  sigset_t set, oset;
+
+  BLOCK_CHILD (set, oset);
+
+  if (js.j_jobslots)
+    {
+      /* XXX could use js.j_firstj here */
+      for (i = 0; i < js.j_jobslots; i++)
+       if (jobs[i] && (running_only == 0 || (running_only && RUNNING(i))))
+         nohup_job (i);
+    }
+
+  UNBLOCK_CHILD (oset);
+}
+
+int
+count_all_jobs ()
+{
+  int i, n;
+  sigset_t set, oset;
+
+  /* This really counts all non-dead jobs. */
+  BLOCK_CHILD (set, oset);
+  /* XXX could use js.j_firstj here */
+  for (i = n = 0; i < js.j_jobslots; i++)
+    {
+#if defined (DEBUG)
+      if (i < js.j_firstj && jobs[i])
+       itrace("count_all_jobs: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);
+      if (i > js.j_lastj && jobs[i])
+       itrace("count_all_jobs: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);
+#endif
+      if (jobs[i] && DEADJOB(i) == 0)
+       n++;
+    }
+  UNBLOCK_CHILD (oset);
+  return n;
+}
+
+static void
+mark_all_jobs_as_dead ()
+{
+  register int i;
+  sigset_t set, oset;
+
+  if (js.j_jobslots == 0)
+    return;
+
+  BLOCK_CHILD (set, oset);
+
+  /* XXX could use js.j_firstj here */
+  for (i = 0; i < js.j_jobslots; i++)
+    if (jobs[i])
+      {
+       jobs[i]->state = JDEAD;
+       js.j_ndead++;
+      }
+
+  UNBLOCK_CHILD (oset);
+}
+
+/* Mark all dead jobs as notified, so delete_job () cleans them out
+   of the job table properly.  POSIX.2 says we need to save the
+   status of the last CHILD_MAX jobs, so we count the number of dead
+   jobs and mark only enough as notified to save CHILD_MAX statuses. */
+static void
+mark_dead_jobs_as_notified (force)
+     int force;
+{
+  register int i, ndead, ndeadproc;
+  sigset_t set, oset;
+
+  if (js.j_jobslots == 0)
+    return;
+
+  BLOCK_CHILD (set, oset);
+
+  /* If FORCE is non-zero, we don't have to keep CHILD_MAX statuses
+     around; just run through the array. */
+  if (force)
+    {
+    /* XXX could use js.j_firstj here */
+      for (i = 0; i < js.j_jobslots; i++)
+       {
+         if (jobs[i] && DEADJOB (i) && (interactive_shell || (find_last_pid (i, 0) != last_asynchronous_pid)))
+           jobs[i]->flags |= J_NOTIFIED;
+       }
+      UNBLOCK_CHILD (oset);
+      return;
+    }
+
+  /* Mark enough dead jobs as notified to keep CHILD_MAX processes left in the
+     array with the corresponding not marked as notified.  This is a better
+     way to avoid pid aliasing and reuse problems than keeping the POSIX-
+     mandated CHILD_MAX jobs around.  delete_job() takes care of keeping the
+     bgpids list regulated. */
+          
+  /* Count the number of dead jobs */
+  /* XXX could use js.j_firstj here */
+  for (i = ndead = ndeadproc = 0; i < js.j_jobslots; i++)
+    {
+#if defined (DEBUG)
+      if (i < js.j_firstj && jobs[i])
+       itrace("mark_dead_jobs_as_notified: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);
+      if (i > js.j_lastj && jobs[i])
+       itrace("mark_dead_jobs_as_notified: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);
+#endif
+      if (jobs[i] && DEADJOB (i))
+       {
+         ndead++;
+         ndeadproc += processes_in_job (i);
+       }
+    }
+
+#ifdef DEBUG
+# if 0
+  if (ndeadproc != js.c_reaped)
+    itrace("mark_dead_jobs_as_notified: ndeadproc (%d) != js.c_reaped (%d)", ndeadproc, js.c_reaped);
+# endif
+  if (ndead != js.j_ndead)
+    itrace("mark_dead_jobs_as_notified: ndead (%d) != js.j_ndead (%d)", ndead, js.j_ndead);
+#endif
+
+  if (js.c_childmax < 0)
+    js.c_childmax = getmaxchild ();
+  if (js.c_childmax < 0)
+    js.c_childmax = DEFAULT_CHILD_MAX;
+
+  /* Don't do anything if the number of dead processes is less than CHILD_MAX
+     and we're not forcing a cleanup. */
+  if (ndeadproc <= js.c_childmax)
+    {
+      UNBLOCK_CHILD (oset);
+      return;
+    }
+
+#if 0
+itrace("mark_dead_jobs_as_notified: child_max = %d ndead = %d ndeadproc = %d", js.c_childmax, ndead, ndeadproc);
+#endif
+
+  /* Mark enough dead jobs as notified that we keep CHILD_MAX jobs in
+     the list.  This isn't exactly right yet; changes need to be made
+     to stop_pipeline so we don't mark the newer jobs after we've
+     created CHILD_MAX slots in the jobs array.  This needs to be
+     integrated with a way to keep the jobs array from growing without
+     bound.  Maybe we wrap back around to 0 after we reach some max
+     limit, and there are sufficient job slots free (keep track of total
+     size of jobs array (js.j_jobslots) and running count of number of jobs
+     in jobs array.  Then keep a job index corresponding to the `oldest job'
+     and start this loop there, wrapping around as necessary.  In effect,
+     we turn the list into a circular buffer. */
+  /* XXX could use js.j_firstj here */
+  for (i = 0; i < js.j_jobslots; i++)
+    {
+      if (jobs[i] && DEADJOB (i) && (interactive_shell || (find_last_pid (i, 0) != last_asynchronous_pid)))
+       {
+#if defined (DEBUG)
+         if (i < js.j_firstj && jobs[i])
+           itrace("mark_dead_jobs_as_notified: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);
+         if (i > js.j_lastj && jobs[i])
+           itrace("mark_dead_jobs_as_notified: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);
+#endif
+         /* If marking this job as notified would drop us down below
+            child_max, don't mark it so we can keep at least child_max
+            statuses.  XXX -- need to check what Posix actually says
+            about keeping statuses. */
+         if ((ndeadproc -= processes_in_job (i)) <= js.c_childmax)
+           break;
+         jobs[i]->flags |= J_NOTIFIED;
+       }
+    }
+
+  UNBLOCK_CHILD (oset);
+}
+
+/* Here to allow other parts of the shell (like the trap stuff) to
+   freeze and unfreeze the jobs list. */
+int
+freeze_jobs_list ()
+{
+  int o;
+
+  o = jobs_list_frozen;
+  jobs_list_frozen = 1;
+  return o;
+}
+
+void
+unfreeze_jobs_list ()
+{
+  jobs_list_frozen = 0;
+}
+
+/* Allow or disallow job control to take place.  Returns the old value
+   of job_control. */
+int
+set_job_control (arg)
+     int arg;
+{
+  int old;
+
+  old = job_control;
+  job_control = arg;
+
+  if (terminal_pgrp == NO_PID)
+    terminal_pgrp = tcgetpgrp (shell_tty);
+  
+  running_in_background = (terminal_pgrp != shell_pgrp);
+
+#if 0
+  if (interactive_shell == 0 && running_in_background == 0 && job_control != old)
+    {
+      if (job_control)
+       initialize_job_signals ();
+      else
+       default_tty_job_signals ();
+    }
+#endif
+
+  /* If we're turning on job control, reset pipeline_pgrp so make_child will
+     put new child processes into the right pgrp */
+  if (job_control != old && job_control)
+    pipeline_pgrp = 0;
+
+  return (old);
+}
+
+/* Turn off all traces of job control.  This is run by children of the shell
+   which are going to do shellsy things, like wait (), etc. */
+void
+without_job_control ()
+{
+  stop_making_children ();
+  start_pipeline ();
+#if defined (PGRP_PIPE)
+  sh_closepipe (pgrp_pipe);
+#endif
+  delete_all_jobs (0);
+  set_job_control (0);
+}
+
+/* If this shell is interactive, terminate all stopped jobs and
+   restore the original terminal process group.  This is done
+   before the `exec' builtin calls shell_execve. */
+void
+end_job_control ()
+{
+  if (interactive_shell || job_control)                /* XXX - should it be just job_control? */
+    {
+      terminate_stopped_jobs ();
+
+      if (original_pgrp >= 0)
+       give_terminal_to (original_pgrp, 1);
+    }
+
+  if (original_pgrp >= 0)
+    setpgid (0, original_pgrp);
+}
+
+/* Restart job control by closing shell tty and reinitializing.  This is
+   called after an exec fails in an interactive shell and we do not exit. */
+void
+restart_job_control ()
+{
+  if (shell_tty != -1)
+    close (shell_tty);
+  initialize_job_control (0);
+}
+
+void
+set_maxchild (nchild)
+     int nchild;
+{
+  static int lmaxchild = -1;
+
+  if (lmaxchild < 0)
+    lmaxchild = getmaxchild ();
+  if (lmaxchild < 0)
+    lmaxchild = DEFAULT_CHILD_MAX;
+
+  /* Clamp value we set.  Minimum is what Posix requires, maximum is defined
+     above as MAX_CHILD_MAX. */
+  if (nchild < lmaxchild)
+    nchild = lmaxchild;
+  else if (nchild > MAX_CHILD_MAX)
+    nchild = MAX_CHILD_MAX;
+
+  js.c_childmax = nchild;
+}
+
+/* Set the handler to run when the shell receives a SIGCHLD signal. */
+void
+set_sigchld_handler ()
+{
+  set_signal_handler (SIGCHLD, sigchld_handler);
+}
+
+#if defined (PGRP_PIPE)
+/* Read from the read end of a pipe.  This is how the process group leader
+   blocks until all of the processes in a pipeline have been made. */
+static void
+pipe_read (pp)
+     int *pp;
+{
+  char ch;
+
+  if (pp[1] >= 0)
+    {
+      close (pp[1]);
+      pp[1] = -1;
+    }
+
+  if (pp[0] >= 0)
+    {
+      while (read (pp[0], &ch, 1) == -1 && errno == EINTR)
+       ;
+    }
+}
+
+/* Functional interface closes our local-to-job-control pipes. */
+void
+close_pgrp_pipe ()
+{
+  sh_closepipe (pgrp_pipe);
+}
+
+void
+save_pgrp_pipe (p, clear)
+     int *p;
+     int clear;
+{
+  p[0] = pgrp_pipe[0];
+  p[1] = pgrp_pipe[1];
+  if (clear)
+    pgrp_pipe[0] = pgrp_pipe[1] = -1;
+}
+
+void
+restore_pgrp_pipe (p)
+     int *p;
+{
+  pgrp_pipe[0] = p[0];
+  pgrp_pipe[1] = p[1];
+}
+
+#endif /* PGRP_PIPE */
diff --git a/lib/readline/doc/Makefile.old b/lib/readline/doc/Makefile.old
new file mode 100644 (file)
index 0000000..58d4dd7
--- /dev/null
@@ -0,0 +1,76 @@
+# This makefile for Readline library documentation is in -*- text -*- mode.
+# Emacs likes it that way.
+RM = rm -f
+
+MAKEINFO    = makeinfo
+TEXI2DVI    = texi2dvi
+TEXI2HTML   = texi2html
+QUIETPS     = #set this to -q to shut up dvips
+DVIPS       = dvips -D 300 $(QUIETPS) -o $@     # tricky
+
+INSTALL_DATA = cp
+infodir = /usr/local/info
+
+RLSRC = rlman.texinfo rluser.texinfo rltech.texinfo
+HISTSRC = hist.texinfo hsuser.texinfo hstech.texinfo
+
+DVIOBJ = readline.dvi history.dvi
+INFOOBJ = readline.info history.info
+PSOBJ = readline.ps history.ps
+HTMLOBJ = readline.html history.html
+
+all: info dvi html ps
+nodvi: info html
+
+readline.dvi: $(RLSRC)
+       $(TEXI2DVI) rlman.texinfo
+       mv rlman.dvi readline.dvi
+
+readline.info: $(RLSRC)
+       $(MAKEINFO) --no-split -o $@ rlman.texinfo
+
+history.dvi: ${HISTSRC}
+       $(TEXI2DVI) hist.texinfo
+       mv hist.dvi history.dvi
+
+history.info: ${HISTSRC}
+       $(MAKEINFO) --no-split -o $@ hist.texinfo
+
+readline.ps:   readline.dvi
+       $(RM) $@
+       $(DVIPS) readline.dvi
+
+history.ps:    history.dvi
+       $(RM) $@
+       $(DVIPS) history.dvi
+
+readline.html: ${RLSRC}
+       $(TEXI2HTML) rlman.texinfo
+       sed -e 's:rlman.html:readline.html:' -e 's:rlman_toc.html:readline_toc.html:' rlman.html > readline.html
+       sed -e 's:rlman.html:readline.html:' -e 's:rlman_toc.html:readline_toc.html:' rlman_toc.html > readline_toc.html
+       $(RM) rlman.html rlman_toc.html
+
+history.html:  ${HISTSRC}
+       $(TEXI2HTML) hist.texinfo
+       sed -e 's:hist.html:history.html:' -e 's:hist_toc.html:history_toc.html:' hist.html > history.html
+       sed -e 's:hist.html:history.html:' -e 's:hist_toc.html:history_toc.html:' hist_toc.html > history_toc.html
+       $(RM) hist.html hist_toc.html
+
+info:  $(INFOOBJ)
+dvi:   $(DVIOBJ)
+ps:    $(PSOBJ)
+html:  $(HTMLOBJ)
+
+clean:
+       $(RM) *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps *.pgs \
+             *.fns *.kys *.tps *.vrs *.o core
+
+distclean: clean
+mostlyclean: clean
+
+maintainer-clean: clean
+       $(RM) *.dvi *.info *.info-* *.ps *.html
+
+install:       info
+       ${INSTALL_DATA} readline.info $(infodir)/readline.info
+       ${INSTALL_DATA} history.info $(infodir)/history.info
index 7b99b5d837cd1d1906edc535c1ec6b582c42585e..36206e2ae015911dad6ececeb8628626d761ec99 100644 (file)
Binary files a/po/._fr.po and b/po/._fr.po differ
diff --git a/subst.c b/subst.c
index b93235c2483c95324c0941143aaeb4ea16a87ecf..40537c4805130fecaec8169a4cb69b5eb8eea826 100644 (file)
--- a/subst.c
+++ b/subst.c
@@ -1812,8 +1812,12 @@ 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_ALLOC here yet */
+         free (temp);          /* XXX - not using SX_NOALLOC here yet */
+#endif
          i = si;
          if (string[i] == '\0')
            break;
@@ -5673,7 +5677,7 @@ command_substitute (string, quoted)
      int quoted;
 {
   pid_t pid, old_pid, old_pipeline_pgrp, old_async_pid;
-  char *istring;
+  char *istring, *s;
   int result, fildes[2], function_value, pflags, rc, tflag;
   WORD_DESC *ret;
 
@@ -5681,8 +5685,15 @@ command_substitute (string, quoted)
 
   /* Don't fork () if there is no need to.  In the case of no command to
      run, just return NULL. */
+#if 1
+  for (s = string; s && *s && (shellblank (*s) || *s == '\n'); s++)
+    ;
+  if (s == 0 || *s == 0)
+    return ((WORD_DESC *)NULL);
+#else
   if (!string || !*string || (string[0] == '\n' && !string[1]))
     return ((WORD_DESC *)NULL);
+#endif
 
   if (wordexp_only && read_but_dont_execute)
     {
@@ -5811,6 +5822,17 @@ command_substitute (string, quoted)
          set_shellopts ();
         }
 
+      /* If we are expanding a redirection, we can dispose of any temporary
+        environment we received, since redirections are not supposed to have
+        access to the temporary environment.  We will have to see whether this
+        affects temporary environments supplied to `eval', but the temporary
+        environment gets copied to builtin_env at some point. */
+      if (expanding_redir)
+       {
+         flush_temporary_env ();
+         expanding_redir = 0;
+       }
+
       remove_quoted_escapes (string);
 
       startup_state = 2;       /* see if we can avoid a fork */
@@ -6745,9 +6767,7 @@ get_var_and_type (varname, value, ind, quoted, flags, varp, valp)
   int vtype, want_indir;
   char *temp, *vname;
   WORD_DESC *wd;
-#if defined (ARRAY_VARS)
   SHELL_VAR *v;
-#endif
   arrayind_t lind;
 
   want_indir = *varname == '!' &&
@@ -6822,7 +6842,7 @@ get_var_and_type (varname, value, ind, quoted, flags, varp, valp)
     {
       if (value && vtype == VT_VARIABLE)
        {
-         *varp = v;
+         *varp = find_variable (vname);
          if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
            *valp = dequote_string (value);
          else
diff --git a/subst.c~ b/subst.c~
new file mode 100644 (file)
index 0000000..b5b88a8
--- /dev/null
+++ b/subst.c~
@@ -0,0 +1,10207 @@
+/* subst.c -- The part of the shell that does parameter, command, arithmetic,
+   and globbing substitutions. */
+
+/* ``Have a little faith, there's magic in the night.  You ain't a
+     beauty, but, hey, you're alright.'' */
+
+/* Copyright (C) 1987-2014 Free Software Foundation, Inc.
+
+   This file is part of GNU Bash, the Bourne Again SHell.
+
+   Bash is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   Bash is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with Bash.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "config.h"
+
+#include "bashtypes.h"
+#include <stdio.h>
+#include "chartypes.h"
+#if defined (HAVE_PWD_H)
+#  include <pwd.h>
+#endif
+#include <signal.h>
+#include <errno.h>
+
+#if defined (HAVE_UNISTD_H)
+#  include <unistd.h>
+#endif
+
+#include "bashansi.h"
+#include "posixstat.h"
+#include "bashintl.h"
+
+#include "shell.h"
+#include "parser.h"
+#include "flags.h"
+#include "jobs.h"
+#include "execute_cmd.h"
+#include "filecntl.h"
+#include "trap.h"
+#include "pathexp.h"
+#include "mailcheck.h"
+
+#include "shmbutil.h"
+#include "typemax.h"
+
+#include "builtins/getopt.h"
+#include "builtins/common.h"
+
+#include "builtins/builtext.h"
+
+#include <tilde/tilde.h>
+#include <glob/strmatch.h>
+
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+/* The size that strings change by. */
+#define DEFAULT_INITIAL_ARRAY_SIZE 112
+#define DEFAULT_ARRAY_SIZE 128
+
+/* Variable types. */
+#define VT_VARIABLE    0
+#define VT_POSPARMS    1
+#define VT_ARRAYVAR    2
+#define VT_ARRAYMEMBER 3
+#define VT_ASSOCVAR    4
+
+#define VT_STARSUB     128     /* $* or ${array[*]} -- used to split */
+
+/* Flags for quoted_strchr */
+#define ST_BACKSL      0x01
+#define ST_CTLESC      0x02
+#define ST_SQUOTE      0x04    /* unused yet */
+#define ST_DQUOTE      0x08    /* unused yet */
+
+/* Flags for the `pflags' argument to param_expand() */
+#define PF_NOCOMSUB    0x01    /* Do not perform command substitution */
+#define PF_IGNUNBOUND  0x02    /* ignore unbound vars even if -u set */
+#define PF_NOSPLIT2    0x04    /* same as W_NOSPLIT2 */
+#define PF_ASSIGNRHS   0x08    /* same as W_ASSIGNRHS */
+
+/* These defs make it easier to use the editor. */
+#define LBRACE         '{'
+#define RBRACE         '}'
+#define LPAREN         '('
+#define RPAREN         ')'
+#define LBRACK         '['
+#define RBRACK         ']'
+
+#if defined (HANDLE_MULTIBYTE)
+#define WLPAREN                L'('
+#define WRPAREN                L')'
+#endif
+
+/* Evaluates to 1 if C is one of the shell's special parameters whose length
+   can be taken, but is also one of the special expansion characters. */
+#define VALID_SPECIAL_LENGTH_PARAM(c) \
+  ((c) == '-' || (c) == '?' || (c) == '#' || (c) == '@')
+
+/* Evaluates to 1 if C is one of the shell's special parameters for which an
+   indirect variable reference may be made. */
+#define VALID_INDIR_PARAM(c) \
+  ((posixly_correct == 0 && (c) == '#') || (posixly_correct == 0 && (c) == '?') || (c) == '@' || (c) == '*')
+
+/* Evaluates to 1 if C is one of the OP characters that follows the parameter
+   in ${parameter[:]OPword}. */
+#define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP)
+
+/* Evaluates to 1 if this is one of the shell's special variables. */
+#define SPECIAL_VAR(name, wi) \
+ ((DIGIT (*name) && all_digits (name)) || \
+      (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \
+      (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))
+
+/* An expansion function that takes a string and a quoted flag and returns
+   a WORD_LIST *.  Used as the type of the third argument to
+   expand_string_if_necessary(). */
+typedef WORD_LIST *EXPFUNC __P((char *, int));
+
+/* Process ID of the last command executed within command substitution. */
+pid_t last_command_subst_pid = NO_PID;
+pid_t current_command_subst_pid = NO_PID;
+
+/* Variables used to keep track of the characters in IFS. */
+SHELL_VAR *ifs_var;
+char *ifs_value;
+unsigned char ifs_cmap[UCHAR_MAX + 1];
+int ifs_is_set, ifs_is_null;
+
+#if defined (HANDLE_MULTIBYTE)
+unsigned char ifs_firstc[MB_LEN_MAX];
+size_t ifs_firstc_len;
+#else
+unsigned char ifs_firstc;
+#endif
+
+/* Sentinel to tell when we are performing variable assignments preceding a
+   command name and putting them into the environment.  Used to make sure
+   we use the temporary environment when looking up variable values. */
+int assigning_in_environment;
+
+/* Used to hold a list of variable assignments preceding a command.  Global
+   so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a
+   SIGCHLD trap and so it can be saved and restored by the trap handlers. */
+WORD_LIST *subst_assign_varlist = (WORD_LIST *)NULL;
+
+/* Extern functions and variables from different files. */
+extern int last_command_exit_value, last_command_exit_signal;
+extern int subshell_environment, line_number;
+extern int subshell_level, parse_and_execute_level, sourcelevel;
+extern int eof_encountered;
+extern int return_catch_flag, return_catch_value;
+extern pid_t dollar_dollar_pid;
+extern int posixly_correct;
+extern char *this_command_name;
+extern struct fd_bitmap *current_fds_to_close;
+extern int wordexp_only;
+extern int expanding_redir;
+extern int tempenv_assign_error;
+extern int builtin_ignoring_errexit;
+
+#if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)
+extern wchar_t *wcsdup __P((const wchar_t *));
+#endif
+
+/* Non-zero means to allow unmatched globbed filenames to expand to
+   a null file. */
+int allow_null_glob_expansion;
+
+/* Non-zero means to throw an error when globbing fails to match anything. */
+int fail_glob_expansion;
+
+#if 0
+/* Variables to keep track of which words in an expanded word list (the
+   output of expand_word_list_internal) are the result of globbing
+   expansions.  GLOB_ARGV_FLAGS is used by execute_cmd.c.
+   (CURRENTLY UNUSED). */
+char *glob_argv_flags;
+static int glob_argv_flags_size;
+#endif
+
+static WORD_LIST *cached_quoted_dollar_at = 0;
+
+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;
+static char extract_string_error, extract_string_fatal;
+
+/* Tell the expansion functions to not longjmp back to top_level on fatal
+   errors.  Enabled when doing completion and prompt string expansion. */
+static int no_longjmp_on_fatal_error = 0;
+
+/* Set by expand_word_unsplit; used to inhibit splitting and re-joining
+   $* on $IFS, primarily when doing assignment statements. */
+static int expand_no_split_dollar_star = 0;
+
+/* A WORD_LIST of words to be expanded by expand_word_list_internal,
+   without any leading variable assignments. */
+static WORD_LIST *garglist = (WORD_LIST *)NULL;
+
+static char *quoted_substring __P((char *, int, int));
+static int quoted_strlen __P((char *));
+static char *quoted_strchr __P((char *, int, int));
+
+static char *expand_string_if_necessary __P((char *, int, EXPFUNC *));
+static inline char *expand_string_to_string_internal __P((char *, int, EXPFUNC *));
+static WORD_LIST *call_expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
+static WORD_LIST *expand_string_internal __P((char *, int));
+static WORD_LIST *expand_string_leave_quoted __P((char *, int));
+static WORD_LIST *expand_string_for_rhs __P((char *, int, int *, int *));
+
+static WORD_LIST *list_quote_escapes __P((WORD_LIST *));
+static WORD_LIST *list_dequote_escapes __P((WORD_LIST *));
+
+static char *make_quoted_char __P((int));
+static WORD_LIST *quote_list __P((WORD_LIST *));
+
+static int unquoted_substring __P((char *, char *));
+static int unquoted_member __P((int, char *));
+
+#if defined (ARRAY_VARS)
+static SHELL_VAR *do_compound_assignment __P((char *, char *, int));
+#endif
+static int do_assignment_internal __P((const WORD_DESC *, int));
+
+static char *string_extract_verbatim __P((char *, size_t, int *, char *, int));
+static char *string_extract __P((char *, int *, char *, int));
+static char *string_extract_double_quoted __P((char *, int *, int));
+static inline char *string_extract_single_quoted __P((char *, int *));
+static inline int skip_single_quoted __P((const char *, size_t, int));
+static int skip_double_quoted __P((char *, size_t, int));
+static char *extract_delimited_string __P((char *, int *, char *, char *, char *, int));
+static char *extract_dollar_brace_string __P((char *, int *, int, int));
+static int skip_matched_pair __P((const char *, int, int, int, int));
+
+static char *pos_params __P((char *, int, int, int));
+
+static unsigned char *mb_getcharlens __P((char *, int));
+
+static char *remove_upattern __P((char *, char *, int));
+#if defined (HANDLE_MULTIBYTE) 
+static wchar_t *remove_wpattern __P((wchar_t *, size_t, wchar_t *, int));
+#endif
+static char *remove_pattern __P((char *, char *, int));
+
+static int match_upattern __P((char *, char *, int, char **, char **));
+#if defined (HANDLE_MULTIBYTE)
+static int match_wpattern __P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **));
+#endif
+static int match_pattern __P((char *, char *, int, char **, char **));
+static int getpatspec __P((int, char *));
+static char *getpattern __P((char *, int, int));
+static char *variable_remove_pattern __P((char *, char *, int, int));
+static char *list_remove_pattern __P((WORD_LIST *, char *, int, int, int));
+static char *parameter_list_remove_pattern __P((int, char *, int, int));
+#ifdef ARRAY_VARS
+static char *array_remove_pattern __P((SHELL_VAR *, char *, int, char *, int));
+#endif
+static char *parameter_brace_remove_pattern __P((char *, char *, int, char *, int, int, int));
+
+static char *string_var_assignment __P((SHELL_VAR *, char *));
+#if defined (ARRAY_VARS)
+static char *array_var_assignment __P((SHELL_VAR *, int, int));
+#endif
+static char *pos_params_assignment __P((WORD_LIST *, int, int));
+static char *string_transform __P((int, SHELL_VAR *, char *));
+static char *list_transform __P((int, SHELL_VAR *, WORD_LIST *, int, int));
+static char *parameter_list_transform __P((int, int, int));
+#if defined ARRAY_VARS
+static char *array_transform __P((int, SHELL_VAR *, char *, int));
+#endif
+static char *parameter_brace_transform __P((char *, char *, int, char *, int, int, int));
+
+static char *process_substitute __P((char *, int));
+
+static char *read_comsub __P((int, int, int *));
+
+#ifdef ARRAY_VARS
+static arrayind_t array_length_reference __P((char *));
+#endif
+
+static int valid_brace_expansion_word __P((char *, int));
+static int chk_atstar __P((char *, int, int *, int *));
+static int chk_arithsub __P((const char *, int));
+
+static WORD_DESC *parameter_brace_expand_word __P((char *, int, int, int, arrayind_t *));
+static char *parameter_brace_find_indir __P((char *, int, int, int));
+static WORD_DESC *parameter_brace_expand_indir __P((char *, int, int, int *, int *));
+static WORD_DESC *parameter_brace_expand_rhs __P((char *, char *, int, int, int *, int *));
+static void parameter_brace_expand_error __P((char *, char *));
+
+static int valid_length_expression __P((char *));
+static intmax_t parameter_brace_expand_length __P((char *));
+
+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 int shouldexp_replacement __P((char *));
+
+static char *pos_params_pat_subst __P((char *, char *, char *, int));
+
+static char *parameter_brace_patsub __P((char *, char *, int, char *, 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 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));
+
+static WORD_LIST *expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
+
+static WORD_LIST *word_list_split __P((WORD_LIST *));
+
+static void exp_jump_to_top_level __P((int));
+
+static WORD_LIST *separate_out_assignments __P((WORD_LIST *));
+static WORD_LIST *glob_expand_word_list __P((WORD_LIST *, int));
+#ifdef BRACE_EXPANSION
+static WORD_LIST *brace_expand_word_list __P((WORD_LIST *, int));
+#endif
+#if defined (ARRAY_VARS)
+static int make_internal_declare __P((char *, char *));
+#endif
+static WORD_LIST *shell_expand_word_list __P((WORD_LIST *, int));
+static WORD_LIST *expand_word_list_internal __P((WORD_LIST *, int));
+
+/* **************************************************************** */
+/*                                                                 */
+/*                     Utility Functions                           */
+/*                                                                 */
+/* **************************************************************** */
+
+#if defined (DEBUG)
+void
+dump_word_flags (flags)
+     int flags;
+{
+  int f;
+
+  f = flags;
+  fprintf (stderr, "%d -> ", f);
+  if (f & W_ARRAYIND)
+    {
+      f &= ~W_ARRAYIND;
+      fprintf (stderr, "W_ARRAYIND%s", f ? "|" : "");
+    }
+  if (f & W_ASSIGNASSOC)
+    {
+      f &= ~W_ASSIGNASSOC;
+      fprintf (stderr, "W_ASSIGNASSOC%s", f ? "|" : "");
+    }
+  if (f & W_ASSIGNARRAY)
+    {
+      f &= ~W_ASSIGNARRAY;
+      fprintf (stderr, "W_ASSIGNARRAY%s", f ? "|" : "");
+    }
+  if (f & W_HASCTLESC)
+    {
+      f &= ~W_HASCTLESC;
+      fprintf (stderr, "W_HASCTLESC%s", f ? "|" : "");
+    }
+  if (f & W_NOPROCSUB)
+    {
+      f &= ~W_NOPROCSUB;
+      fprintf (stderr, "W_NOPROCSUB%s", f ? "|" : "");
+    }
+  if (f & W_DQUOTE)
+    {
+      f &= ~W_DQUOTE;
+      fprintf (stderr, "W_DQUOTE%s", f ? "|" : "");
+    }
+  if (f & W_HASQUOTEDNULL)
+    {
+      f &= ~W_HASQUOTEDNULL;
+      fprintf (stderr, "W_HASQUOTEDNULL%s", f ? "|" : "");
+    }
+  if (f & W_ASSIGNARG)
+    {
+      f &= ~W_ASSIGNARG;
+      fprintf (stderr, "W_ASSIGNARG%s", f ? "|" : "");
+    }
+  if (f & W_ASSNBLTIN)
+    {
+      f &= ~W_ASSNBLTIN;
+      fprintf (stderr, "W_ASSNBLTIN%s", f ? "|" : "");
+    }
+  if (f & W_ASSNGLOBAL)
+    {
+      f &= ~W_ASSNGLOBAL;
+      fprintf (stderr, "W_ASSNGLOBAL%s", f ? "|" : "");
+    }
+  if (f & W_ASSIGNINT)
+    {
+      f &= ~W_ASSIGNINT;
+      fprintf (stderr, "W_ASSIGNINT%s", f ? "|" : "");
+    }
+  if (f & W_COMPASSIGN)
+    {
+      f &= ~W_COMPASSIGN;
+      fprintf (stderr, "W_COMPASSIGN%s", f ? "|" : "");
+    }
+  if (f & W_NOEXPAND)
+    {
+      f &= ~W_NOEXPAND;
+      fprintf (stderr, "W_NOEXPAND%s", f ? "|" : "");
+    }
+  if (f & W_ITILDE)
+    {
+      f &= ~W_ITILDE;
+      fprintf (stderr, "W_ITILDE%s", f ? "|" : "");
+    }
+  if (f & W_NOTILDE)
+    {
+      f &= ~W_NOTILDE;
+      fprintf (stderr, "W_NOTILDE%s", f ? "|" : "");
+    }
+  if (f & W_ASSIGNRHS)
+    {
+      f &= ~W_ASSIGNRHS;
+      fprintf (stderr, "W_ASSIGNRHS%s", f ? "|" : "");
+    }
+  if (f & W_NOCOMSUB)
+    {
+      f &= ~W_NOCOMSUB;
+      fprintf (stderr, "W_NOCOMSUB%s", f ? "|" : "");
+    }
+  if (f & W_DOLLARSTAR)
+    {
+      f &= ~W_DOLLARSTAR;
+      fprintf (stderr, "W_DOLLARSTAR%s", f ? "|" : "");
+    }
+  if (f & W_DOLLARAT)
+    {
+      f &= ~W_DOLLARAT;
+      fprintf (stderr, "W_DOLLARAT%s", f ? "|" : "");
+    }
+  if (f & W_TILDEEXP)
+    {
+      f &= ~W_TILDEEXP;
+      fprintf (stderr, "W_TILDEEXP%s", f ? "|" : "");
+    }
+  if (f & W_NOSPLIT2)
+    {
+      f &= ~W_NOSPLIT2;
+      fprintf (stderr, "W_NOSPLIT2%s", f ? "|" : "");
+    }
+  if (f & W_NOSPLIT)
+    {
+      f &= ~W_NOSPLIT;
+      fprintf (stderr, "W_NOSPLIT%s", f ? "|" : "");
+    }
+  if (f & W_NOBRACE)
+    {
+      f &= ~W_NOBRACE;
+      fprintf (stderr, "W_NOBRACE%s", f ? "|" : "");
+    }
+  if (f & W_NOGLOB)
+    {
+      f &= ~W_NOGLOB;
+      fprintf (stderr, "W_NOGLOB%s", f ? "|" : "");
+    }
+  if (f & W_SPLITSPACE)
+    {
+      f &= ~W_SPLITSPACE;
+      fprintf (stderr, "W_SPLITSPACE%s", f ? "|" : "");
+    }
+  if (f & W_ASSIGNMENT)
+    {
+      f &= ~W_ASSIGNMENT;
+      fprintf (stderr, "W_ASSIGNMENT%s", f ? "|" : "");
+    }
+  if (f & W_QUOTED)
+    {
+      f &= ~W_QUOTED;
+      fprintf (stderr, "W_QUOTED%s", f ? "|" : "");
+    }
+  if (f & W_HASDOLLAR)
+    {
+      f &= ~W_HASDOLLAR;
+      fprintf (stderr, "W_HASDOLLAR%s", f ? "|" : "");
+    }
+  fprintf (stderr, "\n");
+  fflush (stderr);
+}
+#endif
+
+#ifdef INCLUDE_UNUSED
+static char *
+quoted_substring (string, start, end)
+     char *string;
+     int start, end;
+{
+  register int len, l;
+  register char *result, *s, *r;
+
+  len = end - start;
+
+  /* Move to string[start], skipping quoted characters. */
+  for (s = string, l = 0; *s && l < start; )
+    {
+      if (*s == CTLESC)
+       {
+         s++;
+         continue;
+       }
+      l++;
+      if (*s == 0)
+       break;
+    }
+
+  r = result = (char *)xmalloc (2*len + 1);      /* save room for quotes */
+
+  /* Copy LEN characters, including quote characters. */
+  s = string + l;
+  for (l = 0; l < len; s++)
+    {
+      if (*s == CTLESC)
+       *r++ = *s++;
+      *r++ = *s;
+      l++;
+      if (*s == 0)
+       break;
+    }
+  *r = '\0';
+  return result;
+}
+#endif
+
+#ifdef INCLUDE_UNUSED
+/* Return the length of S, skipping over quoted characters */
+static int
+quoted_strlen (s)
+     char *s;
+{
+  register char *p;
+  int i;
+
+  i = 0;
+  for (p = s; *p; p++)
+    {
+      if (*p == CTLESC)
+       {
+         p++;
+         if (*p == 0)
+           return (i + 1);
+       }
+      i++;
+    }
+
+  return i;
+}
+#endif
+
+/* Find the first occurrence of character C in string S, obeying shell
+   quoting rules.  If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
+   characters are skipped.  If (FLAGS & ST_CTLESC) is non-zero, characters
+   escaped with CTLESC are skipped. */
+static char *
+quoted_strchr (s, c, flags)
+     char *s;
+     int c, flags;
+{
+  register char *p;
+
+  for (p = s; *p; p++)
+    {
+      if (((flags & ST_BACKSL) && *p == '\\')
+           || ((flags & ST_CTLESC) && *p == CTLESC))
+       {
+         p++;
+         if (*p == '\0')
+           return ((char *)NULL);
+         continue;
+       }
+      else if (*p == c)
+       return p;
+    }
+  return ((char *)NULL);
+}
+
+/* Return 1 if CHARACTER appears in an unquoted portion of
+   STRING.  Return 0 otherwise.  CHARACTER must be a single-byte character. */
+static int
+unquoted_member (character, string)
+     int character;
+     char *string;
+{
+  size_t slen;
+  int sindex, c;
+  DECLARE_MBSTATE;
+
+  slen = strlen (string);
+  sindex = 0;
+  while (c = string[sindex])
+    {
+      if (c == character)
+       return (1);
+
+      switch (c)
+       {
+       default:
+         ADVANCE_CHAR (string, slen, sindex);
+         break;
+
+       case '\\':
+         sindex++;
+         if (string[sindex])
+           ADVANCE_CHAR (string, slen, sindex);
+         break;
+
+       case '\'':
+         sindex = skip_single_quoted (string, slen, ++sindex);
+         break;
+
+       case '"':
+         sindex = skip_double_quoted (string, slen, ++sindex);
+         break;
+       }
+    }
+  return (0);
+}
+
+/* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
+static int
+unquoted_substring (substr, string)
+     char *substr, *string;
+{
+  size_t slen;
+  int sindex, c, sublen;
+  DECLARE_MBSTATE;
+
+  if (substr == 0 || *substr == '\0')
+    return (0);
+
+  slen = strlen (string);
+  sublen = strlen (substr);
+  for (sindex = 0; c = string[sindex]; )
+    {
+      if (STREQN (string + sindex, substr, sublen))
+       return (1);
+
+      switch (c)
+       {
+       case '\\':
+         sindex++;
+         if (string[sindex])
+           ADVANCE_CHAR (string, slen, sindex);
+         break;
+
+       case '\'':
+         sindex = skip_single_quoted (string, slen, ++sindex);
+         break;
+
+       case '"':
+         sindex = skip_double_quoted (string, slen, ++sindex);
+         break;
+
+       default:
+         ADVANCE_CHAR (string, slen, sindex);
+         break;
+       }
+    }
+  return (0);
+}
+
+/* Most of the substitutions must be done in parallel.  In order
+   to avoid using tons of unclear goto's, I have some functions
+   for manipulating malloc'ed strings.  They all take INDX, a
+   pointer to an integer which is the offset into the string
+   where manipulation is taking place.  They also take SIZE, a
+   pointer to an integer which is the current length of the
+   character array for this string. */
+
+/* Append SOURCE to TARGET at INDEX.  SIZE is the current amount
+   of space allocated to TARGET.  SOURCE can be NULL, in which
+   case nothing happens.  Gets rid of SOURCE by freeing it.
+   Returns TARGET in case the location has changed. */
+INLINE char *
+sub_append_string (source, target, indx, size)
+     char *source, *target;
+     int *indx, *size;
+{
+  if (source)
+    {
+      int srclen, n;
+
+      srclen = STRLEN (source);
+      if (srclen >= (int)(*size - *indx))
+       {
+         n = srclen + *indx;
+         n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE);
+         target = (char *)xrealloc (target, (*size = n));
+       }
+
+      FASTCOPY (source, target + *indx, srclen);
+      *indx += srclen;
+      target[*indx] = '\0';
+
+      free (source);
+    }
+  return (target);
+}
+
+#if 0
+/* UNUSED */
+/* Append the textual representation of NUMBER to TARGET.
+   INDX and SIZE are as in SUB_APPEND_STRING. */
+char *
+sub_append_number (number, target, indx, size)
+     intmax_t number;
+     int *indx, *size;
+     char *target;
+{
+  char *temp;
+
+  temp = itos (number);
+  return (sub_append_string (temp, target, indx, size));
+}
+#endif
+
+/* Extract a substring from STRING, starting at SINDEX and ending with
+   one of the characters in CHARLIST.  Don't make the ending character
+   part of the string.  Leave SINDEX pointing at the ending character.
+   Understand about backslashes in the string.  If (flags & SX_VARNAME)
+   is non-zero, and array variables have been compiled into the shell,
+   everything between a `[' and a corresponding `]' is skipped over.
+   If (flags & SX_NOALLOC) is non-zero, don't return the substring, just
+   update SINDEX.  If (flags & SX_REQMATCH) is non-zero, the string must
+   contain a closing character from CHARLIST. */
+static char *
+string_extract (string, sindex, charlist, flags)
+     char *string;
+     int *sindex;
+     char *charlist;
+     int flags;
+{
+  register int c, i;
+  int found;
+  size_t slen;
+  char *temp;
+  DECLARE_MBSTATE;
+
+  slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
+  i = *sindex;
+  found = 0;
+  while (c = string[i])
+    {
+      if (c == '\\')
+       {
+         if (string[i + 1])
+           i++;
+         else
+           break;
+       }
+#if defined (ARRAY_VARS)
+      else if ((flags & SX_VARNAME) && c == '[')
+       {
+         int ni;
+         /* If this is an array subscript, skip over it and continue. */
+         ni = skipsubscript (string, i, 0);
+         if (string[ni] == ']')
+           i = ni;
+       }
+#endif
+      else if (MEMBER (c, charlist))
+       {
+         found = 1;
+         break;
+       }
+
+      ADVANCE_CHAR (string, slen, i);
+    }
+
+  /* If we had to have a matching delimiter and didn't find one, return an
+     error and let the caller deal with it. */
+  if ((flags & SX_REQMATCH) && found == 0)
+    {
+      *sindex = i;
+      return (&extract_string_error);
+    }
+  
+  temp = (flags & SX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
+  *sindex = i;
+  
+  return (temp);
+}
+
+/* Extract the contents of STRING as if it is enclosed in double quotes.
+   SINDEX, when passed in, is the offset of the character immediately
+   following the opening double quote; on exit, SINDEX is left pointing after
+   the closing double quote.  If STRIPDQ is non-zero, unquoted double
+   quotes are stripped and the string is terminated by a null byte.
+   Backslashes between the embedded double quotes are processed.  If STRIPDQ
+   is zero, an unquoted `"' terminates the string. */
+static char *
+string_extract_double_quoted (string, sindex, stripdq)
+     char *string;
+     int *sindex, stripdq;
+{
+  size_t slen;
+  char *send;
+  int j, i, t;
+  unsigned char c;
+  char *temp, *ret;            /* The new string we return. */
+  int pass_next, backquote, si;        /* State variables for the machine. */
+  int dquote;
+  DECLARE_MBSTATE;
+
+  slen = strlen (string + *sindex) + *sindex;
+  send = string + slen;
+
+  pass_next = backquote = dquote = 0;
+  temp = (char *)xmalloc (1 + slen - *sindex);
+
+  j = 0;
+  i = *sindex;
+  while (c = string[i])
+    {
+      /* Process a character that was quoted by a backslash. */
+      if (pass_next)
+       {
+         /* XXX - take another look at this in light of Interp 221 */
+         /* Posix.2 sez:
+
+            ``The backslash shall retain its special meaning as an escape
+            character only when followed by one of the characters:
+               $       `       "       \       <newline>''.
+
+            If STRIPDQ is zero, we handle the double quotes here and let
+            expand_word_internal handle the rest.  If STRIPDQ is non-zero,
+            we have already been through one round of backslash stripping,
+            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 ((stripdq == 0 && c != '"') ||
+             (stripdq && ((dquote && (sh_syntaxtab[c] & CBSDQUOTE)) || dquote == 0)))
+           temp[j++] = '\\';
+         pass_next = 0;
+
+add_one_character:
+         COPY_CHAR_I (temp, j, string, send, i);
+         continue;
+       }
+
+      /* A backslash protects the next character.  The code just above
+        handles preserving the backslash in front of any character but
+        a double quote. */
+      if (c == '\\')
+       {
+         pass_next++;
+         i++;
+         continue;
+       }
+
+      /* Inside backquotes, ``the portion of the quoted string from the
+        initial backquote and the characters up to the next backquote
+        that is not preceded by a backslash, having escape characters
+        removed, defines that command''. */
+      if (backquote)
+       {
+         if (c == '`')
+           backquote = 0;
+         temp[j++] = c;
+         i++;
+         continue;
+       }
+
+      if (c == '`')
+       {
+         temp[j++] = c;
+         backquote++;
+         i++;
+         continue;
+       }
+
+      /* Pass everything between `$(' and the matching `)' or a quoted
+        ${ ... } pair through according to the Posix.2 specification. */
+      if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
+       {
+         int free_ret = 1;
+
+         si = i + 2;
+         if (string[i + 1] == LPAREN)
+           ret = extract_command_subst (string, &si, 0);
+         else
+           ret = extract_dollar_brace_string (string, &si, Q_DOUBLE_QUOTES, 0);
+
+         temp[j++] = '$';
+         temp[j++] = string[i + 1];
+
+         /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error
+            is set. */
+         if (ret == 0 && no_longjmp_on_fatal_error)
+           {
+             free_ret = 0;
+             ret = string + i + 2;
+           }
+
+         for (t = 0; ret[t]; t++, j++)
+           temp[j] = ret[t];
+         temp[j] = string[si];
+
+         if (string[si])
+           {
+             j++;
+             i = si + 1;
+           }
+         else
+           i = si;
+
+         if (free_ret)
+           free (ret);
+         continue;
+       }
+
+      /* Add any character but a double quote to the quoted string we're
+        accumulating. */
+      if (c != '"')
+       goto add_one_character;
+
+      /* c == '"' */
+      if (stripdq)
+       {
+         dquote ^= 1;
+         i++;
+         continue;
+       }
+
+      break;
+    }
+  temp[j] = '\0';
+
+  /* Point to after the closing quote. */
+  if (c)
+    i++;
+  *sindex = i;
+
+  return (temp);
+}
+
+/* This should really be another option to string_extract_double_quoted. */
+static int
+skip_double_quoted (string, slen, sind)
+     char *string;
+     size_t slen;
+     int sind;
+{
+  int c, i;
+  char *ret;
+  int pass_next, backquote, si;
+  DECLARE_MBSTATE;
+
+  pass_next = backquote = 0;
+  i = sind;
+  while (c = string[i])
+    {
+      if (pass_next)
+       {
+         pass_next = 0;
+         ADVANCE_CHAR (string, slen, i);
+         continue;
+       }
+      else if (c == '\\')
+       {
+         pass_next++;
+         i++;
+         continue;
+       }
+      else if (backquote)
+       {
+         if (c == '`')
+           backquote = 0;
+         ADVANCE_CHAR (string, slen, i);
+         continue;
+       }
+      else if (c == '`')
+       {
+         backquote++;
+         i++;
+         continue;
+       }
+      else if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
+       {
+         si = i + 2;
+         if (string[i + 1] == LPAREN)
+           ret = extract_command_subst (string, &si, SX_NOALLOC);
+         else
+           ret = extract_dollar_brace_string (string, &si, Q_DOUBLE_QUOTES, SX_NOALLOC);
+
+         i = si + 1;
+         continue;
+       }
+      else if (c != '"')
+       {
+         ADVANCE_CHAR (string, slen, i);
+         continue;
+       }
+      else
+       break;
+    }
+
+  if (c)
+    i++;
+
+  return (i);
+}
+
+/* Extract the contents of STRING as if it is enclosed in single quotes.
+   SINDEX, when passed in, is the offset of the character immediately
+   following the opening single quote; on exit, SINDEX is left pointing after
+   the closing single quote. */
+static inline char *
+string_extract_single_quoted (string, sindex)
+     char *string;
+     int *sindex;
+{
+  register int i;
+  size_t slen;
+  char *t;
+  DECLARE_MBSTATE;
+
+  /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */
+  slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
+  i = *sindex;
+  while (string[i] && string[i] != '\'')
+    ADVANCE_CHAR (string, slen, i);
+
+  t = substring (string, *sindex, i);
+
+  if (string[i])
+    i++;
+  *sindex = i;
+
+  return (t);
+}
+
+static inline int
+skip_single_quoted (string, slen, sind)
+     const char *string;
+     size_t slen;
+     int sind;
+{
+  register int c;
+  DECLARE_MBSTATE;
+
+  c = sind;
+  while (string[c] && string[c] != '\'')
+    ADVANCE_CHAR (string, slen, c);
+
+  if (string[c])
+    c++;
+  return c;
+}
+
+/* Just like string_extract, but doesn't hack backslashes or any of
+   that other stuff.  Obeys CTLESC quoting.  Used to do splitting on $IFS. */
+static char *
+string_extract_verbatim (string, slen, sindex, charlist, flags)
+     char *string;
+     size_t slen;
+     int *sindex;
+     char *charlist;
+     int flags;
+{
+  register int i;
+#if defined (HANDLE_MULTIBYTE)
+  size_t clen;
+  wchar_t *wcharlist;
+#endif
+  int c;
+  char *temp;
+  DECLARE_MBSTATE;
+
+  if (charlist[0] == '\'' && charlist[1] == '\0')
+    {
+      temp = string_extract_single_quoted (string, sindex);
+      --*sindex;       /* leave *sindex at separator character */
+      return temp;
+    }
+
+  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;
+#endif
+  while (c = string[i])
+    {
+#if defined (HANDLE_MULTIBYTE)
+      size_t mblength;
+#endif
+      if ((flags & SX_NOCTLESC) == 0 && c == CTLESC)
+       {
+         i += 2;
+         continue;
+       }
+      /* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL
+        through, to protect the CTLNULs from later calls to
+        remove_quoted_nulls. */
+      else if ((flags & SX_NOESCCTLNUL) == 0 && c == CTLESC && string[i+1] == CTLNUL)
+       {
+         i += 2;
+         continue;
+       }
+
+#if defined (HANDLE_MULTIBYTE)
+      mblength = MBLEN (string + i, slen - i);
+      if (mblength > 1)
+       {
+         wchar_t wc;
+         mblength = mbtowc (&wc, string + i, slen - i);
+         if (MB_INVALIDCH (mblength))
+           {
+             if (MEMBER (c, charlist))
+               break;
+           }
+         else
+           {
+             if (wcharlist == 0)
+               {
+                 size_t len;
+                 len = mbstowcs (wcharlist, charlist, 0);
+                 if (len == -1)
+                   len = 0;
+                 wcharlist = (wchar_t *)xmalloc (sizeof (wchar_t) * (len + 1));
+                 mbstowcs (wcharlist, charlist, len + 1);
+               }
+
+             if (wcschr (wcharlist, wc))
+               break;
+           }
+       }
+      else             
+#endif
+      if (MEMBER (c, charlist))
+       break;
+
+      ADVANCE_CHAR (string, slen, i);
+    }
+
+#if defined (HANDLE_MULTIBYTE)
+  FREE (wcharlist);
+#endif
+
+  temp = substring (string, *sindex, i);
+  *sindex = i;
+
+  return (temp);
+}
+
+/* Extract the $( construct in STRING, and return a new string.
+   Start extracting at (SINDEX) as if we had just seen "$(".
+   Make (SINDEX) get the position of the matching ")". )
+   XFLAGS is additional flags to pass to other extraction functions. */
+char *
+extract_command_subst (string, sindex, xflags)
+     char *string;
+     int *sindex;
+     int xflags;
+{
+  if (string[*sindex] == LPAREN)
+    return (extract_delimited_string (string, sindex, "$(", "(", ")", xflags|SX_COMMAND)); /*)*/
+  else
+    {
+      xflags |= (no_longjmp_on_fatal_error ? SX_NOLONGJMP : 0);
+      return (xparse_dolparen (string, string+*sindex, sindex, xflags));
+    }
+}
+
+/* Extract the $[ construct in STRING, and return a new string. (])
+   Start extracting at (SINDEX) as if we had just seen "$[".
+   Make (SINDEX) get the position of the matching "]". */
+char *
+extract_arithmetic_subst (string, sindex)
+     char *string;
+     int *sindex;
+{
+  return (extract_delimited_string (string, sindex, "$[", "[", "]", 0)); /*]*/
+}
+
+#if defined (PROCESS_SUBSTITUTION)
+/* Extract the <( or >( construct in STRING, and return a new string.
+   Start extracting at (SINDEX) as if we had just seen "<(".
+   Make (SINDEX) get the position of the matching ")". */ /*))*/
+char *
+extract_process_subst (string, starter, sindex, xflags)
+     char *string;
+     char *starter;
+     int *sindex;
+     int xflags;
+{
+#if 0
+  return (extract_delimited_string (string, sindex, starter, "(", ")", SX_COMMAND));
+#else
+  xflags |= (no_longjmp_on_fatal_error ? SX_NOLONGJMP : 0);
+  return (xparse_dolparen (string, string+*sindex, sindex, xflags));
+#endif
+}
+#endif /* PROCESS_SUBSTITUTION */
+
+#if defined (ARRAY_VARS)
+/* This can be fooled by unquoted right parens in the passed string. If
+   each caller verifies that the last character in STRING is a right paren,
+   we don't even need to call extract_delimited_string. */
+char *
+extract_array_assignment_list (string, sindex)
+     char *string;
+     int *sindex;
+{
+  int slen;
+  char *ret;
+
+  slen = strlen (string);      /* ( */
+  if (string[slen - 1] == ')')
+   {
+      ret = substring (string, *sindex, slen - 1);
+      *sindex = slen - 1;
+      return ret;
+    }
+  return 0;  
+}
+#endif
+
+/* Extract and create a new string from the contents of STRING, a
+   character string delimited with OPENER and CLOSER.  SINDEX is
+   the address of an int describing the current offset in STRING;
+   it should point to just after the first OPENER found.  On exit,
+   SINDEX gets the position of the last character of the matching CLOSER.
+   If OPENER is more than a single character, ALT_OPENER, if non-null,
+   contains a character string that can also match CLOSER and thus
+   needs to be skipped. */
+static char *
+extract_delimited_string (string, sindex, opener, alt_opener, closer, flags)
+     char *string;
+     int *sindex;
+     char *opener, *alt_opener, *closer;
+     int flags;
+{
+  int i, c, si;
+  size_t slen;
+  char *t, *result;
+  int pass_character, nesting_level, in_comment;
+  int len_closer, len_opener, len_alt_opener;
+  DECLARE_MBSTATE;
+
+  slen = strlen (string + *sindex) + *sindex;
+  len_opener = STRLEN (opener);
+  len_alt_opener = STRLEN (alt_opener);
+  len_closer = STRLEN (closer);
+
+  pass_character = in_comment = 0;
+
+  nesting_level = 1;
+  i = *sindex;
+
+  while (nesting_level)
+    {
+      c = string[i];
+
+      if (c == 0)
+       break;
+
+      if (in_comment)
+       {
+         if (c == '\n')
+           in_comment = 0;
+         ADVANCE_CHAR (string, slen, i);
+         continue;
+       }
+
+      if (pass_character)      /* previous char was backslash */
+       {
+         pass_character = 0;
+         ADVANCE_CHAR (string, slen, i);
+         continue;
+       }
+
+      /* Not exactly right yet; should handle shell metacharacters and
+        multibyte characters, too.  See COMMENT_BEGIN define in parse.y */
+      if ((flags & SX_COMMAND) && c == '#' && (i == 0 || string[i - 1] == '\n' || shellblank (string[i - 1])))
+       {
+          in_comment = 1;
+          ADVANCE_CHAR (string, slen, i);
+          continue;
+       }
+        
+      if (c == CTLESC || c == '\\')
+       {
+         pass_character++;
+         i++;
+         continue;
+       }
+
+      /* Process a nested command substitution, but only if we're parsing an
+        arithmetic substitution. */
+      if ((flags & SX_COMMAND) && string[i] == '$' && string[i+1] == LPAREN)
+        {
+          si = i + 2;
+          t = extract_command_subst (string, &si, flags|SX_NOALLOC);
+          i = si + 1;
+          continue;
+        }
+
+      /* Process a nested OPENER. */
+      if (STREQN (string + i, opener, len_opener))
+       {
+         si = i + len_opener;
+         t = extract_delimited_string (string, &si, opener, alt_opener, closer, flags|SX_NOALLOC);
+         i = si + 1;
+         continue;
+       }
+
+      /* Process a nested ALT_OPENER */
+      if (len_alt_opener && STREQN (string + i, alt_opener, len_alt_opener))
+       {
+         si = i + len_alt_opener;
+         t = extract_delimited_string (string, &si, alt_opener, alt_opener, closer, flags|SX_NOALLOC);
+         i = si + 1;
+         continue;
+       }
+
+      /* If the current substring terminates the delimited string, decrement
+        the nesting level. */
+      if (STREQN (string + i, closer, len_closer))
+       {
+         i += len_closer - 1;  /* move to last byte of the closer */
+         nesting_level--;
+         if (nesting_level == 0)
+           break;
+       }
+
+      /* Pass old-style command substitution through verbatim. */
+      if (c == '`')
+       {
+         si = i + 1;
+         t = string_extract (string, &si, "`", flags|SX_NOALLOC);
+         i = si + 1;
+         continue;
+       }
+
+      /* Pass single-quoted and double-quoted strings through verbatim. */
+      if (c == '\'' || c == '"')
+       {
+         si = i + 1;
+         i = (c == '\'') ? skip_single_quoted (string, slen, si)
+                         : skip_double_quoted (string, slen, si);
+         continue;
+       }
+
+      /* move past this character, which was not special. */
+      ADVANCE_CHAR (string, slen, i);
+    }
+
+  if (c == 0 && nesting_level)
+    {
+      if (no_longjmp_on_fatal_error == 0)
+       {
+         last_command_exit_value = EXECUTION_FAILURE;
+         report_error (_("bad substitution: no closing `%s' in %s"), closer, string);
+         exp_jump_to_top_level (DISCARD);
+       }
+      else
+       {
+         *sindex = i;
+         return (char *)NULL;
+       }
+    }
+
+  si = i - *sindex - len_closer + 1;
+  if (flags & SX_NOALLOC)
+    result = (char *)NULL;
+  else    
+    {
+      result = (char *)xmalloc (1 + si);
+      strncpy (result, string + *sindex, si);
+      result[si] = '\0';
+    }
+  *sindex = i;
+
+  return (result);
+}
+
+/* Extract a parameter expansion expression within ${ and } from STRING.
+   Obey the Posix.2 rules for finding the ending `}': count braces while
+   skipping over enclosed quoted strings and command substitutions.
+   SINDEX is the address of an int describing the current offset in STRING;
+   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 -- this is very similar to extract_delimited_string -- XXX */
+static char *
+extract_dollar_brace_string (string, sindex, quoted, flags)
+     char *string;
+     int *sindex, quoted, flags;
+{
+  register int i, c;
+  size_t slen;
+  int pass_character, nesting_level, si, dolbrace_state;
+  char *result, *t;
+  DECLARE_MBSTATE;
+
+  pass_character = 0;
+  nesting_level = 1;
+  slen = strlen (string + *sindex) + *sindex;
+
+  /* The handling of dolbrace_state needs to agree with the code in parse.y:
+     parse_matched_pair().  The different initial value is to handle the
+     case where this function is called to parse the word in
+     ${param op word} (SX_WORD). */
+  dolbrace_state = (flags & SX_WORD) ? DOLBRACE_WORD : DOLBRACE_PARAM;
+  if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && (flags & SX_POSIXEXP))
+    dolbrace_state = DOLBRACE_QUOTE;
+
+  i = *sindex;
+  while (c = string[i])
+    {
+      if (pass_character)
+       {
+         pass_character = 0;
+         ADVANCE_CHAR (string, slen, i);
+         continue;
+       }
+
+      /* CTLESCs and backslashes quote the next character. */
+      if (c == CTLESC || c == '\\')
+       {
+         pass_character++;
+         i++;
+         continue;
+       }
+
+      if (string[i] == '$' && string[i+1] == LBRACE)
+       {
+         nesting_level++;
+         i += 2;
+         continue;
+       }
+
+      if (c == RBRACE)
+       {
+         nesting_level--;
+         if (nesting_level == 0)
+           break;
+         i++;
+         continue;
+       }
+
+      /* Pass the contents of old-style command substitutions through
+        verbatim. */
+      if (c == '`')
+       {
+         si = i + 1;
+         t = string_extract (string, &si, "`", flags|SX_NOALLOC);
+         i = si + 1;
+         continue;
+       }
+
+      /* Pass the contents of new-style command substitutions and
+        arithmetic substitutions through verbatim. */
+      if (string[i] == '$' && string[i+1] == LPAREN)
+       {
+         si = i + 2;
+         t = extract_command_subst (string, &si, flags|SX_NOALLOC);
+         i = si + 1;
+         continue;
+       }
+
+      /* Pass the contents of double-quoted strings through verbatim. */
+      if (c == '"')
+       {
+         si = i + 1;
+         i = skip_double_quoted (string, slen, si);
+         /* skip_XXX_quoted leaves index one past close quote */
+         continue;
+       }
+
+      if (c == '\'')
+       {
+/*itrace("extract_dollar_brace_string: c == single quote flags = %d quoted = %d dolbrace_state = %d", flags, quoted, dolbrace_state);*/
+         if (posixly_correct && shell_compatibility_level > 42 && dolbrace_state != DOLBRACE_QUOTE && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
+           ADVANCE_CHAR (string, slen, i);
+         else
+           {
+             si = i + 1;
+             i = skip_single_quoted (string, slen, si);
+           }
+
+          continue;
+       }
+
+      /* move past this character, which was not special. */
+      ADVANCE_CHAR (string, slen, i);
+
+      /* This logic must agree with parse.y:parse_matched_pair, since they
+        share the same defines. */
+      if (dolbrace_state == DOLBRACE_PARAM && c == '%' && (i - *sindex) > 1)
+       dolbrace_state = DOLBRACE_QUOTE;
+      else if (dolbrace_state == DOLBRACE_PARAM && c == '#' && (i - *sindex) > 1)
+        dolbrace_state = DOLBRACE_QUOTE;
+      else if (dolbrace_state == DOLBRACE_PARAM && c == '/' && (i - *sindex) > 1)
+        dolbrace_state = DOLBRACE_QUOTE2;      /* XXX */
+      else if (dolbrace_state == DOLBRACE_PARAM && c == '^' && (i - *sindex) > 1)
+        dolbrace_state = DOLBRACE_QUOTE;
+      else if (dolbrace_state == DOLBRACE_PARAM && c == ',' && (i - *sindex) > 1)
+        dolbrace_state = DOLBRACE_QUOTE;
+      else if (dolbrace_state == DOLBRACE_PARAM && strchr ("#%^,~:-=?+/", c) != 0)
+       dolbrace_state = DOLBRACE_OP;
+      else if (dolbrace_state == DOLBRACE_OP && strchr ("#%^,~:-=?+/", c) == 0)
+       dolbrace_state = DOLBRACE_WORD;
+    }
+
+  if (c == 0 && nesting_level)
+    {
+      if (no_longjmp_on_fatal_error == 0)
+       {                       /* { */
+         last_command_exit_value = EXECUTION_FAILURE;
+         report_error (_("bad substitution: no closing `%s' in %s"), "}", string);
+         exp_jump_to_top_level (DISCARD);
+       }
+      else
+       {
+         *sindex = i;
+         return ((char *)NULL);
+       }
+    }
+
+  result = (flags & SX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
+  *sindex = i;
+
+  return (result);
+}
+
+/* Remove backslashes which are quoting backquotes from STRING.  Modifies
+   STRING, and returns a pointer to it. */
+char *
+de_backslash (string)
+     char *string;
+{
+  register size_t slen;
+  register int i, j, prev_i;
+  DECLARE_MBSTATE;
+
+  slen = strlen (string);
+  i = j = 0;
+
+  /* Loop copying string[i] to string[j], i >= j. */
+  while (i < slen)
+    {
+      if (string[i] == '\\' && (string[i + 1] == '`' || string[i + 1] == '\\' ||
+                             string[i + 1] == '$'))
+       i++;
+      prev_i = i;
+      ADVANCE_CHAR (string, slen, i);
+      if (j < prev_i)
+       do string[j++] = string[prev_i++]; while (prev_i < i);
+      else
+       j = i;
+    }
+  string[j] = '\0';
+
+  return (string);
+}
+
+#if 0
+/*UNUSED*/
+/* Replace instances of \! in a string with !. */
+void
+unquote_bang (string)
+     char *string;
+{
+  register int i, j;
+  register char *temp;
+
+  temp = (char *)xmalloc (1 + strlen (string));
+
+  for (i = 0, j = 0; (temp[j] = string[i]); i++, j++)
+    {
+      if (string[i] == '\\' && string[i + 1] == '!')
+       {
+         temp[j] = '!';
+         i++;
+       }
+    }
+  strcpy (string, temp);
+  free (temp);
+}
+#endif
+
+#define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
+
+/* This function assumes s[i] == open; returns with s[ret] == close; used to
+   parse array subscripts.  FLAGS & 1 means to not attempt to skip over
+   matched pairs of quotes or backquotes, or skip word expansions; it is
+   intended to be used after expansion has been performed and during final
+   assignment parsing (see arrayfunc.c:assign_compound_array_list()). */
+static int
+skip_matched_pair (string, start, open, close, flags)
+     const char *string;
+     int start, open, close, flags;
+{
+  int i, pass_next, backq, si, c, count;
+  size_t slen;
+  char *temp, *ss;
+  DECLARE_MBSTATE;
+
+  slen = strlen (string + start) + start;
+  no_longjmp_on_fatal_error = 1;
+
+  i = start + 1;               /* skip over leading bracket */
+  count = 1;
+  pass_next = backq = 0;
+  ss = (char *)string;
+  while (c = string[i])
+    {
+      if (pass_next)
+       {
+         pass_next = 0;
+         if (c == 0)
+           CQ_RETURN(i);
+         ADVANCE_CHAR (string, slen, i);
+         continue;
+       }
+      else if (c == '\\')
+       {
+         pass_next = 1;
+         i++;
+         continue;
+       }
+      else if (backq)
+       {
+         if (c == '`')
+           backq = 0;
+         ADVANCE_CHAR (string, slen, i);
+         continue;
+       }
+      else if ((flags & 1) == 0 && c == '`')
+       {
+         backq = 1;
+         i++;
+         continue;
+       }
+      else if ((flags & 1) == 0 && c == open)
+       {
+         count++;
+         i++;
+         continue;
+       }
+      else if (c == close)
+       {
+         count--;
+         if (count == 0)
+           break;
+         i++;
+         continue;
+       }
+      else if ((flags & 1) == 0 && (c == '\'' || c == '"'))
+       {
+         i = (c == '\'') ? skip_single_quoted (ss, slen, ++i)
+                         : skip_double_quoted (ss, slen, ++i);
+         /* no increment, the skip functions increment past the closing quote. */
+       }
+      else if ((flags&1) == 0 && c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
+       {
+         si = i + 2;
+         if (string[si] == '\0')
+           CQ_RETURN(si);
+
+         if (string[i+1] == LPAREN)
+           temp = extract_delimited_string (ss, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
+         else
+           temp = extract_dollar_brace_string (ss, &si, 0, SX_NOALLOC);
+         i = si;
+         if (string[i] == '\0')        /* don't increment i past EOS in loop */
+           break;
+         i++;
+         continue;
+       }
+      else
+       ADVANCE_CHAR (string, slen, i);
+    }
+
+  CQ_RETURN(i);
+}
+
+#if defined (ARRAY_VARS)
+int
+skipsubscript (string, start, flags)
+     const char *string;
+     int start, flags;
+{
+  return (skip_matched_pair (string, start, '[', ']', flags));
+}
+#endif
+
+/* Skip characters in STRING until we find a character in DELIMS, and return
+   the index of that character.  START is the index into string at which we
+   begin.  This is similar in spirit to strpbrk, but it returns an index into
+   STRING and takes a starting index.  This little piece of code knows quite
+   a lot of shell syntax.  It's very similar to skip_double_quoted and other
+   functions of that ilk. */
+int
+skip_to_delim (string, start, delims, flags)
+     char *string;
+     int start;
+     char *delims;
+     int flags;
+{
+  int i, pass_next, backq, si, c, invert, skipquote, skipcmd, noprocsub;
+  size_t slen;
+  char *temp, open[3];
+  DECLARE_MBSTATE;
+
+  slen = strlen (string + start) + start;
+  if (flags & SD_NOJMP)
+    no_longjmp_on_fatal_error = 1;
+  invert = (flags & SD_INVERT);
+  skipcmd = (flags & SD_NOSKIPCMD) == 0;
+  noprocsub = (flags & SD_NOPROCSUB);
+
+  i = start;
+  pass_next = backq = 0;
+  while (c = string[i])
+    {
+      /* If this is non-zero, we should not let quote characters be delimiters
+        and the current character is a single or double quote.  We should not
+        test whether or not it's a delimiter until after we skip single- or
+        double-quoted strings. */
+      skipquote = ((flags & SD_NOQUOTEDELIM) && (c == '\'' || c =='"'));
+      if (pass_next)
+       {
+         pass_next = 0;
+         if (c == 0)
+           CQ_RETURN(i);
+         ADVANCE_CHAR (string, slen, i);
+         continue;
+       }
+      else if (c == '\\')
+       {
+         pass_next = 1;
+         i++;
+         continue;
+       }
+      else if (backq)
+       {
+         if (c == '`')
+           backq = 0;
+         ADVANCE_CHAR (string, slen, i);
+         continue;
+       }
+      else if (c == '`')
+       {
+         backq = 1;
+         i++;
+         continue;
+       }
+      else if (skipquote == 0 && invert == 0 && member (c, delims))
+       break;
+      else if (c == '\'' || c == '"')
+       {
+         i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
+                         : skip_double_quoted (string, slen, ++i);
+         /* no increment, the skip functions increment past the closing quote. */
+       }
+      else if (c == '$' && ((skipcmd && string[i+1] == LPAREN) || string[i+1] == LBRACE))
+       {
+         si = i + 2;
+         if (string[si] == '\0')
+           CQ_RETURN(si);
+
+         if (string[i+1] == LPAREN)
+           temp = extract_delimited_string (string, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
+         else
+           temp = extract_dollar_brace_string (string, &si, 0, SX_NOALLOC);
+         i = si;
+         if (string[i] == '\0')        /* don't increment i past EOS in loop */
+           break;
+         i++;
+         continue;
+       }
+#if defined (PROCESS_SUBSTITUTION)
+      else if (skipcmd && noprocsub == 0 && (c == '<' || c == '>') && string[i+1] == LPAREN)
+       {
+         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
+         i = si;
+         if (string[i] == '\0')
+           break;
+         i++;
+         continue;
+       }
+#endif /* PROCESS_SUBSTITUTION */
+#if defined (EXTENDED_GLOB)
+      else if ((flags & SD_EXTGLOB) && extended_glob && string[i+1] == LPAREN && member (c, "?*+!@"))
+       {
+         si = i + 2;
+         if (string[si] == '\0')
+           CQ_RETURN(si);
+
+         open[0] = c;
+         open[1] = LPAREN;
+         open[2] = '\0';
+         temp = extract_delimited_string (string, &si, open, "(", ")", SX_NOALLOC); /* ) */
+
+         i = si;
+         if (string[i] == '\0')        /* don't increment i past EOS in loop */
+           break;
+         i++;
+         continue;
+       }
+#endif
+      else if ((flags & SD_GLOB) && c == LBRACK)
+       {
+         si = i + 1;
+         if (string[si] == '\0')
+           CQ_RETURN(si);
+
+         temp = extract_delimited_string (string, &si, "[", "[", "]", SX_NOALLOC); /* ] */
+
+         i = si;
+         if (string[i] == '\0')        /* don't increment i past EOS in loop */
+           break;
+         i++;
+         continue;
+       }
+      else if ((skipquote || invert) && (member (c, delims) == 0))
+       break;
+      else
+       ADVANCE_CHAR (string, slen, i);
+    }
+
+  CQ_RETURN(i);
+}
+
+#if defined (READLINE)
+/* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
+   an unclosed quoted string), or if the character at EINDEX is quoted
+   by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
+   single and double-quoted string parsing functions should not return an
+   error if there are unclosed quotes or braces.  The characters that this
+   recognizes need to be the same as the contents of
+   rl_completer_quote_characters. */
+
+int
+char_is_quoted (string, eindex)
+     char *string;
+     int eindex;
+{
+  int i, pass_next, c;
+  size_t slen;
+  DECLARE_MBSTATE;
+
+  slen = strlen (string);
+  no_longjmp_on_fatal_error = 1;
+  i = pass_next = 0;
+  while (i <= eindex)
+    {
+      c = string[i];
+
+      if (pass_next)
+       {
+         pass_next = 0;
+         if (i >= eindex)      /* XXX was if (i >= eindex - 1) */
+           CQ_RETURN(1);
+         ADVANCE_CHAR (string, slen, i);
+         continue;
+       }
+      else if (c == '\\')
+       {
+         pass_next = 1;
+         i++;
+         continue;
+       }
+      else if (c == '\'' || c == '"')
+       {
+         i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
+                         : skip_double_quoted (string, slen, ++i);
+         if (i > eindex)
+           CQ_RETURN(1);
+         /* no increment, the skip_xxx functions go one past end */
+       }
+      else
+       ADVANCE_CHAR (string, slen, i);
+    }
+
+  CQ_RETURN(0);
+}
+
+int
+unclosed_pair (string, eindex, openstr)
+     char *string;
+     int eindex;
+     char *openstr;
+{
+  int i, pass_next, openc, olen;
+  size_t slen;
+  DECLARE_MBSTATE;
+
+  slen = strlen (string);
+  olen = strlen (openstr);
+  i = pass_next = openc = 0;
+  while (i <= eindex)
+    {
+      if (pass_next)
+       {
+         pass_next = 0;
+         if (i >= eindex)      /* XXX was if (i >= eindex - 1) */
+           return 0;
+         ADVANCE_CHAR (string, slen, i);
+         continue;
+       }
+      else if (string[i] == '\\')
+       {
+         pass_next = 1;
+         i++;
+         continue;
+       }
+      else if (STREQN (string + i, openstr, olen))
+       {
+         openc = 1 - openc;
+         i += olen;
+       }
+      else if (string[i] == '\'' || string[i] == '"')
+       {
+         i = (string[i] == '\'') ? skip_single_quoted (string, slen, i)
+                                 : skip_double_quoted (string, slen, i);
+         if (i > eindex)
+           return 0;
+       }
+      else
+       ADVANCE_CHAR (string, slen, i);
+    }
+  return (openc);
+}
+
+/* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
+   individual words.  If DELIMS is NULL, the current value of $IFS is used
+   to split the string, and the function follows the shell field splitting
+   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. */
+WORD_LIST *
+split_at_delims (string, slen, delims, sentinel, flags, nwp, cwp)
+     char *string;
+     int slen;
+     char *delims;
+     int sentinel, flags;
+     int *nwp, *cwp;
+{
+  int ts, te, i, nw, cw, ifs_split, dflags;
+  char *token, *d, *d2;
+  WORD_LIST *ret, *tl;
+
+  if (string == 0 || *string == '\0')
+    {
+      if (nwp)
+       *nwp = 0;
+      if (cwp)
+       *cwp = 0;       
+      return ((WORD_LIST *)NULL);
+    }
+
+  d = (delims == 0) ? ifs_value : delims;
+  ifs_split = delims == 0;
+
+  /* Make d2 the non-whitespace characters in delims */
+  d2 = 0;
+  if (delims)
+    {
+      size_t slength;
+#if defined (HANDLE_MULTIBYTE)
+      size_t mblength = 1;
+#endif
+      DECLARE_MBSTATE;
+
+      slength = strlen (delims);
+      d2 = (char *)xmalloc (slength + 1);
+      i = ts = 0;
+      while (delims[i])
+       {
+#if defined (HANDLE_MULTIBYTE)
+         mbstate_t state_bak;
+         state_bak = state;
+         mblength = MBRLEN (delims + i, slength, &state);
+         if (MB_INVALIDCH (mblength))
+           state = state_bak;
+         else if (mblength > 1)
+           {
+             memcpy (d2 + ts, delims + i, mblength);
+             ts += mblength;
+             i += mblength;
+             slength -= mblength;
+             continue;
+           }
+#endif
+         if (whitespace (delims[i]) == 0)
+           d2[ts++] = delims[i];
+
+         i++;
+         slength--;
+       }
+      d2[ts] = '\0';
+    }
+
+  ret = (WORD_LIST *)NULL;
+
+  /* Remove sequences of whitespace characters at the start of the string, as
+     long as those characters are delimiters. */
+  for (i = 0; member (string[i], d) && spctabnl (string[i]); i++)
+    ;
+  if (string[i] == '\0')
+    return (ret);
+
+  ts = i;
+  nw = 0;
+  cw = -1;
+  dflags = flags|SD_NOJMP;
+  while (1)
+    {
+      te = skip_to_delim (string, ts, d, dflags);
+
+      /* If we have a non-whitespace delimiter character, use it to make a
+        separate field.  This is just about what $IFS splitting does and
+        is closer to the behavior of the shell parser. */
+      if (ts == te && d2 && member (string[ts], d2))
+       {
+         te = ts + 1;
+         /* If we're using IFS splitting, the non-whitespace delimiter char
+            and any additional IFS whitespace delimits a field. */
+         if (ifs_split)
+           while (member (string[te], d) && spctabnl (string[te]))
+             te++;
+         else
+           while (member (string[te], d2))
+             te++;
+       }
+
+      token = substring (string, ts, te);
+
+      ret = add_string_to_list (token, ret);
+      free (token);
+      nw++;
+
+      if (sentinel >= ts && sentinel <= te)
+       cw = nw;
+
+      /* If the cursor is at whitespace just before word start, set the
+        sentinel word to the current word. */
+      if (cwp && cw == -1 && sentinel == ts-1)
+       cw = nw;
+
+      /* If the cursor is at whitespace between two words, make a new, empty
+        word, add it before (well, after, since the list is in reverse order)
+        the word we just added, and set the current word to that one. */
+      if (cwp && cw == -1 && sentinel < ts)
+       {
+         tl = make_word_list (make_word (""), ret->next);
+         ret->next = tl;
+         cw = nw;
+         nw++;
+       }
+
+      if (string[te] == 0)
+       break;
+
+      i = te;
+      while (member (string[i], d) && (ifs_split || spctabnl(string[i])))
+       i++;
+
+      if (string[i])
+       ts = i;
+      else
+       break;
+    }
+
+  /* Special case for SENTINEL at the end of STRING.  If we haven't found
+     the word containing SENTINEL yet, and the index we're looking for is at
+     the end of STRING (or past the end of the previously-found token,
+     possible if the end of the line is composed solely of IFS whitespace)
+     add an additional null argument and set the current word pointer to that. */
+  if (cwp && cw == -1 && (sentinel >= slen || sentinel >= te))
+    {
+      if (whitespace (string[sentinel - 1]))
+       {
+         token = "";
+         ret = add_string_to_list (token, ret);
+         nw++;
+       }
+      cw = nw;
+    }
+
+  if (nwp)
+    *nwp = nw;
+  if (cwp)
+    *cwp = cw;
+
+  FREE (d2);
+
+  return (REVERSE_LIST (ret, WORD_LIST *));
+}
+#endif /* READLINE */
+
+#if 0
+/* UNUSED */
+/* Extract the name of the variable to bind to from the assignment string. */
+char *
+assignment_name (string)
+     char *string;
+{
+  int offset;
+  char *temp;
+
+  offset = assignment (string, 0);
+  if (offset == 0)
+    return (char *)NULL;
+  temp = substring (string, 0, offset);
+  return (temp);
+}
+#endif
+
+/* **************************************************************** */
+/*                                                                 */
+/*     Functions to convert strings to WORD_LISTs and vice versa    */
+/*                                                                 */
+/* **************************************************************** */
+
+/* Return a single string of all the words in LIST.  SEP is the separator
+   to put between individual elements of LIST in the output string. */
+char *
+string_list_internal (list, sep)
+     WORD_LIST *list;
+     char *sep;
+{
+  register WORD_LIST *t;
+  char *result, *r;
+  int word_len, sep_len, result_size;
+
+  if (list == 0)
+    return ((char *)NULL);
+
+  /* Short-circuit quickly if we don't need to separate anything. */
+  if (list->next == 0)
+    return (savestring (list->word->word));
+
+  /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
+  sep_len = STRLEN (sep);
+  result_size = 0;
+
+  for (t = list; t; t = t->next)
+    {
+      if (t != list)
+       result_size += sep_len;
+      result_size += strlen (t->word->word);
+    }
+
+  r = result = (char *)xmalloc (result_size + 1);
+
+  for (t = list; t; t = t->next)
+    {
+      if (t != list && sep_len)
+       {
+         if (sep_len > 1)
+           {
+             FASTCOPY (sep, r, sep_len);
+             r += sep_len;
+           }
+         else
+           *r++ = sep[0];
+       }
+
+      word_len = strlen (t->word->word);
+      FASTCOPY (t->word->word, r, word_len);
+      r += word_len;
+    }
+
+  *r = '\0';
+  return (result);
+}
+
+/* Return a single string of all the words present in LIST, separating
+   each word with a space. */
+char *
+string_list (list)
+     WORD_LIST *list;
+{
+  return (string_list_internal (list, " "));
+}
+
+/* An external interface that can be used by the rest of the shell to
+   obtain a string containing the first character in $IFS.  Handles all
+   the multibyte complications.  If LENP is non-null, it is set to the
+   length of the returned string. */
+char *
+ifs_firstchar (lenp)
+     int *lenp;
+{
+  char *ret;
+  int len;
+
+  ret = xmalloc (MB_LEN_MAX + 1);
+#if defined (HANDLE_MULTIBYTE)
+  if (ifs_firstc_len == 1)
+    {
+      ret[0] = ifs_firstc[0];
+      ret[1] = '\0';
+      len = ret[0] ? 1 : 0;
+    }
+  else
+    {
+      memcpy (ret, ifs_firstc, ifs_firstc_len);
+      ret[len = ifs_firstc_len] = '\0';
+    }
+#else
+  ret[0] = ifs_firstc;
+  ret[1] = '\0';
+  len = ret[0] ? 0 : 1;
+#endif
+
+  if (lenp)
+    *lenp = len;
+
+  return ret;
+}
+
+/* Return a single string of all the words present in LIST, obeying the
+   quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
+   expansion [of $*] appears within a double quoted string, it expands
+   to a single field with the value of each parameter separated by the
+   first character of the IFS variable, or by a <space> if IFS is unset." */
+char *
+string_list_dollar_star (list)
+     WORD_LIST *list;
+{
+  char *ret;
+#if defined (HANDLE_MULTIBYTE)
+#  if defined (__GNUC__)
+  char sep[MB_CUR_MAX + 1];
+#  else
+  char *sep = 0;
+#  endif
+#else
+  char sep[2];
+#endif
+
+#if defined (HANDLE_MULTIBYTE)
+#  if !defined (__GNUC__)
+  sep = (char *)xmalloc (MB_CUR_MAX + 1);
+#  endif /* !__GNUC__ */
+  if (ifs_firstc_len == 1)
+    {
+      sep[0] = ifs_firstc[0];
+      sep[1] = '\0';
+    }
+  else
+    {
+      memcpy (sep, ifs_firstc, ifs_firstc_len);
+      sep[ifs_firstc_len] = '\0';
+    }
+#else
+  sep[0] = ifs_firstc;
+  sep[1] = '\0';
+#endif
+
+  ret = string_list_internal (list, sep);
+#if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
+  free (sep);
+#endif
+  return ret;
+}
+
+/* Turn $@ into a string.  If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
+   is non-zero, the $@ appears within double quotes, and we should quote
+   the list before converting it into a string.  If IFS is unset, and the
+   word is not quoted, we just need to quote CTLESC and CTLNUL characters
+   in the words in the list, because the default value of $IFS is
+   <space><tab><newline>, IFS characters in the words in the list should
+   also be split.  If IFS is null, and the word is not quoted, we need
+   to quote the words in the list to preserve the positional parameters
+   exactly. */
+char *
+string_list_dollar_at (list, quoted)
+     WORD_LIST *list;
+     int quoted;
+{
+  char *ifs, *ret;
+#if defined (HANDLE_MULTIBYTE)
+#  if defined (__GNUC__)
+  char sep[MB_CUR_MAX + 1];
+#  else
+  char *sep = 0;
+#  endif /* !__GNUC__ */
+#else
+  char sep[2];
+#endif
+  WORD_LIST *tlist;
+
+  /* XXX this could just be ifs = ifs_value; */
+  ifs = ifs_var ? value_cell (ifs_var) : (char *)0;
+
+#if defined (HANDLE_MULTIBYTE)
+#  if !defined (__GNUC__)
+  sep = (char *)xmalloc (MB_CUR_MAX + 1);
+#  endif /* !__GNUC__ */
+  if (ifs && *ifs)
+    {
+      if (ifs_firstc_len == 1)
+       {
+         sep[0] = ifs_firstc[0];
+         sep[1] = '\0';
+       }
+      else
+       {
+         memcpy (sep, ifs_firstc, ifs_firstc_len);
+         sep[ifs_firstc_len] = '\0';
+       }
+    }
+  else
+    {
+      sep[0] = ' ';
+      sep[1] = '\0';
+    }
+#else
+  sep[0] = (ifs == 0 || *ifs == 0) ? ' ' : *ifs;
+  sep[1] = '\0';
+#endif
+
+  /* XXX -- why call quote_list if ifs == 0?  we can get away without doing
+     it now that quote_escapes quotes spaces */
+  tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES|Q_PATQUOTE))
+               ? quote_list (list)
+               : list_quote_escapes (list);
+
+  ret = string_list_internal (tlist, sep);
+#if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
+  free (sep);
+#endif
+  return ret;
+}
+
+/* Turn the positional parameters into a string, understanding quoting and
+   the various subtleties of using the first character of $IFS as the
+   separator.  Calls string_list_dollar_at, string_list_dollar_star, and
+   string_list as appropriate. */
+char *
+string_list_pos_params (pchar, list, quoted)
+     int pchar;
+     WORD_LIST *list;
+     int quoted;
+{
+  char *ret;
+  WORD_LIST *tlist;
+
+  if (pchar == '*' && (quoted & Q_DOUBLE_QUOTES))
+    {
+      tlist = quote_list (list);
+      word_list_remove_quoted_nulls (tlist);
+      ret = string_list_dollar_star (tlist);
+    }
+  else if (pchar == '*' && (quoted & Q_HERE_DOCUMENT))
+    {
+      tlist = quote_list (list);
+      word_list_remove_quoted_nulls (tlist);
+      ret = string_list (tlist);
+    }
+  else if (pchar == '*')
+    {
+      /* Even when unquoted, string_list_dollar_star does the right thing
+        making sure that the first character of $IFS is used as the
+        separator. */
+      ret = string_list_dollar_star (list);
+    }
+  else if (pchar == '@' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
+    /* We use string_list_dollar_at, but only if the string is quoted, since
+       that quotes the escapes if it's not, which we don't want.  We could
+       use string_list (the old code did), but that doesn't do the right
+       thing if the first character of $IFS is not a space.  We use
+       string_list_dollar_star if the string is unquoted so we make sure that
+       the elements of $@ are separated by the first character of $IFS for
+       later splitting. */
+    ret = string_list_dollar_at (list, quoted);
+  else if (pchar == '@')
+    ret = string_list_dollar_star (list);
+  else
+    ret = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (list) : list);
+
+  return ret;
+}
+
+/* Return the list of words present in STRING.  Separate the string into
+   words at any of the characters found in SEPARATORS.  If QUOTED is
+   non-zero then word in the list will have its quoted flag set, otherwise
+   the quoted flag is left as make_word () deemed fit.
+
+   This obeys the P1003.2 word splitting semantics.  If `separators' is
+   exactly <space><tab><newline>, then the splitting algorithm is that of
+   the Bourne shell, which treats any sequence of characters from `separators'
+   as a delimiter.  If IFS is unset, which results in `separators' being set
+   to "", no splitting occurs.  If separators has some other value, the
+   following rules are applied (`IFS white space' means zero or more
+   occurrences of <space>, <tab>, or <newline>, as long as those characters
+   are in `separators'):
+
+       1) IFS white space is ignored at the start and the end of the
+          string.
+       2) Each occurrence of a character in `separators' that is not
+          IFS white space, along with any adjacent occurrences of
+          IFS white space delimits a field.
+       3) Any nonzero-length sequence of IFS white space delimits a field.
+   */
+
+/* BEWARE!  list_string strips null arguments.  Don't call it twice and
+   expect to have "" preserved! */
+
+/* This performs word splitting and quoted null character removal on
+   STRING. */
+#define issep(c) \
+       (((separators)[0]) ? ((separators)[1] ? isifs(c) \
+                                             : (c) == (separators)[0]) \
+                          : 0)
+
+WORD_LIST *
+list_string (string, separators, quoted)
+     register char *string, *separators;
+     int quoted;
+{
+  WORD_LIST *result;
+  WORD_DESC *t;
+  char *current_word, *s;
+  int sindex, sh_style_split, whitesep, xflags;
+  size_t slen;
+
+  if (!string || !*string)
+    return ((WORD_LIST *)NULL);
+
+  sh_style_split = separators && separators[0] == ' ' &&
+                                separators[1] == '\t' &&
+                                separators[2] == '\n' &&
+                                separators[3] == '\0';
+  for (xflags = 0, s = ifs_value; s && *s; s++)
+    {
+      if (*s == CTLESC) xflags |= SX_NOCTLESC;
+      else if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
+    }
+
+  slen = 0;
+  /* Remove sequences of whitespace at the beginning of STRING, as
+     long as those characters appear in IFS.  Do not do this if
+     STRING is quoted or if there are no separator characters. */
+  if (!quoted || !separators || !*separators)
+    {
+      for (s = string; *s && spctabnl (*s) && issep (*s); s++);
+
+      if (!*s)
+       return ((WORD_LIST *)NULL);
+
+      string = s;
+    }
+
+  /* OK, now STRING points to a word that does not begin with white space.
+     The splitting algorithm is:
+       extract a word, stopping at a separator
+       skip sequences of spc, tab, or nl as long as they are separators
+     This obeys the field splitting rules in Posix.2. */
+  slen = (MB_CUR_MAX > 1) ? strlen (string) : 1;
+  for (result = (WORD_LIST *)NULL, sindex = 0; string[sindex]; )
+    {
+      /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
+        unless multibyte chars are possible. */
+      current_word = string_extract_verbatim (string, slen, &sindex, separators, xflags);
+      if (current_word == 0)
+       break;
+
+      /* If we have a quoted empty string, add a quoted null argument.  We
+        want to preserve the quoted null character iff this is a quoted
+        empty string; otherwise the quoted null characters are removed
+        below. */
+      if (QUOTED_NULL (current_word))
+       {
+         t = alloc_word_desc ();
+         t->word = make_quoted_char ('\0');
+         t->flags |= W_QUOTED|W_HASQUOTEDNULL;
+         result = make_word_list (t, result);
+       }
+      else if (current_word[0] != '\0')
+       {
+         /* If we have something, then add it regardless.  However,
+            perform quoted null character removal on the current word. */
+         remove_quoted_nulls (current_word);
+         result = add_string_to_list (current_word, result);
+         result->word->flags &= ~W_HASQUOTEDNULL;      /* just to be sure */
+         if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
+           result->word->flags |= W_QUOTED;
+       }
+
+      /* If we're not doing sequences of separators in the traditional
+        Bourne shell style, then add a quoted null argument. */
+      else if (!sh_style_split && !spctabnl (string[sindex]))
+       {
+         t = alloc_word_desc ();
+         t->word = make_quoted_char ('\0');
+         t->flags |= W_QUOTED|W_HASQUOTEDNULL;
+         result = make_word_list (t, result);
+       }
+
+      free (current_word);
+
+      /* Note whether or not the separator is IFS whitespace, used later. */
+      whitesep = string[sindex] && spctabnl (string[sindex]);
+
+      /* Move past the current separator character. */
+      if (string[sindex])
+       {
+         DECLARE_MBSTATE;
+         ADVANCE_CHAR (string, slen, sindex);
+       }
+
+      /* Now skip sequences of space, tab, or newline characters if they are
+        in the list of separators. */
+      while (string[sindex] && spctabnl (string[sindex]) && issep (string[sindex]))
+       sindex++;
+
+      /* If the first separator was IFS whitespace and the current character
+        is a non-whitespace IFS character, it should be part of the current
+        field delimiter, not a separate delimiter that would result in an
+        empty field.  Look at POSIX.2, 3.6.5, (3)(b). */
+      if (string[sindex] && whitesep && issep (string[sindex]) && !spctabnl (string[sindex]))
+       {
+         sindex++;
+         /* An IFS character that is not IFS white space, along with any
+            adjacent IFS white space, shall delimit a field. (SUSv3) */
+         while (string[sindex] && spctabnl (string[sindex]) && isifs (string[sindex]))
+           sindex++;
+       }
+    }
+  return (REVERSE_LIST (result, WORD_LIST *));
+}
+
+/* Parse a single word from STRING, using SEPARATORS to separate fields.
+   ENDPTR is set to the first character after the word.  This is used by
+   the `read' builtin.  This is never called with SEPARATORS != $IFS;
+   it should be simplified.
+
+   XXX - this function is very similar to list_string; they should be
+        combined - XXX */
+char *
+get_word_from_string (stringp, separators, endptr)
+     char **stringp, *separators, **endptr;
+{
+  register char *s;
+  char *current_word;
+  int sindex, sh_style_split, whitesep, xflags;
+  size_t slen;
+
+  if (!stringp || !*stringp || !**stringp)
+    return ((char *)NULL);
+
+  sh_style_split = separators && separators[0] == ' ' &&
+                                separators[1] == '\t' &&
+                                separators[2] == '\n' &&
+                                separators[3] == '\0';
+  for (xflags = 0, s = ifs_value; s && *s; s++)
+    {
+      if (*s == CTLESC) xflags |= SX_NOCTLESC;
+      if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
+    }
+
+  s = *stringp;
+  slen = 0;
+
+  /* Remove sequences of whitespace at the beginning of STRING, as
+     long as those characters appear in IFS. */
+  if (sh_style_split || !separators || !*separators)
+    {
+      for (; *s && spctabnl (*s) && isifs (*s); s++);
+
+      /* If the string is nothing but whitespace, update it and return. */
+      if (!*s)
+       {
+         *stringp = s;
+         if (endptr)
+           *endptr = s;
+         return ((char *)NULL);
+       }
+    }
+
+  /* OK, S points to a word that does not begin with white space.
+     Now extract a word, stopping at a separator, save a pointer to
+     the first character after the word, then skip sequences of spc,
+     tab, or nl as long as they are separators.
+
+     This obeys the field splitting rules in Posix.2. */
+  sindex = 0;
+  /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
+     unless multibyte chars are possible. */
+  slen = (MB_CUR_MAX > 1) ? strlen (s) : 1;
+  current_word = string_extract_verbatim (s, slen, &sindex, separators, xflags);
+
+  /* Set ENDPTR to the first character after the end of the word. */
+  if (endptr)
+    *endptr = s + sindex;
+
+  /* Note whether or not the separator is IFS whitespace, used later. */
+  whitesep = s[sindex] && spctabnl (s[sindex]);
+
+  /* Move past the current separator character. */
+  if (s[sindex])
+    {
+      DECLARE_MBSTATE;
+      ADVANCE_CHAR (s, slen, sindex);
+    }
+
+  /* Now skip sequences of space, tab, or newline characters if they are
+     in the list of separators. */
+  while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
+    sindex++;
+
+  /* If the first separator was IFS whitespace and the current character is
+     a non-whitespace IFS character, it should be part of the current field
+     delimiter, not a separate delimiter that would result in an empty field.
+     Look at POSIX.2, 3.6.5, (3)(b). */
+  if (s[sindex] && whitesep && isifs (s[sindex]) && !spctabnl (s[sindex]))
+    {
+      sindex++;
+      /* An IFS character that is not IFS white space, along with any adjacent
+        IFS white space, shall delimit a field. */
+      while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
+       sindex++;
+    }
+
+  /* Update STRING to point to the next field. */
+  *stringp = s + sindex;
+  return (current_word);
+}
+
+/* Remove IFS white space at the end of STRING.  Start at the end
+   of the string and walk backwards until the beginning of the string
+   or we find a character that's not IFS white space and not CTLESC.
+   Only let CTLESC escape a white space character if SAW_ESCAPE is
+   non-zero.  */
+char *
+strip_trailing_ifs_whitespace (string, separators, saw_escape)
+     char *string, *separators;
+     int saw_escape;
+{
+  char *s;
+
+  s = string + STRLEN (string) - 1;
+  while (s > string && ((spctabnl (*s) && isifs (*s)) ||
+                       (saw_escape && *s == CTLESC && spctabnl (s[1]))))
+    s--;
+  *++s = '\0';
+  return string;
+}
+
+#if 0
+/* UNUSED */
+/* Split STRING into words at whitespace.  Obeys shell-style quoting with
+   backslashes, single and double quotes. */
+WORD_LIST *
+list_string_with_quotes (string)
+     char *string;
+{
+  WORD_LIST *list;
+  char *token, *s;
+  size_t s_len;
+  int c, i, tokstart, len;
+
+  for (s = string; s && *s && spctabnl (*s); s++)
+    ;
+  if (s == 0 || *s == 0)
+    return ((WORD_LIST *)NULL);
+
+  s_len = strlen (s);
+  tokstart = i = 0;
+  list = (WORD_LIST *)NULL;
+  while (1)
+    {
+      c = s[i];
+      if (c == '\\')
+       {
+         i++;
+         if (s[i])
+           i++;
+       }
+      else if (c == '\'')
+       i = skip_single_quoted (s, s_len, ++i);
+      else if (c == '"')
+       i = skip_double_quoted (s, s_len, ++i);
+      else if (c == 0 || spctabnl (c))
+       {
+         /* We have found the end of a token.  Make a word out of it and
+            add it to the word list. */
+         token = substring (s, tokstart, i);
+         list = add_string_to_list (token, list);
+         free (token);
+         while (spctabnl (s[i]))
+           i++;
+         if (s[i])
+           tokstart = i;
+         else
+           break;
+       }
+      else
+       i++;    /* normal character */
+    }
+  return (REVERSE_LIST (list, WORD_LIST *));
+}
+#endif
+
+/********************************************************/
+/*                                                     */
+/*     Functions to perform assignment statements      */
+/*                                                     */
+/********************************************************/
+
+#if defined (ARRAY_VARS)
+static SHELL_VAR *
+do_compound_assignment (name, value, flags)
+     char *name, *value;
+     int flags;
+{
+  SHELL_VAR *v;
+  int mklocal, mkassoc, mkglobal;
+  WORD_LIST *list;
+
+  mklocal = flags & ASS_MKLOCAL;
+  mkassoc = flags & ASS_MKASSOC;
+  mkglobal = flags & ASS_MKGLOBAL;
+
+  if (mklocal && variable_context)
+    {
+      v = find_variable (name);
+      list = expand_compound_array_assignment (v, value, flags);
+      if (mkassoc)
+       v = make_local_assoc_variable (name);
+      else if (v == 0 || (array_p (v) == 0 && assoc_p (v) == 0) || v->context != variable_context)
+        v = make_local_array_variable (name, 0);
+      if (v)
+       assign_compound_array_list (v, list, flags);
+    }
+  /* In a function but forcing assignment in global context */
+  else if (mkglobal && variable_context)
+    {
+      v = find_global_variable (name);
+      list = expand_compound_array_assignment (v, value, flags);
+      if (v == 0 && mkassoc)
+       v = make_new_assoc_variable (name);
+      else if (v && mkassoc && assoc_p (v) == 0)
+       v = convert_var_to_assoc (v);
+      else if (v == 0)
+       v = make_new_array_variable (name);
+      else if (v && mkassoc == 0 && array_p (v) == 0)
+       v = convert_var_to_array (v);
+      if (v)
+       assign_compound_array_list (v, list, flags);
+    }
+  else
+    v = assign_array_from_string (name, value, flags);
+
+  return (v);
+}
+#endif
+
+/* Given STRING, an assignment string, get the value of the right side
+   of the `=', and bind it to the left side.  If EXPAND is true, then
+   perform parameter expansion, command substitution, and arithmetic
+   expansion on the right-hand side.  Perform tilde expansion in any
+   case.  Do not perform word splitting on the result of expansion. */
+static int
+do_assignment_internal (word, expand)
+     const WORD_DESC *word;
+     int expand;
+{
+  int offset, appendop, assign_list, aflags, retval;
+  char *name, *value, *temp;
+  SHELL_VAR *entry;
+#if defined (ARRAY_VARS)
+  char *t;
+  int ni;
+#endif
+  const char *string;
+
+  if (word == 0 || word->word == 0)
+    return 0;
+
+  appendop = assign_list = aflags = 0;
+  string = word->word;
+  offset = assignment (string, 0);
+  name = savestring (string);
+  value = (char *)NULL;
+
+  if (name[offset] == '=')
+    {
+      if (name[offset - 1] == '+')
+       {
+         appendop = 1;
+         name[offset - 1] = '\0';
+       }
+
+      name[offset] = 0;                /* might need this set later */
+      temp = name + offset + 1;
+
+#if defined (ARRAY_VARS)
+      if (expand && (word->flags & W_COMPASSIGN))
+       {
+         assign_list = ni = 1;
+         value = extract_array_assignment_list (temp, &ni);
+       }
+      else
+#endif
+      if (expand && temp[0])
+       value = expand_string_if_necessary (temp, 0, expand_string_assignment);
+      else
+       value = savestring (temp);
+    }
+
+  if (value == 0)
+    {
+      value = (char *)xmalloc (1);
+      value[0] = '\0';
+    }
+
+  if (echo_command_at_execute)
+    {
+      if (appendop)
+       name[offset - 1] = '+';
+      xtrace_print_assignment (name, value, assign_list, 1);
+      if (appendop)
+       name[offset - 1] = '\0';
+    }
+
+#define ASSIGN_RETURN(r)       do { FREE (value); free (name); return (r); } while (0)
+
+  if (appendop)
+    aflags |= ASS_APPEND;
+
+#if defined (ARRAY_VARS)
+  if (t = mbschr (name, '['))  /*]*/
+    {
+      if (assign_list)
+       {
+         report_error (_("%s: cannot assign list to array member"), name);
+         ASSIGN_RETURN (0);
+       }
+      entry = assign_array_element (name, value, aflags);
+      if (entry == 0)
+       ASSIGN_RETURN (0);
+    }
+  else if (assign_list)
+    {
+      if ((word->flags & W_ASSIGNARG) && (word->flags & W_ASSNGLOBAL) == 0)
+       aflags |= ASS_MKLOCAL;
+      if ((word->flags & W_ASSIGNARG) && (word->flags & W_ASSNGLOBAL))
+       aflags |= ASS_MKGLOBAL;
+      if (word->flags & W_ASSIGNASSOC)
+       aflags |= ASS_MKASSOC;
+      entry = do_compound_assignment (name, value, aflags);
+    }
+  else
+#endif /* ARRAY_VARS */
+  entry = bind_variable (name, value, aflags);
+
+  stupidly_hack_special_variables (name);
+
+  /* Return 1 if the assignment seems to have been performed correctly. */
+  if (entry == 0 || readonly_p (entry))
+    retval = 0;                /* assignment failure */
+  else if (noassign_p (entry))
+    {
+      last_command_exit_value = EXECUTION_FAILURE;
+      retval = 1;      /* error status, but not assignment failure */
+    }
+  else
+    retval = 1;
+
+  if (entry && retval != 0 && noassign_p (entry) == 0)
+    VUNSETATTR (entry, att_invisible);
+
+  ASSIGN_RETURN (retval);
+}
+
+/* Perform the assignment statement in STRING, and expand the
+   right side by doing tilde, command and parameter expansion. */
+int
+do_assignment (string)
+     char *string;
+{
+  WORD_DESC td;
+
+  td.flags = W_ASSIGNMENT;
+  td.word = string;
+
+  return do_assignment_internal (&td, 1);
+}
+
+int
+do_word_assignment (word, flags)
+     WORD_DESC *word;
+     int flags;
+{
+  return do_assignment_internal (word, 1);
+}
+
+/* Given STRING, an assignment string, get the value of the right side
+   of the `=', and bind it to the left side.  Do not perform any word
+   expansions on the right hand side. */
+int
+do_assignment_no_expand (string)
+     char *string;
+{
+  WORD_DESC td;
+
+  td.flags = W_ASSIGNMENT;
+  td.word = string;
+
+  return (do_assignment_internal (&td, 0));
+}
+
+/***************************************************
+ *                                                *
+ *  Functions to manage the positional parameters  *
+ *                                                *
+ ***************************************************/
+
+/* Return the word list that corresponds to `$*'. */
+WORD_LIST *
+list_rest_of_args ()
+{
+  register WORD_LIST *list, *args;
+  int i;
+
+  /* Break out of the loop as soon as one of the dollar variables is null. */
+  for (i = 1, list = (WORD_LIST *)NULL; i < 10 && dollar_vars[i]; i++)
+    list = make_word_list (make_bare_word (dollar_vars[i]), list);
+
+  for (args = rest_of_args; args; args = args->next)
+    list = make_word_list (make_bare_word (args->word->word), list);
+
+  return (REVERSE_LIST (list, WORD_LIST *));
+}
+
+int
+number_of_args ()
+{
+  register WORD_LIST *list;
+  int n;
+
+  for (n = 0; n < 9 && dollar_vars[n+1]; n++)
+    ;
+  for (list = rest_of_args; list; list = list->next)
+    n++;
+  return n;
+}
+
+/* Return the value of a positional parameter.  This handles values > 10. */
+char *
+get_dollar_var_value (ind)
+     intmax_t ind;
+{
+  char *temp;
+  WORD_LIST *p;
+
+  if (ind < 10)
+    temp = dollar_vars[ind] ? savestring (dollar_vars[ind]) : (char *)NULL;
+  else /* We want something like ${11} */
+    {
+      ind -= 10;
+      for (p = rest_of_args; p && ind--; p = p->next)
+       ;
+      temp = p ? savestring (p->word->word) : (char *)NULL;
+    }
+  return (temp);
+}
+
+/* Make a single large string out of the dollar digit variables,
+   and the rest_of_args.  If DOLLAR_STAR is 1, then obey the special
+   case of "$*" with respect to IFS. */
+char *
+string_rest_of_args (dollar_star)
+     int dollar_star;
+{
+  register WORD_LIST *list;
+  char *string;
+
+  list = list_rest_of_args ();
+  string = dollar_star ? string_list_dollar_star (list) : string_list (list);
+  dispose_words (list);
+  return (string);
+}
+
+/* Return a string containing the positional parameters from START to
+   END, inclusive.  If STRING[0] == '*', we obey the rules for $*,
+   which only makes a difference if QUOTED is non-zero.  If QUOTED includes
+   Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
+   no quoting chars are added. */
+static char *
+pos_params (string, start, end, quoted)
+     char *string;
+     int start, end, quoted;
+{
+  WORD_LIST *save, *params, *h, *t;
+  char *ret;
+  int i;
+
+  /* see if we can short-circuit.  if start == end, we want 0 parameters. */
+  if (start == end)
+    return ((char *)NULL);
+
+  save = params = list_rest_of_args ();
+  if (save == 0 && start > 0)
+    return ((char *)NULL);
+
+  if (start == 0)              /* handle ${@:0[:x]} specially */
+    {
+      t = make_word_list (make_word (dollar_vars[0]), params);
+      save = params = t;
+    }
+
+  for (i = start ? 1 : 0; params && i < start; i++)
+    params = params->next;
+  if (params == 0)
+    {
+      dispose_words (save);
+      return ((char *)NULL);
+    }
+  for (h = t = params; params && i < end; i++)
+    {
+      t = params;
+      params = params->next;
+    }
+
+  t->next = (WORD_LIST *)NULL;
+
+  ret = string_list_pos_params (string[0], h, quoted);
+
+  if (t != params)
+    t->next = params;
+
+  dispose_words (save);
+  return (ret);
+}
+
+/******************************************************************/
+/*                                                               */
+/*     Functions to expand strings to strings or WORD_LISTs      */
+/*                                                               */
+/******************************************************************/
+
+#if defined (PROCESS_SUBSTITUTION)
+#define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~')
+#else
+#define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
+#endif
+
+/* If there are any characters in STRING that require full expansion,
+   then call FUNC to expand STRING; otherwise just perform quote
+   removal if necessary.  This returns a new string. */
+static char *
+expand_string_if_necessary (string, quoted, func)
+     char *string;
+     int quoted;
+     EXPFUNC *func;
+{
+  WORD_LIST *list;
+  size_t slen;
+  int i, saw_quote;
+  char *ret;
+  DECLARE_MBSTATE;
+
+  /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
+  slen = (MB_CUR_MAX > 1) ? strlen (string) : 0;
+  i = saw_quote = 0;
+  while (string[i])
+    {
+      if (EXP_CHAR (string[i]))
+       break;
+      else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"')
+       saw_quote = 1;
+      ADVANCE_CHAR (string, slen, i);
+    }
+
+  if (string[i])
+    {
+      list = (*func) (string, quoted);
+      if (list)
+       {
+         ret = string_list (list);
+         dispose_words (list);
+       }
+      else
+       ret = (char *)NULL;
+    }
+  else if (saw_quote && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
+    ret = string_quote_removal (string, quoted);
+  else
+    ret = savestring (string);
+
+  return ret;
+}
+
+static inline char *
+expand_string_to_string_internal (string, quoted, func)
+     char *string;
+     int quoted;
+     EXPFUNC *func;
+{
+  WORD_LIST *list;
+  char *ret;
+
+  if (string == 0 || *string == '\0')
+    return ((char *)NULL);
+
+  list = (*func) (string, quoted);
+  if (list)
+    {
+      ret = string_list (list);
+      dispose_words (list);
+    }
+  else
+    ret = (char *)NULL;
+
+  return (ret);
+}
+
+char *
+expand_string_to_string (string, quoted)
+     char *string;
+     int quoted;
+{
+  return (expand_string_to_string_internal (string, quoted, expand_string));
+}
+
+char *
+expand_string_unsplit_to_string (string, quoted)
+     char *string;
+     int quoted;
+{
+  return (expand_string_to_string_internal (string, quoted, expand_string_unsplit));
+}
+
+char *
+expand_assignment_string_to_string (string, quoted)
+     char *string;
+     int quoted;
+{
+  return (expand_string_to_string_internal (string, quoted, expand_string_assignment));
+}
+
+char *
+expand_arith_string (string, quoted)
+     char *string;
+     int quoted;
+{
+  WORD_DESC td;
+  WORD_LIST *list, *tlist;
+  size_t slen;
+  int i, saw_quote;
+  char *ret;
+  DECLARE_MBSTATE;
+
+  /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
+  slen = (MB_CUR_MAX > 1) ? strlen (string) : 0;
+  i = saw_quote = 0;
+  while (string[i])
+    {
+      if (EXP_CHAR (string[i]))
+       break;
+      else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"')
+       saw_quote = 1;
+      ADVANCE_CHAR (string, slen, i);
+    }
+
+  if (string[i])
+    {
+      /* This is expanded version of expand_string_internal as it's called by
+        expand_string_leave_quoted  */
+      td.flags = W_NOPROCSUB;  /* don't want process substitution */
+      td.word = savestring (string);
+      list = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
+      /* This takes care of the calls from expand_string_leave_quoted and
+        expand_string */
+      if (list)
+       {
+         tlist = word_list_split (list);
+         dispose_words (list);
+         list = tlist;
+         if (list)
+           dequote_list (list);
+       }
+      /* This comes from expand_string_if_necessary */
+      if (list)
+       {
+         ret = string_list (list);
+         dispose_words (list);
+       }
+      else
+       ret = (char *)NULL;
+      FREE (td.word);
+    }
+  else if (saw_quote && (quoted & Q_ARITH))
+    ret = string_quote_removal (string, quoted);
+  else if (saw_quote && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
+    ret = string_quote_removal (string, quoted);
+  else
+    ret = savestring (string);
+
+  return ret;
+}
+
+#if defined (COND_COMMAND)
+/* Just remove backslashes in STRING.  Returns a new string. */
+char *
+remove_backslashes (string)
+     char *string;
+{
+  char *r, *ret, *s;
+
+  r = ret = (char *)xmalloc (strlen (string) + 1);
+  for (s = string; s && *s; )
+    {
+      if (*s == '\\')
+       s++;
+      if (*s == 0)
+       break;
+      *r++ = *s++;
+    }
+  *r = '\0';
+  return ret;
+}
+
+/* This needs better error handling. */
+/* Expand W for use as an argument to a unary or binary operator in a
+   [[...]] expression.  If SPECIAL is 1, this is the rhs argument
+   to the != or == operator, and should be treated as a pattern.  In
+   this case, we quote the string specially for the globbing code.  If
+   SPECIAL is 2, this is an rhs argument for the =~ operator, and should
+   be quoted appropriately for regcomp/regexec.  The caller is responsible
+   for removing the backslashes if the unquoted word is needed later. */   
+char *
+cond_expand_word (w, special)
+     WORD_DESC *w;
+     int special;
+{
+  char *r, *p;
+  WORD_LIST *l;
+  int qflags;
+
+  if (w->word == 0 || w->word[0] == '\0')
+    return ((char *)NULL);
+
+  expand_no_split_dollar_star = 1;
+  w->flags |= W_NOSPLIT2;
+  l = call_expand_word_internal (w, 0, 0, (int *)0, (int *)0);
+  expand_no_split_dollar_star = 0;
+  if (l)
+    {
+      if (special == 0)                        /* LHS */
+       {
+         dequote_list (l);
+         r = string_list (l);
+       }
+      else
+       {
+         /* Need to figure out whether or not we should call dequote_escapes
+            or a new dequote_ctlnul function here, and under what
+            circumstances. */
+         qflags = QGLOB_CVTNULL;
+         if (special == 2)
+           qflags |= QGLOB_REGEXP;
+         p = string_list (l);
+         r = quote_string_for_globbing (p, qflags);
+         free (p);
+       }
+      dispose_words (l);
+    }
+  else
+    r = (char *)NULL;
+
+  return r;
+}
+#endif
+
+/* Call expand_word_internal to expand W and handle error returns.
+   A convenience function for functions that don't want to handle
+   any errors or free any memory before aborting. */
+static WORD_LIST *
+call_expand_word_internal (w, q, i, c, e)
+     WORD_DESC *w;
+     int q, i, *c, *e;
+{
+  WORD_LIST *result;
+
+  result = expand_word_internal (w, q, i, c, e);
+  if (result == &expand_word_error || result == &expand_word_fatal)
+    {
+      /* By convention, each time this error is returned, w->word has
+        already been freed (it sometimes may not be in the fatal case,
+        but that doesn't result in a memory leak because we're going
+        to exit in most cases). */
+      w->word = (char *)NULL;
+      last_command_exit_value = EXECUTION_FAILURE;
+      exp_jump_to_top_level ((result == &expand_word_error) ? DISCARD : FORCE_EOF);
+      /* NOTREACHED */
+      return (NULL);
+    }
+  else
+    return (result);
+}
+
+/* Perform parameter expansion, command substitution, and arithmetic
+   expansion on STRING, as if it were a word.  Leave the result quoted.
+   Since this does not perform word splitting, it leaves quoted nulls
+   in the result.  */
+static WORD_LIST *
+expand_string_internal (string, quoted)
+     char *string;
+     int quoted;
+{
+  WORD_DESC td;
+  WORD_LIST *tresult;
+
+  if (string == 0 || *string == 0)
+    return ((WORD_LIST *)NULL);
+
+  td.flags = 0;
+  td.word = savestring (string);
+
+  tresult = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
+
+  FREE (td.word);
+  return (tresult);
+}
+
+/* Expand STRING by performing parameter expansion, command substitution,
+   and arithmetic expansion.  Dequote the resulting WORD_LIST before
+   returning it, but do not perform word splitting.  The call to
+   remove_quoted_nulls () is in here because word splitting normally
+   takes care of quote removal. */
+WORD_LIST *
+expand_string_unsplit (string, quoted)
+     char *string;
+     int quoted;
+{
+  WORD_LIST *value;
+
+  if (string == 0 || *string == '\0')
+    return ((WORD_LIST *)NULL);
+
+  expand_no_split_dollar_star = 1;
+  value = expand_string_internal (string, quoted);
+  expand_no_split_dollar_star = 0;
+
+  if (value)
+    {
+      if (value->word)
+       {
+         remove_quoted_nulls (value->word->word);
+         value->word->flags &= ~W_HASQUOTEDNULL;
+       }
+      dequote_list (value);
+    }
+  return (value);
+}
+
+/* Expand the rhs of an assignment statement */
+WORD_LIST *
+expand_string_assignment (string, quoted)
+     char *string;
+     int quoted;
+{
+  WORD_DESC td;
+  WORD_LIST *value;
+
+  if (string == 0 || *string == '\0')
+    return ((WORD_LIST *)NULL);
+
+  expand_no_split_dollar_star = 1;
+
+  td.flags = W_ASSIGNRHS;
+  td.word = savestring (string);
+  value = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
+  FREE (td.word);
+
+  expand_no_split_dollar_star = 0;
+
+  if (value)
+    {
+      if (value->word)
+       {
+         remove_quoted_nulls (value->word->word);
+         value->word->flags &= ~W_HASQUOTEDNULL;
+       }
+      dequote_list (value);
+    }
+  return (value);
+}
+
+
+/* Expand one of the PS? prompt strings. This is a sort of combination of
+   expand_string_unsplit and expand_string_internal, but returns the
+   passed string when an error occurs.  Might want to trap other calls
+   to jump_to_top_level here so we don't endlessly loop. */
+WORD_LIST *
+expand_prompt_string (string, quoted, wflags)
+     char *string;
+     int quoted;
+     int wflags;
+{
+  WORD_LIST *value;
+  WORD_DESC td;
+
+  if (string == 0 || *string == 0)
+    return ((WORD_LIST *)NULL);
+
+  td.flags = wflags;
+  td.word = savestring (string);
+
+  no_longjmp_on_fatal_error = 1;
+  value = expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
+  no_longjmp_on_fatal_error = 0;
+
+  if (value == &expand_word_error || value == &expand_word_fatal)
+    {
+      value = make_word_list (make_bare_word (string), (WORD_LIST *)NULL);
+      return value;
+    }
+  FREE (td.word);
+  if (value)
+    {
+      if (value->word)
+       {
+         remove_quoted_nulls (value->word->word);
+         value->word->flags &= ~W_HASQUOTEDNULL;
+       }
+      dequote_list (value);
+    }
+  return (value);
+}
+
+/* Expand STRING just as if you were expanding a word, but do not dequote
+   the resultant WORD_LIST.  This is called only from within this file,
+   and is used to correctly preserve quoted characters when expanding
+   things like ${1+"$@"}.  This does parameter expansion, command
+   substitution, arithmetic expansion, and word splitting. */
+static WORD_LIST *
+expand_string_leave_quoted (string, quoted)
+     char *string;
+     int quoted;
+{
+  WORD_LIST *tlist;
+  WORD_LIST *tresult;
+
+  if (string == 0 || *string == '\0')
+    return ((WORD_LIST *)NULL);
+
+  tlist = expand_string_internal (string, quoted);
+
+  if (tlist)
+    {
+      tresult = word_list_split (tlist);
+      dispose_words (tlist);
+      return (tresult);
+    }
+  return ((WORD_LIST *)NULL);
+}
+
+/* This does not perform word splitting or dequote the WORD_LIST
+   it returns. */
+static WORD_LIST *
+expand_string_for_rhs (string, quoted, dollar_at_p, has_dollar_at)
+     char *string;
+     int quoted, *dollar_at_p, *has_dollar_at;
+{
+  WORD_DESC td;
+  WORD_LIST *tresult;
+
+  if (string == 0 || *string == '\0')
+    return (WORD_LIST *)NULL;
+
+  expand_no_split_dollar_star = 1;
+  td.flags = W_NOSPLIT2;               /* no splitting, remove "" and '' */
+  td.word = string;
+  tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at);
+  expand_no_split_dollar_star = 0;
+
+  return (tresult);
+}
+
+/* Expand STRING just as if you were expanding a word.  This also returns
+   a list of words.  Note that filename globbing is *NOT* done for word
+   or string expansion, just when the shell is expanding a command.  This
+   does parameter expansion, command substitution, arithmetic expansion,
+   and word splitting.  Dequote the resultant WORD_LIST before returning. */
+WORD_LIST *
+expand_string (string, quoted)
+     char *string;
+     int quoted;
+{
+  WORD_LIST *result;
+
+  if (string == 0 || *string == '\0')
+    return ((WORD_LIST *)NULL);
+
+  result = expand_string_leave_quoted (string, quoted);
+  return (result ? dequote_list (result) : result);
+}
+
+/***************************************************
+ *                                                *
+ *     Functions to handle quoting chars          *
+ *                                                *
+ ***************************************************/
+
+/* Conventions:
+
+     A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
+     The parser passes CTLNUL as CTLESC CTLNUL. */
+
+/* Quote escape characters in string s, but no other characters.  This is
+   used to protect CTLESC and CTLNUL in variable values from the rest of
+   the word expansion process after the variable is expanded (word splitting
+   and filename generation).  If IFS is null, we quote spaces as well, just
+   in case we split on spaces later (in the case of unquoted $@, we will
+   eventually attempt to split the entire word on spaces).  Corresponding
+   code exists in dequote_escapes.  Even if we don't end up splitting on
+   spaces, quoting spaces is not a problem.  This should never be called on
+   a string that is quoted with single or double quotes or part of a here
+   document (effectively double-quoted). */
+char *
+quote_escapes (string)
+     char *string;
+{
+  register char *s, *t;
+  size_t slen;
+  char *result, *send;
+  int quote_spaces, skip_ctlesc, skip_ctlnul;
+  DECLARE_MBSTATE; 
+
+  slen = strlen (string);
+  send = string + slen;
+
+  quote_spaces = (ifs_value && *ifs_value == 0);
+
+  for (skip_ctlesc = skip_ctlnul = 0, s = ifs_value; s && *s; s++)
+    skip_ctlesc |= *s == CTLESC, skip_ctlnul |= *s == CTLNUL;
+
+  t = result = (char *)xmalloc ((slen * 2) + 1);
+  s = string;
+
+  while (*s)
+    {
+      if ((skip_ctlesc == 0 && *s == CTLESC) || (skip_ctlnul == 0 && *s == CTLNUL) || (quote_spaces && *s == ' '))
+       *t++ = CTLESC;
+      COPY_CHAR_P (t, s, send);
+    }
+  *t = '\0';
+
+  return (result);
+}
+
+static WORD_LIST *
+list_quote_escapes (list)
+     WORD_LIST *list;
+{
+  register WORD_LIST *w;
+  char *t;
+
+  for (w = list; w; w = w->next)
+    {
+      t = w->word->word;
+      w->word->word = quote_escapes (t);
+      free (t);
+    }
+  return list;
+}
+
+/* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
+
+   The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
+   This is necessary to make unquoted CTLESC and CTLNUL characters in the
+   data stream pass through properly.
+
+   We need to remove doubled CTLESC characters inside quoted strings before
+   quoting the entire string, so we do not double the number of CTLESC
+   characters.
+
+   Also used by parts of the pattern substitution code. */
+char *
+dequote_escapes (string)
+     char *string;
+{
+  register char *s, *t, *s1;
+  size_t slen;
+  char *result, *send;
+  int quote_spaces;
+  DECLARE_MBSTATE;
+
+  if (string == 0)
+    return string;
+
+  slen = strlen (string);
+  send = string + slen;
+
+  t = result = (char *)xmalloc (slen + 1);
+
+  if (strchr (string, CTLESC) == 0)
+    return (strcpy (result, string));
+
+  quote_spaces = (ifs_value && *ifs_value == 0);
+
+  s = string;
+  while (*s)
+    {
+      if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' ')))
+       {
+         s++;
+         if (*s == '\0')
+           break;
+       }
+      COPY_CHAR_P (t, s, send);
+    }
+  *t = '\0';
+
+  return result;
+}
+
+static WORD_LIST *
+list_dequote_escapes (list)
+     WORD_LIST *list;
+{
+  register WORD_LIST *w;
+  char *t;
+
+  for (w = list; w; w = w->next)
+    {
+      t = w->word->word;
+      w->word->word = dequote_escapes (t);
+      free (t);
+    }
+  return list;
+}
+
+/* Return a new string with the quoted representation of character C.
+   This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be
+   set in any resultant WORD_DESC where this value is the word. */
+static char *
+make_quoted_char (c)
+     int c;
+{
+  char *temp;
+
+  temp = (char *)xmalloc (3);
+  if (c == 0)
+    {
+      temp[0] = CTLNUL;
+      temp[1] = '\0';
+    }
+  else
+    {
+      temp[0] = CTLESC;
+      temp[1] = c;
+      temp[2] = '\0';
+    }
+  return (temp);
+}
+
+/* Quote STRING, returning a new string.  This turns "" into QUOTED_NULL, so
+   the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where
+   this value is the word. */
+char *
+quote_string (string)
+     char *string;
+{
+  register char *t;
+  size_t slen;
+  char *result, *send;
+
+  if (*string == 0)
+    {
+      result = (char *)xmalloc (2);
+      result[0] = CTLNUL;
+      result[1] = '\0';
+    }
+  else
+    {
+      DECLARE_MBSTATE;
+
+      slen = strlen (string);
+      send = string + slen;
+
+      result = (char *)xmalloc ((slen * 2) + 1);
+
+      for (t = result; string < send; )
+       {
+         *t++ = CTLESC;
+         COPY_CHAR_P (t, string, send);
+       }
+      *t = '\0';
+    }
+  return (result);
+}
+
+/* De-quote quoted characters in STRING. */
+char *
+dequote_string (string)
+     char *string;
+{
+  register char *s, *t;
+  size_t slen;
+  char *result, *send;
+  DECLARE_MBSTATE;
+
+  slen = strlen (string);
+
+  t = result = (char *)xmalloc (slen + 1);
+
+  if (QUOTED_NULL (string))
+    {
+      result[0] = '\0';
+      return (result);
+    }
+
+  /* If no character in the string can be quoted, don't bother examining
+     each character.  Just return a copy of the string passed to us. */
+  if (strchr (string, CTLESC) == NULL)
+    return (strcpy (result, string));
+
+  send = string + slen;
+  s = string;
+  while (*s)
+    {
+      if (*s == CTLESC)
+       {
+         s++;
+         if (*s == '\0')
+           break;
+       }
+      COPY_CHAR_P (t, s, send);
+    }
+
+  *t = '\0';
+  return (result);
+}
+
+/* Quote the entire WORD_LIST list. */
+static WORD_LIST *
+quote_list (list)
+     WORD_LIST *list;
+{
+  register WORD_LIST *w;
+  char *t;
+
+  for (w = list; w; w = w->next)
+    {
+      t = w->word->word;
+      w->word->word = quote_string (t);
+      if (*t == 0)
+       w->word->flags |= W_HASQUOTEDNULL;      /* XXX - turn on W_HASQUOTEDNULL here? */
+      w->word->flags |= W_QUOTED;
+      free (t);
+    }
+  return list;
+}
+
+/* De-quote quoted characters in each word in LIST. */
+WORD_LIST *
+dequote_list (list)
+     WORD_LIST *list;
+{
+  register char *s;
+  register WORD_LIST *tlist;
+
+  for (tlist = list; tlist; tlist = tlist->next)
+    {
+      s = dequote_string (tlist->word->word);
+      if (QUOTED_NULL (tlist->word->word))
+       tlist->word->flags &= ~W_HASQUOTEDNULL;
+      free (tlist->word->word);
+      tlist->word->word = s;
+    }
+  return list;
+}
+
+/* Remove CTLESC protecting a CTLESC or CTLNUL in place.  Return the passed
+   string. */
+char *
+remove_quoted_escapes (string)
+     char *string;
+{
+  char *t;
+
+  if (string)
+    {
+      t = dequote_escapes (string);
+      strcpy (string, t);
+      free (t);
+    }
+
+  return (string);
+}
+
+/* Perform quoted null character removal on STRING.  We don't allow any
+   quoted null characters in the middle or at the ends of strings because
+   of how expand_word_internal works.  remove_quoted_nulls () turns
+   STRING into an empty string iff it only consists of a quoted null,
+   and removes all unquoted CTLNUL characters. */
+char *
+remove_quoted_nulls (string)
+     char *string;
+{
+  register size_t slen;
+  register int i, j, prev_i;
+  DECLARE_MBSTATE;
+
+  if (strchr (string, CTLNUL) == 0)            /* XXX */
+    return string;                             /* XXX */
+
+  slen = strlen (string);
+  i = j = 0;
+
+  while (i < slen)
+    {
+      if (string[i] == CTLESC)
+       {
+         /* Old code had j++, but we cannot assume that i == j at this
+            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;
+         if (i == slen)
+           break;
+       }
+      else if (string[i] == CTLNUL)
+       {
+         i++;
+         continue;
+       }
+
+      prev_i = i;
+      ADVANCE_CHAR (string, slen, i);
+      if (j < prev_i)
+       {
+         do string[j++] = string[prev_i++]; while (prev_i < i);
+       }
+      else
+       j = i;
+    }
+  string[j] = '\0';
+
+  return (string);
+}
+
+/* Perform quoted null character removal on each element of LIST.
+   This modifies LIST. */
+void
+word_list_remove_quoted_nulls (list)
+     WORD_LIST *list;
+{
+  register WORD_LIST *t;
+
+  for (t = list; t; t = t->next)
+    {
+      remove_quoted_nulls (t->word->word);
+      t->word->flags &= ~W_HASQUOTEDNULL;
+    }
+}
+
+/* **************************************************************** */
+/*                                                                 */
+/*        Functions for Matching and Removing Patterns             */
+/*                                                                 */
+/* **************************************************************** */
+
+#if defined (HANDLE_MULTIBYTE)
+#if 0 /* Currently unused */
+static unsigned char *
+mb_getcharlens (string, len)
+     char *string;
+     int len;
+{
+  int i, offset, last;
+  unsigned char *ret;
+  char *p;
+  DECLARE_MBSTATE;
+
+  i = offset = 0;
+  last = 0;
+  ret = (unsigned char *)xmalloc (len);
+  memset (ret, 0, len);
+  while (string[last])
+    {
+      ADVANCE_CHAR (string, len, offset);
+      ret[last] = offset - last;
+      last = offset;
+    }
+  return ret;
+}
+#endif
+#endif
+
+/* Remove the portion of PARAM matched by PATTERN according to OP, where OP
+   can have one of 4 values:
+       RP_LONG_LEFT    remove longest matching portion at start of PARAM
+       RP_SHORT_LEFT   remove shortest matching portion at start of PARAM
+       RP_LONG_RIGHT   remove longest matching portion at end of PARAM
+       RP_SHORT_RIGHT  remove shortest matching portion at end of PARAM
+*/
+
+#define RP_LONG_LEFT   1
+#define RP_SHORT_LEFT  2
+#define RP_LONG_RIGHT  3
+#define RP_SHORT_RIGHT 4
+
+/* Returns its first argument if nothing matched; new memory otherwise */
+static char *
+remove_upattern (param, pattern, op)
+     char *param, *pattern;
+     int op;
+{
+  register int len;
+  register char *end;
+  register char *p, *ret, c;
+
+  len = STRLEN (param);
+  end = param + len;
+
+  switch (op)
+    {
+      case RP_LONG_LEFT:       /* remove longest match at start */
+       for (p = end; p >= param; p--)
+         {
+           c = *p; *p = '\0';
+           if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
+             {
+               *p = c;
+               return (savestring (p));
+             }
+           *p = c;
+
+         }
+       break;
+
+      case RP_SHORT_LEFT:      /* remove shortest match at start */
+       for (p = param; p <= end; p++)
+         {
+           c = *p; *p = '\0';
+           if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
+             {
+               *p = c;
+               return (savestring (p));
+             }
+           *p = c;
+         }
+       break;
+
+      case RP_LONG_RIGHT:      /* remove longest match at end */
+       for (p = param; p <= end; p++)
+         {
+           if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
+             {
+               c = *p; *p = '\0';
+               ret = savestring (param);
+               *p = c;
+               return (ret);
+             }
+         }
+       break;
+
+      case RP_SHORT_RIGHT:     /* remove shortest match at end */
+       for (p = end; p >= param; p--)
+         {
+           if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
+             {
+               c = *p; *p = '\0';
+               ret = savestring (param);
+               *p = c;
+               return (ret);
+             }
+         }
+       break;
+    }
+
+  return (param);      /* no match, return original string */
+}
+
+#if defined (HANDLE_MULTIBYTE)
+/* Returns its first argument if nothing matched; new memory otherwise */
+static wchar_t *
+remove_wpattern (wparam, wstrlen, wpattern, op)
+     wchar_t *wparam;
+     size_t wstrlen;
+     wchar_t *wpattern;
+     int op;
+{
+  wchar_t wc, *ret;
+  int n;
+
+  switch (op)
+    {
+      case RP_LONG_LEFT:       /* remove longest match at start */
+        for (n = wstrlen; n >= 0; n--)
+         {
+           wc = wparam[n]; wparam[n] = L'\0';
+           if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
+             {
+               wparam[n] = wc;
+               return (wcsdup (wparam + n));
+             }
+           wparam[n] = wc;
+         }
+       break;
+
+      case RP_SHORT_LEFT:      /* remove shortest match at start */
+       for (n = 0; n <= wstrlen; n++)
+         {
+           wc = wparam[n]; wparam[n] = L'\0';
+           if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
+             {
+               wparam[n] = wc;
+               return (wcsdup (wparam + n));
+             }
+           wparam[n] = wc;
+         }
+       break;
+
+      case RP_LONG_RIGHT:      /* remove longest match at end */
+        for (n = 0; n <= wstrlen; n++)
+         {
+           if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
+             {
+               wc = wparam[n]; wparam[n] = L'\0';
+               ret = wcsdup (wparam);
+               wparam[n] = wc;
+               return (ret);
+             }
+         }
+       break;
+
+      case RP_SHORT_RIGHT:     /* remove shortest match at end */
+       for (n = wstrlen; n >= 0; n--)
+         {
+           if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
+             {
+               wc = wparam[n]; wparam[n] = L'\0';
+               ret = wcsdup (wparam);
+               wparam[n] = wc;
+               return (ret);
+             }
+         }
+       break;
+    }
+
+  return (wparam);     /* no match, return original string */
+}
+#endif /* HANDLE_MULTIBYTE */
+
+static char *
+remove_pattern (param, pattern, op)
+     char *param, *pattern;
+     int op;
+{
+  char *xret;
+
+  if (param == NULL)
+    return (param);
+  if (*param == '\0' || pattern == NULL || *pattern == '\0')   /* minor optimization */
+    return (savestring (param));
+
+#if defined (HANDLE_MULTIBYTE)
+  if (MB_CUR_MAX > 1)
+    {
+      wchar_t *ret, *oret;
+      size_t n;
+      wchar_t *wparam, *wpattern;
+      mbstate_t ps;
+
+      n = xdupmbstowcs (&wpattern, NULL, pattern);
+      if (n == (size_t)-1)
+       {
+         xret = remove_upattern (param, pattern, op);
+         return ((xret == param) ? savestring (param) : xret);
+       }
+      n = xdupmbstowcs (&wparam, NULL, param);
+
+      if (n == (size_t)-1)
+       {
+         free (wpattern);
+         xret = remove_upattern (param, pattern, op);
+         return ((xret == param) ? savestring (param) : xret);
+       }
+      oret = ret = remove_wpattern (wparam, n, wpattern, op);
+      /* Don't bother to convert wparam back to multibyte string if nothing
+        matched; just return copy of original string */
+      if (ret == wparam)
+        {
+          free (wparam);
+          free (wpattern);
+          return (savestring (param));
+        }
+
+      free (wparam);
+      free (wpattern);
+
+      n = strlen (param);
+      xret = (char *)xmalloc (n + 1);
+      memset (&ps, '\0', sizeof (mbstate_t));
+      n = wcsrtombs (xret, (const wchar_t **)&ret, n, &ps);
+      xret[n] = '\0';          /* just to make sure */
+      free (oret);
+      return xret;      
+    }
+  else
+#endif
+    {
+      xret = remove_upattern (param, pattern, op);
+      return ((xret == param) ? savestring (param) : xret);
+    }
+}
+
+/* Match PAT anywhere in STRING and return the match boundaries.
+   This returns 1 in case of a successful match, 0 otherwise.  SP
+   and EP are pointers into the string where the match begins and
+   ends, respectively.  MTYPE controls what kind of match is attempted.
+   MATCH_BEG and MATCH_END anchor the match at the beginning and end
+   of the string, respectively.  The longest match is returned. */
+static int
+match_upattern (string, pat, mtype, sp, ep)
+     char *string, *pat;
+     int mtype;
+     char **sp, **ep;
+{
+  int c, len, mlen;
+  register char *p, *p1, *npat;
+  char *end;
+  int n1;
+
+  /* If the pattern doesn't match anywhere in the string, go ahead and
+     short-circuit right away.  A minor optimization, saves a bunch of
+     unnecessary calls to strmatch (up to N calls for a string of N
+     characters) if the match is unsuccessful.  To preserve the semantics
+     of the substring matches below, we make sure that the pattern has
+     `*' as first and last character, making a new pattern if necessary. */
+  /* XXX - check this later if I ever implement `**' with special meaning,
+     since this will potentially result in `**' at the beginning or end */
+  len = STRLEN (pat);
+  if (pat[0] != '*' || (pat[0] == '*' && pat[1] == LPAREN && extended_glob) || pat[len - 1] != '*')
+    {
+      p = npat = (char *)xmalloc (len + 3);
+      p1 = pat;
+      if (*p1 != '*' || (*p1 == '*' && p1[1] == LPAREN && extended_glob))
+       *p++ = '*';
+      while (*p1)
+       *p++ = *p1++;
+      if (p1[-1] != '*' || p[-2] == '\\')
+       *p++ = '*';
+      *p = '\0';
+    }
+  else
+    npat = pat;
+  c = strmatch (npat, string, FNMATCH_EXTFLAG | FNMATCH_IGNCASE);
+  if (npat != pat)
+    free (npat);
+  if (c == FNM_NOMATCH)
+    return (0);
+
+  len = STRLEN (string);
+  end = string + len;
+
+  mlen = umatchlen (pat, len);
+
+  switch (mtype)
+    {
+    case MATCH_ANY:
+      for (p = string; p <= end; p++)
+       {
+         if (match_pattern_char (pat, p, FNMATCH_IGNCASE))
+           {
+             p1 = (mlen == -1) ? end : p + mlen;
+             /* p1 - p = length of portion of string to be considered
+                p = current position in string
+                mlen = number of characters consumed by match (-1 for entire string)
+                end = end of string
+                we want to break immediately if the potential match len
+                is greater than the number of characters remaining in the
+                string
+             */
+             if (p1 > end)
+               break;
+             for ( ; p1 >= p; p1--)
+               {
+                 c = *p1; *p1 = '\0';
+                 if (strmatch (pat, p, FNMATCH_EXTFLAG | FNMATCH_IGNCASE) == 0)
+                   {
+                     *p1 = c;
+                     *sp = p;
+                     *ep = p1;
+                     return 1;
+                   }
+                 *p1 = c;
+#if 1
+                 /* If MLEN != -1, we have a fixed length pattern. */
+                 if (mlen != -1)
+                   break;
+#endif
+               }
+           }
+       }
+
+      return (0);
+
+    case MATCH_BEG:
+      if (match_pattern_char (pat, string, FNMATCH_IGNCASE) == 0)
+       return (0);
+
+      for (p = (mlen == -1) ? end : string + mlen; p >= string; p--)
+       {
+         c = *p; *p = '\0';
+         if (strmatch (pat, string, FNMATCH_EXTFLAG | FNMATCH_IGNCASE) == 0)
+           {
+             *p = c;
+             *sp = string;
+             *ep = p;
+             return 1;
+           }
+         *p = c;
+         /* If MLEN != -1, we have a fixed length pattern. */
+         if (mlen != -1)
+           break;
+       }
+
+      return (0);
+
+    case MATCH_END:
+      for (p = end - ((mlen == -1) ? len : mlen); p <= end; p++)
+       {
+         if (strmatch (pat, p, FNMATCH_EXTFLAG | FNMATCH_IGNCASE) == 0)
+           {
+             *sp = p;
+             *ep = end;
+             return 1;
+           }
+         /* If MLEN != -1, we have a fixed length pattern. */
+         if (mlen != -1)
+           break;
+       }
+
+      return (0);
+    }
+
+  return (0);
+}
+
+#if defined (HANDLE_MULTIBYTE)
+
+#define WFOLD(c) (match_ignore_case && iswupper (c) ? towlower (c) : (c))
+
+/* Match WPAT anywhere in WSTRING and return the match boundaries.
+   This returns 1 in case of a successful match, 0 otherwise.  Wide
+   character version. */
+static int
+match_wpattern (wstring, indices, wstrlen, wpat, mtype, sp, ep)
+     wchar_t *wstring;
+     char **indices;
+     size_t wstrlen;
+     wchar_t *wpat;
+     int mtype;
+     char **sp, **ep;
+{
+  wchar_t wc, *wp, *nwpat, *wp1;
+  size_t len;
+  int mlen;
+  int n, n1, n2, simple;
+
+  simple = (wpat[0] != L'\\' && wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'[');
+#if defined (EXTENDED_GLOB)
+  if (extended_glob)
+    simple &= (wpat[1] != L'(' || (wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'+' && wpat[0] != L'!' && wpat[0] != L'@')); /*)*/
+#endif
+
+  /* If the pattern doesn't match anywhere in the string, go ahead and
+     short-circuit right away.  A minor optimization, saves a bunch of
+     unnecessary calls to strmatch (up to N calls for a string of N
+     characters) if the match is unsuccessful.  To preserve the semantics
+     of the substring matches below, we make sure that the pattern has
+     `*' as first and last character, making a new pattern if necessary. */
+  len = wcslen (wpat);
+  if (wpat[0] != L'*' || (wpat[0] == L'*' && wpat[1] == WLPAREN && extended_glob) || wpat[len - 1] != L'*')
+    {
+      wp = nwpat = (wchar_t *)xmalloc ((len + 3) * sizeof (wchar_t));
+      wp1 = wpat;
+      if (*wp1 != L'*' || (*wp1 == '*' && wp1[1] == WLPAREN && extended_glob))
+       *wp++ = L'*';
+      while (*wp1 != L'\0')
+       *wp++ = *wp1++;
+      if (wp1[-1] != L'*' || wp1[-2] == L'\\')
+        *wp++ = L'*';
+      *wp = '\0';
+    }
+  else
+    nwpat = wpat;
+  len = wcsmatch (nwpat, wstring, FNMATCH_EXTFLAG | FNMATCH_IGNCASE);
+  if (nwpat != wpat)
+    free (nwpat);
+  if (len == FNM_NOMATCH)
+    return (0);
+
+  mlen = wmatchlen (wpat, wstrlen);
+
+/* itrace("wmatchlen (%ls) -> %d", wpat, mlen); */
+  switch (mtype)
+    {
+    case MATCH_ANY:
+      for (n = 0; n <= wstrlen; n++)
+       {
+         n2 = simple ? (WFOLD(*wpat) == WFOLD(wstring[n])) : match_pattern_wchar (wpat, wstring + n, FNMATCH_IGNCASE);
+         if (n2)
+           {
+             n1 = (mlen == -1) ? wstrlen : n + mlen;
+             if (n1 > wstrlen)
+               break;
+
+             for ( ; n1 >= n; n1--)
+               {
+                 wc = wstring[n1]; wstring[n1] = L'\0';
+                 if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG | FNMATCH_IGNCASE) == 0)
+                   {
+                     wstring[n1] = wc;
+                     *sp = indices[n];
+                     *ep = indices[n1];
+                     return 1;
+                   }
+                 wstring[n1] = wc;
+                 /* If MLEN != -1, we have a fixed length pattern. */
+                 if (mlen != -1)
+                   break;
+               }
+           }
+       }
+
+      return (0);
+
+    case MATCH_BEG:
+      if (match_pattern_wchar (wpat, wstring, FNMATCH_IGNCASE) == 0)
+       return (0);
+
+      for (n = (mlen == -1) ? wstrlen : mlen; n >= 0; n--)
+       {
+         wc = wstring[n]; wstring[n] = L'\0';
+         if (wcsmatch (wpat, wstring, FNMATCH_EXTFLAG | FNMATCH_IGNCASE) == 0)
+           {
+             wstring[n] = wc;
+             *sp = indices[0];
+             *ep = indices[n];
+             return 1;
+           }
+         wstring[n] = wc;
+         /* If MLEN != -1, we have a fixed length pattern. */
+         if (mlen != -1)
+           break;
+       }
+
+      return (0);
+
+    case MATCH_END:
+      for (n = wstrlen - ((mlen == -1) ? wstrlen : mlen); n <= wstrlen; n++)
+       {
+         if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG | FNMATCH_IGNCASE) == 0)
+           {
+             *sp = indices[n];
+             *ep = indices[wstrlen];
+             return 1;
+           }
+         /* If MLEN != -1, we have a fixed length pattern. */
+         if (mlen != -1)
+           break;
+       }
+
+      return (0);
+    }
+
+  return (0);
+}
+#undef WFOLD
+#endif /* HANDLE_MULTIBYTE */
+
+static int
+match_pattern (string, pat, mtype, sp, ep)
+     char *string, *pat;
+     int mtype;
+     char **sp, **ep;
+{
+#if defined (HANDLE_MULTIBYTE)
+  int ret;
+  size_t n;
+  wchar_t *wstring, *wpat;
+  char **indices;
+  size_t slen, plen, mslen, mplen;
+#endif
+
+  if (string == 0 || *string == 0 || pat == 0 || *pat == 0)
+    return (0);
+
+#if defined (HANDLE_MULTIBYTE)
+  if (MB_CUR_MAX > 1)
+    {
+      if (mbsmbchar (string) == 0 && mbsmbchar (pat) == 0)
+        return (match_upattern (string, pat, mtype, sp, ep));
+
+      n = xdupmbstowcs (&wpat, NULL, pat);
+      if (n == (size_t)-1)
+       return (match_upattern (string, pat, mtype, sp, ep));
+      n = xdupmbstowcs (&wstring, &indices, string);
+      if (n == (size_t)-1)
+       {
+         free (wpat);
+         return (match_upattern (string, pat, mtype, sp, ep));
+       }
+      ret = match_wpattern (wstring, indices, n, wpat, mtype, sp, ep);
+
+      free (wpat);
+      free (wstring);
+      free (indices);
+
+      return (ret);
+    }
+  else
+#endif
+    return (match_upattern (string, pat, mtype, sp, ep));
+}
+
+static int
+getpatspec (c, value)
+     int c;
+     char *value;
+{
+  if (c == '#')
+    return ((*value == '#') ? RP_LONG_LEFT : RP_SHORT_LEFT);
+  else /* c == '%' */
+    return ((*value == '%') ? RP_LONG_RIGHT : RP_SHORT_RIGHT);
+}
+
+/* Posix.2 says that the WORD should be run through tilde expansion,
+   parameter expansion, command substitution and arithmetic expansion.
+   This leaves the result quoted, so quote_string_for_globbing () has
+   to be called to fix it up for strmatch ().  If QUOTED is non-zero,
+   it means that the entire expression was enclosed in double quotes.
+   This means that quoting characters in the pattern do not make any
+   special pattern characters quoted.  For example, the `*' in the
+   following retains its special meaning: "${foo#'*'}". */
+static char *
+getpattern (value, quoted, expandpat)
+     char *value;
+     int quoted, expandpat;
+{
+  char *pat, *tword;
+  WORD_LIST *l;
+#if 0
+  int i;
+#endif
+  /* There is a problem here:  how to handle single or double quotes in the
+     pattern string when the whole expression is between double quotes?
+     POSIX.2 says that enclosing double quotes do not cause the pattern to
+     be quoted, but does that leave us a problem with @ and array[@] and their
+     expansions inside a pattern? */
+#if 0
+  if (expandpat && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *tword)
+    {
+      i = 0;
+      pat = string_extract_double_quoted (tword, &i, 1);
+      free (tword);
+      tword = pat;
+    }
+#endif
+
+  /* expand_string_for_rhs () leaves WORD quoted and does not perform
+     word splitting. */
+  l = *value ? expand_string_for_rhs (value,
+                                     (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? Q_PATQUOTE : quoted,
+                                     (int *)NULL, (int *)NULL)
+            : (WORD_LIST *)0;
+  pat = string_list (l);
+  dispose_words (l);
+  if (pat)
+    {
+      tword = quote_string_for_globbing (pat, QGLOB_CVTNULL);
+      free (pat);
+      pat = tword;
+    }
+  return (pat);
+}
+
+#if 0
+/* Handle removing a pattern from a string as a result of ${name%[%]value}
+   or ${name#[#]value}. */
+static char *
+variable_remove_pattern (value, pattern, patspec, quoted)
+     char *value, *pattern;
+     int patspec, quoted;
+{
+  char *tword;
+
+  tword = remove_pattern (value, pattern, patspec);
+
+  return (tword);
+}
+#endif
+
+static char *
+list_remove_pattern (list, pattern, patspec, itype, quoted)
+     WORD_LIST *list;
+     char *pattern;
+     int patspec, itype, quoted;
+{
+  WORD_LIST *new, *l;
+  WORD_DESC *w;
+  char *tword;
+
+  for (new = (WORD_LIST *)NULL, l = list; l; l = l->next)
+    {
+      tword = remove_pattern (l->word->word, pattern, patspec);
+      w = alloc_word_desc ();
+      w->word = tword ? tword : savestring ("");
+      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_remove_pattern (itype, pattern, patspec, quoted)
+     int itype;
+     char *pattern;
+     int patspec, quoted;
+{
+  char *ret;
+  WORD_LIST *list;
+
+  list = list_rest_of_args ();
+  if (list == 0)
+    return ((char *)NULL);
+  ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
+  dispose_words (list);
+  return (ret);
+}
+
+#if defined (ARRAY_VARS)
+static char *
+array_remove_pattern (var, pattern, patspec, varname, quoted)
+     SHELL_VAR *var;
+     char *pattern;
+     int patspec;
+     char *varname;    /* so we can figure out how it's indexed */
+     int quoted;
+{
+  ARRAY *a;
+  HASH_TABLE *h;
+  int itype;
+  char *ret;
+  WORD_LIST *list;
+  SHELL_VAR *v;
+
+  /* compute itype from varname here */
+  v = array_variable_part (varname, &ret, 0);
+
+  /* XXX */
+  if (v && invisible_p (v))
+    return ((char *)NULL);
+
+  itype = ret[0];
+
+  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_remove_pattern (list, pattern, patspec, itype, quoted);
+  dispose_words (list);
+
+  return ret;
+}
+#endif /* ARRAY_VARS */
+
+static char *
+parameter_brace_remove_pattern (varname, value, ind, patstr, rtype, quoted, flags)
+     char *varname, *value;
+     int ind;
+     char *patstr;
+     int rtype, quoted, flags;
+{
+  int vtype, patspec, starsub;
+  char *temp1, *val, *pattern;
+  SHELL_VAR *v;
+
+  if (value == 0)
+    return ((char *)NULL);
+
+  this_command_name = varname;
+
+  vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
+  if (vtype == -1)
+    return ((char *)NULL);
+
+  starsub = vtype & VT_STARSUB;
+  vtype &= ~VT_STARSUB;
+
+  patspec = getpatspec (rtype, patstr);
+  if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
+    patstr++;
+
+  /* Need to pass getpattern newly-allocated memory in case of expansion --
+     the expansion code will free the passed string on an error. */
+  temp1 = savestring (patstr);
+  pattern = getpattern (temp1, quoted, 1);
+  free (temp1);
+
+  temp1 = (char *)NULL;                /* shut up gcc */
+  switch (vtype)
+    {
+    case VT_VARIABLE:
+    case VT_ARRAYMEMBER:
+      temp1 = remove_pattern (val, pattern, patspec);
+      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_remove_pattern (v, pattern, patspec, 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_remove_pattern (varname[0], pattern, patspec, quoted);
+      if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
+       {
+         val = quote_escapes (temp1);
+         free (temp1);
+         temp1 = val;
+       }
+      break;
+    }
+
+  FREE (pattern);
+  return temp1;
+}    
+
+static char *
+string_var_assignment (v, s)
+     SHELL_VAR *v;
+     char *s;
+{
+  char flags[MAX_ATTRIBUTES], *ret, *val;
+  int i;
+
+  val = sh_quote_reusable (s, 0);
+  i = var_attribute_string (v, 0, flags);
+  ret = (char *)xmalloc (i + strlen (val) + strlen (v->name) + 16);
+  if (i > 0)
+    sprintf (ret, "declare -%s %s=%s", flags, v->name, val);
+  else
+    sprintf (ret, "%s=%s", v->name, val);
+  free (val);
+  return ret;
+}
+
+#if defined (ARRAY_VARS)
+static char *
+array_var_assignment (v, itype, quoted)
+     SHELL_VAR *v;
+     int itype, quoted;
+{
+  char *ret, *val, flags[MAX_ATTRIBUTES];
+  int i;
+
+  if (v == 0)
+    return (char *)NULL;
+  val = array_p (v) ? array_to_assign (array_cell (v), 0)
+                   : assoc_to_assign (assoc_cell (v), 0);
+  if (val == 0)
+    {
+      val = (char *)xmalloc (3);
+      val[0] = '(';
+      val[1] = ')';
+      val[2] = 0;
+    }
+  i = var_attribute_string (v, 0, flags);
+  ret = (char *)xmalloc (i + strlen (val) + strlen (v->name) + 16);
+  sprintf (ret, "declare -%s %s=%s", flags, v->name, val);
+  free (val);
+  return ret;
+}
+#endif
+
+static char *
+pos_params_assignment (list, itype, quoted)
+     WORD_LIST *list;
+     int itype;
+     int quoted;
+{
+  char *temp, *ret;
+
+  /* first, we transform the list to quote each word. */
+  temp = list_transform ('Q', (SHELL_VAR *)0, list, itype, quoted);
+  ret = (char *)xmalloc (strlen (temp) + 8);
+  strcpy (ret, "set -- ");
+  strcpy (ret + 7, temp);
+  free (temp);
+  return ret;
+}
+
+static char *
+string_transform (xc, v, s)
+     int xc;
+     SHELL_VAR *v;
+     char *s;
+{
+  char *ret, flags[MAX_ATTRIBUTES];
+  int i;
+
+  if (((xc == 'A' || xc == 'a') && v == 0) || (xc != 'a' && s == 0))
+    return (char *)NULL;
+
+  switch (xc)
+    {
+      /* Transformations that interrogate the variable */
+      case 'a':
+       i = var_attribute_string (v, 0, flags);
+       ret = (i > 0) ? savestring (flags) : (char *)NULL;
+       break;
+      case 'A':
+       ret = string_var_assignment (v, s);
+       break;
+      /* Transformations that modify the variable's value */
+      case 'E':
+       ret = ansiexpand (s, 0, strlen (s), (int *)0);
+       break;
+      case 'P':
+       ret = decode_prompt_string (s);
+       break;
+      case 'Q':
+       ret = sh_quote_reusable (s, 0);
+       break;
+      default:
+       ret = (char *)NULL;
+       break;
+    }
+  return ret;
+}
+
+static char *
+list_transform (xc, v, list, itype, quoted)
+     int xc;
+     SHELL_VAR *v;
+     WORD_LIST *list;
+     int itype, quoted;
+{
+  WORD_LIST *new, *l;
+  WORD_DESC *w;
+  char *tword;
+
+  for (new = (WORD_LIST *)NULL, l = list; l; l = l->next)
+    {
+      tword = string_transform (xc, v, l->word->word);
+      w = alloc_word_desc ();
+      w->word = tword ? tword : savestring ("");       /* XXX */
+      new = make_word_list (w, new);
+    }
+
+  l = REVERSE_LIST (new, WORD_LIST *);
+  tword = string_list_pos_params (itype, l, quoted);
+  dispose_words (l);
+
+  return (tword);
+}
+
+static char *
+parameter_list_transform (xc, itype, quoted)
+     int xc;
+     int itype;
+     int quoted;
+{
+  char *ret;
+  WORD_LIST *list;
+
+  list = list_rest_of_args ();
+  if (list == 0)
+    return ((char *)NULL);
+  if (xc == 'A')
+    return (pos_params_assignment (list, itype, quoted));
+  ret = list_transform (xc, (SHELL_VAR *)0, list, itype, quoted);
+  dispose_words (list);
+  return (ret);
+}
+
+#if defined (ARRAY_VARS)
+static char *
+array_transform (xc, var, varname, quoted)
+     int xc;
+     SHELL_VAR *var;
+     char *varname;    /* so we can figure out how it's indexed */
+     int quoted;
+{
+  ARRAY *a;
+  HASH_TABLE *h;
+  int itype;
+  char *ret;
+  WORD_LIST *list;
+  SHELL_VAR *v;
+
+  /* compute itype from varname here */
+  v = array_variable_part (varname, &ret, 0);
+
+  /* XXX */
+  if (v && invisible_p (v))
+    return ((char *)NULL);
+
+  itype = ret[0];
+
+  if (xc == 'A')
+    return (array_var_assignment (v, itype, quoted));
+
+  a = (v && array_p (v)) ? array_cell (v) : 0;
+  h = (v && assoc_p (v)) ? assoc_cell (v) : 0;
+  
+  list = a ? array_to_word_list (a) : (h ? assoc_to_word_list (h) : 0);
+  if (list == 0)
+   return ((char *)NULL);
+  ret = list_transform (xc, v, list, itype, quoted);
+  dispose_words (list);
+
+  return ret;
+}
+#endif /* ARRAY_VARS */
+
+static char *
+parameter_brace_transform (varname, value, ind, xform, rtype, quoted, flags)
+     char *varname, *value;
+     int ind;
+     char *xform;
+     int rtype, quoted, flags;
+{
+  int vtype, xc;
+  char *temp1, *val;
+  SHELL_VAR *v;
+
+  xc = xform[0];
+  if (value == 0 && xc != 'A' && xc != 'a')
+    return ((char *)NULL);
+
+  this_command_name = varname;
+
+  vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
+  if (vtype == -1)
+    return ((char *)NULL);
+
+  /* check for valid values of xc */
+  switch (xc)
+    {
+    case 'a':          /* expand to a string with just attributes */
+    case 'A':          /* expand as an assignment statement with attributes */
+    case 'E':          /* expand like $'...' */
+    case 'P':          /* expand like prompt string */
+    case 'Q':          /* quote reusably */
+      break;
+    default:
+      return &expand_param_error;
+    }
+
+  temp1 = (char *)NULL;                /* shut up gcc */
+  switch (vtype & ~VT_STARSUB)
+    {
+    case VT_VARIABLE:
+    case VT_ARRAYMEMBER:
+      temp1 = string_transform (xc, v, val);
+      if (vtype == VT_VARIABLE)
+       FREE (val);
+      if (temp1)
+       {
+         val = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
+                       ? quote_string (temp1)
+                       : quote_escapes (temp1);
+         free (temp1);
+         temp1 = val;
+       }
+      break;
+#if defined (ARRAY_VARS)
+    case VT_ARRAYVAR:
+      temp1 = array_transform (xc, v, varname, quoted);
+      if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
+       {
+         val = quote_escapes (temp1);
+         free (temp1);
+         temp1 = val;
+       }
+      break;
+#endif
+    case VT_POSPARMS:
+      temp1 = parameter_list_transform (xc, varname[0], quoted);
+      if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
+       {
+         val = quote_escapes (temp1);
+         free (temp1);
+         temp1 = val;
+       }
+      break;
+    }
+
+  return temp1;
+}
+
+/*******************************************
+ *                                        *
+ *     Functions to expand WORD_DESCs     *
+ *                                        *
+ *******************************************/
+
+/* 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)
+
+/*****************************************************************/
+/*                                                              */
+/*                 Hacking Process Substitution                 */
+/*                                                              */
+/*****************************************************************/
+
+#if !defined (HAVE_DEV_FD)
+/* Named pipes must be removed explicitly with `unlink'.  This keeps a list
+   of FIFOs the shell has open.  unlink_fifo_list will walk the list and
+   unlink all of them. add_fifo_list adds the name of an open FIFO to the
+   list.  NFIFO is a count of the number of FIFOs in the list. */
+#define FIFO_INCR 20
+
+struct temp_fifo {
+  char *file;
+  pid_t proc;
+};
+
+static struct temp_fifo *fifo_list = (struct temp_fifo *)NULL;
+static int nfifo;
+static int fifo_list_size;
+
+void
+clear_fifo_list ()
+{
+}
+
+char *
+copy_fifo_list (sizep)
+     int *sizep;
+{
+  if (sizep)
+    *sizep = 0;
+  return (char *)NULL;
+}
+
+static void
+add_fifo_list (pathname)
+     char *pathname;
+{
+  if (nfifo >= fifo_list_size - 1)
+    {
+      fifo_list_size += FIFO_INCR;
+      fifo_list = (struct temp_fifo *)xrealloc (fifo_list,
+                               fifo_list_size * sizeof (struct temp_fifo));
+    }
+
+  fifo_list[nfifo].file = savestring (pathname);
+  nfifo++;
+}
+
+void
+unlink_fifo (i)
+     int i;
+{
+  if ((fifo_list[i].proc == -1) || (kill(fifo_list[i].proc, 0) == -1))
+    {
+      unlink (fifo_list[i].file);
+      free (fifo_list[i].file);
+      fifo_list[i].file = (char *)NULL;
+      fifo_list[i].proc = -1;
+    }
+}
+
+void
+unlink_fifo_list ()
+{
+  int saved, i, j;
+
+  if (nfifo == 0)
+    return;
+
+  for (i = saved = 0; i < nfifo; i++)
+    {
+      if ((fifo_list[i].proc == -1) || (kill(fifo_list[i].proc, 0) == -1))
+       {
+         unlink (fifo_list[i].file);
+         free (fifo_list[i].file);
+         fifo_list[i].file = (char *)NULL;
+         fifo_list[i].proc = -1;
+       }
+      else
+       saved++;
+    }
+
+  /* If we didn't remove some of the FIFOs, compact the list. */
+  if (saved)
+    {
+      for (i = j = 0; i < nfifo; i++)
+       if (fifo_list[i].file)
+         {
+           fifo_list[j].file = fifo_list[i].file;
+           fifo_list[j].proc = fifo_list[i].proc;
+           j++;
+         }
+      nfifo = j;
+    }
+  else
+    nfifo = 0;
+}
+
+/* Take LIST, which is a bitmap denoting active FIFOs in fifo_list
+   from some point in the past, and close all open FIFOs in fifo_list
+   that are not marked as active in LIST.  If LIST is NULL, close
+   everything in fifo_list. LSIZE is the number of elements in LIST, in
+   case it's larger than fifo_list_size (size of fifo_list). */
+void
+close_new_fifos (list, lsize)
+     char *list;
+     int lsize;
+{
+  int i;
+
+  if (list == 0)
+    {
+      unlink_fifo_list ();
+      return;
+    }
+
+  for (i = 0; i < lsize; i++)
+    if (list[i] == 0 && i < fifo_list_size && fifo_list[i].proc != -1)
+      unlink_fifo (i);
+
+  for (i = lsize; i < fifo_list_size; i++)
+    unlink_fifo (i);  
+}
+
+int
+fifos_pending ()
+{
+  return nfifo;
+}
+
+int
+num_fifos ()
+{
+  return nfifo;
+}
+
+static char *
+make_named_pipe ()
+{
+  char *tname;
+
+  tname = sh_mktmpname ("sh-np", MT_USERANDOM|MT_USETMPDIR);
+  if (mkfifo (tname, 0600) < 0)
+    {
+      free (tname);
+      return ((char *)NULL);
+    }
+
+  add_fifo_list (tname);
+  return (tname);
+}
+
+#else /* HAVE_DEV_FD */
+
+/* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
+   has open to children.  NFDS is a count of the number of bits currently
+   set in DEV_FD_LIST.  TOTFDS is a count of the highest possible number
+   of open files. */
+static char *dev_fd_list = (char *)NULL;
+static int nfds;
+static int totfds;     /* The highest possible number of open files. */
+
+void
+clear_fifo (i)
+     int i;
+{
+  if (dev_fd_list[i])
+    {
+      dev_fd_list[i] = 0;
+      nfds--;
+    }
+}
+
+void
+clear_fifo_list ()
+{
+  register int i;
+
+  if (nfds == 0)
+    return;
+
+  for (i = 0; nfds && i < totfds; i++)
+    clear_fifo (i);
+
+  nfds = 0;
+}
+
+char *
+copy_fifo_list (sizep)
+     int *sizep;
+{
+  char *ret;
+
+  if (nfds == 0 || totfds == 0)
+    {
+      if (sizep)
+       *sizep = 0;
+      return (char *)NULL;
+    }
+
+  if (sizep)
+    *sizep = totfds;
+  ret = (char *)xmalloc (totfds);
+  return (memcpy (ret, dev_fd_list, totfds));
+}
+
+static void
+add_fifo_list (fd)
+     int fd;
+{
+  if (dev_fd_list == 0 || fd >= totfds)
+    {
+      int ofds;
+
+      ofds = totfds;
+      totfds = getdtablesize ();
+      if (totfds < 0 || totfds > 256)
+       totfds = 256;
+      if (fd >= totfds)
+       totfds = fd + 2;
+
+      dev_fd_list = (char *)xrealloc (dev_fd_list, totfds);
+      memset (dev_fd_list + ofds, '\0', totfds - ofds);
+    }
+
+  dev_fd_list[fd] = 1;
+  nfds++;
+}
+
+int
+fifos_pending ()
+{
+  return 0;    /* used for cleanup; not needed with /dev/fd */
+}
+
+int
+num_fifos ()
+{
+  return nfds;
+}
+
+void
+unlink_fifo (fd)
+     int fd;
+{
+  if (dev_fd_list[fd])
+    {
+      close (fd);
+      dev_fd_list[fd] = 0;
+      nfds--;
+    }
+}
+
+void
+unlink_fifo_list ()
+{
+  register int i;
+
+  if (nfds == 0)
+    return;
+
+  for (i = 0; nfds && i < totfds; i++)
+    unlink_fifo (i);
+
+  nfds = 0;
+}
+
+/* Take LIST, which is a snapshot copy of dev_fd_list from some point in
+   the past, and close all open fds in dev_fd_list that are not marked
+   as open in LIST.  If LIST is NULL, close everything in dev_fd_list.
+   LSIZE is the number of elements in LIST, in case it's larger than
+   totfds (size of dev_fd_list). */
+void
+close_new_fifos (list, lsize)
+     char *list;
+     int lsize;
+{
+  int i;
+
+  if (list == 0)
+    {
+      unlink_fifo_list ();
+      return;
+    }
+
+  for (i = 0; i < lsize; i++)
+    if (list[i] == 0 && i < totfds && dev_fd_list[i])
+      unlink_fifo (i);
+
+  for (i = lsize; i < totfds; i++)
+    unlink_fifo (i);  
+}
+
+#if defined (NOTDEF)
+print_dev_fd_list ()
+{
+  register int i;
+
+  fprintf (stderr, "pid %ld: dev_fd_list:", (long)getpid ());
+  fflush (stderr);
+
+  for (i = 0; i < totfds; i++)
+    {
+      if (dev_fd_list[i])
+       fprintf (stderr, " %d", i);
+    }
+  fprintf (stderr, "\n");
+}
+#endif /* NOTDEF */
+
+static char *
+make_dev_fd_filename (fd)
+     int fd;
+{
+  char *ret, intbuf[INT_STRLEN_BOUND (int) + 1], *p;
+
+  ret = (char *)xmalloc (sizeof (DEV_FD_PREFIX) + 8);
+
+  strcpy (ret, DEV_FD_PREFIX);
+  p = inttostr (fd, intbuf, sizeof (intbuf));
+  strcpy (ret + sizeof (DEV_FD_PREFIX) - 1, p);
+
+  add_fifo_list (fd);
+  return (ret);
+}
+
+#endif /* HAVE_DEV_FD */
+
+/* Return a filename that will open a connection to the process defined by
+   executing STRING.  HAVE_DEV_FD, if defined, means open a pipe and return
+   a filename in /dev/fd corresponding to a descriptor that is one of the
+   ends of the pipe.  If not defined, we use named pipes on systems that have
+   them.  Systems without /dev/fd and named pipes are out of luck.
+
+   OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
+   use the read end of the pipe and dup that file descriptor to fd 0 in
+   the child.  If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
+   writing or use the write end of the pipe in the child, and dup that
+   file descriptor to fd 1 in the child.  The parent does the opposite. */
+
+static char *
+process_substitute (string, open_for_read_in_child)
+     char *string;
+     int open_for_read_in_child;
+{
+  char *pathname;
+  int fd, result;
+  pid_t old_pid, pid;
+#if defined (HAVE_DEV_FD)
+  int parent_pipe_fd, child_pipe_fd;
+  int fildes[2];
+#endif /* HAVE_DEV_FD */
+#if defined (JOB_CONTROL)
+  pid_t old_pipeline_pgrp;
+#endif
+
+  if (!string || !*string || wordexp_only)
+    return ((char *)NULL);
+
+#if !defined (HAVE_DEV_FD)
+  pathname = make_named_pipe ();
+#else /* HAVE_DEV_FD */
+  if (pipe (fildes) < 0)
+    {
+      sys_error (_("cannot make pipe for process substitution"));
+      return ((char *)NULL);
+    }
+  /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
+     the pipe in the parent, otherwise the read end. */
+  parent_pipe_fd = fildes[open_for_read_in_child];
+  child_pipe_fd = fildes[1 - open_for_read_in_child];
+  /* Move the parent end of the pipe to some high file descriptor, to
+     avoid clashes with FDs used by the script. */
+  parent_pipe_fd = move_to_high_fd (parent_pipe_fd, 1, 64);
+
+  pathname = make_dev_fd_filename (parent_pipe_fd);
+#endif /* HAVE_DEV_FD */
+
+  if (pathname == 0)
+    {
+      sys_error (_("cannot make pipe for process substitution"));
+      return ((char *)NULL);
+    }
+
+  old_pid = last_made_pid;
+
+#if defined (JOB_CONTROL)
+  old_pipeline_pgrp = pipeline_pgrp;
+  pipeline_pgrp = shell_pgrp;
+  save_pipeline (1);
+#endif /* JOB_CONTROL */
+
+  pid = make_child ((char *)NULL, 1);
+  if (pid == 0)
+    {
+      reset_terminating_signals ();    /* XXX */
+      free_pushed_string_input ();
+      /* Cancel traps, in trap.c. */
+      restore_original_signals ();     /* XXX - what about special builtins? bash-4.2 */
+      setup_async_signals ();
+      subshell_environment |= SUBSHELL_COMSUB|SUBSHELL_PROCSUB;
+    }
+
+#if defined (JOB_CONTROL)
+  set_sigchld_handler ();
+  stop_making_children ();
+  /* XXX - should we only do this in the parent? (as in command subst) */
+  pipeline_pgrp = old_pipeline_pgrp;
+#endif /* JOB_CONTROL */
+
+  if (pid < 0)
+    {
+      sys_error (_("cannot make child for process substitution"));
+      free (pathname);
+#if defined (HAVE_DEV_FD)
+      close (parent_pipe_fd);
+      close (child_pipe_fd);
+#endif /* HAVE_DEV_FD */
+      return ((char *)NULL);
+    }
+
+  if (pid > 0)
+    {
+#if defined (JOB_CONTROL)
+      restore_pipeline (1);
+#endif
+
+#if !defined (HAVE_DEV_FD)
+      fifo_list[nfifo-1].proc = pid;
+#endif
+
+      last_made_pid = old_pid;
+
+#if defined (JOB_CONTROL) && defined (PGRP_PIPE)
+      close_pgrp_pipe ();
+#endif /* JOB_CONTROL && PGRP_PIPE */
+
+#if defined (HAVE_DEV_FD)
+      close (child_pipe_fd);
+#endif /* HAVE_DEV_FD */
+
+      return (pathname);
+    }
+
+  set_sigint_handler ();
+
+#if defined (JOB_CONTROL)
+  set_job_control (0);
+#endif /* JOB_CONTROL */
+
+#if !defined (HAVE_DEV_FD)
+  /* Open the named pipe in the child. */
+  fd = open (pathname, open_for_read_in_child ? O_RDONLY : O_WRONLY);
+  if (fd < 0)
+    {
+      /* Two separate strings for ease of translation. */
+      if (open_for_read_in_child)
+       sys_error (_("cannot open named pipe %s for reading"), pathname);
+      else
+       sys_error (_("cannot open named pipe %s for writing"), pathname);
+
+      exit (127);
+    }
+  if (open_for_read_in_child)
+    {
+      if (sh_unset_nodelay_mode (fd) < 0)
+       {
+         sys_error (_("cannot reset nodelay mode for fd %d"), fd);
+         exit (127);
+       }
+    }
+#else /* HAVE_DEV_FD */
+  fd = child_pipe_fd;
+#endif /* HAVE_DEV_FD */
+
+  if (dup2 (fd, open_for_read_in_child ? 0 : 1) < 0)
+    {
+      sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname,
+       open_for_read_in_child ? 0 : 1);
+      exit (127);
+    }
+
+  if (fd != (open_for_read_in_child ? 0 : 1))
+    close (fd);
+
+  /* Need to close any files that this process has open to pipes inherited
+     from its parent. */
+  if (current_fds_to_close)
+    {
+      close_fd_bitmap (current_fds_to_close);
+      current_fds_to_close = (struct fd_bitmap *)NULL;
+    }
+
+#if defined (HAVE_DEV_FD)
+  /* Make sure we close the parent's end of the pipe and clear the slot
+     in the fd list so it is not closed later, if reallocated by, for
+     instance, pipe(2). */
+  close (parent_pipe_fd);
+  dev_fd_list[parent_pipe_fd] = 0;
+#endif /* HAVE_DEV_FD */
+
+  /* subshells shouldn't have this flag, which controls using the temporary
+     environment for variable lookups. */
+  expanding_redir = 0;
+
+  result = parse_and_execute (string, "process substitution", (SEVAL_NONINT|SEVAL_NOHIST));
+
+#if !defined (HAVE_DEV_FD)
+  /* Make sure we close the named pipe in the child before we exit. */
+  close (open_for_read_in_child ? 0 : 1);
+#endif /* !HAVE_DEV_FD */
+
+  last_command_exit_value = result;
+  result = run_exit_trap ();
+  exit (result);
+  /*NOTREACHED*/
+}
+#endif /* PROCESS_SUBSTITUTION */
+
+/***********************************/
+/*                                */
+/*     Command Substitution       */
+/*                                */
+/***********************************/
+
+static char *
+read_comsub (fd, quoted, rflag)
+     int fd, quoted;
+     int *rflag;
+{
+  char *istring, buf[128], *bufp, *s;
+  int istring_index, istring_size, c, tflag, skip_ctlesc, skip_ctlnul;
+  ssize_t bufn;
+
+  istring = (char *)NULL;
+  istring_index = istring_size = bufn = tflag = 0;
+
+  for (skip_ctlesc = skip_ctlnul = 0, s = ifs_value; s && *s; s++)
+    skip_ctlesc |= *s == CTLESC, skip_ctlnul |= *s == CTLNUL;
+
+  /* Read the output of the command through the pipe.  This may need to be
+     changed to understand multibyte characters in the future. */
+  while (1)
+    {
+      if (fd < 0)
+       break;
+      if (--bufn <= 0)
+       {
+         bufn = zread (fd, buf, sizeof (buf));
+         if (bufn <= 0) 
+           break;
+         bufp = buf;
+       }
+      c = *bufp++;
+
+      if (c == 0)
+       {
+#if 0
+         internal_warning ("read_comsub: ignored null byte in input");
+#endif
+         continue;
+       }
+
+      /* Add the character to ISTRING, possibly after resizing it. */
+      RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
+
+      /* This is essentially quote_string inline */
+      if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */)
+       istring[istring_index++] = CTLESC;
+      /* Escape CTLESC and CTLNUL in the output to protect those characters
+        from the rest of the word expansions (word splitting and globbing.)
+        This is essentially quote_escapes inline. */
+      else if (skip_ctlesc == 0 && c == CTLESC)
+       {
+         tflag |= W_HASCTLESC;
+         istring[istring_index++] = CTLESC;
+       }
+      else if ((skip_ctlnul == 0 && c == CTLNUL) || (c == ' ' && (ifs_value && *ifs_value == 0)))
+       istring[istring_index++] = CTLESC;
+
+      istring[istring_index++] = c;
+
+#if 0
+#if defined (__CYGWIN__)
+      if (c == '\n' && istring_index > 1 && istring[istring_index - 2] == '\r')
+       {
+         istring_index--;
+         istring[istring_index - 1] = '\n';
+       }
+#endif
+#endif
+    }
+
+  if (istring)
+    istring[istring_index] = '\0';
+
+  /* If we read no output, just return now and save ourselves some
+     trouble. */
+  if (istring_index == 0)
+    {
+      FREE (istring);
+      if (rflag)
+       *rflag = tflag;
+      return (char *)NULL;
+    }
+
+  /* Strip trailing newlines from the output of the command. */
+  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
+    {
+      while (istring_index > 0)
+       {
+         if (istring[istring_index - 1] == '\n')
+           {
+             --istring_index;
+
+             /* If the newline was quoted, remove the quoting char. */
+             if (istring[istring_index - 1] == CTLESC)
+               --istring_index;
+           }
+         else
+           break;
+       }
+      istring[istring_index] = '\0';
+    }
+  else
+    strip_trailing (istring, istring_index - 1, 1);
+
+  if (rflag)
+    *rflag = tflag;
+  return istring;
+}
+
+/* Perform command substitution on STRING.  This returns a WORD_DESC * with the
+   contained string possibly quoted. */
+WORD_DESC *
+command_substitute (string, quoted)
+     char *string;
+     int quoted;
+{
+  pid_t pid, old_pid, old_pipeline_pgrp, old_async_pid;
+  char *istring, *s;
+  int result, fildes[2], function_value, pflags, rc, tflag;
+  WORD_DESC *ret;
+
+  istring = (char *)NULL;
+
+  /* Don't fork () if there is no need to.  In the case of no command to
+     run, just return NULL. */
+#if 1
+  for (s = string; s && *s && (shellblank (*s) || *s == '\n'); s++)
+    ;
+  if (s == 0 || *s == 0)
+    return ((WORD_DESC *)NULL);
+#else
+  if (!string || !*string || (string[0] == '\n' && !string[1]))
+    return ((WORD_DESC *)NULL);
+#endif
+
+  if (wordexp_only && read_but_dont_execute)
+    {
+      last_command_exit_value = EX_WEXPCOMSUB;
+      jump_to_top_level (EXITPROG);
+    }
+itrace("command_substitute: after check, committed to fork");
+  /* We're making the assumption here that the command substitution will
+     eventually run a command from the file system.  Since we'll run
+     maybe_make_export_env in this subshell before executing that command,
+     the parent shell and any other shells it starts will have to remake
+     the environment.  If we make it before we fork, other shells won't
+     have to.  Don't bother if we have any temporary variable assignments,
+     though, because the export environment will be remade after this
+     command completes anyway, but do it if all the words to be expanded
+     are variable assignments. */
+  if (subst_assign_varlist == 0 || garglist == 0)
+    maybe_make_export_env ();  /* XXX */
+
+  /* Flags to pass to parse_and_execute() */
+  pflags = (interactive && sourcelevel == 0) ? SEVAL_RESETLINE : 0;
+
+  /* Pipe the output of executing STRING into the current shell. */
+  if (pipe (fildes) < 0)
+    {
+      sys_error (_("cannot make pipe for command substitution"));
+      goto error_exit;
+    }
+
+  old_pid = last_made_pid;
+#if defined (JOB_CONTROL)
+  old_pipeline_pgrp = pipeline_pgrp;
+  /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
+  if ((subshell_environment & SUBSHELL_PIPE) == 0)
+    pipeline_pgrp = shell_pgrp;
+  cleanup_the_pipeline ();
+#endif /* JOB_CONTROL */
+
+  old_async_pid = last_asynchronous_pid;
+  pid = make_child ((char *)NULL, subshell_environment&SUBSHELL_ASYNC);
+  last_asynchronous_pid = old_async_pid;
+
+  if (pid == 0)
+    {
+      /* Reset the signal handlers in the child, but don't free the
+        trap strings.  Set a flag noting that we have to free the
+        trap strings if we run trap to change a signal disposition. */
+      reset_signal_handlers ();
+      subshell_environment |= SUBSHELL_RESETTRAP;
+    }
+
+#if defined (JOB_CONTROL)
+  /* XXX DO THIS ONLY IN PARENT ? XXX */
+  set_sigchld_handler ();
+  stop_making_children ();
+  if (pid != 0)
+    pipeline_pgrp = old_pipeline_pgrp;
+#else
+  stop_making_children ();
+#endif /* JOB_CONTROL */
+
+  if (pid < 0)
+    {
+      sys_error (_("cannot make child for command substitution"));
+    error_exit:
+
+      last_made_pid = old_pid;
+
+      FREE (istring);
+      close (fildes[0]);
+      close (fildes[1]);
+      return ((WORD_DESC *)NULL);
+    }
+
+  if (pid == 0)
+    {
+      set_sigint_handler ();   /* XXX */
+
+      free_pushed_string_input ();
+
+      if (dup2 (fildes[1], 1) < 0)
+       {
+         sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
+         exit (EXECUTION_FAILURE);
+       }
+
+      /* If standard output is closed in the parent shell
+        (such as after `exec >&-'), file descriptor 1 will be
+        the lowest available file descriptor, and end up in
+        fildes[0].  This can happen for stdin and stderr as well,
+        but stdout is more important -- it will cause no output
+        to be generated from this command. */
+      if ((fildes[1] != fileno (stdin)) &&
+         (fildes[1] != fileno (stdout)) &&
+         (fildes[1] != fileno (stderr)))
+       close (fildes[1]);
+
+      if ((fildes[0] != fileno (stdin)) &&
+         (fildes[0] != fileno (stdout)) &&
+         (fildes[0] != fileno (stderr)))
+       close (fildes[0]);
+
+#ifdef __CYGWIN__
+      /* Let stdio know the fd may have changed from text to binary mode, and
+        make sure to preserve stdout line buffering. */
+      freopen (NULL, "w", stdout);
+      sh_setlinebuf (stdout);
+#endif /* __CYGWIN__ */
+
+      /* The currently executing shell is not interactive. */
+      interactive = 0;
+
+      /* This is a subshell environment. */
+      subshell_environment |= SUBSHELL_COMSUB;
+
+      /* Many shells do not appear to inherit the -v option for command
+        substitutions. */
+      change_flag ('v', FLAG_OFF);
+
+      /* When not in POSIX mode, command substitution does not inherit
+        the -e flag. */
+      if (posixly_correct == 0)
+        {
+          builtin_ignoring_errexit = 0;
+         change_flag ('e', FLAG_OFF);
+         set_shellopts ();
+        }
+
+      /* If we are expanding a redirection, we can dispose of any temporary
+        environment we received, since redirections are not supposed to have
+        access to the temporary environment.  We will have to see whether this
+        affects temporary environments supplied to `eval', but the temporary
+        environment gets copied to builtin_env at some point. */
+      if (expanding_redir)
+       {
+         flush_temporary_env ();
+         expanding_redir = 0;
+       }
+
+      remove_quoted_escapes (string);
+
+      startup_state = 2;       /* see if we can avoid a fork */
+      /* Give command substitution a place to jump back to on failure,
+        so we don't go back up to main (). */
+      result = setjmp_nosigs (top_level);
+
+      /* If we're running a command substitution inside a shell function,
+        trap `return' so we don't return from the function in the subshell
+        and go off to never-never land. */
+      if (result == 0 && return_catch_flag)
+       function_value = setjmp_nosigs (return_catch);
+      else
+       function_value = 0;
+
+      if (result == ERREXIT)
+       rc = last_command_exit_value;
+      else if (result == EXITPROG)
+       rc = last_command_exit_value;
+      else if (result)
+       rc = EXECUTION_FAILURE;
+      else if (function_value)
+       rc = return_catch_value;
+      else
+       {
+         subshell_level++;
+         rc = parse_and_execute (string, "command substitution", pflags|SEVAL_NOHIST);
+         subshell_level--;
+       }
+
+      last_command_exit_value = rc;
+      rc = run_exit_trap ();
+#if defined (PROCESS_SUBSTITUTION)
+      unlink_fifo_list ();
+#endif
+      exit (rc);
+    }
+  else
+    {
+#if defined (JOB_CONTROL) && defined (PGRP_PIPE)
+      close_pgrp_pipe ();
+#endif /* JOB_CONTROL && PGRP_PIPE */
+
+      close (fildes[1]);
+
+      tflag = 0;
+      istring = read_comsub (fildes[0], quoted, &tflag);
+
+      close (fildes[0]);
+
+      current_command_subst_pid = pid;
+      last_command_exit_value = wait_for (pid);
+      last_command_subst_pid = pid;
+      last_made_pid = old_pid;
+
+#if defined (JOB_CONTROL)
+      /* If last_command_exit_value > 128, then the substituted command
+        was terminated by a signal.  If that signal was SIGINT, then send
+        SIGINT to ourselves.  This will break out of loops, for instance. */
+      if (last_command_exit_value == (128 + SIGINT) && last_command_exit_signal == SIGINT)
+       kill (getpid (), SIGINT);
+
+      /* wait_for gives the terminal back to shell_pgrp.  If some other
+        process group should have it, give it away to that group here.
+        pipeline_pgrp is non-zero only while we are constructing a
+        pipeline, so what we are concerned about is whether or not that
+        pipeline was started in the background.  A pipeline started in
+        the background should never get the tty back here. */
+      if (interactive && pipeline_pgrp != (pid_t)0 && (subshell_environment & SUBSHELL_ASYNC) == 0)
+       give_terminal_to (pipeline_pgrp, 0);
+#endif /* JOB_CONTROL */
+
+      ret = alloc_word_desc ();
+      ret->word = istring;
+      ret->flags = tflag;
+
+      return ret;
+    }
+}
+
+/********************************************************
+ *                                                     *
+ *     Utility functions for parameter expansion       *
+ *                                                     *
+ ********************************************************/
+
+#if defined (ARRAY_VARS)
+
+static arrayind_t
+array_length_reference (s)
+     char *s;
+{
+  int len;
+  arrayind_t ind;
+  char *akey;
+  char *t, c;
+  ARRAY *array;
+  HASH_TABLE *h;
+  SHELL_VAR *var;
+
+  var = array_variable_part (s, &t, &len);
+
+  /* If unbound variables should generate an error, report one and return
+     failure. */
+  if ((var == 0 || invisible_p (var) || (assoc_p (var) == 0 && array_p (var) == 0)) && unbound_vars_is_error)
+    {
+      c = *--t;
+      *t = '\0';
+      last_command_exit_value = EXECUTION_FAILURE;
+      err_unboundvar (s);
+      *t = c;
+      return (-1);
+    }
+  else if (var == 0 || invisible_p (var))
+    return 0;
+
+  /* We support a couple of expansions for variables that are not arrays.
+     We'll return the length of the value for v[0], and 1 for v[@] or
+     v[*].  Return 0 for everything else. */
+
+  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 (assoc_p (var))
+       return (h ? assoc_num_elements (h) : 0);
+      else if (array_p (var))
+       return (array ? array_num_elements (array) : 0);
+      else
+       return (var_isset (var) ? 1 : 0);
+    }
+
+  if (assoc_p (var))
+    {
+      t[len - 1] = '\0';
+      akey = expand_assignment_string_to_string (t, 0);        /* [ */
+      t[len - 1] = ']';
+      if (akey == 0 || *akey == 0)
+       {
+         err_badarraysub (t);
+         FREE (akey);
+         return (-1);
+       }
+      t = assoc_reference (assoc_cell (var), akey);
+      free (akey);
+    }
+  else
+    {
+      ind = array_expand_index (var, t, len);
+      /* negative subscripts to indexed arrays count back from end */
+      if (var && array_p (var) && ind < 0)
+       ind = array_max_index (array_cell (var)) + 1 + ind;
+      if (ind < 0)
+       {
+         err_badarraysub (t);
+         return (-1);
+       }
+      if (array_p (var))
+       t = array_reference (array, ind);
+      else
+       t = (ind == 0) ? value_cell (var) : (char *)NULL;
+    }
+
+  len = MB_STRLEN (t);
+  return (len);
+}
+#endif /* ARRAY_VARS */
+
+static int
+valid_brace_expansion_word (name, var_is_special)
+     char *name;
+     int var_is_special;
+{
+  if (DIGIT (*name) && all_digits (name))
+    return 1;
+  else if (var_is_special)
+    return 1;
+#if defined (ARRAY_VARS)
+  else if (valid_array_reference (name))
+    return 1;
+#endif /* ARRAY_VARS */
+  else if (legal_identifier (name))
+    return 1;
+  else
+    return 0;
+}
+
+static int
+chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at)
+     char *name;
+     int quoted;
+     int *quoted_dollar_atp, *contains_dollar_at;
+{
+  char *temp1;
+
+  if (name == 0)
+    {
+      if (quoted_dollar_atp)
+       *quoted_dollar_atp = 0;
+      if (contains_dollar_at)
+       *contains_dollar_at = 0;
+      return 0;
+    }
+
+  /* check for $@ and $* */
+  if (name[0] == '@' && name[1] == 0)
+    {
+      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;
+    }
+  else if (name[0] == '*' && name[1] == '\0' && quoted == 0)
+    {
+      if (contains_dollar_at)
+       *contains_dollar_at = 1;
+      return 1;
+    }
+
+  /* Now check for ${array[@]} and ${array[*]} */
+#if defined (ARRAY_VARS)
+  else if (valid_array_reference (name))
+    {
+      temp1 = mbschr (name, '[');
+      if (temp1 && temp1[1] == '@' && temp1[2] == ']')
+       {
+         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 (contains_dollar_at)
+           *contains_dollar_at = 1;
+         return 1;
+       }
+    }
+#endif
+  return 0;
+}
+
+/* Parameter expand NAME, and return a new string which is the expansion,
+   or NULL if there was no expansion.
+   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. */
+static WORD_DESC *
+parameter_brace_expand_word (name, var_is_special, quoted, pflags, indp)
+     char *name;
+     int var_is_special, quoted, pflags;
+     arrayind_t *indp;
+{
+  WORD_DESC *ret;
+  char *temp, *tt;
+  intmax_t arg_index;
+  SHELL_VAR *var;
+  int atype, rflags;
+  arrayind_t ind;
+
+  ret = 0;
+  temp = 0;
+  rflags = 0;
+
+  if (indp)
+    *indp = INTMAX_MIN;
+
+  /* Handle multiple digit arguments, as in ${11}. */  
+  if (legal_number (name, &arg_index))
+    {
+      tt = get_dollar_var_value (arg_index);
+      if (tt)
+       temp = (*tt && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
+                 ? quote_string (tt)
+                 : quote_escapes (tt);
+      else
+        temp = (char *)NULL;
+      FREE (tt);
+    }
+  else if (var_is_special)      /* ${@} */
+    {
+      int sindex;
+      tt = (char *)xmalloc (2 + strlen (name));
+      tt[sindex = 0] = '$';
+      strcpy (tt + 1, name);
+
+      ret = param_expand (tt, &sindex, quoted, (int *)NULL, (int *)NULL,
+                         (int *)NULL, (int *)NULL, pflags);
+      free (tt);
+    }
+#if defined (ARRAY_VARS)
+  else if (valid_array_reference (name))
+    {
+expand_arrayref:
+      /* XXX - does this leak if name[@] or name[*]? */
+      if (pflags & PF_ASSIGNRHS)
+       {
+         var = array_variable_part (name, &tt, (int *)0);
+         if (ALL_ELEMENT_SUB (tt[0]) && tt[1] == ']')
+           {
+             /* Only treat as double quoted if array variable */
+             if (var && (array_p (var) || assoc_p (var)))
+               temp = array_value (name, quoted|Q_DOUBLE_QUOTES, 0, &atype, &ind);
+             else              
+               temp = array_value (name, quoted, 0, &atype, &ind);
+           }
+         else
+           temp = array_value (name, quoted, 0, &atype, &ind);
+       }
+      else
+       temp = array_value (name, quoted, 0, &atype, &ind);
+      if (atype == 0 && temp)
+       {
+         temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
+                   ? quote_string (temp)
+                   : quote_escapes (temp);
+         rflags |= W_ARRAYIND;
+         if (indp)
+           *indp = ind;
+       }                 
+      else if (atype == 1 && temp && QUOTED_NULL (temp) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
+       rflags |= W_HASQUOTEDNULL;
+    }
+#endif
+  else if (var = find_variable (name))
+    {
+      if (var_isset (var) && invisible_p (var) == 0)
+       {
+#if defined (ARRAY_VARS)
+         if (assoc_p (var))
+           temp = assoc_reference (assoc_cell (var), "0");
+         else if (array_p (var))
+           temp = array_reference (array_cell (var), 0);
+         else
+           temp = value_cell (var);
+#else
+         temp = value_cell (var);
+#endif
+
+         if (temp)
+           temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
+                     ? quote_string (temp)
+                     : quote_escapes (temp);
+       }
+      else
+       temp = (char *)NULL;
+    }
+  else if (var = find_variable_last_nameref (name))
+    {
+      temp = nameref_cell (var);
+#if defined (ARRAY_VARS)
+      /* Handle expanding nameref whose value is x[n] */
+      if (temp && *temp && valid_array_reference (temp))
+       {
+         name = temp;
+         goto expand_arrayref;
+       }
+      else
+#endif
+      /* y=2 ; typeset -n x=y; echo ${x} is not the same as echo ${2} in ksh */
+      if (temp && *temp && legal_identifier (temp) == 0)
+        {
+         last_command_exit_value = EXECUTION_FAILURE;
+         report_error (_("%s: invalid variable name for name reference"), temp);
+         temp = &expand_param_error;
+        }
+      else
+       temp = (char *)NULL;
+    }
+  else
+    temp = (char *)NULL;
+
+  if (ret == 0)
+    {
+      ret = alloc_word_desc ();
+      ret->word = temp;
+      ret->flags |= rflags;
+    }
+  return ret;
+}
+
+static char *
+parameter_brace_find_indir (name, var_is_special, quoted, find_nameref)
+     char *name;
+     int var_is_special, quoted, find_nameref;
+{
+  char *temp, *t;
+  WORD_DESC *w;
+  SHELL_VAR *v;
+
+  if (find_nameref && var_is_special == 0 && (v = find_variable_last_nameref (name)) &&
+      nameref_p (v) && (t = nameref_cell (v)) && *t)
+    return (savestring (t));
+
+  /* If var_is_special == 0, and name is not an array reference, this does
+     more expansion than necessary.  It should really look up the variable's
+     value and not try to expand it. */
+  w = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND, 0);
+  t = w->word;
+  /* Have to dequote here if necessary */
+  if (t)
+    {
+      temp = (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
+               ? dequote_string (t)
+               : dequote_escapes (t);
+      free (t);
+      t = temp;
+    }
+  dispose_word_desc (w);
+
+  return t;
+}
+  
+/* Expand an indirect reference to a variable: ${!NAME} expands to the
+   value of the variable whose name is the value of NAME. */
+static WORD_DESC *
+parameter_brace_expand_indir (name, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at)
+     char *name;
+     int var_is_special, quoted;
+     int *quoted_dollar_atp, *contains_dollar_at;
+{
+  char *temp, *t;
+  WORD_DESC *w;
+  SHELL_VAR *v;
+
+  /* See if it's a nameref first, behave in ksh93-compatible fashion.
+     There is at least one incompatibility: given ${!foo[0]} where foo=bar,
+     bash performs an indirect lookup on foo[0] and expands the result;
+     ksh93 expands bar[0].  We could do that here -- there are enough usable
+     primitives to do that -- but do not at this point. */
+  if (var_is_special == 0 && (v = find_variable_last_nameref (name)))
+    {
+      if (nameref_p (v) && (t = nameref_cell (v)) && *t)
+       {
+         w = alloc_word_desc ();
+         w->word = savestring (t);
+         w->flags = 0;
+         return w;
+       }
+    }
+
+  t = parameter_brace_find_indir (name, var_is_special, quoted, 0);
+
+  chk_atstar (t, quoted, quoted_dollar_atp, contains_dollar_at);
+  if (t == 0)
+    return (WORD_DESC *)NULL;
+
+  w = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted, 0, 0);
+  free (t);
+
+  return w;
+}
+
+/* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
+   depending on the value of C, the separating character.  C can be one of
+   "-", "+", or "=".  QUOTED is true if the entire brace expression occurs
+   between double quotes. */
+static WORD_DESC *
+parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
+     char *name, *value;
+     int c, quoted, *qdollaratp, *hasdollarat;
+{
+  WORD_DESC *w;
+  WORD_LIST *l;
+  char *t, *t1, *temp, *vname;
+  int hasdol;
+
+  /* If the entire expression is between double quotes, we want to treat
+     the value as a double-quoted string, with the exception that we strip
+     embedded unescaped double quotes (for sh backwards compatibility). */
+  if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *value)
+    {
+      hasdol = 0;
+      temp = string_extract_double_quoted (value, &hasdol, 1);
+    }
+  else
+    temp = value;
+
+  w = alloc_word_desc ();
+  hasdol = 0;
+  /* XXX was 0 not quoted */
+  l = *temp ? expand_string_for_rhs (temp, quoted, &hasdol, (int *)NULL)
+           : (WORD_LIST *)0;
+  if (hasdollarat)
+    *hasdollarat = hasdol || (l && l->next);
+  if (temp != value)
+    free (temp);
+  if (l)
+    {
+      /* The expansion of TEMP returned something.  We need to treat things
+         slightly differently if HASDOL is non-zero.  If we have "$@", the
+         individual words have already been quoted.  We need to turn them
+         into a string with the words separated by the first character of
+         $IFS without any additional quoting, so string_list_dollar_at won't
+         do the right thing.  We use string_list_dollar_star instead. */
+      temp = (hasdol || l->next) ? string_list_dollar_star (l) : string_list (l);
+
+      /* If l->next is not null, we know that TEMP contained "$@", since that
+        is the only expansion that creates more than one word. */
+      if (qdollaratp && ((hasdol && quoted) || l->next))
+       *qdollaratp = 1;
+      /* If we have a quoted null result (QUOTED_NULL(temp)) and the word is
+        a quoted null (l->next == 0 && QUOTED_NULL(l->word->word)), the
+        flags indicate it (l->word->flags & W_HASQUOTEDNULL), and the
+        expansion is quoted (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
+        (which is more paranoia than anything else), we need to return the
+        quoted null string and set the flags to indicate it. */
+      if (l->next == 0 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && QUOTED_NULL (temp) && QUOTED_NULL (l->word->word) && (l->word->flags & W_HASQUOTEDNULL))
+       {
+         w->flags |= W_HASQUOTEDNULL;
+       }
+      dispose_words (l);
+    }
+  else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol)
+    {
+      /* Posix interp 221 changed the rules on this.  The idea is that
+        something like "$xxx$@" should expand the same as "${foo-$xxx$@}"
+        when foo and xxx are unset.  The problem is that it's not in any
+        way backwards compatible and few other shells do it.  We're eventually
+        going to try and split the difference (heh) a little bit here. */
+      /* hasdol == 1 means we saw a quoted dollar at.  */
+
+      /* The brace expansion occurred between double quotes and there was
+        a $@ in TEMP.  It does not matter if the $@ is quoted, as long as
+        it does not expand to anything.  In this case, we want to return
+        a quoted empty string. */
+      temp = make_quoted_char ('\0');
+      w->flags |= W_HASQUOTEDNULL;
+    }
+  else
+    temp = (char *)NULL;
+
+  if (c == '-' || c == '+')
+    {
+      w->word = temp;
+      return w;
+    }
+
+  /* c == '=' */
+  t = temp ? savestring (temp) : savestring ("");
+  t1 = dequote_string (t);
+  free (t);
+
+  /* bash-4.4/5.0 */
+  vname = name;
+  if (*name == '!' &&
+      (legal_variable_starter ((unsigned char)name[1]) || DIGIT (name[1]) || VALID_INDIR_PARAM (name[1])))
+    {
+      vname = parameter_brace_find_indir (name + 1, SPECIAL_VAR (name, 1), quoted, 1);
+      if (vname == 0 || *vname == 0)
+       {
+         report_error (_("%s: invalid indirect expansion"), name);
+         free (vname);
+         dispose_word (w);
+         return &expand_wdesc_error;
+       }
+      if (legal_identifier (vname) == 0)
+       {
+         report_error (_("%s: invalid variable name"), vname);
+         free (vname);
+         dispose_word (w);
+         return &expand_wdesc_error;
+       }
+    }
+    
+#if defined (ARRAY_VARS)
+  if (valid_array_reference (vname))
+    assign_array_element (vname, t1, 0);
+  else
+#endif /* ARRAY_VARS */
+  bind_variable (vname, t1, 0);
+
+  stupidly_hack_special_variables (vname);
+
+  if (vname != name)
+    free (vname);
+
+  /* From Posix group discussion Feb-March 2010.  Issue 7 0000221 */
+  free (temp);
+
+  w->word = t1;
+  return w;
+}
+
+/* Deal with the right hand side of a ${name:?value} expansion in the case
+   that NAME is null or not set.  If VALUE is non-null it is expanded and
+   used as the error message to print, otherwise a standard message is
+   printed. */
+static void
+parameter_brace_expand_error (name, value)
+     char *name, *value;
+{
+  WORD_LIST *l;
+  char *temp;
+
+  last_command_exit_value = EXECUTION_FAILURE; /* ensure it's non-zero */
+  if (value && *value)
+    {
+      l = expand_string (value, 0);
+      temp =  string_list (l);
+      report_error ("%s: %s", name, temp ? temp : ""); /* XXX was value not "" */
+      FREE (temp);
+      dispose_words (l);
+    }
+  else
+    report_error (_("%s: parameter null or not set"), name);
+
+  /* Free the data we have allocated during this expansion, since we
+     are about to longjmp out. */
+  free (name);
+  FREE (value);
+}
+
+/* Return 1 if NAME is something for which parameter_brace_expand_length is
+   OK to do. */
+static int
+valid_length_expression (name)
+     char *name;
+{
+  return (name[1] == '\0' ||                                   /* ${#} */
+         ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0') ||  /* special param */
+         (DIGIT (name[1]) && all_digits (name + 1)) || /* ${#11} */
+#if defined (ARRAY_VARS)
+         valid_array_reference (name + 1) ||                   /* ${#a[7]} */
+#endif
+         legal_identifier (name + 1));                         /* ${#PS1} */
+}
+
+/* Handle the parameter brace expansion that requires us to return the
+   length of a parameter. */
+static intmax_t
+parameter_brace_expand_length (name)
+     char *name;
+{
+  char *t, *newname;
+  intmax_t number, arg_index;
+  WORD_LIST *list;
+#if defined (ARRAY_VARS)
+  SHELL_VAR *var;
+#endif
+
+  if (name[1] == '\0')                 /* ${#} */
+    number = number_of_args ();
+  else if ((name[1] == '@' || name[1] == '*') && name[2] == '\0')      /* ${#@}, ${#*} */
+    number = number_of_args ();
+  else if ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0')
+    {
+      /* Take the lengths of some of the shell's special parameters. */
+      switch (name[1])
+       {
+       case '-':
+         t = which_set_flags ();
+         break;
+       case '?':
+         t = itos (last_command_exit_value);
+         break;
+       case '$':
+         t = itos (dollar_dollar_pid);
+         break;
+       case '!':
+         if (last_asynchronous_pid == NO_PID)
+           t = (char *)NULL;   /* XXX - error if set -u set? */
+         else
+           t = itos (last_asynchronous_pid);
+         break;
+       case '#':
+         t = itos (number_of_args ());
+         break;
+       }
+      number = STRLEN (t);
+      FREE (t);
+    }
+#if defined (ARRAY_VARS)
+  else if (valid_array_reference (name + 1))
+    number = array_length_reference (name + 1);
+#endif /* ARRAY_VARS */
+  else
+    {
+      number = 0;
+
+      if (legal_number (name + 1, &arg_index))         /* ${#1} */
+       {
+         t = get_dollar_var_value (arg_index);
+         if (t == 0 && unbound_vars_is_error)
+           return INTMAX_MIN;
+         number = MB_STRLEN (t);
+         FREE (t);
+       }
+#if defined (ARRAY_VARS)
+      else if ((var = find_variable (name + 1)) && (invisible_p (var) == 0) && (array_p (var) || assoc_p (var)))
+       {
+         if (assoc_p (var))
+           t = assoc_reference (assoc_cell (var), "0");
+         else
+           t = array_reference (array_cell (var), 0);
+         if (t == 0 && unbound_vars_is_error)
+           return INTMAX_MIN;
+         number = MB_STRLEN (t);
+       }
+#endif
+      else                             /* ${#PS1} */
+       {
+         newname = savestring (name);
+         newname[0] = '$';
+         list = expand_string (newname, Q_DOUBLE_QUOTES);
+         t = list ? string_list (list) : (char *)NULL;
+         free (newname);
+         if (list)
+           dispose_words (list);
+
+         number = t ? MB_STRLEN (t) : 0;
+         FREE (t);
+       }
+    }
+
+  return (number);
+}
+
+/* Skip characters in SUBSTR until DELIM.  SUBSTR is an arithmetic expression,
+   so we do some ad-hoc parsing of an arithmetic expression to find
+   the first DELIM, instead of using strchr(3).  Two rules:
+       1.  If the substring contains a `(', read until closing `)'.
+       2.  If the substring contains a `?', read past one `:' for each `?'.
+*/
+
+static char *
+skiparith (substr, delim)
+     char *substr;
+     int delim;
+{
+  size_t sublen;
+  int skipcol, pcount, i;
+  DECLARE_MBSTATE;
+
+  sublen = strlen (substr);
+  i = skipcol = pcount = 0;
+  while (substr[i])
+    {
+      /* Balance parens */
+      if (substr[i] == LPAREN)
+       {
+         pcount++;
+         i++;
+         continue;
+       }
+      if (substr[i] == RPAREN && pcount)
+       {
+         pcount--;
+         i++;
+         continue;
+       }
+      if (pcount)
+       {
+         ADVANCE_CHAR (substr, sublen, i);
+         continue;
+       }
+
+      /* Skip one `:' for each `?' */
+      if (substr[i] == ':' && skipcol)
+       {
+         skipcol--;
+         i++;
+         continue;
+       }
+      if (substr[i] == delim)
+       break;
+      if (substr[i] == '?')
+       {
+         skipcol++;
+         i++;
+         continue;
+       }
+      ADVANCE_CHAR (substr, sublen, i);
+    }
+
+  return (substr + i);
+}
+
+/* Verify and limit the start and end of the desired substring.  If
+   VTYPE == 0, a regular shell variable is being used; if it is 1,
+   then the positional parameters are being used; if it is 2, then
+   VALUE is really a pointer to an array variable that should be used.
+   Return value is 1 if both values were OK, 0 if there was a problem
+   with an invalid expression, or -1 if the values were out of range. */
+static int
+verify_substring_values (v, value, substr, vtype, e1p, e2p)
+     SHELL_VAR *v;
+     char *value, *substr;
+     int vtype;
+     intmax_t *e1p, *e2p;
+{
+  char *t, *temp1, *temp2;
+  arrayind_t len;
+  int expok;
+#if defined (ARRAY_VARS)
+ ARRAY *a;
+ HASH_TABLE *h;
+#endif
+
+  /* duplicate behavior of strchr(3) */
+  t = skiparith (substr, ':');
+  if (*t && *t == ':')
+    *t = '\0';
+  else
+    t = (char *)0;
+
+  temp1 = expand_arith_string (substr, Q_DOUBLE_QUOTES);
+  *e1p = evalexp (temp1, &expok);
+  free (temp1);
+  if (expok == 0)
+    return (0);
+
+  len = -1;    /* paranoia */
+  switch (vtype)
+    {
+    case VT_VARIABLE:
+    case VT_ARRAYMEMBER:
+      len = MB_STRLEN (value);
+      break;
+    case VT_POSPARMS:
+      len = number_of_args () + 1;
+      if (*e1p == 0)
+       len++;          /* add one arg if counting from $0 */
+      break;
+#if defined (ARRAY_VARS)
+    case VT_ARRAYVAR:
+      /* For arrays, the first value deals with array indices.  Negative
+        offsets count from one past the array's maximum index.  Associative
+        arrays treat the number of elements as the maximum index. */
+      if (assoc_p (v))
+       {
+         h = assoc_cell (v);
+         len = assoc_num_elements (h) + (*e1p < 0);
+       }
+      else
+       {
+         a = (ARRAY *)value;
+         len = array_max_index (a) + (*e1p < 0);       /* arrays index from 0 to n - 1 */
+       }
+      break;
+#endif
+    }
+
+  if (len == -1)       /* paranoia */
+    return -1;
+
+  if (*e1p < 0)                /* negative offsets count from end */
+    *e1p += len;
+
+  if (*e1p > len || *e1p < 0)
+    return (-1);
+
+#if defined (ARRAY_VARS)
+  /* For arrays, the second offset deals with the number of elements. */
+  if (vtype == VT_ARRAYVAR)
+    len = assoc_p (v) ? assoc_num_elements (h) : array_num_elements (a);
+#endif
+
+  if (t)
+    {
+      t++;
+      temp2 = savestring (t);
+      temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES);
+      free (temp2);
+      t[-1] = ':';
+      *e2p = evalexp (temp1, &expok);
+      free (temp1);
+      if (expok == 0)
+       return (0);
+#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 */
+      if (vtype == VT_ARRAYVAR && *e2p < 0)
+#endif
+       {
+         internal_error (_("%s: substring expression < 0"), t);
+         return (0);
+       }
+#if defined (ARRAY_VARS)
+      /* In order to deal with sparse arrays, push the intelligence about how
+        to deal with the number of elements desired down to the array-
+        specific functions.  */
+      if (vtype != VT_ARRAYVAR)
+#endif
+       {
+         if (*e2p < 0)
+           {
+             *e2p += len;
+             if (*e2p < 0 || *e2p < *e1p)
+               {
+                 internal_error (_("%s: substring expression < 0"), t);
+                 return (0);
+               }
+           }
+         else
+           *e2p += *e1p;               /* want E2 chars starting at E1 */
+         if (*e2p > len)
+           *e2p = len;
+       }
+    }
+  else
+    *e2p = len;
+
+  return (1);
+}
+
+/* Return the type of variable specified by VARNAME (simple variable,
+   positional param, or array variable).  Also return the value specified
+   by VARNAME (value of a variable or a reference to an array element).
+   QUOTED is the standard description of quoting state, using Q_* defines.
+   FLAGS is currently a set of flags to pass to array_value.  If IND is
+   non-null and not INTMAX_MIN, and FLAGS includes AV_USEIND, IND is
+   passed to array_value so the array index is not computed again.
+   If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
+   characters in the value are quoted with CTLESC and takes appropriate
+   steps.  For convenience, *VALP is set to the dequoted VALUE. */
+static int
+get_var_and_type (varname, value, ind, quoted, flags, varp, valp)
+     char *varname, *value;
+     arrayind_t ind;
+     int quoted, flags;
+     SHELL_VAR **varp;
+     char **valp;
+{
+  int vtype, want_indir;
+  char *temp, *vname;
+  WORD_DESC *wd;
+  SHELL_VAR *v;
+  arrayind_t lind;
+
+  want_indir = *varname == '!' &&
+    (legal_variable_starter ((unsigned char)varname[1]) || DIGIT (varname[1])
+                                       || VALID_INDIR_PARAM (varname[1]));
+  if (want_indir)
+    vname = parameter_brace_find_indir (varname+1, SPECIAL_VAR (varname, 1), quoted, 1);
+    /* XXX - what if vname == 0 || *vname == 0 ? */
+  else
+    vname = varname;
+    
+  /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
+  vtype = (vname[0] == '@' || vname[0] == '*') && vname[1] == '\0';
+  if (vtype == VT_POSPARMS && vname[0] == '*')
+    vtype |= VT_STARSUB;
+  *varp = (SHELL_VAR *)NULL;
+
+#if defined (ARRAY_VARS)
+  if (valid_array_reference (vname))
+    {
+      v = array_variable_part (vname, &temp, (int *)0);
+      /* If we want to signal array_value to use an already-computed index,
+        set LIND to that index */
+      lind = (ind != INTMAX_MIN && (flags & AV_USEIND)) ? ind : 0;
+      if (v && invisible_p (v))
+       {
+         vtype = VT_ARRAYMEMBER;
+         *varp = (SHELL_VAR *)NULL;
+         *valp = (char *)NULL;
+       }
+      if (v && (array_p (v) || assoc_p (v)))
+       { /* [ */
+         if (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']')
+           {
+             /* Callers have to differentiate between indexed and associative */
+             vtype = VT_ARRAYVAR;
+             if (temp[0] == '*')
+               vtype |= VT_STARSUB;
+             *valp = array_p (v) ? (char *)array_cell (v) : (char *)assoc_cell (v);
+           }
+         else
+           {
+             vtype = VT_ARRAYMEMBER;
+             *valp = array_value (vname, Q_DOUBLE_QUOTES, flags, (int *)NULL, &lind);
+           }
+         *varp = v;
+       }
+      else if (v && (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']'))
+       {
+         vtype = VT_VARIABLE;
+         *varp = v;
+         if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
+           *valp = dequote_string (value);
+         else
+           *valp = dequote_escapes (value);
+       }
+      else
+       {
+         vtype = VT_ARRAYMEMBER;
+         *varp = v;
+         *valp = array_value (vname, Q_DOUBLE_QUOTES, flags, (int *)NULL, &lind);
+       }
+    }
+  else if ((v = find_variable (vname)) && (invisible_p (v) == 0) && (assoc_p (v) || array_p (v)))
+    {
+      vtype = VT_ARRAYMEMBER;
+      *varp = v;
+      *valp = assoc_p (v) ? assoc_reference (assoc_cell (v), "0") : array_reference (array_cell (v), 0);
+    }
+  else
+#endif
+    {
+      if (value && vtype == VT_VARIABLE)
+       {
+         *varp = find_variable (vname);
+         if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
+           *valp = dequote_string (value);
+         else
+           *valp = dequote_escapes (value);
+       }
+      else
+       *valp = value;
+    }
+
+  if (want_indir)
+    free (vname);
+
+  return vtype;
+}
+
+/******************************************************/
+/*                                                   */
+/* Functions to extract substrings of variable values */
+/*                                                   */
+/******************************************************/
+
+#if defined (HANDLE_MULTIBYTE)
+/* Character-oriented rather than strictly byte-oriented substrings.  S and
+   E, rather being strict indices into STRING, indicate character (possibly
+   multibyte character) positions that require calculation.
+   Used by the ${param:offset[:length]} expansion. */
+static char *
+mb_substring (string, s, e)
+     char *string;
+     int s, e;
+{
+  char *tt;
+  int start, stop, i, slen;
+  DECLARE_MBSTATE;
+
+  start = 0;
+  /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
+  slen = (MB_CUR_MAX > 1) ? STRLEN (string) : 0;
+
+  i = s;
+  while (string[start] && i--)
+    ADVANCE_CHAR (string, slen, start);
+  stop = start;
+  i = e - s;
+  while (string[stop] && i--)
+    ADVANCE_CHAR (string, slen, stop);
+  tt = substring (string, start, stop);
+  return tt;
+}
+#endif
+  
+/* Process a variable substring expansion: ${name:e1[:e2]}.  If VARNAME
+   is `@', use the positional parameters; otherwise, use the value of
+   VARNAME.  If VARNAME is an array variable, use the array elements. */
+
+static char *
+parameter_brace_substring (varname, value, ind, substr, quoted, flags)
+     char *varname, *value;
+     int ind;
+     char *substr;
+     int quoted, flags;
+{
+  intmax_t e1, e2;
+  int vtype, r, starsub;
+  char *temp, *val, *tt, *oname;
+  SHELL_VAR *v;
+
+  if (value == 0 && ((varname[0] != '@' && varname[0] != '*') || varname[1]))
+    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);
+    }
+
+  starsub = vtype & VT_STARSUB;
+  vtype &= ~VT_STARSUB;
+
+  r = verify_substring_values (v, val, substr, vtype, &e1, &e2);
+  this_command_name = oname;
+  if (r <= 0)
+    {
+      if (vtype == VT_VARIABLE)
+       FREE (val);
+      return ((r == 0) ? &expand_param_error : (char *)NULL);
+    }
+
+  switch (vtype)
+    {
+    case VT_VARIABLE:
+    case VT_ARRAYMEMBER:
+#if defined (HANDLE_MULTIBYTE)
+      if (MB_CUR_MAX > 1)
+       tt = mb_substring (val, e1, e2);
+      else
+#endif
+      tt = substring (val, e1, e2);
+
+      if (vtype == VT_VARIABLE)
+       FREE (val);
+      if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
+       temp = quote_string (tt);
+      else
+       temp = tt ? quote_escapes (tt) : (char *)NULL;
+      FREE (tt);
+      break;
+    case VT_POSPARMS:
+      tt = pos_params (varname, e1, e2, quoted);
+      if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
+       {
+         temp = tt ? quote_escapes (tt) : (char *)NULL;
+         FREE (tt);
+       }
+      else
+       temp = tt;
+      break;
+#if defined (ARRAY_VARS)
+    case VT_ARRAYVAR:
+      if (assoc_p (v))
+       /* we convert to list and take first e2 elements starting at e1th
+          element -- officially undefined for now */   
+       temp = assoc_subrange (assoc_cell (v), e1, e2, starsub, quoted);
+      else
+      /* We want E2 to be the number of elements desired (arrays can be sparse,
+        so verify_substring_values just returns the numbers specified and we
+        rely on array_subrange to understand how to deal with them). */
+       temp = array_subrange (array_cell (v), e1, e2, starsub, quoted);
+      /* array_subrange now calls array_quote_escapes as appropriate, so the
+        caller no longer needs to. */
+      break;
+#endif
+    default:
+      temp = (char *)NULL;
+    }
+
+  return temp;
+}
+
+/****************************************************************/
+/*                                                             */
+/* Functions to perform pattern substitution on variable values */
+/*                                                             */
+/****************************************************************/
+
+static int
+shouldexp_replacement (s)
+     char *s;
+{
+  register char *p;
+
+  for (p = s; p && *p; p++)
+    {
+      if (*p == '\\')
+       p++;
+      else if (*p == '&')
+       return 1;
+    }
+  return 0;
+}
+
+char *
+pat_subst (string, pat, rep, mflags)
+     char *string, *pat, *rep;
+     int mflags;
+{
+  char *ret, *s, *e, *str, *rstr, *mstr;
+  int rsize, rptr, l, replen, mtype, rxpand, rslen, mlen;
+
+  if (string  == 0)
+    return (savestring (""));
+
+  mtype = mflags & MATCH_TYPEMASK;
+
+#if 0  /* bash-4.2 ? */
+  rxpand = (rep && *rep) ? shouldexp_replacement (rep) : 0;
+#else
+  rxpand = 0;
+#endif
+
+  /* Special cases:
+   *   1.  A null pattern with mtype == MATCH_BEG means to prefix STRING
+   *       with REP and return the result.
+   *   2.  A null pattern with mtype == MATCH_END means to append REP to
+   *       STRING and return the result.
+   * These don't understand or process `&' in the replacement string.
+   */
+  if ((pat == 0 || *pat == 0) && (mtype == MATCH_BEG || mtype == MATCH_END))
+    {
+      replen = STRLEN (rep);
+      l = STRLEN (string);
+      ret = (char *)xmalloc (replen + l + 2);
+      if (replen == 0)
+       strcpy (ret, string);
+      else if (mtype == MATCH_BEG)
+       {
+         strcpy (ret, rep);
+         strcpy (ret + replen, string);
+       }
+      else
+       {
+         strcpy (ret, string);
+         strcpy (ret + l, rep);
+       }
+      return (ret);
+    }
+
+  ret = (char *)xmalloc (rsize = 64);
+  ret[0] = '\0';
+
+  for (replen = STRLEN (rep), rptr = 0, str = string;;)
+    {
+      if (match_pattern (str, pat, mtype, &s, &e) == 0)
+       break;
+      l = s - str;
+
+      if (rxpand)
+        {
+          int x;
+          mlen = e - s;
+          mstr = xmalloc (mlen + 1);
+         for (x = 0; x < mlen; x++)
+           mstr[x] = s[x];
+          mstr[mlen] = '\0';
+          rstr = strcreplace (rep, '&', mstr, 0);
+          rslen = strlen (rstr);
+        }
+      else
+        {
+          rstr = rep;
+          rslen = replen;
+        }
+        
+      RESIZE_MALLOCED_BUFFER (ret, rptr, (l + rslen), rsize, 64);
+
+      /* OK, now copy the leading unmatched portion of the string (from
+        str to s) to ret starting at rptr (the current offset).  Then copy
+        the replacement string at ret + rptr + (s - str).  Increment
+        rptr (if necessary) and str and go on. */
+      if (l)
+       {
+         strncpy (ret + rptr, str, l);
+         rptr += l;
+       }
+      if (replen)
+       {
+         strncpy (ret + rptr, rstr, rslen);
+         rptr += rslen;
+       }
+      str = e;         /* e == end of match */
+
+      if (rstr != rep)
+       free (rstr);
+
+      if (((mflags & MATCH_GLOBREP) == 0) || mtype != MATCH_ANY)
+       break;
+
+      if (s == e)
+       {
+         /* On a zero-length match, make sure we copy one character, since
+            we increment one character to avoid infinite recursion. */
+         RESIZE_MALLOCED_BUFFER (ret, rptr, 1, rsize, 64);
+         ret[rptr++] = *str++;
+         e++;          /* avoid infinite recursion on zero-length match */
+       }
+    }
+
+  /* Now copy the unmatched portion of the input string */
+  if (str && *str)
+    {
+      RESIZE_MALLOCED_BUFFER (ret, rptr, STRLEN(str) + 1, rsize, 64);
+      strcpy (ret + rptr, str);
+    }
+  else
+    ret[rptr] = '\0';
+
+  return ret;
+}
+
+/* Do pattern match and replacement on the positional parameters. */
+static char *
+pos_params_pat_subst (string, pat, rep, mflags)
+     char *string, *pat, *rep;
+     int mflags;
+{
+  WORD_LIST *save, *params;
+  WORD_DESC *w;
+  char *ret;
+  int pchar, qflags;
+
+  save = params = list_rest_of_args ();
+  if (save == 0)
+    return ((char *)NULL);
+
+  for ( ; params; params = params->next)
+    {
+      ret = pat_subst (params->word->word, pat, rep, mflags);
+      w = alloc_word_desc ();
+      w->word = ret ? ret : savestring ("");
+      dispose_word (params->word);
+      params->word = w;
+    }
+
+  pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
+  qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
+
+  ret = string_list_pos_params (pchar, save, qflags);
+
+  dispose_words (save);
+
+  return (ret);
+}
+
+/* Perform pattern substitution on VALUE, which is the expansion of
+   VARNAME.  PATSUB is an expression supplying the pattern to match
+   and the string to substitute.  QUOTED is a flags word containing
+   the type of quoting currently in effect. */
+static char *
+parameter_brace_patsub (varname, value, ind, patsub, quoted, flags)
+     char *varname, *value;
+     int ind;
+     char *patsub;
+     int quoted, flags;
+{
+  int vtype, mflags, starsub, delim;
+  char *val, *temp, *pat, *rep, *p, *lpatsub, *tt;
+  SHELL_VAR *v;
+
+  if (value == 0)
+    return ((char *)NULL);
+
+  this_command_name = varname;
+
+  vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
+  if (vtype == -1)
+    return ((char *)NULL);
+
+  starsub = vtype & VT_STARSUB;
+  vtype &= ~VT_STARSUB;
+
+  mflags = 0;
+  /* PATSUB is never NULL when this is called. */
+  if (*patsub == '/')
+    {
+      mflags |= MATCH_GLOBREP;
+      patsub++;
+    }
+
+  /* Malloc this because expand_string_if_necessary or one of the expansion
+     functions in its call chain may free it on a substitution error. */
+  lpatsub = savestring (patsub);
+
+  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
+    mflags |= MATCH_QUOTED;
+
+  if (starsub)
+    mflags |= MATCH_STARSUB;
+
+  /* If the pattern starts with a `/', make sure we skip over it when looking
+     for the replacement delimiter. */
+  delim = skip_to_delim (lpatsub, ((*patsub == '/') ? 1 : 0), "/", 0);
+  if (lpatsub[delim] == '/')
+    {
+      lpatsub[delim] = 0;
+      rep = lpatsub + delim + 1;
+    }
+  else
+    rep = (char *)NULL;
+
+  if (rep && *rep == '\0')
+    rep = (char *)NULL;
+
+  /* Perform the same expansions on the pattern as performed by the
+     pattern removal expansions. */
+  pat = getpattern (lpatsub, quoted, 1);
+
+  if (rep)
+    {
+      /* We want to perform quote removal on the expanded replacement even if
+        the entire expansion is double-quoted because the parser and string
+        extraction functions treated quotes in the replacement string as
+        special.  THIS IS NOT BACKWARDS COMPATIBLE WITH BASH-4.2. */
+      if (shell_compatibility_level > 42)
+       rep = expand_string_if_necessary (rep, quoted & ~(Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT), expand_string_unsplit);
+      /* This is the bash-4.2 code. */      
+      else if ((mflags & MATCH_QUOTED) == 0)
+       rep = expand_string_if_necessary (rep, quoted, expand_string_unsplit);
+      else
+       rep = expand_string_to_string_internal (rep, quoted, expand_string_unsplit);
+    }
+
+  /* ksh93 doesn't allow the match specifier to be a part of the expanded
+     pattern.  This is an extension.  Make sure we don't anchor the pattern
+     at the beginning or end of the string if we're doing global replacement,
+     though. */
+  p = pat;
+  if (mflags & MATCH_GLOBREP)
+    mflags |= MATCH_ANY;
+  else if (pat && pat[0] == '#')
+    {
+      mflags |= MATCH_BEG;
+      p++;
+    }
+  else if (pat && pat[0] == '%')
+    {
+      mflags |= MATCH_END;
+      p++;
+    }
+  else
+    mflags |= MATCH_ANY;
+
+  /* OK, we now want to substitute REP for PAT in VAL.  If
+     flags & MATCH_GLOBREP is non-zero, the substitution is done
+     everywhere, otherwise only the first occurrence of PAT is
+     replaced.  The pattern matching code doesn't understand
+     CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
+     values passed in (VT_VARIABLE) so the pattern substitution
+     code works right.  We need to requote special chars after
+     we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
+     other cases if QUOTED == 0, since the posparams and arrays
+     indexed by * or @ do special things when QUOTED != 0. */
+
+  switch (vtype)
+    {
+    case VT_VARIABLE:
+    case VT_ARRAYMEMBER:
+      temp = pat_subst (val, p, rep, mflags);
+      if (vtype == VT_VARIABLE)
+       FREE (val);
+      if (temp)
+       {
+         tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp);
+         free (temp);
+         temp = tt;
+       }
+      break;
+    case VT_POSPARMS:
+      temp = pos_params_pat_subst (val, p, rep, mflags);
+      if (temp && (mflags & MATCH_QUOTED) == 0)
+       {
+         tt = quote_escapes (temp);
+         free (temp);
+         temp = tt;
+       }
+      break;
+#if defined (ARRAY_VARS)
+    case VT_ARRAYVAR:
+      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
+        array_quote_escapes as appropriate before adding the
+        space separators; ditto for assoc_patsub. */
+      break;
+#endif
+    }
+
+  FREE (pat);
+  FREE (rep);
+  free (lpatsub);
+
+  return temp;
+}
+
+/****************************************************************/
+/*                                                             */
+/*   Functions to perform case modification on variable values  */
+/*                                                             */
+/****************************************************************/
+
+/* Do case modification on the positional parameters. */
+
+static char *
+pos_params_modcase (string, pat, modop, mflags)
+     char *string, *pat;
+     int modop;
+     int mflags;
+{
+  WORD_LIST *save, *params;
+  WORD_DESC *w;
+  char *ret;
+  int pchar, qflags;
+
+  save = params = list_rest_of_args ();
+  if (save == 0)
+    return ((char *)NULL);
+
+  for ( ; params; params = params->next)
+    {
+      ret = sh_modcase (params->word->word, pat, modop);
+      w = alloc_word_desc ();
+      w->word = ret ? ret : savestring ("");
+      dispose_word (params->word);
+      params->word = w;
+    }
+
+  pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
+  qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
+
+  ret = string_list_pos_params (pchar, save, qflags);
+  dispose_words (save);
+
+  return (ret);
+}
+
+/* Perform case modification on VALUE, which is the expansion of
+   VARNAME.  MODSPEC is an expression supplying the type of modification
+   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)
+     char *varname, *value;
+     int ind, modspec;
+     char *patspec;
+     int quoted, flags;
+{
+  int vtype, starsub, modop, mflags, x;
+  char *val, *temp, *pat, *p, *lpat, *tt;
+  SHELL_VAR *v;
+
+  if (value == 0)
+    return ((char *)NULL);
+
+  this_command_name = varname;
+
+  vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
+  if (vtype == -1)
+    return ((char *)NULL);
+
+  starsub = vtype & VT_STARSUB;
+  vtype &= ~VT_STARSUB;
+
+  modop = 0;
+  mflags = 0;
+  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
+    mflags |= MATCH_QUOTED;
+  if (starsub)
+    mflags |= MATCH_STARSUB;
+  
+  p = patspec;
+  if (modspec == '^')
+    {
+      x = p && p[0] == modspec;
+      modop = x ? CASE_UPPER : CASE_UPFIRST;
+      p += x;
+    }
+  else if (modspec == ',')
+    {
+      x = p && p[0] == modspec;
+      modop = x ? CASE_LOWER : CASE_LOWFIRST;
+      p += x;
+    }
+  else if (modspec == '~')
+    {
+      x = p && p[0] == modspec;
+      modop = x ? CASE_TOGGLEALL : CASE_TOGGLE;
+      p += x;
+    }
+    
+  lpat = p ? savestring (p) : 0;
+  /* Perform the same expansions on the pattern as performed by the
+     pattern removal expansions.  FOR LATER */
+  pat = lpat ? getpattern (lpat, quoted, 1) : 0;
+
+  /* OK, now we do the case modification. */
+  switch (vtype)
+    {
+    case VT_VARIABLE:
+    case VT_ARRAYMEMBER:
+      temp = sh_modcase (val, pat, modop);
+      if (vtype == VT_VARIABLE)
+       FREE (val);
+      if (temp)
+       {
+         tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp);
+         free (temp);
+         temp = tt;
+       }
+      break;
+
+    case VT_POSPARMS:
+      temp = pos_params_modcase (val, pat, modop, mflags);
+      if (temp && (mflags & MATCH_QUOTED)  == 0)
+       {
+         tt = quote_escapes (temp);
+         free (temp);
+         temp = tt;
+       }
+      break;
+
+#if defined (ARRAY_VARS)
+    case VT_ARRAYVAR:
+      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
+        as appropriate before adding the space separators; ditto for
+        assoc_modcase. */
+      break;
+#endif
+    }
+
+  FREE (pat);
+  free (lpat);
+
+  return temp;
+}
+
+/* Check for unbalanced parens in S, which is the contents of $(( ... )).  If
+   any occur, this must be a nested command substitution, so return 0.
+   Otherwise, return 1.  A valid arithmetic expression must always have a
+   ( before a matching ), so any cases where there are more right parens
+   means that this must not be an arithmetic expression, though the parser
+   will not accept it without a balanced total number of parens. */
+static int
+chk_arithsub (s, len)
+     const char *s;
+     int len;
+{
+  int i, count;
+  DECLARE_MBSTATE;
+
+  i = count = 0;
+  while (i < len)
+    {
+      if (s[i] == LPAREN)
+       count++;
+      else if (s[i] == RPAREN)
+       {
+         count--;
+         if (count < 0)
+           return 0;
+       }
+
+      switch (s[i])
+       {
+       default:
+         ADVANCE_CHAR (s, len, i);
+         break;
+
+       case '\\':
+         i++;
+         if (s[i])
+           ADVANCE_CHAR (s, len, i);
+         break;
+
+       case '\'':
+         i = skip_single_quoted (s, len, ++i);
+         break;
+
+       case '"':
+         i = skip_double_quoted ((char *)s, len, ++i);
+         break;
+       }
+    }
+
+  return (count == 0);
+}
+
+/****************************************************************/
+/*                                                             */
+/*     Functions to perform parameter expansion on a string    */
+/*                                                             */
+/****************************************************************/
+
+/* ${[#][!]name[[:][^[^]][,[,]]#[#]%[%]-=?+[word][:e1[:e2]]]} */
+static WORD_DESC *
+parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, contains_dollar_at)
+     char *string;
+     int *indexp, quoted, *quoted_dollar_atp, *contains_dollar_at, pflags;
+{
+  int check_nullness, var_is_set, var_is_null, var_is_special;
+  int want_substring, want_indir, want_patsub, want_casemod;
+  char *name, *value, *temp, *temp1;
+  WORD_DESC *tdesc, *ret;
+  int t_index, sindex, c, tflag, modspec;
+  intmax_t number;
+  arrayind_t ind;
+
+  temp = temp1 = value = (char *)NULL;
+  var_is_set = var_is_null = var_is_special = check_nullness = 0;
+  want_substring = want_indir = want_patsub = want_casemod = 0;
+
+  sindex = *indexp;
+  t_index = ++sindex;
+  /* ${#var} doesn't have any of the other parameter expansions on it. */
+  if (string[t_index] == '#' && legal_variable_starter (string[t_index+1]))            /* {{ */
+    name = string_extract (string, &t_index, "}", SX_VARNAME);
+  else
+#if defined (CASEMOD_EXPANSIONS)
+    /* To enable case-toggling expansions using the `~' operator character
+       change the 1 to 0. */
+#  if defined (CASEMOD_CAPCASE)
+    name = string_extract (string, &t_index, "#%^,~:-=?+/@}", SX_VARNAME);
+#  else
+    name = string_extract (string, &t_index, "#%^,:-=?+/@}", SX_VARNAME);
+#  endif /* CASEMOD_CAPCASE */
+#else
+    name = string_extract (string, &t_index, "#%:-=?+/@}", SX_VARNAME);
+#endif /* CASEMOD_EXPANSIONS */
+
+  /* Handle ${@[stuff]} now that @ is a word expansion operator.  Not exactly
+     the cleanest code ever. */
+  if (*name == 0 && sindex == t_index && string[sindex] == '@')
+    {
+      name = (char *)xrealloc (name, 2);
+      name[0] = '@';
+      name[1] = '\0';
+      t_index++;
+    }
+
+  ret = 0;
+  tflag = 0;
+
+  ind = INTMAX_MIN;
+
+  /* If the name really consists of a special variable, then make sure
+     that we have the entire name.  We don't allow indirect references
+     to special variables except `#', `?', `@' and `*'.  This clause is
+     designed to handle ${#SPECIAL} and ${!SPECIAL}, not anything more
+     general. */
+  if ((sindex == t_index && VALID_SPECIAL_LENGTH_PARAM (string[t_index])) ||
+      (sindex == t_index && string[sindex] == '#' && VALID_SPECIAL_LENGTH_PARAM (string[sindex + 1])) ||
+      (sindex == t_index - 1 && string[sindex] == '!' && VALID_INDIR_PARAM (string[t_index])))
+    {
+      t_index++;
+      temp1 = string_extract (string, &t_index, "#%:-=?+/@}", 0);
+      name = (char *)xrealloc (name, 3 + (strlen (temp1)));
+      *name = string[sindex];
+      if (string[sindex] == '!')
+       {
+         /* indirect reference of $#, $?, $@, or $* */
+         name[1] = string[sindex + 1];
+         strcpy (name + 2, temp1);
+       }
+      else     
+       strcpy (name + 1, temp1);
+      free (temp1);
+    }
+  sindex = t_index;
+
+  /* Find out what character ended the variable name.  Then
+     do the appropriate thing. */
+  if (c = string[sindex])
+    sindex++;
+
+  /* If c is followed by one of the valid parameter expansion
+     characters, move past it as normal.  If not, assume that
+     a substring specification is being given, and do not move
+     past it. */
+  if (c == ':' && VALID_PARAM_EXPAND_CHAR (string[sindex]))
+    {
+      check_nullness++;
+      if (c = string[sindex])
+       sindex++;
+    }
+  else if (c == ':' && string[sindex] != RBRACE)
+    want_substring = 1;
+  else if (c == '/' /* && string[sindex] != RBRACE */) /* XXX */
+    want_patsub = 1;
+#if defined (CASEMOD_EXPANSIONS)
+  else if (c == '^' || c == ',' || c == '~')
+    {
+      modspec = c;
+      want_casemod = 1;
+    }
+#endif
+
+  /* Catch the valid and invalid brace expressions that made it through the
+     tests above. */
+  /* ${#-} is a valid expansion and means to take the length of $-.
+     Similarly for ${#?} and ${##}... */
+  if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
+       VALID_SPECIAL_LENGTH_PARAM (c) && string[sindex] == RBRACE)
+    {
+      name = (char *)xrealloc (name, 3);
+      name[1] = c;
+      name[2] = '\0';
+      c = string[sindex++];
+    }
+
+  /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
+  if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
+       member (c, "%:=+/") && string[sindex] == RBRACE)
+    {
+      temp = (char *)NULL;
+      goto bad_substitution;
+    }
+
+  /* Indirect expansion begins with a `!'.  A valid indirect expansion is
+     either a variable name, one of the positional parameters or a special
+     variable that expands to one of the positional parameters. */
+  want_indir = *name == '!' &&
+    (legal_variable_starter ((unsigned char)name[1]) || DIGIT (name[1])
+                                       || VALID_INDIR_PARAM (name[1]));
+
+  /* Determine the value of this variable. */
+
+  /* Check for special variables, directly referenced. */
+  if (SPECIAL_VAR (name, want_indir))
+    var_is_special++;
+
+  /* Check for special expansion things, like the length of a parameter */
+  if (*name == '#' && name[1])
+    {
+      /* If we are not pointing at the character just after the
+        closing brace, then we haven't gotten all of the name.
+        Since it begins with a special character, this is a bad
+        substitution.  Also check NAME for validity before trying
+        to go on. */
+      if (string[sindex - 1] != RBRACE || (valid_length_expression (name) == 0))
+       {
+         temp = (char *)NULL;
+         goto bad_substitution;
+       }
+
+      number = parameter_brace_expand_length (name);
+      if (number == INTMAX_MIN && unbound_vars_is_error)
+       {
+         last_command_exit_value = EXECUTION_FAILURE;
+         err_unboundvar (name+1);
+         free (name);
+         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
+       }
+      free (name);
+
+      *indexp = sindex;
+      if (number < 0)
+        return (&expand_wdesc_error);
+      else
+       {
+         ret = alloc_word_desc ();
+         ret->word = itos (number);
+         return ret;
+       }
+    }
+
+  /* ${@} is identical to $@. */
+  if (name[0] == '@' && name[1] == '\0')
+    {
+      if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
+       *quoted_dollar_atp = 1;
+
+      if (contains_dollar_at)
+       *contains_dollar_at = 1;
+
+      tflag |= W_DOLLARAT;
+    }
+
+  /* Process ${!PREFIX*} expansion. */
+  if (want_indir && string[sindex - 1] == RBRACE &&
+      (string[sindex - 2] == '*' || string[sindex - 2] == '@') &&
+      legal_variable_starter ((unsigned char) name[1]))
+    {
+      char **x;
+      WORD_LIST *xlist;
+
+      temp1 = savestring (name + 1);
+      number = strlen (temp1);
+      temp1[number - 1] = '\0';
+      x = all_variables_matching_prefix (temp1);
+      xlist = strvec_to_word_list (x, 0, 0);
+      if (string[sindex - 2] == '*')
+       temp = string_list_dollar_star (xlist);
+      else
+       {
+         temp = string_list_dollar_at (xlist, quoted);
+         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
+           *quoted_dollar_atp = 1;
+         if (contains_dollar_at)
+           *contains_dollar_at = 1;
+
+         tflag |= W_DOLLARAT;
+       }
+      free (x);
+      dispose_words (xlist);
+      free (temp1);
+      *indexp = sindex;
+
+      free (name);
+
+      ret = alloc_word_desc ();
+      ret->word = temp;
+      ret->flags = tflag;      /* XXX */
+      return ret;
+    }
+
+#if defined (ARRAY_VARS)      
+  /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
+  if (want_indir && string[sindex - 1] == RBRACE &&
+      string[sindex - 2] == ']' && valid_array_reference (name+1))
+    {
+      char *x, *x1;
+
+      temp1 = savestring (name + 1);
+      x = array_variable_name (temp1, &x1, (int *)0);  /* [ */
+      FREE (x);
+      if (ALL_ELEMENT_SUB (x1[0]) && x1[1] == ']')
+       {
+         temp = array_keys (temp1, quoted);    /* handles assoc vars too */
+         if (x1[0] == '@')
+           {
+             if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
+               *quoted_dollar_atp = 1;
+             if (contains_dollar_at)
+               *contains_dollar_at = 1;
+
+             tflag |= W_DOLLARAT;
+           }       
+
+         free (temp1);
+         *indexp = sindex;
+
+         ret = alloc_word_desc ();
+         ret->word = temp;
+         ret->flags = tflag;   /* XXX */
+         return ret;
+       }
+
+      free (temp1);
+    }
+#endif /* ARRAY_VARS */
+      
+  /* Make sure that NAME is valid before trying to go on. */
+  if (valid_brace_expansion_word (want_indir ? name + 1 : name,
+                                       var_is_special) == 0)
+    {
+      temp = (char *)NULL;
+      goto bad_substitution;
+    }
+
+  if (want_indir)
+    {
+      tdesc = parameter_brace_expand_indir (name + 1, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at);
+      /* Turn off the W_ARRAYIND flag because there is no way for this function
+        to return the index we're supposed to be using. */
+      if (tdesc && tdesc->flags)
+       tdesc->flags &= ~W_ARRAYIND;
+    }
+  else
+    tdesc = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND|(pflags&(PF_NOSPLIT2|PF_ASSIGNRHS)), &ind);
+
+  if (tdesc)
+    {
+      temp = tdesc->word;
+      tflag = tdesc->flags;
+      dispose_word_desc (tdesc);
+    }
+  else
+    temp = (char  *)0;
+
+  if (temp == &expand_param_error || temp == &expand_param_fatal)
+    {
+      FREE (name);
+      FREE (value);
+      return (temp == &expand_param_error ? &expand_wdesc_error : &expand_wdesc_fatal);
+    }
+
+#if defined (ARRAY_VARS)
+  if (valid_array_reference (name))
+    chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at);
+#endif
+
+  var_is_set = temp != (char *)0;
+  var_is_null = check_nullness && (var_is_set == 0 || *temp == 0);
+  /* XXX - this may not need to be restricted to special variables */
+  if (check_nullness)
+    var_is_null |= var_is_set && var_is_special && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && QUOTED_NULL (temp);
+
+  /* Get the rest of the stuff inside the braces. */
+  if (c && c != RBRACE)
+    {
+      /* Extract the contents of the ${ ... } expansion
+        according to the Posix.2 rules. */
+      value = extract_dollar_brace_string (string, &sindex, quoted, (c == '%' || c == '#' || c =='/' || c == '^' || c == ',' || c ==':') ? SX_POSIXEXP|SX_WORD : SX_WORD);
+      if (string[sindex] == RBRACE)
+       sindex++;
+      else
+       goto bad_substitution;
+    }
+  else
+    value = (char *)NULL;
+
+  *indexp = sindex;
+
+  /* All the cases where an expansion can possibly generate an unbound
+     variable error. */
+  if (want_substring || want_patsub || want_casemod || c == '#' || c == '%' || c == RBRACE)
+    {
+      if (var_is_set == 0 && unbound_vars_is_error && ((name[0] != '@' && name[0] != '*') || name[1]))
+       {
+         last_command_exit_value = EXECUTION_FAILURE;
+         err_unboundvar (name);
+         FREE (value);
+         FREE (temp);
+         free (name);
+         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
+       }
+    }
+    
+  /* 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);
+      FREE (name);
+      FREE (value);
+      FREE (temp);
+
+      if (temp1 == &expand_param_error)
+       return (&expand_wdesc_error);
+      else if (temp1 == &expand_param_fatal)
+       return (&expand_wdesc_fatal);
+
+      ret = alloc_word_desc ();
+      ret->word = temp1;
+      /* We test quoted_dollar_atp because we want variants with double-quoted
+        "$@" to take a different code path. In fact, we make sure at the end
+        of expand_word_internal that we're only looking at these flags if
+        quoted_dollar_at == 0. */
+      if (temp1 && 
+          (quoted_dollar_atp == 0 || *quoted_dollar_atp == 0) &&
+         QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
+       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
+      return ret;
+    }
+  else if (want_patsub)
+    {
+      temp1 = parameter_brace_patsub (name, temp, ind, value, quoted, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
+      FREE (name);
+      FREE (value);
+      FREE (temp);
+
+      if (temp1 == &expand_param_error)
+       return (&expand_wdesc_error);
+      else if (temp1 == &expand_param_fatal)
+       return (&expand_wdesc_fatal);
+
+      ret = alloc_word_desc ();
+      ret->word = temp1;
+      if (temp1 && 
+          (quoted_dollar_atp == 0 || *quoted_dollar_atp == 0) &&
+         QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
+       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
+      return ret;
+    }
+#if defined (CASEMOD_EXPANSIONS)
+  else if (want_casemod)
+    {
+      temp1 = parameter_brace_casemod (name, temp, ind, modspec, value, quoted, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
+      FREE (name);
+      FREE (value);
+      FREE (temp);
+
+      if (temp1 == &expand_param_error)
+       return (&expand_wdesc_error);
+      else if (temp1 == &expand_param_fatal)
+       return (&expand_wdesc_fatal);
+
+      ret = alloc_word_desc ();
+      ret->word = temp1;
+      if (temp1 &&
+          (quoted_dollar_atp == 0 || *quoted_dollar_atp == 0) &&
+         QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
+       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
+      return ret;
+    }
+#endif
+
+  /* Do the right thing based on which character ended the variable name. */
+  switch (c)
+    {
+    default:
+    case '\0':
+    bad_substitution:
+      last_command_exit_value = EXECUTION_FAILURE;
+      report_error (_("%s: bad substitution"), string ? string : "??");
+      FREE (value);
+      FREE (temp);
+      free (name);
+      return &expand_wdesc_error;
+
+    case RBRACE:
+      break;
+
+    case '@':
+      temp1 = parameter_brace_transform (name, temp, ind, value, c, quoted, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
+      if (temp1 == &expand_param_error || temp1 == &expand_param_fatal)
+       goto bad_substitution;
+
+      free (temp);
+      free (value);
+      free (name);
+
+      ret = alloc_word_desc ();
+      ret->word = temp1;
+      if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
+       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
+      return ret;
+
+    case '#':  /* ${param#[#]pattern} */
+    case '%':  /* ${param%[%]pattern} */
+      if (value == 0 || *value == '\0' || temp == 0 || *temp == '\0')
+       {
+         FREE (value);
+         break;
+       }
+      temp1 = parameter_brace_remove_pattern (name, temp, ind, value, c, quoted, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
+      free (temp);
+      free (value);
+      free (name);
+
+      ret = alloc_word_desc ();
+      ret->word = temp1;
+      if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
+       ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
+      return ret;
+
+    case '-':
+    case '=':
+    case '?':
+    case '+':
+      if (var_is_set && var_is_null == 0)
+       {
+         /* If the operator is `+', we don't want the value of the named
+            variable for anything, just the value of the right hand side. */
+         if (c == '+')
+           {
+             /* XXX -- if we're double-quoted and the named variable is "$@",
+                       we want to turn off any special handling of "$@" --
+                       we're not using it, so whatever is on the rhs applies. */
+             if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
+               *quoted_dollar_atp = 0;
+             if (contains_dollar_at)
+               *contains_dollar_at = 0;
+
+             FREE (temp);
+             if (value)
+               {
+                 /* From Posix discussion on austin-group list.  Issue 221
+                    requires that backslashes escaping `}' inside
+                    double-quoted ${...} be removed. */
+                 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
+                   quoted |= Q_DOLBRACE;
+                 ret = parameter_brace_expand_rhs (name, value, c,
+                                                   quoted,
+                                                   quoted_dollar_atp,
+                                                   contains_dollar_at);
+                 /* XXX - fix up later, esp. noting presence of
+                          W_HASQUOTEDNULL in ret->flags */
+                 free (value);
+               }
+             else
+               temp = (char *)NULL;
+           }
+         else
+           {
+             FREE (value);
+           }
+         /* Otherwise do nothing; just use the value in TEMP. */
+       }
+      else     /* VAR not set or VAR is NULL. */
+       {
+         FREE (temp);
+         temp = (char *)NULL;
+         if (c == '=' && var_is_special)
+           {
+             last_command_exit_value = EXECUTION_FAILURE;
+             report_error (_("$%s: cannot assign in this way"), name);
+             free (name);
+             free (value);
+             return &expand_wdesc_error;
+           }
+         else if (c == '?')
+           {
+             parameter_brace_expand_error (name, value);
+             return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
+           }
+         else if (c != '+')
+           {
+             /* XXX -- if we're double-quoted and the named variable is "$@",
+                       we want to turn off any special handling of "$@" --
+                       we're not using it, so whatever is on the rhs applies. */
+             if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
+               *quoted_dollar_atp = 0;
+             if (contains_dollar_at)
+               *contains_dollar_at = 0;
+
+             /* From Posix discussion on austin-group list.  Issue 221 requires
+                that backslashes escaping `}' inside double-quoted ${...} be
+                removed. */
+             if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
+               quoted |= Q_DOLBRACE;
+             ret = parameter_brace_expand_rhs (name, value, c, quoted,
+                                               quoted_dollar_atp,
+                                               contains_dollar_at);
+             /* XXX - fix up later, esp. noting presence of
+                      W_HASQUOTEDNULL in tdesc->flags */
+           }
+         free (value);
+       }
+
+      break;
+    }
+  free (name);
+
+  if (ret == 0)
+    {
+      ret = alloc_word_desc ();
+      ret->flags = tflag;
+      ret->word = temp;
+    }
+  return (ret);
+}
+
+/* Expand a single ${xxx} expansion.  The braces are optional.  When
+   the braces are used, parameter_brace_expand() does the work,
+   possibly calling param_expand recursively. */
+static WORD_DESC *
+param_expand (string, sindex, quoted, expanded_something,
+             contains_dollar_at, quoted_dollar_at_p, had_quoted_null_p,
+             pflags)
+     char *string;
+     int *sindex, quoted, *expanded_something, *contains_dollar_at;
+     int *quoted_dollar_at_p, *had_quoted_null_p, pflags;
+{
+  char *temp, *temp1, uerror[3];
+  int zindex, t_index, expok;
+  unsigned char c;
+  intmax_t number;
+  SHELL_VAR *var;
+  WORD_LIST *list;
+  WORD_DESC *tdesc, *ret;
+  int tflag;
+
+  zindex = *sindex;
+  c = string[++zindex];
+
+  temp = (char *)NULL;
+  ret = tdesc = (WORD_DESC *)NULL;
+  tflag = 0;
+
+  /* Do simple cases first. Switch on what follows '$'. */
+  switch (c)
+    {
+    /* $0 .. $9? */
+    case '0':
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+      temp1 = dollar_vars[TODIGIT (c)];
+      if (unbound_vars_is_error && temp1 == (char *)NULL)
+       {
+         uerror[0] = '$';
+         uerror[1] = c;
+         uerror[2] = '\0';
+         last_command_exit_value = EXECUTION_FAILURE;
+         err_unboundvar (uerror);
+         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
+       }
+      if (temp1)
+       temp = (*temp1 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
+                 ? quote_string (temp1)
+                 : quote_escapes (temp1);
+      else
+       temp = (char *)NULL;
+
+      break;
+
+    /* $$ -- pid of the invoking shell. */
+    case '$':
+      temp = itos (dollar_dollar_pid);
+      break;
+
+    /* $# -- number of positional parameters. */
+    case '#':
+      temp = itos (number_of_args ());
+      break;
+
+    /* $? -- return value of the last synchronous command. */
+    case '?':
+      temp = itos (last_command_exit_value);
+      break;
+
+    /* $- -- flags supplied to the shell on invocation or by `set'. */
+    case '-':
+      temp = which_set_flags ();
+      break;
+
+      /* $! -- Pid of the last asynchronous command. */
+    case '!':
+      /* If no asynchronous pids have been created, expand to nothing.
+        If `set -u' has been executed, and no async processes have
+        been created, this is an expansion error. */
+      if (last_asynchronous_pid == NO_PID)
+       {
+         if (expanded_something)
+           *expanded_something = 0;
+         temp = (char *)NULL;
+         if (unbound_vars_is_error)
+           {
+             uerror[0] = '$';
+             uerror[1] = c;
+             uerror[2] = '\0';
+             last_command_exit_value = EXECUTION_FAILURE;
+             err_unboundvar (uerror);
+             return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
+           }
+       }
+      else
+       temp = itos (last_asynchronous_pid);
+      break;
+
+    /* The only difference between this and $@ is when the arg is quoted. */
+    case '*':          /* `$*' */
+      list = list_rest_of_args ();
+
+#if 0
+      /* According to austin-group posix proposal by Geoff Clare in
+        <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
+
+       "The shell shall write a message to standard error and
+        immediately exit when it tries to expand an unset parameter
+        other than the '@' and '*' special parameters."
+      */
+
+      if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
+       {
+         uerror[0] = '$';
+         uerror[1] = '*';
+         uerror[2] = '\0';
+         last_command_exit_value = EXECUTION_FAILURE;
+         err_unboundvar (uerror);
+         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
+       }
+#endif
+
+      /* If there are no command-line arguments, this should just
+        disappear if there are other characters in the expansion,
+        even if it's quoted. */
+      if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && list == 0)
+       temp = (char *)NULL;
+      else if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES|Q_PATQUOTE))
+       {
+         /* If we have "$*" we want to make a string of the positional
+            parameters, separated by the first character of $IFS, and
+            quote the whole string, including the separators.  If IFS
+            is unset, the parameters are separated by ' '; if $IFS is
+            null, the parameters are concatenated. */
+         temp = (quoted & (Q_DOUBLE_QUOTES|Q_PATQUOTE)) ? string_list_dollar_star (list) : string_list (list);
+         if (temp)
+           {
+             temp1 = (quoted & Q_DOUBLE_QUOTES) ? quote_string (temp) : temp;
+             if (*temp == 0)
+               tflag |= W_HASQUOTEDNULL;
+             if (temp != temp1)
+               free (temp);
+             temp = temp1;
+           }
+       }
+      else
+       {
+         /* We check whether or not we're eventually going to split $* here,
+            for example when IFS is empty and we are processing the rhs of
+            an assignment statement.  In that case, we don't separate the
+            arguments at all.  Otherwise, if the $* is not quoted it is
+            identical to $@ */
+#  if defined (HANDLE_MULTIBYTE)
+         if (expand_no_split_dollar_star && ifs_firstc[0] == 0)
+#  else
+         if (expand_no_split_dollar_star && ifs_firstc == 0)
+#  endif
+           temp = string_list_dollar_star (list);
+         else
+           {
+             temp = string_list_dollar_at (list, quoted);
+             if (quoted == 0 && (ifs_is_set == 0 || ifs_is_null))
+               tflag |= W_SPLITSPACE;
+           }
+
+         if (expand_no_split_dollar_star == 0 && contains_dollar_at)
+           *contains_dollar_at = 1;
+       }
+
+      dispose_words (list);
+      break;
+
+    /* When we have "$@" what we want is "$1" "$2" "$3" ... This
+       means that we have to turn quoting off after we split into
+       the individually quoted arguments so that the final split
+       on the first character of $IFS is still done.  */
+    case '@':          /* `$@' */
+      list = list_rest_of_args ();
+
+#if 0
+      /* According to austin-group posix proposal by Geoff Clare in
+        <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
+
+       "The shell shall write a message to standard error and
+        immediately exit when it tries to expand an unset parameter
+        other than the '@' and '*' special parameters."
+      */
+
+      if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
+       {
+         uerror[0] = '$';
+         uerror[1] = '@';
+         uerror[2] = '\0';
+         last_command_exit_value = EXECUTION_FAILURE;
+         err_unboundvar (uerror);
+         return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
+       }
+#endif
+
+      /* We want to flag the fact that we saw this.  We can't turn
+        off quoting entirely, because other characters in the
+        string might need it (consider "\"$@\""), but we need some
+        way to signal that the final split on the first character
+        of $IFS should be done, even though QUOTED is 1. */
+      /* XXX - should this test include Q_PATQUOTE? */
+      if (quoted_dollar_at_p && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
+       *quoted_dollar_at_p = 1;
+      if (contains_dollar_at)
+       *contains_dollar_at = 1;
+
+      /* We want to separate the positional parameters with the first
+        character of $IFS in case $IFS is something other than a space.
+        We also want to make sure that splitting is done no matter what --
+        according to POSIX.2, this expands to a list of the positional
+        parameters no matter what IFS is set to. */
+      /* XXX - what to do when in a context where word splitting is not
+        performed? Even when IFS is not the default, posix seems to imply
+        that we behave like unquoted $* ?  Maybe we should use PF_NOSPLIT2
+        here. */
+      temp = string_list_dollar_at (list, (pflags & PF_ASSIGNRHS) ? (quoted|Q_DOUBLE_QUOTES) : quoted);
+
+      tflag |= W_DOLLARAT;
+      dispose_words (list);
+      break;
+
+    case LBRACE:
+      tdesc = parameter_brace_expand (string, &zindex, quoted, pflags,
+                                     quoted_dollar_at_p,
+                                     contains_dollar_at);
+
+      if (tdesc == &expand_wdesc_error || tdesc == &expand_wdesc_fatal)
+       return (tdesc);
+      temp = tdesc ? tdesc->word : (char *)0;
+
+      /* XXX */
+      /* Quoted nulls should be removed if there is anything else
+        in the string. */
+      /* Note that we saw the quoted null so we can add one back at
+        the end of this function if there are no other characters
+        in the string, discard TEMP, and go on.  The exception to
+        this is when we have "${@}" and $1 is '', since $@ needs
+        special handling. */
+      if (tdesc && tdesc->word && (tdesc->flags & W_HASQUOTEDNULL) && QUOTED_NULL (temp))
+       {
+         if (had_quoted_null_p)
+           *had_quoted_null_p = 1;
+         if (*quoted_dollar_at_p == 0)
+           {
+             free (temp);
+             tdesc->word = temp = (char *)NULL;
+           }
+           
+       }
+
+      ret = tdesc;
+      goto return0;
+
+    /* Do command or arithmetic substitution. */
+    case LPAREN:
+      /* We have to extract the contents of this paren substitution. */
+      t_index = zindex + 1;
+      temp = extract_command_subst (string, &t_index, 0);
+      zindex = t_index;
+
+      /* For Posix.2-style `$(( ))' arithmetic substitution,
+        extract the expression and pass it to the evaluator. */
+      if (temp && *temp == LPAREN)
+       {
+         char *temp2;
+         temp1 = temp + 1;
+         temp2 = savestring (temp1);
+         t_index = strlen (temp2) - 1;
+
+         if (temp2[t_index] != RPAREN)
+           {
+             free (temp2);
+             goto comsub;
+           }
+
+         /* Cut off ending `)' */
+         temp2[t_index] = '\0';
+
+         if (chk_arithsub (temp2, t_index) == 0)
+           {
+             free (temp2);
+#if 0
+             internal_warning (_("future versions of the shell will force evaluation as an arithmetic substitution"));
+#endif
+             goto comsub;
+           }
+
+         /* Expand variables found inside the expression. */
+         temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES|Q_ARITH);
+         free (temp2);
+
+arithsub:
+         /* No error messages. */
+         this_command_name = (char *)NULL;
+         number = evalexp (temp1, &expok);
+         free (temp);
+         free (temp1);
+         if (expok == 0)
+           {
+             if (interactive_shell == 0 && posixly_correct)
+               {
+                 last_command_exit_value = EXECUTION_FAILURE;
+                 return (&expand_wdesc_fatal);
+               }
+             else
+               return (&expand_wdesc_error);
+           }
+         temp = itos (number);
+         break;
+       }
+
+comsub:
+      if (pflags & PF_NOCOMSUB)
+       /* we need zindex+1 because string[zindex] == RPAREN */
+       temp1 = substring (string, *sindex, zindex+1);
+      else
+       {
+         tdesc = command_substitute (temp, quoted);
+         temp1 = tdesc ? tdesc->word : (char *)NULL;
+         if (tdesc)
+           dispose_word_desc (tdesc);
+       }
+      FREE (temp);
+      temp = temp1;
+      break;
+
+    /* Do POSIX.2d9-style arithmetic substitution.  This will probably go
+       away in a future bash release. */
+    case '[':
+      /* Extract the contents of this arithmetic substitution. */
+      t_index = zindex + 1;
+      temp = extract_arithmetic_subst (string, &t_index);
+      zindex = t_index;
+      if (temp == 0)
+       {
+         temp = savestring (string);
+         if (expanded_something)
+           *expanded_something = 0;
+         goto return0;
+       }         
+
+       /* Do initial variable expansion. */
+      temp1 = expand_arith_string (temp, Q_DOUBLE_QUOTES|Q_ARITH);
+
+      goto arithsub;
+
+    default:
+      /* Find the variable in VARIABLE_LIST. */
+      temp = (char *)NULL;
+
+      for (t_index = zindex; (c = string[zindex]) && legal_variable_char (c); zindex++)
+       ;
+      temp1 = (zindex > t_index) ? substring (string, t_index, zindex) : (char *)NULL;
+
+      /* If this isn't a variable name, then just output the `$'. */
+      if (temp1 == 0 || *temp1 == '\0')
+       {
+         FREE (temp1);
+         temp = (char *)xmalloc (2);
+         temp[0] = '$';
+         temp[1] = '\0';
+         if (expanded_something)
+           *expanded_something = 0;
+         goto return0;
+       }
+
+      /* If the variable exists, return its value cell. */
+      var = find_variable (temp1);
+
+      if (var && invisible_p (var) == 0 && var_isset (var))
+       {
+#if defined (ARRAY_VARS)
+         if (assoc_p (var) || array_p (var))
+           {
+             temp = array_p (var) ? array_reference (array_cell (var), 0)
+                                  : assoc_reference (assoc_cell (var), "0");
+             if (temp)
+               temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
+                         ? quote_string (temp)
+                         : quote_escapes (temp);
+             else if (unbound_vars_is_error)
+               goto unbound_variable;
+           }
+         else
+#endif
+           {
+             temp = value_cell (var);
+
+             temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
+                       ? quote_string (temp)
+                       : quote_escapes (temp);
+           }
+
+         free (temp1);
+
+         goto return0;
+       }
+      else if (var && (invisible_p (var) || var_isset (var) == 0))
+       temp = (char *)NULL;
+      else if ((var = find_variable_last_nameref (temp1)) && var_isset (var) && invisible_p (var) == 0)
+       {
+         temp = nameref_cell (var);
+#if defined (ARRAY_VARS)
+         if (temp && *temp && valid_array_reference (temp))
+           {
+             tdesc = parameter_brace_expand_word (temp, SPECIAL_VAR (temp, 0), quoted, pflags, (arrayind_t *)NULL);
+             if (tdesc == &expand_wdesc_error || tdesc == &expand_wdesc_fatal)
+               return (tdesc);
+             ret = tdesc;
+             goto return0;
+           }
+         else
+#endif
+         /* y=2 ; typeset -n x=y; echo $x is not the same as echo $2 in ksh */
+         if (temp && *temp && legal_identifier (temp) == 0)
+           {
+             last_command_exit_value = EXECUTION_FAILURE;
+             report_error (_("%s: invalid variable name for name reference"), temp);
+             return (&expand_wdesc_error);     /* XXX */
+           }
+         else
+           temp = (char *)NULL;
+       }
+
+      temp = (char *)NULL;
+
+unbound_variable:
+      if (unbound_vars_is_error)
+       {
+         last_command_exit_value = EXECUTION_FAILURE;
+         err_unboundvar (temp1);
+       }
+      else
+       {
+         free (temp1);
+         goto return0;
+       }
+
+      free (temp1);
+      last_command_exit_value = EXECUTION_FAILURE;
+      return ((unbound_vars_is_error && interactive_shell == 0)
+               ? &expand_wdesc_fatal
+               : &expand_wdesc_error);
+    }
+
+  if (string[zindex])
+    zindex++;
+
+return0:
+  *sindex = zindex;
+
+  if (ret == 0)
+    {
+      ret = alloc_word_desc ();
+      ret->flags = tflag;      /* XXX */
+      ret->word = temp;
+    }
+  return ret;
+}
+
+void
+invalidate_cached_quoted_dollar_at ()
+{
+  dispose_words (cached_quoted_dollar_at);
+  cached_quoted_dollar_at = 0;
+}
+
+/* Make a word list which is the result of parameter and variable
+   expansion, command substitution, arithmetic substitution, and
+   quote removal of WORD.  Return a pointer to a WORD_LIST which is
+   the result of the expansion.  If WORD contains a null word, the
+   word list returned is also null.
+
+   QUOTED contains flag values defined in shell.h.
+
+   ISEXP is used to tell expand_word_internal that the word should be
+   treated as the result of an expansion.  This has implications for
+   how IFS characters in the word are treated.
+
+   CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
+   they point to an integer value which receives information about expansion.
+   CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
+   EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
+   else zero.
+
+   This only does word splitting in the case of $@ expansion.  In that
+   case, we split on ' '. */
+
+/* Values for the local variable quoted_state. */
+#define UNQUOTED        0
+#define PARTIALLY_QUOTED 1
+#define WHOLLY_QUOTED    2
+
+static WORD_LIST *
+expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_something)
+     WORD_DESC *word;
+     int quoted, isexp;
+     int *contains_dollar_at;
+     int *expanded_something;
+{
+  WORD_LIST *list;
+  WORD_DESC *tword;
+
+  /* The intermediate string that we build while expanding. */
+  char *istring;
+
+  /* The current size of the above object. */
+  int istring_size;
+
+  /* Index into ISTRING. */
+  int istring_index;
+
+  /* Temporary string storage. */
+  char *temp, *temp1;
+
+  /* The text of WORD. */
+  register char *string;
+
+  /* The size of STRING. */
+  size_t string_size;
+
+  /* The index into STRING. */
+  int sindex;
+
+  /* This gets 1 if we see a $@ while quoted. */
+  int quoted_dollar_at;
+
+  /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
+     whether WORD contains no quoting characters, a partially quoted
+     string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
+  int quoted_state;
+
+  /* State flags */
+  int had_quoted_null;
+  int has_dollar_at, temp_has_dollar_at;
+  int split_on_spaces;
+  int tflag;
+  int pflags;                  /* flags passed to param_expand */
+
+  int assignoff;               /* If assignment, offset of `=' */
+
+  register unsigned char c;    /* Current character. */
+  int t_index;                 /* For calls to string_extract_xxx. */
+
+  char twochars[2];
+
+  DECLARE_MBSTATE;
+
+  /* OK, let's see if we can optimize a common idiom: "$@" */
+  if (STREQ (word->word, "\"$@\"") &&
+      (word->flags == (W_HASDOLLAR|W_QUOTED)) &&
+      dollar_vars[1])          /* XXX - check IFS here as well? */
+    {
+      if (contains_dollar_at)
+       *contains_dollar_at = 1;
+      if (expanded_something)
+       *expanded_something = 1;
+      if (cached_quoted_dollar_at)
+       return (copy_word_list (cached_quoted_dollar_at));
+      list = list_rest_of_args ();
+      list = quote_list (list);
+      cached_quoted_dollar_at = copy_word_list (list);
+      return (list);
+    }
+
+  istring = (char *)xmalloc (istring_size = DEFAULT_INITIAL_ARRAY_SIZE);
+  istring[istring_index = 0] = '\0';
+  quoted_dollar_at = had_quoted_null = has_dollar_at = 0;
+  split_on_spaces = 0;
+  quoted_state = UNQUOTED;
+
+  string = word->word;
+  if (string == 0)
+    goto finished_with_string;
+  /* Don't need the string length for the SADD... and COPY_ macros unless
+     multibyte characters are possible. */
+  string_size = (MB_CUR_MAX > 1) ? strlen (string) : 1;
+
+  if (contains_dollar_at)
+    *contains_dollar_at = 0;
+
+  assignoff = -1;
+
+  /* Begin the expansion. */
+
+  for (sindex = 0; ;)
+    {
+      c = string[sindex];
+
+      /* Case on top-level character. */
+      switch (c)
+       {
+       case '\0':
+         goto finished_with_string;
+
+       case CTLESC:
+         sindex++;
+#if HANDLE_MULTIBYTE
+         if (MB_CUR_MAX > 1 && string[sindex])
+           {
+             SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
+           }
+         else
+#endif
+           {
+             temp = (char *)xmalloc (3);
+             temp[0] = CTLESC;
+             temp[1] = c = string[sindex];
+             temp[2] = '\0';
+           }
+
+dollar_add_string:
+         if (string[sindex])
+           sindex++;
+
+add_string:
+         if (temp)
+           {
+             istring = sub_append_string (temp, istring, &istring_index, &istring_size);
+             temp = (char *)0;
+           }
+
+         break;
+
+#if defined (PROCESS_SUBSTITUTION)
+         /* Process substitution. */
+       case '<':
+       case '>':
+         {
+           /* bash-4.4/bash-5.0
+              XXX - technically this should only be expanded at the start
+              of a word */
+           if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (word->flags & (W_DQUOTE|W_NOPROCSUB)) || posixly_correct)
+             {
+               sindex--;       /* add_character: label increments sindex */
+               goto add_character;
+             }
+           else
+             t_index = sindex + 1; /* skip past both '<' and LPAREN */
+
+           temp1 = extract_process_subst (string, (c == '<') ? "<(" : ">(", &t_index, 0); /*))*/
+           sindex = t_index;
+
+           /* If the process substitution specification is `<()', we want to
+              open the pipe for writing in the child and produce output; if
+              it is `>()', we want to open the pipe for reading in the child
+              and consume input. */
+           temp = temp1 ? process_substitute (temp1, (c == '>')) : (char *)0;
+
+           FREE (temp1);
+
+           goto dollar_add_string;
+         }
+#endif /* PROCESS_SUBSTITUTION */
+
+       case '=':
+         /* Posix.2 section 3.6.1 says that tildes following `=' in words
+            which are not assignment statements are not expanded.  If the
+            shell isn't in posix mode, though, we perform tilde expansion
+            on `likely candidate' unquoted assignment statements (flags
+            include W_ASSIGNMENT but not W_QUOTED).  A likely candidate
+            contains an unquoted :~ or =~.  Something to think about: we
+            now have a flag that says  to perform tilde expansion on arguments
+            to `assignment builtins' like declare and export that look like
+            assignment statements.  We now do tilde expansion on such words
+            even in POSIX mode. */     
+         if (word->flags & (W_ASSIGNRHS|W_NOTILDE))
+           {
+             if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
+               goto add_ifs_character;
+             else
+               goto add_character;
+           }
+         /* If we're not in posix mode or forcing assignment-statement tilde
+            expansion, note where the `=' appears in the word and prepare to
+            do tilde expansion following the first `='. */
+         if ((word->flags & W_ASSIGNMENT) &&
+             (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
+             assignoff == -1 && sindex > 0)
+           assignoff = sindex;
+         if (sindex == assignoff && string[sindex+1] == '~')   /* XXX */
+           word->flags |= W_ITILDE;
+#if 0
+         else if ((word->flags & W_ASSIGNMENT) &&
+                  (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
+                  string[sindex+1] == '~')
+           word->flags |= W_ITILDE;
+#endif
+         if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
+           goto add_ifs_character;
+         else
+           goto add_character;
+
+       case ':':
+         if (word->flags & W_NOTILDE)
+           {
+             if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
+               goto add_ifs_character;
+             else
+               goto add_character;
+           }
+
+         if ((word->flags & (W_ASSIGNMENT|W_ASSIGNRHS|W_TILDEEXP)) &&
+             string[sindex+1] == '~')
+           word->flags |= W_ITILDE;
+
+         if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
+           goto add_ifs_character;
+         else
+           goto add_character;
+
+       case '~':
+         /* If the word isn't supposed to be tilde expanded, or we're not
+            at the start of a word or after an unquoted : or = in an
+            assignment statement, we don't do tilde expansion.  If we don't want
+            tilde expansion when expanding words to be passed to the arithmetic
+            evaluator, remove the check for Q_ARITH. */
+         if ((word->flags & (W_NOTILDE|W_DQUOTE)) ||
+             (sindex > 0 && ((word->flags & W_ITILDE) == 0)) ||
+             ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) && ((quoted & Q_ARITH) == 0)))
+           {
+             word->flags &= ~W_ITILDE;
+             if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
+               goto add_ifs_character;
+             else
+               goto add_character;
+           }
+
+         if (word->flags & W_ASSIGNRHS)
+           tflag = 2;
+         else if (word->flags & (W_ASSIGNMENT|W_TILDEEXP))
+           tflag = 1;
+         else
+           tflag = 0;
+
+         temp = bash_tilde_find_word (string + sindex, tflag, &t_index);
+           
+         word->flags &= ~W_ITILDE;
+
+         if (temp && *temp && t_index > 0)
+           {
+             temp1 = bash_tilde_expand (temp, tflag);
+             if  (temp1 && *temp1 == '~' && STREQ (temp, temp1))
+               {
+                 FREE (temp);
+                 FREE (temp1);
+                 goto add_character;           /* tilde expansion failed */
+               }
+             free (temp);
+             temp = temp1;
+             sindex += t_index;
+             goto add_quoted_string;           /* XXX was add_string */
+           }
+         else
+           {
+             FREE (temp);
+             goto add_character;
+           }
+       
+       case '$':
+         if (expanded_something)
+           *expanded_something = 1;
+
+         temp_has_dollar_at = 0;
+         pflags = (word->flags & W_NOCOMSUB) ? PF_NOCOMSUB : 0;
+         if (word->flags & W_NOSPLIT2)
+           pflags |= PF_NOSPLIT2;
+         if (word->flags & W_ASSIGNRHS)
+           pflags |= PF_ASSIGNRHS;
+         tword = param_expand (string, &sindex, quoted, expanded_something,
+                              &temp_has_dollar_at, &quoted_dollar_at,
+                              &had_quoted_null, pflags);
+         has_dollar_at += temp_has_dollar_at;
+         split_on_spaces += (tword->flags & W_SPLITSPACE);
+
+         if (tword == &expand_wdesc_error || tword == &expand_wdesc_fatal)
+           {
+             free (string);
+             free (istring);
+             return ((tword == &expand_wdesc_error) ? &expand_word_error
+                                                    : &expand_word_fatal);
+           }
+         if (contains_dollar_at && has_dollar_at)
+           *contains_dollar_at = 1;
+
+         if (tword && (tword->flags & W_HASQUOTEDNULL))
+           had_quoted_null = 1;
+
+         temp = tword ? tword->word : (char *)NULL;
+         dispose_word_desc (tword);
+
+         /* Kill quoted nulls; we will add them back at the end of
+            expand_word_internal if nothing else in the string */
+         if (had_quoted_null && temp && QUOTED_NULL (temp))
+           {
+             FREE (temp);
+             temp = (char *)NULL;
+           }
+
+         goto add_string;
+         break;
+
+       case '`':               /* Backquoted command substitution. */
+         {
+           t_index = sindex++;
+
+           temp = string_extract (string, &sindex, "`", SX_REQMATCH);
+           /* The test of sindex against t_index is to allow bare instances of
+              ` to pass through, for backwards compatibility. */
+           if (temp == &extract_string_error || temp == &extract_string_fatal)
+             {
+               if (sindex - 1 == t_index)
+                 {
+                   sindex = t_index;
+                   goto add_character;
+                 }
+               last_command_exit_value = EXECUTION_FAILURE;
+               report_error (_("bad substitution: no closing \"`\" in %s") , string+t_index);
+               free (string);
+               free (istring);
+               return ((temp == &extract_string_error) ? &expand_word_error
+                                                       : &expand_word_fatal);
+             }
+               
+           if (expanded_something)
+             *expanded_something = 1;
+
+           if (word->flags & W_NOCOMSUB)
+             /* sindex + 1 because string[sindex] == '`' */
+             temp1 = substring (string, t_index, sindex + 1);
+           else
+             {
+               de_backslash (temp);
+               tword = command_substitute (temp, quoted);
+               temp1 = tword ? tword->word : (char *)NULL;
+               if (tword)
+                 dispose_word_desc (tword);
+             }
+           FREE (temp);
+           temp = temp1;
+           goto dollar_add_string;
+         }
+
+       case '\\':
+         if (string[sindex + 1] == '\n')
+           {
+             sindex += 2;
+             continue;
+           }
+
+         c = string[++sindex];
+
+         if (quoted & Q_HERE_DOCUMENT)
+           tflag = CBSHDOC;
+         else if (quoted & Q_DOUBLE_QUOTES)
+           tflag = CBSDQUOTE;
+         else
+           tflag = 0;
+
+         /* From Posix discussion on austin-group list:  Backslash escaping
+            a } in ${...} is removed.  Issue 0000221 */
+         if ((quoted & Q_DOLBRACE) && c == RBRACE)
+           {
+             SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size);
+           }
+         /* This is the fix for " $@\ " */
+         else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && ((sh_syntaxtab[c] & tflag) == 0) && isexp == 0 && isifs (c))
+           {
+             RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size,
+                                     DEFAULT_ARRAY_SIZE);
+             istring[istring_index++] = CTLESC;
+             istring[istring_index++] = '\\';
+             istring[istring_index] = '\0';
+
+             SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size);
+           }
+         else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && ((sh_syntaxtab[c] & tflag) == 0))
+           {
+             SCOPY_CHAR_I (twochars, '\\', c, string, sindex, string_size);
+           }
+         else if (c == 0)
+           {
+             c = CTLNUL;
+             sindex--;         /* add_character: label increments sindex */
+             goto add_character;
+           }
+         else
+           {
+             SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size);
+           }
+
+         sindex++;
+add_twochars:
+         /* BEFORE jumping here, we need to increment sindex if appropriate */
+         RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size,
+                                 DEFAULT_ARRAY_SIZE);
+         istring[istring_index++] = twochars[0];
+         istring[istring_index++] = twochars[1];
+         istring[istring_index] = '\0';
+
+         break;
+
+       case '"':
+         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) && ((quoted & Q_ARITH) == 0))
+           goto add_character;
+
+         t_index = ++sindex;
+         temp = string_extract_double_quoted (string, &sindex, 0);
+
+         /* If the quotes surrounded the entire string, then the
+            whole word was quoted. */
+         quoted_state = (t_index == 1 && string[sindex] == '\0')
+                           ? WHOLLY_QUOTED
+                           : PARTIALLY_QUOTED;
+
+         if (temp && *temp)
+           {
+             tword = alloc_word_desc ();
+             tword->word = temp;
+
+             temp = (char *)NULL;
+
+             temp_has_dollar_at = 0;   /* XXX */
+             /* 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;
+
+             if (list == &expand_word_error || list == &expand_word_fatal)
+               {
+                 free (istring);
+                 free (string);
+                 /* expand_word_internal has already freed temp_word->word
+                    for us because of the way it prints error messages. */
+                 tword->word = (char *)NULL;
+                 dispose_word (tword);
+                 return list;
+               }
+
+             dispose_word (tword);
+
+             /* "$@" (a double-quoted dollar-at) expands into nothing,
+                not even a NULL word, when there are no positional
+                parameters. */
+             if (list == 0 && has_dollar_at)
+               {
+                 quoted_dollar_at++;
+                 break;
+               }
+
+             /* 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
+                can expand into more than one word.  It's going to come back
+                from the above call to expand_word_internal as a list with
+                a single word, in which all characters are quoted and
+                separated by blanks.  What we want to do is to turn it back
+                into a list for the next piece of code. */
+             if (list)
+               dequote_list (list);
+
+             if (list && list->word && (list->word->flags & W_HASQUOTEDNULL))
+               had_quoted_null = 1;            /* XXX */
+
+             if (has_dollar_at)
+               {
+                 quoted_dollar_at++;
+                 if (contains_dollar_at)
+                   *contains_dollar_at = 1;
+                 if (expanded_something)
+                   *expanded_something = 1;
+               }
+           }
+         else
+           {
+             /* What we have is "".  This is a minor optimization. */
+             FREE (temp);
+             list = (WORD_LIST *)NULL;
+           }
+
+         /* The code above *might* return a list (consider the case of "$@",
+            where it returns "$1", "$2", etc.).  We can't throw away the
+            rest of the list, and we have to make sure each word gets added
+            as quoted.  We test on tresult->next:  if it is non-NULL, we
+            quote the whole list, save it to a string with string_list, and
+            add that string. We don't need to quote the results of this
+            (and it would be wrong, since that would quote the separators
+            as well), so we go directly to add_string. */
+         if (list)
+           {
+             if (list->next)
+               {
+                 /* Testing quoted_dollar_at makes sure that "$@" is
+                    split correctly when $IFS does not contain a space. */
+                 temp = quoted_dollar_at
+                               ? string_list_dollar_at (list, Q_DOUBLE_QUOTES)
+                               : string_list (quote_list (list));
+                 dispose_words (list);
+                 goto add_string;
+               }
+             else
+               {
+                 temp = savestring (list->word->word);
+                 tflag = list->word->flags;
+                 dispose_words (list);
+
+                 /* If the string is not a quoted null string, we want
+                    to remove any embedded unquoted CTLNUL characters.
+                    We do not want to turn quoted null strings back into
+                    the empty string, though.  We do this because we
+                    want to remove any quoted nulls from expansions that
+                    contain other characters.  For example, if we have
+                    x"$*"y or "x$*y" and there are no positional parameters,
+                    the $* should expand into nothing. */
+                 /* We use the W_HASQUOTEDNULL flag to differentiate the
+                    cases:  a quoted null character as above and when
+                    CTLNUL is contained in the (non-null) expansion
+                    of some variable.  We use the had_quoted_null flag to
+                    pass the value through this function to its caller. */
+                 if ((tflag & W_HASQUOTEDNULL) && QUOTED_NULL (temp) == 0)
+                   remove_quoted_nulls (temp); /* XXX */
+               }
+           }
+         else
+           temp = (char *)NULL;
+
+         /* We do not want to add quoted nulls to strings that are only
+            partially quoted; we can throw them away.  The exception to
+            this is when we are going to be performing word splitting,
+            since we have to preserve a null argument if the next character
+            will cause word splitting. */
+         if (temp == 0 && quoted_state == PARTIALLY_QUOTED && (word->flags & (W_NOSPLIT|W_NOSPLIT2)))
+           continue;
+
+       add_quoted_string:
+
+         if (temp)
+           {
+             temp1 = temp;
+             temp = quote_string (temp);
+             free (temp1);
+             goto add_string;
+           }
+         else
+           {
+             /* Add NULL arg. */
+             c = CTLNUL;
+             sindex--;         /* add_character: label increments sindex */
+             goto add_character;
+           }
+
+         /* break; */
+
+       case '\'':
+         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
+           goto add_character;
+
+         t_index = ++sindex;
+         temp = string_extract_single_quoted (string, &sindex);
+
+         /* If the entire STRING was surrounded by single quotes,
+            then the string is wholly quoted. */
+         quoted_state = (t_index == 1 && string[sindex] == '\0')
+                           ? WHOLLY_QUOTED
+                           : PARTIALLY_QUOTED;
+
+         /* If all we had was '', it is a null expansion. */
+         if (*temp == '\0')
+           {
+             free (temp);
+             temp = (char *)NULL;
+           }
+         else
+           remove_quoted_escapes (temp);       /* ??? */
+
+         /* We do not want to add quoted nulls to strings that are only
+            partially quoted; such nulls are discarded. */
+         if (temp == 0 && (quoted_state == PARTIALLY_QUOTED))
+           continue;
+
+         /* If we have a quoted null expansion, add a quoted NULL to istring. */
+         if (temp == 0)
+           {
+             c = CTLNUL;
+             sindex--;         /* add_character: label increments sindex */
+             goto add_character;
+           }
+         else
+           goto add_quoted_string;
+
+         /* break; */
+
+       default:
+         /* This is the fix for " $@ " */
+       add_ifs_character:
+         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (isexp == 0 && isifs (c)))
+           {
+             if (string[sindex])       /* from old goto dollar_add_string */
+               sindex++;
+             if (c == 0)
+               {
+                 c = CTLNUL;
+                 goto add_character;
+               }
+             else
+               {
+#if HANDLE_MULTIBYTE
+                 if (MB_CUR_MAX > 1)
+                   sindex--;
+
+                 if (MB_CUR_MAX > 1)
+                   {
+                     SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
+                   }
+                 else
+#endif
+                   {
+                     twochars[0] = CTLESC;
+                     twochars[1] = c;
+                     goto add_twochars;
+                   }
+               }
+           }
+
+         SADD_MBCHAR (temp, string, sindex, string_size);
+
+       add_character:
+         RESIZE_MALLOCED_BUFFER (istring, istring_index, 1, istring_size,
+                                 DEFAULT_ARRAY_SIZE);
+         istring[istring_index++] = c;
+         istring[istring_index] = '\0';
+
+         /* Next character. */
+         sindex++;
+       }
+    }
+
+finished_with_string:
+  /* OK, we're ready to return.  If we have a quoted string, and
+     quoted_dollar_at is not set, we do no splitting at all; otherwise
+     we split on ' '.  The routines that call this will handle what to
+     do if nothing has been expanded. */
+
+  /* Partially and wholly quoted strings which expand to the empty
+     string are retained as an empty arguments.  Unquoted strings
+     which expand to the empty string are discarded.  The single
+     exception is the case of expanding "$@" when there are no
+     positional parameters.  In that case, we discard the expansion. */
+
+  /* Because of how the code that handles "" and '' in partially
+     quoted strings works, we need to make ISTRING into a QUOTED_NULL
+     if we saw quoting characters, but the expansion was empty.
+     "" and '' are tossed away before we get to this point when
+     processing partially quoted strings.  This makes "" and $xxx""
+     equivalent when xxx is unset.  We also look to see whether we
+     saw a quoted null from a ${} expansion and add one back if we
+     need to. */
+
+  /* If we expand to nothing and there were no single or double quotes
+     in the word, we throw it away.  Otherwise, we return a NULL word.
+     The single exception is for $@ surrounded by double quotes when
+     there are no positional parameters.  In that case, we also throw
+     the word away. */
+
+  if (*istring == '\0')
+    {
+      if (quoted_dollar_at == 0 && (had_quoted_null || quoted_state == PARTIALLY_QUOTED))
+       {
+         istring[0] = CTLNUL;
+         istring[1] = '\0';
+         tword = make_bare_word (istring);
+         tword->flags |= W_HASQUOTEDNULL;              /* XXX */
+         list = make_word_list (tword, (WORD_LIST *)NULL);
+         if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
+           tword->flags |= W_QUOTED;
+       }
+      /* According to sh, ksh, and Posix.2, if a word expands into nothing
+        and a double-quoted "$@" appears anywhere in it, then the entire
+        word is removed. */
+      else  if (quoted_state == UNQUOTED || quoted_dollar_at)
+       list = (WORD_LIST *)NULL;
+#if 0
+      else
+       {
+         tword = make_bare_word (istring);
+         if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
+           tword->flags |= W_QUOTED;
+         list = make_word_list (tword, (WORD_LIST *)NULL);
+       }
+#else
+      else
+       list = (WORD_LIST *)NULL;
+#endif
+    }
+  else if (word->flags & W_NOSPLIT)
+    {
+      tword = make_bare_word (istring);
+      if (word->flags & W_ASSIGNMENT)
+       tword->flags |= W_ASSIGNMENT;   /* XXX */
+      if (word->flags & W_COMPASSIGN)
+       tword->flags |= W_COMPASSIGN;   /* XXX */
+      if (word->flags & W_NOGLOB)
+       tword->flags |= W_NOGLOB;       /* XXX */
+      if (word->flags & W_NOBRACE)
+       tword->flags |= W_NOBRACE;      /* XXX */
+      if (word->flags & W_NOEXPAND)
+       tword->flags |= W_NOEXPAND;     /* XXX */
+      if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
+       tword->flags |= W_QUOTED;
+      if (had_quoted_null && QUOTED_NULL (istring))
+       tword->flags |= W_HASQUOTEDNULL;
+      list = make_word_list (tword, (WORD_LIST *)NULL);
+    }
+  else
+    {
+      char *ifs_chars;
+      char *tstring;
+
+      ifs_chars = (quoted_dollar_at || has_dollar_at) ? ifs_value : (char *)NULL;
+
+      /* If we have $@, we need to split the results no matter what.  If
+        IFS is unset or NULL, string_list_dollar_at has separated the
+        positional parameters with a space, so we split on space (we have
+        set ifs_chars to " \t\n" above if ifs is unset).  If IFS is set,
+        string_list_dollar_at has separated the positional parameters
+        with the first character of $IFS, so we split on $IFS.  If
+        SPLIT_ON_SPACES is set, we expanded $* (unquoted) with IFS either
+        unset or null, and we want to make sure that we split on spaces
+        regardless of what else has happened to IFS since the expansion. */
+      if (split_on_spaces)
+       list = list_string (istring, " ", 1);   /* XXX quoted == 1? */
+      /* If we have $@ (has_dollar_at != 0) and we are in a context where we
+        don't want to split the result (W_NOSPLIT2), and we are not quoted,
+        we have already separated the arguments with the first character of
+        $IFS.  In this case, we want to return a list with a single word
+        with the separator possibly replaced with a space (it's what other
+        shells seem to do).
+        quoted_dollar_at is internal to this function and is set if we are
+        passed an argument that is unquoted (quoted == 0) but we encounter a
+        double-quoted $@ while expanding it. */
+      else if (has_dollar_at && quoted_dollar_at == 0 && ifs_chars && quoted == 0 && (word->flags & W_NOSPLIT2))
+       {
+         /* Only split and rejoin if we have to */
+         if (*ifs_chars && *ifs_chars != ' ')
+           {
+             list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
+             tstring = string_list (list);
+           }
+         else
+           tstring = istring;
+         tword = make_bare_word (tstring);
+         if (tstring != istring)
+           free (tstring);
+         goto set_word_flags;
+       }
+      else if (has_dollar_at && ifs_chars)
+       list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
+      else
+       {
+         tword = make_bare_word (istring);
+set_word_flags:
+         if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
+           tword->flags |= W_QUOTED;
+         if (word->flags & W_ASSIGNMENT)
+           tword->flags |= W_ASSIGNMENT;
+         if (word->flags & W_COMPASSIGN)
+           tword->flags |= W_COMPASSIGN;
+         if (word->flags & W_NOGLOB)
+           tword->flags |= W_NOGLOB;
+         if (word->flags & W_NOBRACE)
+           tword->flags |= W_NOBRACE;
+         if (word->flags & W_NOEXPAND)
+           tword->flags |= W_NOEXPAND;
+         if (had_quoted_null && QUOTED_NULL (istring))
+           tword->flags |= W_HASQUOTEDNULL;    /* XXX */
+         list = make_word_list (tword, (WORD_LIST *)NULL);
+       }
+    }
+
+  free (istring);
+  return (list);
+}
+
+/* **************************************************************** */
+/*                                                                 */
+/*                Functions for Quote Removal                      */
+/*                                                                 */
+/* **************************************************************** */
+
+/* Perform quote removal on STRING.  If QUOTED > 0, assume we are obeying the
+   backslash quoting rules for within double quotes or a here document. */
+char *
+string_quote_removal (string, quoted)
+     char *string;
+     int quoted;
+{
+  size_t slen;
+  char *r, *result_string, *temp, *send;
+  int sindex, tindex, dquote;
+  unsigned char c;
+  DECLARE_MBSTATE;
+
+  /* The result can be no longer than the original string. */
+  slen = strlen (string);
+  send = string + slen;
+
+  r = result_string = (char *)xmalloc (slen + 1);
+
+  for (dquote = sindex = 0; c = string[sindex];)
+    {
+      switch (c)
+       {
+       case '\\':
+         c = string[++sindex];
+         if (c == 0)
+           {
+             *r++ = '\\';
+             break;
+           }
+         if (((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) && (sh_syntaxtab[c] & CBSDQUOTE) == 0)
+           *r++ = '\\';
+         /* FALLTHROUGH */
+
+       default:
+         SCOPY_CHAR_M (r, string, send, sindex);
+         break;
+
+       case '\'':
+         if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote)
+           {
+             *r++ = c;
+             sindex++;
+             break;
+           }
+         tindex = sindex + 1;
+         temp = string_extract_single_quoted (string, &tindex);
+         if (temp)
+           {
+             strcpy (r, temp);
+             r += strlen (r);
+             free (temp);
+           }
+         sindex = tindex;
+         break;
+
+       case '"':
+         dquote = 1 - dquote;
+         sindex++;
+         break;
+       }
+    }
+    *r = '\0';
+    return (result_string);
+}
+
+#if 0
+/* UNUSED */
+/* Perform quote removal on word WORD.  This allocates and returns a new
+   WORD_DESC *. */
+WORD_DESC *
+word_quote_removal (word, quoted)
+     WORD_DESC *word;
+     int quoted;
+{
+  WORD_DESC *w;
+  char *t;
+
+  t = string_quote_removal (word->word, quoted);
+  w = alloc_word_desc ();
+  w->word = t ? t : savestring ("");
+  return (w);
+}
+
+/* Perform quote removal on all words in LIST.  If QUOTED is non-zero,
+   the members of the list are treated as if they are surrounded by
+   double quotes.  Return a new list, or NULL if LIST is NULL. */
+WORD_LIST *
+word_list_quote_removal (list, quoted)
+     WORD_LIST *list;
+     int quoted;
+{
+  WORD_LIST *result, *t, *tresult, *e;
+
+  for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
+    {
+      tresult = make_word_list (word_quote_removal (t->word, quoted), (WORD_LIST *)NULL);
+#if 0
+      result = (WORD_LIST *) list_append (result, tresult);
+#else
+      if (result == 0)
+       result = e = tresult;
+      else
+       {
+         e->next = tresult;
+         while (e->next)
+           e = e->next;
+       }
+#endif
+    }
+  return (result);
+}
+#endif
+
+/*******************************************
+ *                                        *
+ *    Functions to perform word splitting  *
+ *                                        *
+ *******************************************/
+
+void
+setifs (v)
+     SHELL_VAR *v;
+{
+  char *t;
+  unsigned char uc;
+
+  ifs_var = v;
+  ifs_value = (v && value_cell (v)) ? value_cell (v) : " \t\n";
+
+  ifs_is_set = ifs_var != 0;
+  ifs_is_null = ifs_is_set && (*ifs_value == 0);
+
+  /* Should really merge ifs_cmap with sh_syntaxtab.  XXX - doesn't yet
+     handle multibyte chars in IFS */
+  memset (ifs_cmap, '\0', sizeof (ifs_cmap));
+  for (t = ifs_value ; t && *t; t++)
+    {
+      uc = *t;
+      ifs_cmap[uc] = 1;
+    }
+
+#if defined (HANDLE_MULTIBYTE)
+  if (ifs_value == 0)
+    {
+      ifs_firstc[0] = '\0';
+      ifs_firstc_len = 1;
+    }
+  else
+    {
+      size_t ifs_len;
+      ifs_len = strnlen (ifs_value, MB_CUR_MAX);
+      ifs_firstc_len = MBLEN (ifs_value, ifs_len);
+      if (ifs_firstc_len == 1 || ifs_firstc_len == 0 || MB_INVALIDCH (ifs_firstc_len))
+       {
+         ifs_firstc[0] = ifs_value[0];
+         ifs_firstc[1] = '\0';
+         ifs_firstc_len = 1;
+       }
+      else
+       memcpy (ifs_firstc, ifs_value, ifs_firstc_len);
+    }
+#else
+  ifs_firstc = ifs_value ? *ifs_value : 0;
+#endif
+}
+
+char *
+getifs ()
+{
+  return ifs_value;
+}
+
+/* This splits a single word into a WORD LIST on $IFS, but only if the word
+   is not quoted.  list_string () performs quote removal for us, even if we
+   don't do any splitting. */
+WORD_LIST *
+word_split (w, ifs_chars)
+     WORD_DESC *w;
+     char *ifs_chars;
+{
+  WORD_LIST *result;
+
+  if (w)
+    {
+      char *xifs;
+
+      xifs = ((w->flags & W_QUOTED) || ifs_chars == 0) ? "" : ifs_chars;
+      result = list_string (w->word, xifs, w->flags & W_QUOTED);
+    }
+  else
+    result = (WORD_LIST *)NULL;
+
+  return (result);
+}
+
+/* Perform word splitting on LIST and return the RESULT.  It is possible
+   to return (WORD_LIST *)NULL. */
+static WORD_LIST *
+word_list_split (list)
+     WORD_LIST *list;
+{
+  WORD_LIST *result, *t, *tresult, *e;
+
+  for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
+    {
+      tresult = word_split (t->word, ifs_value);
+      if (result == 0)
+        result = e = tresult;
+      else
+       {
+         e->next = tresult;
+         while (e->next)
+           e = e->next;
+       }
+    }
+  return (result);
+}
+
+/**************************************************
+ *                                               *
+ *    Functions to expand an entire WORD_LIST    *
+ *                                               *
+ **************************************************/
+
+/* Do any word-expansion-specific cleanup and jump to top_level */
+static void
+exp_jump_to_top_level (v)
+     int v;
+{
+  set_pipestatus_from_exit (last_command_exit_value);
+
+  /* Cleanup code goes here. */
+  expand_no_split_dollar_star = 0;     /* XXX */
+  expanding_redir = 0;
+  assigning_in_environment = 0;
+
+  if (parse_and_execute_level == 0)
+    top_level_cleanup ();                      /* from sig.c */
+
+  jump_to_top_level (v);
+}
+
+/* Put NLIST (which is a WORD_LIST * of only one element) at the front of
+   ELIST, and set ELIST to the new list. */
+#define PREPEND_LIST(nlist, elist) \
+       do { nlist->next = elist; elist = nlist; } while (0)
+
+/* Separate out any initial variable assignments from TLIST.  If set -k has
+   been executed, remove all assignment statements from TLIST.  Initial
+   variable assignments and other environment assignments are placed
+   on SUBST_ASSIGN_VARLIST. */
+static WORD_LIST *
+separate_out_assignments (tlist)
+     WORD_LIST *tlist;
+{
+  register WORD_LIST *vp, *lp;
+
+  if (tlist == 0)
+    return ((WORD_LIST *)NULL);
+
+  if (subst_assign_varlist)
+    dispose_words (subst_assign_varlist);      /* Clean up after previous error */
+
+  subst_assign_varlist = (WORD_LIST *)NULL;
+  vp = lp = tlist;
+
+  /* Separate out variable assignments at the start of the command.
+     Loop invariant: vp->next == lp
+     Loop postcondition:
+       lp = list of words left after assignment statements skipped
+       tlist = original list of words
+  */
+  while (lp && (lp->word->flags & W_ASSIGNMENT))
+    {
+      vp = lp;
+      lp = lp->next;
+    }
+
+  /* If lp != tlist, we have some initial assignment statements.
+     We make SUBST_ASSIGN_VARLIST point to the list of assignment
+     words and TLIST point to the remaining words.  */
+  if (lp != tlist)
+    {
+      subst_assign_varlist = tlist;
+      /* ASSERT(vp->next == lp); */
+      vp->next = (WORD_LIST *)NULL;    /* terminate variable list */
+      tlist = lp;                      /* remainder of word list */
+    }
+
+  /* vp == end of variable list */
+  /* tlist == remainder of original word list without variable assignments */
+  if (!tlist)
+    /* All the words in tlist were assignment statements */
+    return ((WORD_LIST *)NULL);
+
+  /* ASSERT(tlist != NULL); */
+  /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
+
+  /* If the -k option is in effect, we need to go through the remaining
+     words, separate out the assignment words, and place them on
+     SUBST_ASSIGN_VARLIST. */
+  if (place_keywords_in_env)
+    {
+      WORD_LIST *tp;   /* tp == running pointer into tlist */
+
+      tp = tlist;
+      lp = tlist->next;
+
+      /* Loop Invariant: tp->next == lp */
+      /* Loop postcondition: tlist == word list without assignment statements */
+      while (lp)
+       {
+         if (lp->word->flags & W_ASSIGNMENT)
+           {
+             /* Found an assignment statement, add this word to end of
+                subst_assign_varlist (vp). */
+             if (!subst_assign_varlist)
+               subst_assign_varlist = vp = lp;
+             else
+               {
+                 vp->next = lp;
+                 vp = lp;
+               }
+
+             /* Remove the word pointed to by LP from TLIST. */
+             tp->next = lp->next;
+             /* ASSERT(vp == lp); */
+             lp->next = (WORD_LIST *)NULL;
+             lp = tp->next;
+           }
+         else
+           {
+             tp = lp;
+             lp = lp->next;
+           }
+       }
+    }
+  return (tlist);
+}
+
+#define WEXP_VARASSIGN 0x001
+#define WEXP_BRACEEXP  0x002
+#define WEXP_TILDEEXP  0x004
+#define WEXP_PARAMEXP  0x008
+#define WEXP_PATHEXP   0x010
+
+/* All of the expansions, including variable assignments at the start of
+   the list. */
+#define WEXP_ALL       (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
+
+/* All of the expansions except variable assignments at the start of
+   the list. */
+#define WEXP_NOVARS    (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
+
+/* All of the `shell expansions': brace expansion, tilde expansion, parameter
+   expansion, command substitution, arithmetic expansion, word splitting, and
+   quote removal. */
+#define WEXP_SHELLEXP  (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
+
+/* Take the list of words in LIST and do the various substitutions.  Return
+   a new list of words which is the expanded list, and without things like
+   variable assignments. */
+
+WORD_LIST *
+expand_words (list)
+     WORD_LIST *list;
+{
+  return (expand_word_list_internal (list, WEXP_ALL));
+}
+
+/* Same as expand_words (), but doesn't hack variable or environment
+   variables. */
+WORD_LIST *
+expand_words_no_vars (list)
+     WORD_LIST *list;
+{
+  return (expand_word_list_internal (list, WEXP_NOVARS));
+}
+
+WORD_LIST *
+expand_words_shellexp (list)
+     WORD_LIST *list;
+{
+  return (expand_word_list_internal (list, WEXP_SHELLEXP));
+}
+
+static WORD_LIST *
+glob_expand_word_list (tlist, eflags)
+     WORD_LIST *tlist;
+     int eflags;
+{
+  char **glob_array, *temp_string;
+  register int glob_index;
+  WORD_LIST *glob_list, *output_list, *disposables, *next;
+  WORD_DESC *tword;
+
+  output_list = disposables = (WORD_LIST *)NULL;
+  glob_array = (char **)NULL;
+  while (tlist)
+    {
+      /* For each word, either globbing is attempted or the word is
+        added to orig_list.  If globbing succeeds, the results are
+        added to orig_list and the word (tlist) is added to the list
+        of disposable words.  If globbing fails and failed glob
+        expansions are left unchanged (the shell default), the
+        original word is added to orig_list.  If globbing fails and
+        failed glob expansions are removed, the original word is
+        added to the list of disposable words.  orig_list ends up
+        in reverse order and requires a call to REVERSE_LIST to
+        be set right.  After all words are examined, the disposable
+        words are freed. */
+      next = tlist->next;
+
+      /* If the word isn't an assignment and contains an unquoted
+        pattern matching character, then glob it. */
+      if ((tlist->word->flags & W_NOGLOB) == 0 &&
+         unquoted_glob_pattern_p (tlist->word->word))
+       {
+         glob_array = shell_glob_filename (tlist->word->word);
+
+         /* Handle error cases.
+            I don't think we should report errors like "No such file
+            or directory".  However, I would like to report errors
+            like "Read failed". */
+
+         if (glob_array == 0 || GLOB_FAILED (glob_array))
+           {
+             glob_array = (char **)xmalloc (sizeof (char *));
+             glob_array[0] = (char *)NULL;
+           }
+
+         /* Dequote the current word in case we have to use it. */
+         if (glob_array[0] == NULL)
+           {
+             temp_string = dequote_string (tlist->word->word);
+             free (tlist->word->word);
+             tlist->word->word = temp_string;
+           }
+
+         /* Make the array into a word list. */
+         glob_list = (WORD_LIST *)NULL;
+         for (glob_index = 0; glob_array[glob_index]; glob_index++)
+           {
+             tword = make_bare_word (glob_array[glob_index]);
+             glob_list = make_word_list (tword, glob_list);
+           }
+
+         if (glob_list)
+           {
+             output_list = (WORD_LIST *)list_append (glob_list, output_list);
+             PREPEND_LIST (tlist, disposables);
+           }
+         else if (fail_glob_expansion != 0)
+           {
+             last_command_exit_value = EXECUTION_FAILURE;
+             report_error (_("no match: %s"), tlist->word->word);
+             exp_jump_to_top_level (DISCARD);
+           }
+         else if (allow_null_glob_expansion == 0)
+           {
+             /* Failed glob expressions are left unchanged. */
+             PREPEND_LIST (tlist, output_list);
+           }
+         else
+           {
+             /* Failed glob expressions are removed. */
+             PREPEND_LIST (tlist, disposables);
+           }
+       }
+      else
+       {
+         /* Dequote the string. */
+         temp_string = dequote_string (tlist->word->word);
+         free (tlist->word->word);
+         tlist->word->word = temp_string;
+         PREPEND_LIST (tlist, output_list);
+       }
+
+      strvec_dispose (glob_array);
+      glob_array = (char **)NULL;
+
+      tlist = next;
+    }
+
+  if (disposables)
+    dispose_words (disposables);
+
+  if (output_list)
+    output_list = REVERSE_LIST (output_list, WORD_LIST *);
+
+  return (output_list);
+}
+
+#if defined (BRACE_EXPANSION)
+static WORD_LIST *
+brace_expand_word_list (tlist, eflags)
+     WORD_LIST *tlist;
+     int eflags;
+{
+  register char **expansions;
+  char *temp_string;
+  WORD_LIST *disposables, *output_list, *next;
+  WORD_DESC *w;
+  int eindex;
+
+  for (disposables = output_list = (WORD_LIST *)NULL; tlist; tlist = next)
+    {
+      next = tlist->next;
+
+      if (tlist->word->flags & W_NOBRACE)
+        {
+/*itrace("brace_expand_word_list: %s: W_NOBRACE", tlist->word->word);*/
+         PREPEND_LIST (tlist, output_list);
+         continue;
+        }
+
+      if ((tlist->word->flags & (W_COMPASSIGN|W_ASSIGNARG)) == (W_COMPASSIGN|W_ASSIGNARG))
+        {
+/*itrace("brace_expand_word_list: %s: W_COMPASSIGN|W_ASSIGNARG", tlist->word->word);*/
+         PREPEND_LIST (tlist, output_list);
+         continue;
+        }
+
+      /* Only do brace expansion if the word has a brace character.  If
+        not, just add the word list element to BRACES and continue.  In
+        the common case, at least when running shell scripts, this will
+        degenerate to a bunch of calls to `mbschr', and then what is
+        basically a reversal of TLIST into BRACES, which is corrected
+        by a call to REVERSE_LIST () on BRACES when the end of TLIST
+        is reached. */
+      if (mbschr (tlist->word->word, LBRACE))
+       {
+         expansions = brace_expand (tlist->word->word);
+
+         for (eindex = 0; temp_string = expansions[eindex]; eindex++)
+           {
+             w = alloc_word_desc ();
+             w->word = temp_string;
+
+             /* If brace expansion didn't change the word, preserve
+                the flags.  We may want to preserve the flags
+                unconditionally someday -- XXX */
+             if (STREQ (temp_string, tlist->word->word))
+               w->flags = tlist->word->flags;
+             else
+               w = make_word_flags (w, temp_string);
+
+             output_list = make_word_list (w, output_list);
+           }
+         free (expansions);
+
+         /* Add TLIST to the list of words to be freed after brace
+            expansion has been performed. */
+         PREPEND_LIST (tlist, disposables);
+       }
+      else
+       PREPEND_LIST (tlist, output_list);
+    }
+
+  if (disposables)
+    dispose_words (disposables);
+
+  if (output_list)
+    output_list = REVERSE_LIST (output_list, WORD_LIST *);
+
+  return (output_list);
+}
+#endif
+
+#if defined (ARRAY_VARS)
+/* Take WORD, a compound associative array assignment, and internally run
+   'declare -A w', where W is the variable name portion of WORD. */
+static int
+make_internal_declare (word, option)
+     char *word;
+     char *option;
+{
+  int t;
+  WORD_LIST *wl;
+  WORD_DESC *w;
+
+  w = make_word (word);
+
+  t = assignment (w->word, 0);
+  w->word[t] = '\0';
+
+  wl = make_word_list (w, (WORD_LIST *)NULL);
+  wl = make_word_list (make_word (option), wl);
+
+  return (declare_builtin (wl));  
+}  
+#endif
+
+static WORD_LIST *
+shell_expand_word_list (tlist, eflags)
+     WORD_LIST *tlist;
+     int eflags;
+{
+  WORD_LIST *expanded, *orig_list, *new_list, *next, *temp_list;
+  int expanded_something, has_dollar_at;
+  char *temp_string;
+
+  /* We do tilde expansion all the time.  This is what 1003.2 says. */
+  new_list = (WORD_LIST *)NULL;
+  for (orig_list = tlist; tlist; tlist = next)
+    {
+      temp_string = tlist->word->word;
+
+      next = tlist->next;
+
+#if defined (ARRAY_VARS)
+      /* If this is a compound array assignment to a builtin that accepts
+         such assignments (e.g., `declare'), take the assignment and perform
+         it separately, handling the semantics of declarations inside shell
+         functions.  This avoids the double-evaluation of such arguments,
+         because `declare' does some evaluation of compound assignments on
+         its own. */
+      if ((tlist->word->flags & (W_COMPASSIGN|W_ASSIGNARG)) == (W_COMPASSIGN|W_ASSIGNARG))
+       {
+         int t;
+         char opts[8], opti;
+
+         opti = 0;
+         if (tlist->word->flags & (W_ASSIGNASSOC|W_ASSNGLOBAL|W_ASSIGNARRAY))
+           opts[opti++] = '-';
+
+         if ((tlist->word->flags & (W_ASSIGNASSOC|W_ASSNGLOBAL)) == (W_ASSIGNASSOC|W_ASSNGLOBAL))
+           {
+             opts[opti++] = 'g';
+             opts[opti++] = 'A';
+           }
+         else if (tlist->word->flags & W_ASSIGNASSOC)
+           opts[opti++] = 'A';
+         else if ((tlist->word->flags & (W_ASSIGNARRAY|W_ASSNGLOBAL)) == (W_ASSIGNARRAY|W_ASSNGLOBAL))
+           {
+             opts[opti++] = 'g';
+             opts[opti++] = 'a';
+           }
+         else if (tlist->word->flags & W_ASSIGNARRAY)
+           opts[opti++] = 'a';
+         else if (tlist->word->flags & W_ASSNGLOBAL)
+           opts[opti++] = 'g';
+
+#if 0
+         /* If we have special handling note the integer attribute */
+         if (opti > 0 && (tlist->word->flags & W_ASSIGNINT))
+           opts[opti++] = 'i';
+#endif
+
+         opts[opti] = '\0';
+         if (opti > 0)
+           make_internal_declare (tlist->word->word, opts);
+
+         t = do_word_assignment (tlist->word, 0);
+         if (t == 0)
+           {
+             last_command_exit_value = EXECUTION_FAILURE;
+             exp_jump_to_top_level (DISCARD);
+           }
+
+         /* Now transform the word as ksh93 appears to do and go on */
+         t = assignment (tlist->word->word, 0);
+         tlist->word->word[t] = '\0';
+         tlist->word->flags &= ~(W_ASSIGNMENT|W_NOSPLIT|W_COMPASSIGN|W_ASSIGNARG|W_ASSIGNASSOC|W_ASSIGNARRAY);
+       }
+#endif
+
+      expanded_something = 0;
+      expanded = expand_word_internal
+       (tlist->word, 0, 0, &has_dollar_at, &expanded_something);
+
+      if (expanded == &expand_word_error || expanded == &expand_word_fatal)
+       {
+         /* By convention, each time this error is returned,
+            tlist->word->word has already been freed. */
+         tlist->word->word = (char *)NULL;
+
+         /* Dispose our copy of the original list. */
+         dispose_words (orig_list);
+         /* Dispose the new list we're building. */
+         dispose_words (new_list);
+
+         last_command_exit_value = EXECUTION_FAILURE;
+         if (expanded == &expand_word_error)
+           exp_jump_to_top_level (DISCARD);
+         else
+           exp_jump_to_top_level (FORCE_EOF);
+       }
+
+      /* Don't split words marked W_NOSPLIT. */
+      if (expanded_something && (tlist->word->flags & W_NOSPLIT) == 0)
+       {
+         temp_list = word_list_split (expanded);
+         dispose_words (expanded);
+       }
+      else
+       {
+         /* If no parameter expansion, command substitution, process
+            substitution, or arithmetic substitution took place, then
+            do not do word splitting.  We still have to remove quoted
+            null characters from the result. */
+         word_list_remove_quoted_nulls (expanded);
+         temp_list = expanded;
+       }
+
+      expanded = REVERSE_LIST (temp_list, WORD_LIST *);
+      new_list = (WORD_LIST *)list_append (expanded, new_list);
+    }
+
+  if (orig_list)  
+    dispose_words (orig_list);
+
+  if (new_list)
+    new_list = REVERSE_LIST (new_list, WORD_LIST *);
+
+  return (new_list);
+}
+
+/* The workhorse for expand_words () and expand_words_no_vars ().
+   First arg is LIST, a WORD_LIST of words.
+   Second arg EFLAGS is a flags word controlling which expansions are
+   performed.
+
+   This does all of the substitutions: brace expansion, tilde expansion,
+   parameter expansion, command substitution, arithmetic expansion,
+   process substitution, word splitting, and pathname expansion, according
+   to the bits set in EFLAGS.  Words with the W_QUOTED or W_NOSPLIT bits
+   set, or for which no expansion is done, do not undergo word splitting.
+   Words with the W_NOGLOB bit set do not undergo pathname expansion; words
+   with W_NOBRACE set do not undergo brace expansion (see
+   brace_expand_word_list above). */
+static WORD_LIST *
+expand_word_list_internal (list, eflags)
+     WORD_LIST *list;
+     int eflags;
+{
+  WORD_LIST *new_list, *temp_list;
+  int tint;
+
+  tempenv_assign_error = 0;
+  if (list == 0)
+    return ((WORD_LIST *)NULL);
+
+  garglist = new_list = copy_word_list (list);
+  if (eflags & WEXP_VARASSIGN)
+    {
+      garglist = new_list = separate_out_assignments (new_list);
+      if (new_list == 0)
+       {
+         if (subst_assign_varlist)
+           {
+             /* All the words were variable assignments, so they are placed
+                into the shell's environment. */
+             for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
+               {
+                 this_command_name = (char *)NULL;     /* no arithmetic errors */
+                 tint = do_word_assignment (temp_list->word, 0);
+                 /* Variable assignment errors in non-interactive shells
+                    running in Posix.2 mode cause the shell to exit. */
+                 if (tint == 0)
+                   {
+                     last_command_exit_value = EXECUTION_FAILURE;
+                     if (interactive_shell == 0 && posixly_correct)
+                       exp_jump_to_top_level (FORCE_EOF);
+                     else
+                       exp_jump_to_top_level (DISCARD);
+                   }
+               }
+             dispose_words (subst_assign_varlist);
+             subst_assign_varlist = (WORD_LIST *)NULL;
+           }
+         return ((WORD_LIST *)NULL);
+       }
+    }
+
+  /* Begin expanding the words that remain.  The expansions take place on
+     things that aren't really variable assignments. */
+
+#if defined (BRACE_EXPANSION)
+  /* Do brace expansion on this word if there are any brace characters
+     in the string. */
+  if ((eflags & WEXP_BRACEEXP) && brace_expansion && new_list)
+    new_list = brace_expand_word_list (new_list, eflags);
+#endif /* BRACE_EXPANSION */
+
+  /* Perform the `normal' shell expansions: tilde expansion, parameter and
+     variable substitution, command substitution, arithmetic expansion,
+     and word splitting. */
+  new_list = shell_expand_word_list (new_list, eflags);
+
+  /* Okay, we're almost done.  Now let's just do some filename
+     globbing. */
+  if (new_list)
+    {
+      if ((eflags & WEXP_PATHEXP) && disallow_filename_globbing == 0)
+       /* Glob expand the word list unless globbing has been disabled. */
+       new_list = glob_expand_word_list (new_list, eflags);
+      else
+       /* Dequote the words, because we're not performing globbing. */
+       new_list = dequote_list (new_list);
+    }
+
+  if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist)
+    {
+      sh_wassign_func_t *assign_func;
+      int is_special_builtin, is_builtin_or_func;
+
+      /* If the remainder of the words expand to nothing, Posix.2 requires
+        that the variable and environment assignments affect the shell's
+        environment. */
+      assign_func = new_list ? assign_in_env : do_word_assignment;
+      tempenv_assign_error = 0;
+
+      is_builtin_or_func = (new_list && new_list->word && (find_shell_builtin (new_list->word->word) || find_function (new_list->word->word)));
+      /* Posix says that special builtins exit if a variable assignment error
+        occurs in an assignment preceding it. */
+      is_special_builtin = (posixly_correct && new_list && new_list->word && find_special_builtin (new_list->word->word));
+      
+      for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
+       {
+         this_command_name = (char *)NULL;
+         assigning_in_environment = (assign_func == assign_in_env);
+         tint = (*assign_func) (temp_list->word, is_builtin_or_func);
+         assigning_in_environment = 0;
+         /* Variable assignment errors in non-interactive shells running
+            in Posix.2 mode cause the shell to exit. */
+         if (tint == 0)
+           {
+             if (assign_func == do_word_assignment)
+               {
+                 last_command_exit_value = EXECUTION_FAILURE;
+                 if (interactive_shell == 0 && posixly_correct && is_special_builtin)
+                   exp_jump_to_top_level (FORCE_EOF);
+                 else
+                   exp_jump_to_top_level (DISCARD);
+               }
+             else
+               tempenv_assign_error++;
+           }
+       }
+
+      dispose_words (subst_assign_varlist);
+      subst_assign_varlist = (WORD_LIST *)NULL;
+    }
+
+  return (new_list);
+}
index 72ec06a2c1fd8dde92acea5e8ac773e35f1d061b..3efcf32d68e9722024b6ca9d67f9e81b2aa5ac04 100755 (executable)
@@ -1,4 +1,4 @@
-BUILD_DIR=/usr/local/build/bash/bash-current
+BUILD_DIR=/usr/local/build/chet/bash/bash-current
 THIS_SH=$BUILD_DIR/bash
 PATH=$PATH:$BUILD_DIR
 
index 844d31206605785fa0e2d4a749d4fcd388776322..bbacf301333321c45bbdd75f1fa59b660ba81e81 100644 (file)
@@ -1,3 +1,5 @@
+EMPTY=/tmp/empty
+
 shopt -s globstar
 s()
 {
@@ -8,8 +10,8 @@ p()
   printf '<%q>\n' "$@"
 }
 
-mkdir -p /tmp/empty/a/a/a
-cd /tmp/empty
+mkdir -p $EMPTY/a/a/a
+cd $EMPTY
 
 # good
 p **
@@ -17,8 +19,8 @@ p **/**
 p **/**/**
 
 rm -rf a
-mkdir -p /tmp/empty/{a,b}/{a,b}/{a,b}/{a,b}
-cd /tmp/empty
+mkdir -p $EMPTY/{a,b}/{a,b}/{a,b}/{a,b}
+cd $EMPTY
 
 # good
 s '**/a'
@@ -77,4 +79,4 @@ s '**/**/a/**'
 p **/**/a/**
 
 cd -
-rm -rf /tmp/empty
+rm -rf $EMPTY
diff --git a/tests/misc/regress/log.orig b/tests/misc/regress/log.orig
new file mode 100644 (file)
index 0000000..c1f1e19
--- /dev/null
@@ -0,0 +1,50 @@
+:; ./shx
+
+sh:
+<&$fd  ok
+nlbq   Mon Aug  3 02:45:00 EDT 1992
+bang   geoff
+quote  712824302
+setbq  defmsgid=<1992Aug3.024502.6176@host>
+bgwait sleep done... wait 6187
+
+
+bash:
+<&$fd  ok
+nlbq   Mon Aug  3 02:45:09 EDT 1992
+bang   geoff
+quote  712824311
+setbq  defmsgid=<1992Aug3.024512.6212@host>
+bgwait sleep done... wait 6223
+
+
+ash:
+<&$fd  shx1: 4: Syntax error: Bad fd number
+nlbq   Mon Aug  3 02:45:19 EDT 1992
+bang   geoff
+quote  getdate: `"now"' not a valid date
+
+setbq  defmsgid=<1992Aug3.` echo 024521
+bgwait sleep done... wait 6241
+
+
+ksh:
+<&$fd  ok
+nlbq   ./shx: 6248 Memory fault - core dumped
+bang   geoff
+quote  getdate: `"now"' not a valid date
+
+setbq  defmsgid=<1992Aug3.024530.6257@host>
+bgwait no such job: 6265
+wait 6265
+sleep done... 
+
+zsh:
+<&$fd  ok
+nlbq   Mon Aug 3 02:45:36 EDT 1992
+bang   shx3: event not found: /s/ [4]
+quote  712824337
+setbq  defmsgid=<..6290@host>
+bgwait shx7: unmatched " [9]
+sleep done... 
+:; 
diff --git a/tests/misc/regress/shx.orig b/tests/misc/regress/shx.orig
new file mode 100644 (file)
index 0000000..4b3bf2b
--- /dev/null
@@ -0,0 +1,10 @@
+#! /bin/sh
+for cmd in sh bash ash ksh zsh
+do
+       echo
+       echo $cmd:
+       for demo in shx?
+       do
+               $cmd $demo
+       done
+done
index ad946ad422de06c330cdba0f0524d61d9360520f..562952ff0064771edab49b1a63e554b6ba3a540d 100644 (file)
@@ -2709,7 +2709,7 @@ bind_variable (name, value, flags)
      shell_variables table.  This allows sourced scripts to modify values
      given to them in a temporary environment while modifying the variable
      value that the caller sees. */
-  if (temporary_env)
+  if (temporary_env && value)          /* XXX - can value be null here? */
     bind_tempenv_variable (name, value);
 
   /* XXX -- handle local variables here. */
@@ -3931,6 +3931,17 @@ merge_temporary_env ()
     dispose_temporary_env (push_temp_var);
 }
 
+void
+flush_temporary_env ()
+{
+  if (temporary_env)
+    {
+      hash_flush (temporary_env, free_variable_hash_data);
+      hash_dispose (temporary_env);
+      temporary_env = (HASH_TABLE *)NULL;
+    }
+}
+
 /* **************************************************************** */
 /*                                                                 */
 /*          Creating and manipulating the environment              */
index 64677028ea20fe12bd90d52a90ab3edb7485b24f..4574ca8c621ef8599a7f46721e118b2e08b69755 100644 (file)
@@ -322,6 +322,7 @@ extern void dispose_used_env_vars __P((void));
 extern void dispose_function_env __P((void));
 extern void dispose_builtin_env __P((void));
 extern void merge_temporary_env __P((void));
+extern void flush_temporary_env __P((void));
 extern void merge_builtin_env __P((void));
 extern void kill_all_local_variables __P((void));