]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
commit bash-20130705 snapshot
authorChet Ramey <chet@caleb.ins.cwru.edu>
Mon, 5 Aug 2013 13:54:26 +0000 (09:54 -0400)
committerChet Ramey <chet@caleb.ins.cwru.edu>
Mon, 5 Aug 2013 13:54:26 +0000 (09:54 -0400)
18 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]
cross-build/cygwin32.cache.old [new file with mode: 0644]
doc/FAQ.orig [new file with mode: 0644]
doc/bash.1
doc/bash.1~ [new file with mode: 0644]
examples/loadables/Makefile.in.save [new file with mode: 0644]
lib/readline/doc/Makefile.old [new file with mode: 0644]
lib/sh/casemod.c
lib/sh/casemod.c~ [new file with mode: 0644]
parse.y
parse.y~ [new file with mode: 0644]
tests/RUN-ONE-TEST
tests/misc/regress/log.orig [new file with mode: 0644]
tests/misc/regress/shx.orig [new file with mode: 0644]

index d79bb5016883a8e51491f3156861c924090d3b19..d4adb6284daa1193a4baab35ecffeaf2cd42b285 100644 (file)
@@ -5023,3 +5023,10 @@ subst.c
          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>
diff --git a/CWRU/CWRU.chlog~ b/CWRU/CWRU.chlog~
new file mode 100644 (file)
index 0000000..d79bb50
--- /dev/null
@@ -0,0 +1,5025 @@
+                                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>
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 */
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.
index bd0a90473763a9331ac2fac78a7e0e8bbb71cb81..26b86cd482cb015bc2a44b279c123cb80c5385cf 100644 (file)
@@ -10072,7 +10072,7 @@ subsequently reset.  The exit status is true unless a
 is readonly.
 .TP
 \fBwait\fP [\fB\--n\fP] [\fIn ...\fP]
-Wait for each specified process and return its termination status.
+Wait for each specified child process and return its termination status.
 Each
 .I n
 may be a process
diff --git a/doc/bash.1~ b/doc/bash.1~
new file mode 100644 (file)
index 0000000..bd0a904
--- /dev/null
@@ -0,0 +1,10304 @@
+.\"
+.\" MAN PAGE COMMENTS to
+.\"
+.\"    Chet Ramey
+.\"    Case Western Reserve University
+.\"    chet@po.cwru.edu
+.\"
+.\"    Last Change: Thu Jun 27 10:36:53 EDT 2013
+.\"
+.\" bash_builtins, strip all but Built-Ins section
+.if \n(zZ=1 .ig zZ
+.if \n(zY=1 .ig zY
+.TH BASH 1 "2013 June 27" "GNU Bash 4.3"
+.\"
+.\" There's some problem with having a `@'
+.\" in a tagged paragraph with the BSD man macros.
+.\" It has to do with `@' appearing in the }1 macro.
+.\" This is a problem on 4.3 BSD and Ultrix, but Sun
+.\" appears to have fixed it.
+.\" If you're seeing the characters
+.\" `@u-3p' appearing before the lines reading
+.\" `possible-hostname-completions
+.\" and `complete-hostname' down in READLINE,
+.\" then uncomment this redefinition.
+.\"
+.de }1
+.ds ]X \&\\*(]B\\
+.nr )E 0
+.if !"\\$1"" .nr )I \\$1n
+.}f
+.ll \\n(LLu
+.in \\n()Ru+\\n(INu+\\n()Iu
+.ti \\n(INu
+.ie !\\n()Iu+\\n()Ru-\w\a\\*(]X\au-3p \{\\*(]X
+.br\}
+.el \\*(]X\h\a|\\n()Iu+\\n()Ru\a\c
+.}f
+..
+.\"
+.\" File Name macro.  This used to be `.PN', for Path Name,
+.\" but Sun doesn't seem to like that very much.
+.\"
+.de FN
+\fI\|\\$1\|\fP
+..
+.SH NAME
+bash \- GNU Bourne-Again SHell
+.SH SYNOPSIS
+.B bash
+[options]
+[command_string | file]
+.SH COPYRIGHT
+.if n Bash is Copyright (C) 1989-2013 by the Free Software Foundation, Inc.
+.if t Bash is Copyright \(co 1989-2013 by the Free Software Foundation, Inc.
+.SH DESCRIPTION
+.B Bash
+is an \fBsh\fR-compatible command language interpreter that
+executes commands read from the standard input or from a file.
+.B Bash
+also incorporates useful features from the \fIKorn\fP and \fIC\fP
+shells (\fBksh\fP and \fBcsh\fP).
+.PP
+.B Bash
+is intended to be a conformant implementation of the
+Shell and Utilities portion of the IEEE POSIX specification
+(IEEE Standard 1003.1).
+.B Bash
+can be configured to be POSIX-conformant by default.
+.SH OPTIONS
+All of the  single-character shell options documented in the
+description of the \fBset\fR builtin command can be used as options
+when the shell is invoked.
+In addition, \fBbash\fR
+interprets the following options when it is invoked:
+.PP
+.PD 0
+.TP 10
+.B \-c
+If the
+.B \-c
+option is present, then commands are read from the first non-option argument
+.IR command_string .
+If there are arguments after the
+.IR command_string ,
+they are assigned to the positional parameters, starting with
+.BR $0 .
+.TP
+.B \-i
+If the
+.B \-i
+option is present, the shell is
+.IR interactive .
+.TP
+.B \-l
+Make
+.B bash
+act as if it had been invoked as a login shell (see
+.SM
+.B INVOCATION
+below).
+.TP
+.B \-r
+If the
+.B \-r
+option is present, the shell becomes
+.I restricted
+(see
+.SM
+.B "RESTRICTED SHELL"
+below).
+.TP
+.B \-s
+If the
+.B \-s
+option is present, or if no arguments remain after option
+processing, then commands are read from the standard input.
+This option allows the positional parameters to be set
+when invoking an interactive shell.
+.TP
+.B \-D
+A list of all double-quoted strings preceded by \fB$\fP
+is printed on the standard output.
+These are the strings that
+are subject to language translation when the current locale
+is not \fBC\fP or \fBPOSIX\fP.
+This implies the \fB\-n\fP option; no commands will be executed.
+.TP
+.B [\-+]O [\fIshopt_option\fP]
+\fIshopt_option\fP is one of the shell options accepted by the
+\fBshopt\fP builtin (see
+.SM
+.B SHELL BUILTIN COMMANDS
+below).
+If \fIshopt_option\fP is present, \fB\-O\fP sets the value of that option;
+\fB+O\fP unsets it.
+If \fIshopt_option\fP is not supplied, the names and values of the shell
+options accepted by \fBshopt\fP are printed on the standard output.
+If the invocation option is \fB+O\fP, the output is displayed in a format
+that may be reused as input.
+.TP
+.B \-\-
+A
+.B \-\-
+signals the end of options and disables further option processing.
+Any arguments after the
+.B \-\-
+are treated as filenames and arguments.  An argument of
+.B \-
+is equivalent to \fB\-\-\fP.
+.PD
+.PP
+.B Bash
+also interprets a number of multi-character options.
+These options must appear on the command line before the
+single-character options to be recognized.
+.PP
+.PD 0
+.TP
+.B \-\-debugger
+Arrange for the debugger profile to be executed before the shell
+starts.
+Turns on extended debugging mode (see the description of the
+.B extdebug
+option to the
+.B shopt
+builtin below).
+.TP
+.B \-\-dump\-po\-strings
+Equivalent to \fB\-D\fP, but the output is in the GNU \fIgettext\fP
+\fBpo\fP (portable object) file format.
+.TP
+.B \-\-dump\-strings
+Equivalent to \fB\-D\fP.
+.TP
+.B \-\-help
+Display a usage message on standard output and exit successfully.
+.TP
+\fB\-\-init\-file\fP \fIfile\fP
+.PD 0
+.TP
+\fB\-\-rcfile\fP \fIfile\fP
+.PD
+Execute commands from
+.I file
+instead of the standard personal initialization file
+.I ~/.bashrc
+if the shell is interactive (see
+.SM
+.B INVOCATION
+below).
+.TP
+.B \-\-login
+Equivalent to \fB\-l\fP.
+.TP
+.B \-\-noediting
+Do not use the GNU
+.B readline
+library to read command lines when the shell is interactive.
+.TP
+.B \-\-noprofile
+Do not read either the system-wide startup file
+.FN /etc/profile
+or any of the personal initialization files
+.IR ~/.bash_profile ,
+.IR ~/.bash_login ,
+or
+.IR ~/.profile .
+By default,
+.B bash
+reads these files when it is invoked as a login shell (see
+.SM
+.B INVOCATION
+below).
+.TP
+.B \-\-norc
+Do not read and execute the personal initialization file
+.I ~/.bashrc
+if the shell is interactive.
+This option is on by default if the shell is invoked as
+.BR sh .
+.TP
+.B \-\-posix
+Change the behavior of \fBbash\fP where the default operation differs
+from the POSIX standard to match the standard (\fIposix mode\fP).
+See
+.SM
+.B "SEE ALSO"
+below for a reference to a document that details how posix mode affects
+bash's behavior.
+.TP
+.B \-\-restricted
+The shell becomes restricted (see
+.SM
+.B "RESTRICTED SHELL"
+below).
+.TP
+.B \-\-verbose
+Equivalent to  \fB\-v\fP.
+.TP
+.B \-\-version
+Show version information for this instance of
+.B bash
+on the standard output and exit successfully.
+.PD
+.SH ARGUMENTS
+If arguments remain after option processing, and neither the
+.B \-c
+nor the
+.B \-s
+option has been supplied, the first argument is assumed to
+be the name of a file containing shell commands.
+If
+.B bash
+is invoked in this fashion, 
+.B $0
+is set to the name of the file, and the positional parameters
+are set to the remaining arguments.
+.B Bash
+reads and executes commands from this file, then exits.
+\fBBash\fP's exit status is the exit status of the last command
+executed in the script.
+If no commands are executed, the exit status is 0.
+An attempt is first made to open the file in the current directory, and,
+if no file is found, then the shell searches the directories in
+.SM
+.B PATH
+for the script.
+.SH INVOCATION
+A \fIlogin shell\fP is one whose first character of argument zero is a
+.BR \- ,
+or one started with the 
+.B \-\-login
+option.
+.PP
+An \fIinteractive\fP shell is one started without non-option arguments
+and without the
+.B \-c
+option
+whose standard input and error are
+both connected to terminals (as determined by
+.IR isatty (3)),
+or one started with the
+.B \-i
+option.
+.SM
+.B PS1
+is set and
+.B $\-
+includes
+.B i
+if
+.B bash
+is interactive,
+allowing a shell script or a startup file to test this state.
+.PP
+The following paragraphs describe how
+.B bash
+executes its startup files.
+If any of the files exist but cannot be read,
+.B bash
+reports an error.
+Tildes are expanded in filenames as described below under
+.B "Tilde Expansion"
+in the
+.SM
+.B EXPANSION
+section.
+.PP
+When
+.B bash
+is invoked as an interactive login shell, or as a non-interactive shell
+with the \fB\-\-login\fP option, it first reads and
+executes commands from the file \fI/etc/profile\fP, if that
+file exists.
+After reading that file, it looks for \fI~/.bash_profile\fP,
+\fI~/.bash_login\fP, and \fI~/.profile\fP, in that order, and reads
+and executes commands from the first one that exists and is readable.
+The
+.B \-\-noprofile
+option may be used when the shell is started to inhibit this behavior.
+.PP
+When a login shell exits,
+.B bash
+reads and executes commands from the file \fI~/.bash_logout\fP, if it
+exists.
+.PP
+When an interactive shell that is not a login shell is started,
+.B bash
+reads and executes commands from \fI~/.bashrc\fP, if that file exists.
+This may be inhibited by using the
+.B \-\-norc
+option.
+The \fB\-\-rcfile\fP \fIfile\fP option will force
+.B bash
+to read and execute commands from \fIfile\fP instead of \fI~/.bashrc\fP.
+.PP
+When
+.B bash
+is started non-interactively, to run a shell script, for example, it
+looks for the variable
+.SM
+.B BASH_ENV
+in the environment, expands its value if it appears there, and uses the
+expanded value as the name of a file to read and execute.
+.B Bash
+behaves as if the following command were executed:
+.sp .5
+.RS
+.if t \f(CWif [ \-n "$BASH_ENV" ]; then . "$BASH_ENV"; fi\fP
+.if n if [ \-n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
+.RE
+.sp .5
+but the value of the
+.SM
+.B PATH
+variable is not used to search for the filename.
+.PP
+If
+.B bash
+is invoked with the name
+.BR sh ,
+it tries to mimic the startup behavior of historical versions of
+.B sh
+as closely as possible,
+while conforming to the POSIX standard as well.
+When invoked as an interactive login shell, or a non-interactive
+shell with the \fB\-\-login\fP option, it first attempts to
+read and execute commands from
+.I /etc/profile
+and
+.IR ~/.profile ,
+in that order.
+The
+.B \-\-noprofile
+option may be used to inhibit this behavior.
+When invoked as an interactive shell with the name
+.BR sh ,
+.B bash
+looks for the variable
+.SM
+.BR ENV ,
+expands its value if it is defined, and uses the
+expanded value as the name of a file to read and execute.
+Since a shell invoked as
+.B sh
+does not attempt to read and execute commands from any other startup
+files, the
+.B \-\-rcfile
+option has no effect.
+A non-interactive shell invoked with the name
+.B sh
+does not attempt to read any other startup files. 
+When invoked as
+.BR sh ,
+.B bash
+enters
+.I posix
+mode after the startup files are read.
+.PP
+When
+.B bash
+is started in
+.I posix
+mode, as with the
+.B \-\-posix
+command line option, it follows the POSIX standard for startup files.
+In this mode, interactive shells expand the
+.SM
+.B ENV
+variable and commands are read and executed from the file
+whose name is the expanded value.
+No other startup files are read.
+.PP
+.B Bash
+attempts to determine when it is being run with its standard input
+connected to a network connection, as when executed by the remote shell
+daemon, usually \fIrshd\fP, or the secure shell daemon \fIsshd\fP.
+If
+.B bash
+determines it is being run in this fashion, it reads and executes
+commands from \fI~/.bashrc\fP, if that file exists and is readable.
+It will not do this if invoked as \fBsh\fP.
+The
+.B \-\-norc
+option may be used to inhibit this behavior, and the
+.B \-\-rcfile
+option may be used to force another file to be read, but neither
+\fIrshd\fP nor \fIsshd\fP generally invoke the shell with those options
+or allow them to be specified.
+.PP
+If the shell is started with the effective user (group) id not equal to the
+real user (group) id, and the \fB\-p\fP option is not supplied, no startup
+files are read, shell functions are not inherited from the environment, the
+.SM
+.BR SHELLOPTS ,
+.SM
+.BR BASHOPTS ,
+.SM
+.BR CDPATH ,
+and
+.SM
+.B GLOBIGNORE
+variables, if they appear in the environment, are ignored,
+and the effective user id is set to the real user id.
+If the \fB\-p\fP option is supplied at invocation, the startup behavior is
+the same, but the effective user id is not reset.
+.SH DEFINITIONS
+.PP
+The following definitions are used throughout the rest of this
+document.
+.PD 0
+.TP
+.B blank 
+A space or tab.
+.TP
+.B word
+A sequence of characters considered as a single unit by the shell.
+Also known as a
+.BR token .
+.TP
+.B name
+A 
+.I word
+consisting only of alphanumeric characters and underscores, and
+beginning with an alphabetic character or an underscore.  Also
+referred to as an
+.BR identifier .
+.TP
+.B metacharacter
+A character that, when unquoted, separates words.  One of the following:
+.br
+.RS
+.PP
+.if t \fB|  &  ;  (  )  <  >  space  tab\fP
+.if n \fB|  & ; ( ) < > space tab\fP
+.RE
+.PP
+.TP
+.B control operator
+A \fItoken\fP that performs a control function.  It is one of the following
+symbols:
+.RS
+.PP
+.if t \fB||  &  &&  ;  ;;  (  )  |  |&    <newline>\fP
+.if n \fB|| & && ; ;; ( ) | |& <newline>\fP
+.RE
+.PD
+.SH "RESERVED WORDS"
+\fIReserved words\fP are words that have a special meaning to the shell.
+The following words are recognized as reserved when unquoted and either
+the first word of a simple command (see
+.SM
+.B SHELL GRAMMAR
+below) or the third word of a 
+.B case 
+or
+.B for
+command:
+.if t .RS
+.PP
+.B
+.if n ! case  coproc  do done elif else esac fi for function if in select then until while { } time [[ ]]
+.if t !    case    coproc    do    done    elif    else    esac    fi    for    function    if    in    select    then    until    while    {    }    time    [[    ]]
+.if t .RE
+.SH "SHELL GRAMMAR"
+.SS Simple Commands
+.PP
+A \fIsimple command\fP is a sequence of optional variable assignments
+followed by \fBblank\fP-separated words and redirections, and
+terminated by a \fIcontrol operator\fP.  The first word
+specifies the command to be executed, and is passed as argument zero.
+The remaining words are passed as arguments to the invoked command.
+.PP
+The return value of a \fIsimple command\fP is its exit status, or
+128+\fIn\^\fP if the command is terminated by signal
+.IR n .
+.SS Pipelines
+.PP
+A \fIpipeline\fP is a sequence of one or more commands separated by
+one of the control operators
+.B |
+or \fB|&\fP.
+The format for a pipeline is:
+.RS
+.PP
+[\fBtime\fP [\fB\-p\fP]] [ ! ] \fIcommand\fP [ [\fB|\fP\(bv\fB|&\fP] \fIcommand2\fP ... ]
+.RE
+.PP
+The standard output of
+.I command
+is connected via a pipe to the standard input of
+.IR command2 .
+This connection is performed before any redirections specified by the
+command (see
+.SM
+.B REDIRECTION
+below).
+If \fB|&\fP is used, \fIcommand\fP's standard error, in addition to its
+standard output, is connected to
+\fIcommand2\fP's standard input through the pipe;
+it is shorthand for \fB2>&1 |\fP.
+This implicit redirection of the standard error to the standard output is
+performed after any redirections specified by the command.
+.PP
+The return status of a pipeline is the exit status of the last
+command, unless the \fBpipefail\fP option is enabled.
+If \fBpipefail\fP is enabled, the pipeline's return status is the
+value of the last (rightmost) command to exit with a non-zero status,
+or zero if all commands exit successfully.
+If the reserved word
+.B !
+precedes a pipeline, the exit status of that pipeline is the logical
+negation of the exit status as described above.
+The shell waits for all commands in the pipeline to
+terminate before returning a value.
+.PP
+If the
+.B time
+reserved word precedes a pipeline, the elapsed as well as user and
+system time consumed by its execution are reported when the pipeline
+terminates.
+The \fB\-p\fP option changes the output format to that specified by POSIX.
+When the shell is in \fIposix mode\fP, it does not recognize
+\fBtime\fP as a reserved word if the next token begins with a `-'.
+The
+.SM
+.B TIMEFORMAT
+variable may be set to a format string that specifies how the timing
+information should be displayed; see the description of
+.SM
+.B TIMEFORMAT
+under
+.B "Shell Variables"
+below.
+.PP
+When the shell is in \fIposix mode\fP, \fBtime\fP
+may be followed by a newline.  In this case, the shell displays the
+total user and system time consumed by the shell and its children.
+The
+.SM
+.B TIMEFORMAT
+variable may be used to specify the format of
+the time information.
+.PP
+Each command in a pipeline is executed as a separate process (i.e., in a
+subshell).
+.SS Lists
+.PP
+A \fIlist\fP is a sequence of one or more pipelines separated by one
+of the operators
+.BR ; ,
+.BR & ,
+.BR && ,
+or
+.BR || ,
+and optionally terminated by one of
+.BR ; ,
+.BR & ,
+or
+.BR <newline> .
+.PP
+Of these list operators,
+.B &&
+and
+.B ||
+have equal precedence, followed by
+.B ;
+and
+.BR & ,
+which have equal precedence.
+.PP
+A sequence of one or more newlines may appear in a \fIlist\fP instead
+of a semicolon to delimit commands.
+.PP
+If a command is terminated by the control operator
+.BR & ,
+the shell executes the command in the \fIbackground\fP
+in a subshell.  The shell does not wait for the command to
+finish, and the return status is 0.  Commands separated by a
+.B ;
+are executed sequentially; the shell waits for each
+command to terminate in turn.  The return status is the
+exit status of the last command executed.
+.PP
+AND and OR lists are sequences of one of more pipelines separated by the
+\fB&&\fP and \fB||\fP control operators, respectively.
+AND and OR lists are executed with left associativity.
+An AND list has the form
+.RS
+.PP
+\fIcommand1\fP \fB&&\fP \fIcommand2\fP
+.RE
+.PP
+.I command2
+is executed if, and only if,
+.I command1
+returns an exit status of zero.
+.PP
+An OR list has the form
+.RS
+.PP
+\fIcommand1\fP \fB||\fP \fIcommand2\fP
+.PP
+.RE
+.PP
+.I command2
+is executed if and only if
+.I command1
+returns a non-zero exit status.
+The return status of
+AND and OR lists is the exit status of the last command
+executed in the list.
+.SS Compound Commands
+.PP
+A \fIcompound command\fP is one of the following.
+In most cases a \fIlist\fP in a command's description may be separated from
+the rest of the command by one or more newlines, and may be followed by a
+newline in place of a semicolon.
+.TP
+(\fIlist\fP)
+\fIlist\fP is executed in a subshell environment (see
+.SM
+\fBCOMMAND EXECUTION ENVIRONMENT\fP
+below).
+Variable assignments and builtin
+commands that affect the shell's environment do not remain in effect
+after the command completes.  The return status is the exit status of
+\fIlist\fP.
+.TP
+{ \fIlist\fP; }
+\fIlist\fP is simply executed in the current shell environment.
+\fIlist\fP must be terminated with a newline or semicolon.
+This is known as a \fIgroup command\fP.
+The return status is the exit status of
+\fIlist\fP.
+Note that unlike the metacharacters \fB(\fP and \fB)\fP, \fB{\fP and
+\fB}\fP are \fIreserved words\fP and must occur where a reserved
+word is permitted to be recognized.  Since they do not cause a word
+break, they must be separated from \fIlist\fP by whitespace or another
+shell metacharacter.
+.TP
+((\fIexpression\fP))
+The \fIexpression\fP is evaluated according to the rules described
+below under
+.SM
+.BR "ARITHMETIC EVALUATION" .
+If the value of the expression is non-zero, the return status is 0;
+otherwise the return status is 1.  This is exactly equivalent to
+\fBlet "\fIexpression\fP"\fR.
+.TP
+\fB[[\fP \fIexpression\fP \fB]]\fP
+Return a status of 0 or 1 depending on the evaluation of
+the conditional expression \fIexpression\fP.
+Expressions are composed of the primaries described below under
+.SM
+.BR "CONDITIONAL EXPRESSIONS" .
+Word splitting and pathname expansion are not performed on the words
+between the \fB[[\fP and \fB]]\fP; tilde expansion,
+parameter and variable expansion,
+arithmetic expansion, command substitution, process
+substitution, and quote removal are performed.
+Conditional operators such as \fB\-f\fP must be unquoted to be recognized
+as primaries.
+.if t .sp 0.5
+.if n .sp 1
+When used with \fB[[\fP, the \fB<\fP and \fB>\fP operators sort
+lexicographically using the current locale.
+.if t .sp 0.5
+.if n .sp 1
+When the \fB==\fP and \fB!=\fP operators are used, the string to the
+right of the operator is considered a pattern and matched according
+to the rules described below under \fBPattern Matching\fP.
+The \fB=\fP operator is equivalent to \fB==\fP.
+If the shell option
+.B nocasematch
+is enabled, the match is performed without regard to the case
+of alphabetic characters.
+The return value is 0 if the string matches (\fB==\fP) or does not match
+(\fB!=\fP) the pattern, and 1 otherwise.
+Any part of the pattern may be quoted to force the quoted portion
+to be matched as a string.
+.if t .sp 0.5
+.if n .sp 1
+An additional binary operator, \fB=~\fP, is available, with the same
+precedence as \fB==\fP and \fB!=\fP.
+When it is used, the string to the right of the operator is considered
+an extended regular expression and matched accordingly (as in \fIregex\fP(3)).  
+The return value is 0 if the string matches
+the pattern, and 1 otherwise.
+If the regular expression is syntactically incorrect, the conditional
+expression's return value is 2.
+If the shell option
+.B nocasematch
+is enabled, the match is performed without regard to the case
+of alphabetic characters.
+Any part of the pattern may be quoted to force the quoted portion
+to be matched as a string.
+Bracket expressions in regular expressions must be treated carefully,
+since normal quoting characters lose their meanings between brackets.
+If the pattern is stored in a shell variable, quoting the variable
+expansion forces the entire pattern to be matched as a string.
+Substrings matched by parenthesized subexpressions within the regular
+expression are saved in the array variable
+.SM
+.BR BASH_REMATCH .
+The element of
+.SM
+.B BASH_REMATCH
+with index 0 is the portion of the string
+matching the entire regular expression.
+The element of
+.SM
+.B BASH_REMATCH
+with index \fIn\fP is the portion of the
+string matching the \fIn\fPth parenthesized subexpression.
+.if t .sp 0.5
+.if n .sp 1
+Expressions may be combined using the following operators, listed
+in decreasing order of precedence:
+.if t .sp 0.5
+.if n .sp 1
+.RS
+.PD 0
+.TP
+.B ( \fIexpression\fP )
+Returns the value of \fIexpression\fP.
+This may be used to override the normal precedence of operators.
+.TP
+.B ! \fIexpression\fP
+True if
+.I expression
+is false.
+.TP
+\fIexpression1\fP \fB&&\fP \fIexpression2\fP
+True if both
+.I expression1
+and
+.I expression2
+are true.
+.TP
+\fIexpression1\fP \fB||\fP \fIexpression2\fP
+True if either
+.I expression1
+or
+.I expression2
+is true.
+.PD
+.LP
+The \fB&&\fP and \fB||\fP
+operators do not evaluate \fIexpression2\fP if the value of
+\fIexpression1\fP is sufficient to determine the return value of
+the entire conditional expression.
+.RE
+.TP
+\fBfor\fP \fIname\fP [ [ \fBin\fP [ \fIword ...\fP ] ] ; ] \fBdo\fP \fIlist\fP ; \fBdone\fP
+The list of words following \fBin\fP is expanded, generating a list
+of items.
+The variable \fIname\fP is set to each element of this list
+in turn, and \fIlist\fP is executed each time.
+If the \fBin\fP \fIword\fP is omitted, the \fBfor\fP command executes
+\fIlist\fP once for each positional parameter that is set (see
+.SM
+.B PARAMETERS
+below).
+The return status is the exit status of the last command that executes.
+If the expansion of the items following \fBin\fP results in an empty
+list, no commands are executed, and the return status is 0.
+.TP
+\fBfor\fP (( \fIexpr1\fP ; \fIexpr2\fP ; \fIexpr3\fP )) ; \fBdo\fP \fIlist\fP ; \fBdone\fP
+First, the arithmetic expression \fIexpr1\fP is evaluated according
+to the rules described below under
+.SM
+.BR "ARITHMETIC EVALUATION" .
+The arithmetic expression \fIexpr2\fP is then evaluated repeatedly
+until it evaluates to zero.
+Each time \fIexpr2\fP evaluates to a non-zero value, \fIlist\fP is
+executed and the arithmetic expression \fIexpr3\fP is evaluated.
+If any expression is omitted, it behaves as if it evaluates to 1.
+The return value is the exit status of the last command in \fIlist\fP
+that is executed, or false if any of the expressions is invalid.
+.TP
+\fBselect\fP \fIname\fP [ \fBin\fP \fIword\fP ] ; \fBdo\fP \fIlist\fP ; \fBdone\fP
+The list of words following \fBin\fP is expanded, generating a list
+of items.  The set of expanded words is printed on the standard
+error, each preceded by a number.  If the \fBin\fP
+\fIword\fP is omitted, the positional parameters are printed (see
+.SM
+.B PARAMETERS
+below).  The
+.SM
+.B PS3
+prompt is then displayed and a line read from the standard input.
+If the line consists of a number corresponding to one of
+the displayed words, then the value of
+.I name
+is set to that word.  If the line is empty, the words and prompt
+are displayed again.  If EOF is read, the command completes.  Any
+other value read causes
+.I name
+to be set to null.  The line read is saved in the variable
+.SM
+.BR REPLY .
+The
+.I list
+is executed after each selection until a
+.B break
+command is executed.
+The exit status of
+.B select
+is the exit status of the last command executed in
+.IR list ,
+or zero if no commands were executed.
+.TP
+\fBcase\fP \fIword\fP \fBin\fP [ [(] \fIpattern\fP [ \fB|\fP \fIpattern\fP ] \
+... ) \fIlist\fP ;; ] ... \fBesac\fP
+A \fBcase\fP command first expands \fIword\fP, and tries to match
+it against each \fIpattern\fP in turn, using the same matching rules
+as for pathname expansion (see
+.B Pathname Expansion
+below).
+The \fIword\fP is expanded using tilde
+expansion, parameter and variable expansion, arithmetic substitution,
+command substitution, process substitution and quote removal.
+Each \fIpattern\fP examined is expanded using tilde
+expansion, parameter and variable expansion, arithmetic substitution,
+command substitution, and process substitution.
+If the shell option
+.B nocasematch
+is enabled, the match is performed without regard to the case
+of alphabetic characters.
+When a match is found, the corresponding \fIlist\fP is executed.
+If the \fB;;\fP operator is used, no subsequent matches are attempted after
+the first pattern match.
+Using \fB;&\fP in place of \fB;;\fP causes execution to continue with
+the \fIlist\fP associated with the next set of patterns.
+Using \fB;;&\fP in place of \fB;;\fP causes the shell to test the next
+pattern list in the statement, if any, and execute any associated \fIlist\fP
+on a successful match.
+The exit status is zero if no
+pattern matches.  Otherwise, it is the exit status of the
+last command executed in \fIlist\fP.
+.TP
+\fBif\fP \fIlist\fP; \fBthen\fP \fIlist;\fP \
+[ \fBelif\fP \fIlist\fP; \fBthen\fP \fIlist\fP; ] ... \
+[ \fBelse\fP \fIlist\fP; ] \fBfi\fP
+The
+.B if 
+.I list
+is executed.  If its exit status is zero, the
+\fBthen\fP \fIlist\fP is executed.  Otherwise, each \fBelif\fP
+\fIlist\fP is executed in turn, and if its exit status is zero,
+the corresponding \fBthen\fP \fIlist\fP is executed and the
+command completes.  Otherwise, the \fBelse\fP \fIlist\fP is
+executed, if present.  The exit status is the exit status of the
+last command executed, or zero if no condition tested true.
+.TP
+\fBwhile\fP \fIlist-1\fP; \fBdo\fP \fIlist-2\fP; \fBdone\fP
+.PD 0
+.TP
+\fBuntil\fP \fIlist-1\fP; \fBdo\fP \fIlist-2\fP; \fBdone\fP
+.PD
+The \fBwhile\fP command continuously executes the list
+\fIlist-2\fP as long as the last command in the list \fIlist-1\fP returns
+an exit status of zero.  The \fBuntil\fP command is identical
+to the \fBwhile\fP command, except that the test is negated;
+.I list-2
+is executed as long as the last command in
+.I list-1
+returns a non-zero exit status.
+The exit status of the \fBwhile\fP and \fBuntil\fP commands
+is the exit status
+of the last command executed in \fIlist-2\fP, or zero if
+none was executed.
+.SS Coprocesses
+.PP
+A \fIcoprocess\fP is a shell command preceded by the \fBcoproc\fP reserved
+word.
+A coprocess is executed asynchronously in a subshell, as if the command
+had been terminated with the \fB&\fP control operator, with a two-way pipe
+established between the executing shell and the coprocess.
+.PP
+The format for a coprocess is:
+.RS
+.PP
+\fBcoproc\fP [\fINAME\fP] \fIcommand\fP [\fIredirections\fP]
+.RE
+.PP
+This creates a coprocess named \fINAME\fP.
+If \fINAME\fP is not supplied, the default name is \fBCOPROC\fP.
+\fINAME\fP must not be supplied if \fIcommand\fP is a \fIsimple
+command\fP (see above); otherwise, it is interpreted as the first word
+of the simple command.
+When the coprocess is executed, the shell creates an array variable (see
+.B Arrays
+below) named \fINAME\fP in the context of the executing shell.
+The standard output of
+.I command
+is connected via a pipe to a file descriptor in the executing shell,
+and that file descriptor is assigned to \fINAME\fP[0].
+The standard input of
+.I command
+is connected via a pipe to a file descriptor in the executing shell,
+and that file descriptor is assigned to \fINAME\fP[1].
+This pipe is established before any redirections specified by the
+command (see
+.SM
+.B REDIRECTION
+below).
+The file descriptors can be utilized as arguments to shell commands
+and redirections using standard word expansions.
+The file descriptors are not available in subshells.
+The process ID of the shell spawned to execute the coprocess is
+available as the value of the variable \fINAME\fP_PID.
+The \fBwait\fP
+builtin command may be used to wait for the coprocess to terminate.
+.PP
+Since the coprocess is created as an asynchronous command,
+the \fBcoproc\fP command always returns success.
+The return status of a coprocess is the exit status of \fIcommand\fP.
+.SS Shell Function Definitions
+.PP
+A shell function is an object that is called like a simple command and
+executes a compound command with a new set of positional parameters.
+Shell functions are declared as follows:
+.TP
+\fIname\fP () \fIcompound\-command\fP [\fIredirection\fP]
+.PD 0
+.TP
+\fBfunction\fP \fIname\fP [()] \fIcompound\-command\fP [\fIredirection\fP]
+.PD
+This defines a function named \fIname\fP.
+The reserved word \fBfunction\fP is optional.
+If the \fBfunction\fP reserved word is supplied, the parentheses are optional.
+The \fIbody\fP of the function is the compound command
+.I compound\-command 
+(see \fBCompound Commands\fP above).
+That command is usually a \fIlist\fP of commands between { and }, but
+may be any command listed under \fBCompound Commands\fP above.
+\fIcompound\-command\fP is executed whenever \fIname\fP is specified as the
+name of a simple command.
+When in \fIposix mode\fP, \fIname\fP may not be the name of one of the
+POSIX \fIspecial builtins\fP.
+Any redirections (see
+.SM
+.B REDIRECTION
+below) specified when a function is defined are performed
+when the function is executed.
+The exit status of a function definition is zero unless a syntax error
+occurs or a readonly function with the same name already exists.
+When executed, the exit status of a function is the exit status of the
+last command executed in the body.  (See
+.SM
+.B FUNCTIONS
+below.)
+.SH COMMENTS
+In a non-interactive shell, or an interactive shell in which the
+.B interactive_comments
+option to the
+.B shopt
+builtin is enabled (see
+.SM
+.B "SHELL BUILTIN COMMANDS"
+below), a word beginning with
+.B #
+causes that word and all remaining characters on that line to
+be ignored.  An interactive shell without the
+.B interactive_comments
+option enabled does not allow comments.  The
+.B interactive_comments
+option is on by default in interactive shells.
+.SH QUOTING
+\fIQuoting\fP is used to remove the special meaning of certain
+characters or words to the shell.  Quoting can be used to 
+disable special treatment for special characters, to prevent
+reserved words from being recognized as such, and to prevent
+parameter expansion.
+.PP
+Each of the \fImetacharacters\fP listed above under
+.SM
+.B DEFINITIONS
+has special meaning to the shell and must be quoted if it is to
+represent itself.
+.PP
+When the command history expansion facilities are being used
+(see
+.SM
+.B HISTORY EXPANSION
+below), the
+\fIhistory expansion\fP character, usually \fB!\fP, must be quoted
+to prevent history expansion.
+.PP
+There are three quoting mechanisms: the
+.IR "escape character" ,
+single quotes, and double quotes.
+.PP
+A non-quoted backslash (\fB\e\fP) is the
+.IR "escape character" .
+It preserves the literal value of the next character that follows,
+with the exception of <newline>.  If a \fB\e\fP<newline> pair
+appears, and the backslash is not itself quoted, the \fB\e\fP<newline>
+is treated as a line continuation (that is, it is removed from the
+input stream and effectively ignored).
+.PP
+Enclosing characters in single quotes preserves the literal value
+of each character within the quotes.  A single quote may not occur
+between single quotes, even when preceded by a backslash.
+.PP
+Enclosing characters in double quotes preserves the literal value
+of all characters within the quotes, with the exception of
+.BR $ ,
+.BR \` ,
+.BR \e ,
+and, when history expansion is enabled,
+.BR ! .
+The characters
+.B $
+and
+.B \`
+retain their special meaning within double quotes.  The backslash
+retains its special meaning only when followed by one of the following
+characters:
+.BR $ ,
+.BR \` ,
+\^\fB"\fP\^,
+.BR \e ,
+or
+.BR <newline> .
+A double quote may be quoted within double quotes by preceding it with
+a backslash.
+If enabled, history expansion will be performed unless an
+.B !
+appearing in double quotes is escaped using a backslash.
+The backslash preceding the
+.B !
+is not removed.
+.PP
+The special parameters
+.B *
+and
+.B @
+have special meaning when in double
+quotes (see
+.SM
+.B PARAMETERS
+below).
+.PP
+Words of the form \fB$\fP\(aq\fIstring\fP\(aq are treated specially.  The
+word expands to \fIstring\fP, with backslash-escaped characters replaced
+as specified by the ANSI C standard.  Backslash escape sequences, if
+present, are decoded as follows:
+.RS
+.PD 0
+.TP
+.B \ea
+alert (bell)
+.TP
+.B \eb
+backspace
+.TP
+.B \ee
+.TP
+.B \eE
+an escape character
+.TP   
+.B \ef
+form feed
+.TP  
+.B \en
+new line
+.TP     
+.B \er
+carriage return
+.TP
+.B \et
+horizontal tab
+.TP   
+.B \ev
+vertical tab
+.TP
+.B \e\e
+backslash
+.TP
+.B \e\(aq
+single quote
+.TP
+.B \e\(dq
+double quote
+.TP   
+.B \e\fInnn\fP
+the eight-bit character whose value is the octal value \fInnn\fP
+(one to three digits)
+.TP
+.B \ex\fIHH\fP
+the eight-bit character whose value is the hexadecimal value \fIHH\fP
+(one or two hex digits)
+.TP
+.B \eu\fIHHHH\fP
+the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value
+\fIHHHH\fP (one to four hex digits)
+.TP
+.B \eU\fIHHHHHHHH\fP
+the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value
+\fIHHHHHHHH\fP (one to eight hex digits)
+.TP
+.B \ec\fIx\fP
+a control-\fIx\fP character
+.PD
+.RE
+.LP
+The expanded result is single-quoted, as if the dollar sign had
+not been present.
+.PP
+A double-quoted string preceded by a dollar sign (\fB$\fP\(dq\fIstring\fP\(dq)
+will cause the string to be translated according to the current locale.
+If the current locale is \fBC\fP or \fBPOSIX\fP, the dollar sign
+is ignored.
+If the string is translated and replaced, the replacement is
+double-quoted.
+.SH PARAMETERS
+A
+.I parameter
+is an entity that stores values.
+It can be a
+.IR name ,
+a number, or one of the special characters listed below under
+.BR "Special Parameters" .
+A
+.I variable
+is a parameter denoted by a
+.IR name .
+A variable has a \fIvalue\fP and zero or more \fIattributes\fP.
+Attributes are assigned using the
+.B declare
+builtin command (see
+.B declare
+below in
+.SM
+.BR "SHELL BUILTIN COMMANDS" ).
+.PP
+A parameter is set if it has been assigned a value.  The null string is
+a valid value.  Once a variable is set, it may be unset only by using
+the
+.B unset
+builtin command (see
+.SM
+.B SHELL BUILTIN COMMANDS
+below).
+.PP
+A
+.I variable
+may be assigned to by a statement of the form
+.RS
+.PP
+\fIname\fP=[\fIvalue\fP]
+.RE
+.PP
+If
+.I value
+is not given, the variable is assigned the null string.  All
+.I values
+undergo tilde expansion, parameter and variable expansion,
+command substitution, arithmetic expansion, and quote
+removal (see
+.SM
+.B EXPANSION
+below).  If the variable has its
+.B integer
+attribute set, then
+.I value
+is evaluated as an arithmetic expression even if the $((...)) expansion is
+not used (see
+.B "Arithmetic Expansion"
+below).
+Word splitting is not performed, with the exception
+of \fB"$@"\fP as explained below under
+.BR "Special Parameters" .
+Pathname expansion is not performed.
+Assignment statements may also appear as arguments to the
+.BR alias ,
+.BR declare ,
+.BR typeset ,
+.BR export ,
+.BR readonly ,
+and
+.B local
+builtin commands.
+When in \fIposix mode\fP, these builtins may appear in a command after
+one or more instances of the \fBcommand\fP builtin and retain these
+assignment statement properties.
+.PP
+In the context where an assignment statement is assigning a value
+to a shell variable or array index, the += operator can be used to
+append to or add to the variable's previous value.
+When += is applied to a variable for which the \fIinteger\fP attribute has been
+set, \fIvalue\fP is evaluated as an arithmetic expression and added to the
+variable's current value, which is also evaluated.
+When += is applied to an array variable using compound assignment (see
+.B Arrays
+below), the
+variable's value is not unset (as it is when using =), and new values are
+appended to the array beginning at one greater than the array's maximum index
+(for indexed arrays) or added as additional key\-value pairs in an
+associative array.
+When applied to a string-valued variable, \fIvalue\fP is expanded and
+appended to the variable's value.
+.PP
+A variable can be assigned the \fInameref\fP attribute using the
+\fB\-n\fP option to the \fBdeclare\fP or \fBlocal\fP builtin commands
+(see the descriptions of \fBdeclare\fP and \fBlocal\fP below)
+to create a \fInameref\fP, or a reference to another variable.
+This allows variables to be manipulated indirectly.
+Whenever the nameref variable is referenced or assigned to, the operation
+is actually performed on the variable specified by the nameref variable's
+value.
+A nameref is commonly used within shell functions to refer to a variable
+whose name is passed as an argument to the function.
+For instance, if a variable name is passed to a shell function as its first
+argument, running
+.sp .5
+.RS
+.if t \f(CWdeclare -n ref=$1\fP
+.if n declare -n ref=$1
+.RE
+.sp .5
+inside the function creates a nameref variable \fBref\fP whose value is
+the variable name passed as the first argument.
+References and assignments to \fBref\fP are treated as references and
+assignments to the variable whose name was passed as \fB$1\fP.
+If the control variable in a \fBfor\fP loop has the nameref attribute,
+the list of words can be a list of shell variables, and a name reference
+will be established for each word in the list, in turn, when the loop is
+executed.
+Array variables cannot be given the \fB\-n\fP attribute.
+However, nameref variables can reference array variables and subscripted
+array variables.
+Namerefs can be unset using the \fB\-n\fP option to the \fBunset\fP builtin.
+Otherwise, if \fBunset\fP is executed with the name of a nameref variable
+as an argument, the variable referenced by the nameref variable will be unset.
+.SS Positional Parameters
+.PP
+A
+.I positional parameter
+is a parameter denoted by one or more
+digits, other than the single digit 0.  Positional parameters are
+assigned from the shell's arguments when it is invoked,
+and may be reassigned using the
+.B set
+builtin command.  Positional parameters may not be assigned to
+with assignment statements.  The positional parameters are
+temporarily replaced when a shell function is executed (see
+.SM
+.B FUNCTIONS
+below).
+.PP
+When a positional parameter consisting of more than a single
+digit is expanded, it must be enclosed in braces (see
+.SM
+.B EXPANSION
+below).
+.SS Special Parameters
+.PP
+The shell treats several parameters specially.  These parameters may
+only be referenced; assignment to them is not allowed.
+.PD 0
+.TP
+.B *
+Expands to the positional parameters, starting from one.  When the
+expansion occurs within double quotes, it expands to a single word
+with the value of each parameter separated by the first character
+of the 
+.SM
+.B IFS
+special variable.  That is, "\fB$*\fP" is equivalent
+to "\fB$1\fP\fIc\fP\fB$2\fP\fIc\fP\fB...\fP", where
+.I c
+is the first character of the value of the
+.SM
+.B IFS
+variable.  If
+.SM
+.B IFS
+is unset, the parameters are separated by spaces.
+If
+.SM
+.B IFS
+is null, the parameters are joined without intervening separators.
+.TP
+.B @
+Expands to the positional parameters, starting from one.  When the
+expansion occurs within double quotes, each parameter expands to a
+separate word.  That is, "\fB$@\fP" is equivalent to
+"\fB$1\fP" "\fB$2\fP" ...
+If the double-quoted expansion occurs within a word, the expansion of
+the first parameter is joined with the beginning part of the original
+word, and the expansion of the last parameter is joined with the last
+part of the original word.
+When there are no positional parameters, "\fB$@\fP" and 
+.B $@
+expand to nothing (i.e., they are removed).
+.TP
+.B #
+Expands to the number of positional parameters in decimal.
+.TP
+.B ?
+Expands to the exit status of the most recently executed foreground
+pipeline.
+.TP
+.B \-
+Expands to the current option flags as specified upon invocation, 
+by the
+.B set
+builtin command, or those set by the shell itself
+(such as the
+.B \-i
+option).
+.TP
+.B $
+Expands to the process ID of the shell.  In a () subshell, it
+expands to the process ID of the current shell, not the
+subshell.
+.TP
+.B !
+Expands to the process ID of the most recently executed background
+(asynchronous) command.
+.TP
+.B 0
+Expands to the name of the shell or shell script.  This is set at
+shell initialization.  If
+.B bash
+is invoked with a file of commands,
+.B $0
+is set to the name of that file.  If
+.B bash
+is started with the
+.B \-c
+option, then
+.B $0
+is set to the first argument after the string to be
+executed, if one is present.  Otherwise, it is set
+to the filename used to invoke
+.BR bash ,
+as given by argument zero.
+.TP
+.B _
+At shell startup, set to the absolute pathname used to invoke the
+shell or shell script being executed as passed in the environment
+or argument list.
+Subsequently, expands to the last argument to the previous command,
+after expansion.
+Also set to the full pathname used to invoke each command executed
+and placed in the environment exported to that command.
+When checking mail, this parameter holds the name of the mail file
+currently being checked.
+.PD
+.SS Shell Variables
+.PP
+The following variables are set by the shell:
+.PP
+.PD 0
+.TP
+.B BASH
+Expands to the full filename used to invoke this instance of
+.BR bash .
+.TP
+.B BASHOPTS
+A colon-separated list of enabled shell options.  Each word in
+the list is a valid argument for the
+.B \-s
+option to the
+.B shopt
+builtin command (see
+.SM
+.B "SHELL BUILTIN COMMANDS"
+below).  The options appearing in
+.SM
+.B BASHOPTS
+are those reported as
+.I on
+by \fBshopt\fP.
+If this variable is in the environment when
+.B bash
+starts up, each shell option in the list will be enabled before
+reading any startup files.
+This variable is read-only.
+.TP
+.B BASHPID
+Expands to the process ID of the current \fBbash\fP process.
+This differs from \fB$$\fP under certain circumstances, such as subshells
+that do not require \fBbash\fP to be re-initialized.
+.TP
+.B BASH_ALIASES
+An associative array variable whose members correspond to the internal
+list of aliases as maintained by the \fBalias\fP builtin.
+Elements added to this array appear in the alias list; unsetting array
+elements cause aliases to be removed from the alias list.
+.TP
+.B BASH_ARGC
+An array variable whose values are the number of parameters in each
+frame of the current \fBbash\fP execution call stack.
+The number of
+parameters to the current subroutine (shell function or script executed
+with \fB.\fP or \fBsource\fP) is at the top of the stack.
+When a subroutine is executed, the number of parameters passed is pushed onto
+.SM
+.BR BASH_ARGC .
+The shell sets
+.SM
+.B BASH_ARGC
+only when in extended debugging mode (see the description of the
+.B extdebug
+option to the
+.B shopt
+builtin below)
+.TP
+.B BASH_ARGV
+An array variable containing all of the parameters in the current \fBbash\fP
+execution call stack.  The final parameter of the last subroutine call
+is at the top of the stack; the first parameter of the initial call is
+at the bottom.  When a subroutine is executed, the parameters supplied
+are pushed onto
+.SM
+.BR BASH_ARGV .
+The shell sets
+.SM
+.B BASH_ARGV
+only when in extended debugging mode
+(see the description of the
+.B extdebug
+option to the
+.B shopt
+builtin below)
+.TP
+.B BASH_CMDS
+An associative array variable whose members correspond to the internal
+hash table of commands as maintained by the \fBhash\fP builtin.
+Elements added to this array appear in the hash table; unsetting array
+elements cause commands to be removed from the hash table.
+.TP
+.B BASH_COMMAND
+The command currently being executed or about to be executed, unless the
+shell is executing a command as the result of a trap,
+in which case it is the command executing at the time of the trap.
+.TP
+.B BASH_EXECUTION_STRING
+The command argument to the \fB\-c\fP invocation option.
+.TP
+.B BASH_LINENO
+An array variable whose members are the line numbers in source files
+where each corresponding member of
+.SM
+.B FUNCNAME
+was invoked.
+\fB${BASH_LINENO[\fP\fI$i\fP\fB]}\fP is the line number in the source
+file (\fB${BASH_SOURCE[\fP\fI$i+1\fP\fB]}\fP) where
+\fB${FUNCNAME[\fP\fI$i\fP\fB]}\fP was called
+(or \fB${BASH_LINENO[\fP\fI$i-1\fP\fB]}\fP if referenced within another
+shell function).
+Use
+.SM
+.B LINENO
+to obtain the current line number.
+.TP
+.B BASH_REMATCH
+An array variable whose members are assigned by the \fB=~\fP binary
+operator to the \fB[[\fP conditional command.
+The element with index 0 is the portion of the string
+matching the entire regular expression.
+The element with index \fIn\fP is the portion of the
+string matching the \fIn\fPth parenthesized subexpression.
+This variable is read-only.
+.TP
+.B BASH_SOURCE
+An array variable whose members are the source filenames
+where the corresponding shell function names in the
+.SM
+.B FUNCNAME
+array variable are defined.
+The shell function
+\fB${FUNCNAME[\fP\fI$i\fP\fB]}\fP is defined in the file
+\fB${BASH_SOURCE[\fP\fI$i\fP\fB]}\fP and called from
+\fB${BASH_SOURCE[\fP\fI$i+1\fP\fB]}\fP.
+.TP
+.B BASH_SUBSHELL
+Incremented by one within each subshell or subshell environment when
+the shell begins executing in that environment.
+The initial value is 0.
+.TP
+.B BASH_VERSINFO
+A readonly array variable whose members hold version information for
+this instance of
+.BR bash .
+The values assigned to the array members are as follows:
+.sp .5
+.RS
+.TP 24
+.B BASH_VERSINFO[\fR0\fP]
+The major version number (the \fIrelease\fP).
+.TP
+.B BASH_VERSINFO[\fR1\fP]
+The minor version number (the \fIversion\fP).
+.TP
+.B BASH_VERSINFO[\fR2\fP]
+The patch level.
+.TP
+.B BASH_VERSINFO[\fR3\fP]
+The build version.
+.TP
+.B BASH_VERSINFO[\fR4\fP]
+The release status (e.g., \fIbeta1\fP).
+.TP
+.B BASH_VERSINFO[\fR5\fP]
+The value of
+.SM
+.BR MACHTYPE .
+.RE
+.TP
+.B BASH_VERSION
+Expands to a string describing the version of this instance of
+.BR bash .
+.TP
+.B COMP_CWORD
+An index into \fB${COMP_WORDS}\fP of the word containing the current
+cursor position.
+This variable is available only in shell functions invoked by the
+programmable completion facilities (see \fBProgrammable Completion\fP
+below).
+.TP
+.B COMP_KEY
+The key (or final key of a key sequence) used to invoke the current
+completion function.
+.TP
+.B COMP_LINE
+The current command line.
+This variable is available only in shell functions and external
+commands invoked by the
+programmable completion facilities (see \fBProgrammable Completion\fP
+below).
+.TP
+.B COMP_POINT
+The index of the current cursor position relative to the beginning of
+the current command.
+If the current cursor position is at the end of the current command,
+the value of this variable is equal to \fB${#COMP_LINE}\fP.
+This variable is available only in shell functions and external
+commands invoked by the
+programmable completion facilities (see \fBProgrammable Completion\fP
+below).
+.TP
+.B COMP_TYPE
+Set to an integer value corresponding to the type of completion attempted
+that caused a completion function to be called:
+\fITAB\fP, for normal completion,
+\fI?\fP, for listing completions after successive tabs,
+\fI!\fP, for listing alternatives on partial word completion,
+\fI@\fP, to list completions if the word is not unmodified,
+or
+\fI%\fP, for menu completion.
+This variable is available only in shell functions and external
+commands invoked by the
+programmable completion facilities (see \fBProgrammable Completion\fP
+below).
+.TP
+.B COMP_WORDBREAKS
+The set of characters that the \fBreadline\fP library treats as word
+separators when performing word completion.
+If
+.SM
+.B COMP_WORDBREAKS
+is unset, it loses its special properties, even if it is
+subsequently reset.
+.TP
+.B COMP_WORDS
+An array variable (see \fBArrays\fP below) consisting of the individual
+words in the current command line.
+The line is split into words as \fBreadline\fP would split it, using
+.SM
+.B COMP_WORDBREAKS
+as described above.
+This variable is available only in shell functions invoked by the
+programmable completion facilities (see \fBProgrammable Completion\fP
+below).
+.TP
+.B COPROC
+An array variable (see \fBArrays\fP below) created to hold the file descriptors
+for output from and input to an unnamed coprocess (see \fBCoprocesses\fP
+above).
+.TP
+.B DIRSTACK
+An array variable (see
+.B Arrays
+below) containing the current contents of the directory stack.
+Directories appear in the stack in the order they are displayed by the
+.B dirs
+builtin.
+Assigning to members of this array variable may be used to modify
+directories already in the stack, but the
+.B pushd
+and
+.B popd
+builtins must be used to add and remove directories.
+Assignment to this variable will not change the current directory.
+If
+.SM
+.B DIRSTACK
+is unset, it loses its special properties, even if it is
+subsequently reset.
+.TP
+.B EUID
+Expands to the effective user ID of the current user, initialized at
+shell startup.  This variable is readonly.
+.TP
+.B FUNCNAME
+An array variable containing the names of all shell functions
+currently in the execution call stack.
+The element with index 0 is the name of any currently-executing
+shell function.
+The bottom-most element (the one with the highest index) is
+.if t \f(CW"main"\fP.
+.if n "main".
+This variable exists only when a shell function is executing.
+Assignments to
+.SM
+.B FUNCNAME
+have no effect and return an error status.
+If
+.SM
+.B FUNCNAME
+is unset, it loses its special properties, even if it is
+subsequently reset.
+.if t .sp 0.5
+.if n .sp 1
+This variable can be used with \fBBASH_LINENO\fP and \fBBASH_SOURCE\fP.
+Each element of \fBFUNCNAME\fP has corresponding elements in
+\fBBASH_LINENO\fP and \fBBASH_SOURCE\fP to describe the call stack.
+For instance, \fB${FUNCNAME[\fP\fI$i\fP\fB]}\fP was called from the file
+\fB${BASH_SOURCE[\fP\fI$i+1\fP\fB]}\fP at line number
+\fB${BASH_LINENO[\fP\fI$i\fP\fB]}\fP.
+The \fBcaller\fP builtin displays the current call stack using this
+information.
+.TP
+.B GROUPS
+An array variable containing the list of groups of which the current
+user is a member.
+Assignments to    
+.SM
+.B GROUPS
+have no effect and return an error status.
+If
+.SM
+.B GROUPS
+is unset, it loses its special properties, even if it is
+subsequently reset.
+.TP
+.B HISTCMD
+The history number, or index in the history list, of the current
+command.
+If
+.SM
+.B HISTCMD
+is unset, it loses its special properties, even if it is
+subsequently reset.
+.TP
+.B HOSTNAME
+Automatically set to the name of the current host.
+.TP
+.B HOSTTYPE
+Automatically set to a string that uniquely
+describes the type of machine on which
+.B bash
+is executing.
+The default is system-dependent.
+.TP
+.B LINENO
+Each time this parameter is referenced, the shell substitutes
+a decimal number representing the current sequential line number
+(starting with 1) within a script or function.  When not in a
+script or function, the value substituted is not guaranteed to
+be meaningful.
+If
+.SM
+.B LINENO
+is unset, it loses its special properties, even if it is
+subsequently reset.
+.TP
+.B MACHTYPE
+Automatically set to a string that fully describes the system
+type on which
+.B bash
+is executing, in the standard GNU \fIcpu-company-system\fP format.
+The default is system-dependent.
+.TP
+.B MAPFILE
+An array variable (see \fBArrays\fP below) created to hold the text
+read by the \fBmapfile\fP builtin when no variable name is supplied.
+.TP
+.B OLDPWD
+The previous working directory as set by the
+.B cd
+command.
+.TP
+.B OPTARG
+The value of the last option argument processed by the
+.B getopts
+builtin command (see
+.SM
+.B SHELL BUILTIN COMMANDS
+below).
+.TP
+.B OPTIND
+The index of the next argument to be processed by the
+.B getopts
+builtin command (see
+.SM
+.B SHELL BUILTIN COMMANDS
+below).
+.TP
+.B OSTYPE
+Automatically set to a string that
+describes the operating system on which
+.B bash
+is executing.
+The default is system-dependent.
+.TP
+.B PIPESTATUS
+An array variable (see
+.B Arrays
+below) containing a list of exit status values from the processes
+in the most-recently-executed foreground pipeline (which may
+contain only a single command).
+.TP
+.B PPID
+The process ID of the shell's parent.  This variable is readonly.
+.TP
+.B PWD
+The current working directory as set by the
+.B cd
+command.
+.TP
+.B RANDOM
+Each time this parameter is referenced, a random integer between
+0 and 32767 is
+generated.  The sequence of random numbers may be initialized by assigning
+a value to
+.SM
+.BR RANDOM .
+If
+.SM
+.B RANDOM
+is unset, it loses its special properties, even if it is
+subsequently reset.
+.TP
+.B READLINE_LINE
+The contents of the
+.B readline
+line buffer, for use with
+.if t \f(CWbind -x\fP
+.if n "bind -x"
+(see
+.SM
+.B "SHELL BUILTIN COMMANDS"
+below).
+.TP
+.B READLINE_POINT
+The position of the insertion point in the
+.B readline
+line buffer, for use with
+.if t \f(CWbind -x\fP
+.if n "bind -x"
+(see
+.SM
+.B "SHELL BUILTIN COMMANDS"
+below).
+.TP
+.B REPLY
+Set to the line of input read by the
+.B read
+builtin command when no arguments are supplied.
+.TP
+.B SECONDS
+Each time this parameter is
+referenced, the number of seconds since shell invocation is returned.  If a
+value is assigned to 
+.SM
+.BR SECONDS ,
+the value returned upon subsequent
+references is
+the number of seconds since the assignment plus the value assigned.
+If
+.SM
+.B SECONDS
+is unset, it loses its special properties, even if it is
+subsequently reset.
+.TP
+.B SHELLOPTS
+A colon-separated list of enabled shell options.  Each word in
+the list is a valid argument for the
+.B \-o
+option to the
+.B set
+builtin command (see
+.SM
+.B "SHELL BUILTIN COMMANDS"
+below).  The options appearing in
+.SM
+.B SHELLOPTS
+are those reported as
+.I on
+by \fBset \-o\fP.
+If this variable is in the environment when
+.B bash
+starts up, each shell option in the list will be enabled before
+reading any startup files.
+This variable is read-only.
+.TP
+.B SHLVL
+Incremented by one each time an instance of
+.B bash
+is started.
+.TP
+.B UID
+Expands to the user ID of the current user, initialized at shell startup.
+This variable is readonly.
+.PD
+.PP
+The following variables are used by the shell.  In some cases,
+.B bash
+assigns a default value to a variable; these cases are noted
+below.
+.PP
+.PD 0
+.TP
+.B BASH_COMPAT
+The value is used to set the shell's compatibility level.
+See the description of the \fBshopt\fP builtin below under
+\fBSHELL BUILTIN COMMANDS\fP
+for a description of the various compatibility
+levels and their effects.
+The value may be a decimal number (e.g., 4.2) or an integer (e.g., 42)
+corresponding to the desired compatibility level.
+If \fBBASH_COMPAT\fP is unset or set to the empty string, the compatibility
+level is set to the default for the current version.
+If \fBBASH_COMPAT\fP is set to a value that is not one of the valid
+compatibility levels, the shell prints an error message and sets the
+compatibility level to the default for the current version.
+The valid compatibility levels correspond to the compatibility options
+accepted by the \fBshopt\fP builtin described below (for example,
+\fBcompat42\fP means that 4.2 and 42 are valid values).
+The current version is also a valid value.
+.TP
+.B BASH_ENV
+If this parameter is set when \fBbash\fP is executing a shell script,
+its value is interpreted as a filename containing commands to
+initialize the shell, as in
+.IR ~/.bashrc .
+The value of
+.SM
+.B BASH_ENV
+is subjected to parameter expansion, command substitution, and arithmetic
+expansion before being interpreted as a filename.
+.SM
+.B PATH
+is not used to search for the resultant filename.
+.TP
+.B BASH_XTRACEFD
+If set to an integer corresponding to a valid file descriptor, \fBbash\fP
+will write the trace output generated when
+.if t \f(CWset -x\fP
+.if n \fIset -x\fP
+is enabled to that file descriptor.
+The file descriptor is closed when
+.SM
+.B BASH_XTRACEFD
+is unset or assigned a new value.
+Unsetting
+.SM
+.B BASH_XTRACEFD
+or assigning it the empty string causes the
+trace output to be sent to the standard error.
+Note that setting
+.SM
+.B BASH_XTRACEFD
+to 2 (the standard error file
+descriptor) and then unsetting it will result in the standard error
+being closed.
+.TP
+.B CDPATH
+The search path for the
+.B cd
+command.
+This is a colon-separated list of directories in which the shell looks
+for destination directories specified by the
+.B cd
+command.
+A sample value is
+.if t \f(CW".:~:/usr"\fP.
+.if n ".:~:/usr".
+.TP
+.B CHILD_MAX
+Set the number of exited child status values for the shell to remember.
+Bash will not allow this value to be decreased below a POSIX-mandated
+minimum, and there is a maximum value (currently 8192) that this may
+not exceed.
+The minimum value is system-dependent.
+.TP
+.B COLUMNS
+Used by the \fBselect\fP compound command to determine the terminal width
+when printing selection lists.
+Automatically set if the
+.B checkwinsize
+option is enabled or in an interactive shell upon receipt of a
+.SM
+.BR SIGWINCH .
+.TP
+.B COMPREPLY
+An array variable from which \fBbash\fP reads the possible completions
+generated by a shell function invoked by the programmable completion
+facility (see \fBProgrammable Completion\fP below).
+Each array element contains one possible completion.
+.TP
+.B EMACS
+If \fBbash\fP finds this variable in the environment when the shell starts
+with value
+.if t \f(CWt\fP,
+.if n "t",
+it assumes that the shell is running in an Emacs shell buffer and disables
+line editing.
+.TP
+.B ENV
+Similar to
+.SM
+.BR BASH_ENV ;
+used when the shell is invoked in POSIX mode.
+.TP
+.B FCEDIT
+The default editor for the
+.B fc
+builtin command.
+.TP
+.B FIGNORE
+A colon-separated list of suffixes to ignore when performing
+filename completion (see
+.SM
+.B READLINE
+below).
+A filename whose suffix matches one of the entries in 
+.SM
+.B FIGNORE
+is excluded from the list of matched filenames.
+A sample value is
+.if t \f(CW".o:~"\fP.
+.if n ".o:~".
+.TP
+.B FUNCNEST
+If set to a numeric value greater than 0, defines a maximum function
+nesting level.  Function invocations that exceed this nesting level
+will cause the current command to abort.
+.TP
+.B GLOBIGNORE
+A colon-separated list of patterns defining the set of filenames to
+be ignored by pathname expansion.
+If a filename matched by a pathname expansion pattern also matches one
+of the patterns in
+.SM
+.BR GLOBIGNORE ,
+it is removed from the list of matches.
+.TP
+.B HISTCONTROL
+A colon-separated list of values controlling how commands are saved on
+the history list.
+If the list of values includes
+.IR ignorespace ,
+lines which begin with a
+.B space
+character are not saved in the history list.
+A value of 
+.I ignoredups
+causes lines matching the previous history entry to not be saved.
+A value of
+.I ignoreboth
+is shorthand for \fIignorespace\fP and \fIignoredups\fP.
+A value of
+.IR erasedups
+causes all previous lines matching the current line to be removed from
+the history list before that line is saved.
+Any value not in the above list is ignored.
+If
+.SM
+.B HISTCONTROL
+is unset, or does not include a valid value,
+all lines read by the shell parser are saved on the history list,
+subject to the value of
+.SM
+.BR HISTIGNORE .
+The second and subsequent lines of a multi-line compound command are
+not tested, and are added to the history regardless of the value of
+.SM
+.BR HISTCONTROL .
+.TP
+.B HISTFILE
+The name of the file in which command history is saved (see
+.SM
+.B HISTORY
+below).  The default value is \fI~/.bash_history\fP.  If unset, the
+command history is not saved when a shell exits.
+.TP
+.B HISTFILESIZE
+The maximum number of lines contained in the history file.  When this
+variable is assigned a value, the history file is truncated, if
+necessary,
+to contain no more than that number of lines by removing the oldest entries.
+The history file is also truncated to this size after
+writing it when a shell exits.
+If the value is 0, the history file is truncated to zero size.
+Non-numeric values and numeric values less than zero inhibit truncation.
+The shell sets the default value to the value of \fBHISTSIZE\fP
+after reading any startup files.
+.TP
+.B HISTIGNORE
+A colon-separated list of patterns used to decide which command lines
+should be saved on the history list.  Each pattern is anchored at the
+beginning of the line and must match the complete line (no implicit
+`\fB*\fP' is appended).  Each pattern is tested against the line
+after the checks specified by
+.SM
+.B HISTCONTROL
+are applied.
+In addition to the normal shell pattern matching characters, `\fB&\fP'
+matches the previous history line.  `\fB&\fP' may be escaped using a
+backslash; the backslash is removed before attempting a match.
+The second and subsequent lines of a multi-line compound command are
+not tested, and are added to the history regardless of the value of
+.SM
+.BR HISTIGNORE .
+.TP
+.B HISTSIZE
+The number of commands to remember in the command history (see
+.SM
+.B HISTORY
+below).
+If the value is 0, commands are not saved in the history list.
+Numeric values less than zero result in every command being saved
+on the history list (there is no limit).
+The shell sets the default value to 500 after reading any startup files.
+.TP
+.B HISTTIMEFORMAT
+If this variable is set and not null, its value is used as a format string
+for \fIstrftime\fP(3) to print the time stamp associated with each history
+entry displayed by the \fBhistory\fP builtin.
+If this variable is set, time stamps are written to the history file so
+they may be preserved across shell sessions.
+This uses the history comment character to distinguish timestamps from
+other history lines.
+.TP
+.B HOME
+The home directory of the current user; the default argument for the
+\fBcd\fP builtin command.
+The value of this variable is also used when performing tilde expansion.
+.TP
+.B HOSTFILE
+Contains the name of a file in the same format as
+.FN /etc/hosts
+that should be read when the shell needs to complete a
+hostname.
+The list of possible hostname completions may be changed while the
+shell is running;
+the next time hostname completion is attempted after the
+value is changed,
+.B bash
+adds the contents of the new file to the existing list.
+If
+.SM
+.B HOSTFILE
+is set, but has no value, or does not name a readable file,
+\fBbash\fP attempts to read
+.FN /etc/hosts
+to obtain the list of possible hostname completions.
+When
+.SM
+.B HOSTFILE
+is unset, the hostname list is cleared.
+.TP
+.B IFS
+The
+.I Internal Field Separator
+that is used
+for word splitting after expansion and to
+split lines into words with the
+.B read
+builtin command.  The default value is
+``<space><tab><newline>''.
+.TP
+.B IGNOREEOF
+Controls the
+action of an interactive shell on receipt of an
+.SM
+.B EOF
+character as the sole input.  If set, the value is the number of
+consecutive
+.SM
+.B EOF
+characters which must be
+typed as the first characters on an input line before
+.B bash
+exits.  If the variable exists but does not have a numeric value, or
+has no value, the default value is 10.  If it does not exist,
+.SM
+.B EOF
+signifies the end of input to the shell.
+.TP
+.B INPUTRC
+The filename for the
+.B readline
+startup file, overriding the default of
+.FN ~/.inputrc
+(see
+.SM
+.B READLINE
+below).
+.TP
+.B LANG
+Used to determine the locale category for any category not specifically
+selected with a variable starting with \fBLC_\fP.
+.TP
+.B LC_ALL
+This variable overrides the value of
+.SM
+.B LANG
+and any other
+\fBLC_\fP variable specifying a locale category.
+.TP
+.B LC_COLLATE
+This variable determines the collation order used when sorting the
+results of pathname expansion, and determines the behavior of range
+expressions, equivalence classes, and collating sequences within
+pathname expansion and pattern matching.
+.TP
+.B LC_CTYPE
+This variable determines the interpretation of characters and the
+behavior of character classes within pathname expansion and pattern
+matching.
+.TP
+.B LC_MESSAGES
+This variable determines the locale used to translate double-quoted
+strings preceded by a \fB$\fP.
+.TP
+.B LC_NUMERIC
+This variable determines the locale category used for number formatting.
+.TP
+.B LINES
+Used by the \fBselect\fP compound command to determine the column length
+for printing selection lists.
+Automatically set if the
+.B checkwinsize
+option is enabled or in an interactive shell upon receipt of a
+.SM
+.BR SIGWINCH .
+.TP
+.B MAIL
+If this parameter is set to a file or directory name and the
+.SM
+.B MAILPATH
+variable is not set,
+.B bash
+informs the user of the arrival of mail in the specified file or
+Maildir-format directory.
+.TP
+.B MAILCHECK
+Specifies how
+often (in seconds)
+.B bash
+checks for mail.  The default is 60 seconds.  When it is time to check
+for mail, the shell does so before displaying the primary prompt.
+If this variable is unset, or set to a value that is not a number
+greater than or equal to zero, the shell disables mail checking.
+.TP
+.B MAILPATH
+A colon-separated list of filenames to be checked for mail. 
+The message to be printed when mail arrives in a particular file
+may be specified by separating the filename from the message with a `?'.
+When used in the text of the message, \fB$_\fP expands to the name of
+the current mailfile. 
+Example:
+.RS
+.PP
+\fBMAILPATH\fP=\(aq/var/mail/bfox?"You have mail":~/shell\-mail?"$_ has mail!"\(aq
+.PP
+.B Bash
+supplies a default value for this variable, but the location of the user
+mail files that it uses is system dependent (e.g., /var/mail/\fB$USER\fP).
+.RE
+.TP
+.B OPTERR
+If set to the value 1,
+.B bash
+displays error messages generated by the
+.B getopts
+builtin command (see
+.SM
+.B SHELL BUILTIN COMMANDS
+below).
+.SM
+.B OPTERR
+is initialized to 1 each time the shell is invoked or a shell
+script is executed.
+.TP
+.B PATH
+The search path for commands.  It
+is a colon-separated list of directories in which
+the shell looks for commands (see
+.SM
+.B COMMAND EXECUTION
+below).
+A zero-length (null) directory name in the value of
+.SM
+.B PATH
+indicates the current directory.
+A null directory name may appear as two adjacent colons, or as an initial
+or trailing colon.
+The default path is system-dependent,
+and is set by the administrator who installs
+.BR bash .
+A common value is
+.if t \f(CW/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin\fP.
+.if n ``/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin''.
+.TP
+.B POSIXLY_CORRECT
+If this variable is in the environment when \fBbash\fP starts, the shell
+enters \fIposix mode\fP before reading the startup files, as if the
+.B \-\-posix
+invocation option had been supplied.  If it is set while the shell is
+running, \fBbash\fP enables \fIposix mode\fP, as if the command
+.if t \f(CWset -o posix\fP
+.if n \fIset -o posix\fP
+had been executed.
+.TP
+.B PROMPT_COMMAND
+If set, the value is executed as a command prior to issuing each primary
+prompt.
+.TP
+.B PROMPT_DIRTRIM
+If set to a number greater than zero, the value is used as the number of
+trailing directory components to retain when expanding the \fB\ew\fP and
+\fB\eW\fP prompt string escapes (see
+.SM
+.B PROMPTING
+below).  Characters removed are replaced with an ellipsis.
+.TP
+.B PS1
+The value of this parameter is expanded (see
+.SM
+.B PROMPTING
+below) and used as the primary prompt string.  The default value is
+``\fB\es\-\ev\e$ \fP''.
+.TP
+.B PS2
+The value of this parameter is expanded as with
+.SM
+.B PS1
+and used as the secondary prompt string.  The default is
+``\fB> \fP''.
+.TP
+.B PS3
+The value of this parameter is used as the prompt for the
+.B select
+command (see
+.SM
+.B SHELL GRAMMAR
+above).
+.TP
+.B PS4
+The value of this parameter is expanded as with
+.SM
+.B PS1
+and the value is printed before each command
+.B bash
+displays during an execution trace.  The first character of
+.SM
+.B PS4
+is replicated multiple times, as necessary, to indicate multiple
+levels of indirection.  The default is ``\fB+ \fP''.
+.TP
+.B SHELL
+The full pathname to the shell is kept in this environment variable.
+If it is not set when the shell starts,
+.B bash
+assigns to it the full pathname of the current user's login shell.
+.TP
+.B TIMEFORMAT
+The value of this parameter is used as a format string specifying
+how the timing information for pipelines prefixed with the
+.B time
+reserved word should be displayed.
+The \fB%\fP character introduces an escape sequence that is
+expanded to a time value or other information.
+The escape sequences and their meanings are as follows; the
+braces denote optional portions.
+.sp .5
+.RS
+.PD 0
+.TP 10
+.B %%
+A literal \fB%\fP.
+.TP
+.B %[\fIp\fP][l]R
+The elapsed time in seconds.
+.TP
+.B %[\fIp\fP][l]U
+The number of CPU seconds spent in user mode.
+.TP
+.B %[\fIp\fP][l]S
+The number of CPU seconds spent in system mode.
+.TP
+.B %P
+The CPU percentage, computed as (%U + %S) / %R.
+.PD
+.RE
+.IP
+The optional \fIp\fP is a digit specifying the \fIprecision\fP,
+the number of fractional digits after a decimal point.
+A value of 0 causes no decimal point or fraction to be output.
+At most three places after the decimal point may be specified;
+values of \fIp\fP greater than 3 are changed to 3.
+If \fIp\fP is not specified, the value 3 is used.
+.IP
+The optional \fBl\fP specifies a longer format, including
+minutes, of the form \fIMM\fPm\fISS\fP.\fIFF\fPs.
+The value of \fIp\fP determines whether or not the fraction is
+included.
+.IP
+If this variable is not set, \fBbash\fP acts as if it had the
+value \fB$\(aq\enreal\et%3lR\enuser\et%3lU\ensys\e\t%3lS\(aq\fP.
+If the value is null, no timing information is displayed.
+A trailing newline is added when the format string is displayed.
+.PD 0
+.TP
+.B TMOUT
+If set to a value greater than zero,
+.SM
+.B TMOUT
+is treated as the
+default timeout for the \fBread\fP builtin.
+The \fBselect\fP command terminates if input does not arrive
+after
+.SM
+.B TMOUT
+seconds when input is coming from a terminal.
+In an interactive shell, the value is interpreted as the
+number of seconds to wait for a line of input after issuing the
+primary prompt.
+.B Bash
+terminates after waiting for that number of seconds if a complete
+line of input does not arrive.
+.TP
+.B TMPDIR
+If set, \fBbash\fP uses its value as the name of a directory in which
+\fBbash\fP creates temporary files for the shell's use.
+.TP
+.B auto_resume
+This variable controls how the shell interacts with the user and
+job control.  If this variable is set, single word simple
+commands without redirections are treated as candidates for resumption
+of an existing stopped job.  There is no ambiguity allowed; if there is
+more than one job beginning with the string typed, the job most recently
+accessed is selected.  The
+.I name
+of a stopped job, in this context, is the command line used to
+start it.
+If set to the value
+.IR exact ,
+the string supplied must match the name of a stopped job exactly;
+if set to
+.IR substring ,
+the string supplied needs to match a substring of the name of a
+stopped job.  The
+.I substring
+value provides functionality analogous to the
+.B %?
+job identifier (see
+.SM
+.B JOB CONTROL
+below).  If set to any other value, the supplied string must
+be a prefix of a stopped job's name; this provides functionality
+analogous to the \fB%\fP\fIstring\fP job identifier.
+.TP
+.B histchars
+The two or three characters which control history expansion
+and tokenization (see
+.SM
+.B HISTORY EXPANSION
+below).  The first character is the \fIhistory expansion\fP character,
+the character which signals the start of a history
+expansion, normally `\fB!\fP'.
+The second character is the \fIquick substitution\fP
+character, which is used as shorthand for re-running the previous
+command entered, substituting one string for another in the command.
+The default is `\fB^\fP'.
+The optional third character is the character
+which indicates that the remainder of the line is a comment when found
+as the first character of a word, normally `\fB#\fP'.  The history
+comment character causes history substitution to be skipped for the
+remaining words on the line.  It does not necessarily cause the shell
+parser to treat the rest of the line as a comment.
+.PD
+.SS Arrays
+.B Bash
+provides one-dimensional indexed and associative array variables.
+Any variable may be used as an indexed array; the
+.B declare
+builtin will explicitly declare an array.
+There is no maximum
+limit on the size of an array, nor any requirement that members
+be indexed or assigned contiguously.
+Indexed arrays are referenced using integers (including arithmetic
+expressions)  and are zero-based; associative arrays are referenced
+using arbitrary strings.
+Unless otherwise noted, indexed array indices must be non-negative integers.
+.PP
+An indexed array is created automatically if any variable is assigned to
+using the syntax \fIname\fP[\fIsubscript\fP]=\fIvalue\fP.  The
+.I subscript
+is treated as an arithmetic expression that must evaluate to a number.
+To explicitly declare an indexed array, use
+.B declare \-a \fIname\fP
+(see
+.SM
+.B SHELL BUILTIN COMMANDS
+below).
+.B declare \-a \fIname\fP[\fIsubscript\fP]
+is also accepted; the \fIsubscript\fP is ignored.
+.PP
+Associative arrays are created using
+.BR "declare \-A \fIname\fP" .
+.PP
+Attributes may be
+specified for an array variable using the
+.B declare
+and
+.B readonly
+builtins.  Each attribute applies to all members of an array.
+.PP
+Arrays are assigned to using compound assignments of the form
+\fIname\fP=\fB(\fPvalue\fI1\fP ... value\fIn\fP\fB)\fP, where each
+\fIvalue\fP is of the form [\fIsubscript\fP]=\fIstring\fP.
+Indexed array assignments do not require anything but \fIstring\fP.
+When assigning to indexed arrays, if the optional brackets and subscript
+are supplied, that index is assigned to;
+otherwise the index of the element assigned is the last index assigned
+to by the statement plus one.  Indexing starts at zero.
+.PP
+When assigning to an associative array, the subscript is required.
+.PP
+This syntax is also accepted by the
+.B declare
+builtin.  Individual array elements may be assigned to using the
+\fIname\fP[\fIsubscript\fP]=\fIvalue\fP syntax introduced above.
+When assigning to an indexed array, if
+.I name
+is subscripted by a negative number, that number is
+interpreted as relative to one greater than the maximum index of
+\fIname\fP, so negative indices count back from the end of the
+array, and an index of \-1 references the last element.
+.PP
+Any element of an array may be referenced using
+${\fIname\fP[\fIsubscript\fP]}.  The braces are required to avoid
+conflicts with pathname expansion.  If
+\fIsubscript\fP is \fB@\fP or \fB*\fP, the word expands to
+all members of \fIname\fP.  These subscripts differ only when the
+word appears within double quotes.  If the word is double-quoted,
+${\fIname\fP[*]} expands to a single
+word with the value of each array member separated by the first
+character of the
+.SM
+.B IFS
+special variable, and ${\fIname\fP[@]} expands each element of
+\fIname\fP to a separate word.  When there are no array members,
+${\fIname\fP[@]} expands to nothing.
+If the double-quoted expansion occurs within a word, the expansion of
+the first parameter is joined with the beginning part of the original
+word, and the expansion of the last parameter is joined with the last
+part of the original word.
+This is analogous to the expansion
+of the special parameters \fB*\fP and \fB@\fP (see
+.B Special Parameters
+above).  ${#\fIname\fP[\fIsubscript\fP]} expands to the length of
+${\fIname\fP[\fIsubscript\fP]}.  If \fIsubscript\fP is \fB*\fP or
+\fB@\fP, the expansion is the number of elements in the array.
+Referencing an array variable without a subscript is equivalent to
+referencing the array with a subscript of 0.
+If the
+.I subscript
+used to reference an element of an indexed array
+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 element.
+.PP
+An array variable is considered set if a subscript has been assigned a
+value.  The null string is a valid value.
+.PP
+It is possible to obtain the keys (indices) of an array as well as the values.
+${\fB!\fP\fIname\fP[\fI@\fP]} and ${\fB!\fP\fIname\fP[\fI*\fP]}
+expand to the indices assigned in array variable \fIname\fP.
+The treatment when in double quotes is similar to the expansion of the
+special parameters \fI@\fP and \fI*\fP within double quotes.
+.PP
+The
+.B unset
+builtin is used to destroy arrays.  \fBunset\fP \fIname\fP[\fIsubscript\fP]
+destroys the array element at index \fIsubscript\fP.
+Negative subscripts to indexed arrays are interpreted as described above.
+Care must be taken to avoid unwanted side effects caused by pathname
+expansion.
+\fBunset\fP \fIname\fP, where \fIname\fP is an array, or
+\fBunset\fP \fIname\fP[\fIsubscript\fP], where
+\fIsubscript\fP is \fB*\fP or \fB@\fP, removes the entire array.
+.PP
+The
+.BR declare ,
+.BR local ,
+and
+.B readonly
+builtins each accept a
+.B \-a
+option to specify an indexed array and a
+.B \-A
+option to specify an associative array.
+If both options are supplied, 
+.B \-A
+takes precedence.
+The
+.B read
+builtin accepts a
+.B \-a
+option to assign a list of words read from the standard input
+to an array.  The
+.B set
+and
+.B declare
+builtins display array values in a way that allows them to be
+reused as assignments.
+.SH EXPANSION
+Expansion is performed on the command line after it has been split into
+words.  There are seven kinds of expansion performed:
+.IR "brace expansion" ,
+.IR "tilde expansion" ,
+.IR "parameter and variable expansion" ,
+.IR "command substitution" ,
+.IR "arithmetic expansion" ,
+.IR "word splitting" ,
+and
+.IR "pathname expansion" .
+.PP
+The order of expansions is: brace expansion, tilde expansion,
+parameter, variable and arithmetic expansion and
+command substitution
+(done in a left-to-right fashion), word splitting, and pathname
+expansion.
+.PP
+On systems that can support it, there is an additional expansion
+available: \fIprocess substitution\fP.
+.PP
+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 of
+"\fB$@\fP" and "\fB${\fP\fIname\fP\fB[@]}\fP"
+as explained above (see
+.SM
+.BR PARAMETERS ).
+.SS Brace Expansion
+.PP
+.I "Brace expansion"
+is a mechanism by which arbitrary strings
+may be generated.  This mechanism is similar to
+\fIpathname expansion\fP, but the filenames generated
+need not exist.  Patterns to be brace expanded take
+the form of an optional
+.IR preamble ,
+followed by either a series of comma-separated strings or
+a sequence expression between a pair of braces, followed by
+an optional
+.IR postscript .
+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.
+.PP
+Brace expansions may be nested.  The results of each expanded
+string are not sorted; left to right order is preserved.
+For example, a\fB{\fPd,c,b\fB}\fPe expands into `ade ace abe'.
+.PP
+A sequence expression takes the form
+\fB{\fP\fIx\fP\fB..\fP\fIy\fP\fB[..\fP\fIincr\fP\fB]}\fP,
+where \fIx\fP and \fIy\fP are either integers or single characters,
+and \fIincr\fP, an optional increment, is an integer.
+When integers are supplied, the expression expands to each number between
+\fIx\fP and \fIy\fP, inclusive.
+Supplied integers may be prefixed with \fI0\fP to force each term to have the
+same width.
+When either \fIx\fP or \fPy\fP begins with a zero, the shell
+attempts to force all generated terms to contain the same number of digits,
+zero-padding where necessary.
+When characters are supplied, the expression expands to each character
+lexicographically between \fIx\fP and \fIy\fP, inclusive,
+using the default C locale.
+Note that both \fIx\fP and \fIy\fP 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.
+.PP
+Brace expansion is performed before any other expansions,
+and any characters special to other expansions are preserved
+in the result.  It is strictly textual.
+.B Bash
+does not apply any syntactic interpretation to the context of the
+expansion or the text between the braces.
+.PP
+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 \fB{\fP or \fB,\fP may be quoted with a backslash to prevent its
+being considered part of a brace expression.
+To avoid conflicts with parameter expansion, the string \fB${\fP
+is not considered eligible for brace expansion.
+.PP
+This construct is typically used as shorthand when the common
+prefix of the strings to be generated is longer than in the
+above example:
+.RS
+.PP
+mkdir /usr/local/src/bash/{old,new,dist,bugs}
+.RE
+or
+.RS
+chown root /usr/{ucb/{ex,edit},lib/{ex?.?*,how_ex}}
+.RE
+.PP
+Brace expansion introduces a slight incompatibility with
+historical versions of
+.BR sh .
+.B sh
+does not treat opening or closing braces specially when they
+appear as part of a word, and preserves them in the output.
+.B Bash
+removes braces from words as a consequence of brace
+expansion.  For example, a word entered to
+.B sh
+as \fIfile{1,2}\fP
+appears identically in the output.  The same word is
+output as
+.I file1 file2
+after expansion by
+.BR bash .
+If strict compatibility with
+.B sh
+is desired, start
+.B bash
+with the
+.B +B 
+option or disable brace expansion with the
+.B +B
+option to the
+.B set
+command (see
+.SM
+.B SHELL BUILTIN COMMANDS
+below).
+.SS Tilde Expansion
+.PP
+If a word begins with an unquoted tilde character (`\fB~\fP'), all of
+the characters preceding the first unquoted slash (or all characters,
+if there is no unquoted slash) are considered a \fItilde-prefix\fP.
+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 \fIlogin name\fP.
+If this login name is the null string, the tilde is replaced with the
+value of the shell parameter
+.SM
+.BR HOME .
+If
+.SM
+.B HOME
+is unset, the home directory of the user executing the shell is
+substituted instead.
+Otherwise, the tilde-prefix is replaced with the home directory
+associated with the specified login name.
+.PP
+If the tilde-prefix is a `~+', the value of the shell variable
+.SM
+.B PWD
+replaces the tilde-prefix.
+If the tilde-prefix is a `~\-', the value of the shell variable
+.SM
+.BR OLDPWD ,
+if it is set, is substituted.
+If the characters following the tilde in the tilde-prefix consist
+of a number \fIN\fP, 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
+.B dirs
+builtin invoked with the tilde-prefix as an argument.
+If the characters following the tilde in the tilde-prefix consist of a
+number without a leading `+' or `\-', `+' is assumed.
+.PP
+If the login name is invalid, or the tilde expansion fails, the word
+is unchanged.
+.PP
+Each variable assignment is checked for unquoted tilde-prefixes immediately
+following a
+.B :
+or the first
+.BR = .
+In these cases, tilde expansion is also performed.
+Consequently, one may use filenames with tildes in assignments to
+.SM
+.BR PATH ,
+.SM
+.BR MAILPATH ,
+and
+.SM
+.BR CDPATH ,
+and the shell assigns the expanded value.
+.SS Parameter Expansion
+.PP
+The `\fB$\fP' 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 could be
+interpreted as part of the name.
+.PP
+When braces are used, the matching ending brace is the first `\fB}\fP'
+not escaped by a backslash or within a quoted string, and not within an
+embedded arithmetic expansion, command substitution, or parameter
+expansion.
+.PP
+.PD 0
+.TP
+${\fIparameter\fP}
+The value of \fIparameter\fP is substituted.  The braces are required
+when
+.I parameter
+is a positional parameter with more than one digit,
+or when
+.I parameter
+is followed by a character which is not to be
+interpreted as part of its name.
+The \fIparameter\fP is a shell parameter as described above
+\fBPARAMETERS\fP) or an array reference (\fBArrays\fP).
+.PD
+.PP
+If the first character of \fIparameter\fP is an exclamation point (\fB!\fP),
+it introduces a level of variable indirection.
+\fBBash\fP uses the value of the variable formed from the rest of
+\fIparameter\fP 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 \fIparameter\fP itself.
+This is known as \fIindirect expansion\fP.
+The exceptions to this are the expansions of ${\fB!\fP\fIprefix\fP\fB*\fP} and
+${\fB!\fP\fIname\fP[\fI@\fP]} described below.
+The exclamation point must immediately follow the left brace in order to
+introduce indirection.
+.PP
+In each of the cases below, \fIword\fP is subject to tilde expansion,
+parameter expansion, command substitution, and arithmetic expansion.
+.PP
+When not performing substring expansion, using the forms documented below
+(e.g., \fB:-\fP),
+\fBbash\fP tests for a parameter that is unset or null.  Omitting the colon
+results in a test only for a parameter that is unset.
+.PP
+.PD 0
+.TP
+${\fIparameter\fP\fB:\-\fP\fIword\fP}
+\fBUse Default Values\fP.  If
+.I parameter
+is unset or null, the expansion of
+.I word
+is substituted.  Otherwise, the value of
+.I parameter
+is substituted.
+.TP
+${\fIparameter\fP\fB:=\fP\fIword\fP}
+\fBAssign Default Values\fP.
+If
+.I parameter
+is unset or null, the expansion of
+.I word
+is assigned to
+.IR parameter .
+The value of
+.I parameter
+is then substituted.  Positional parameters and special parameters may
+not be assigned to in this way.
+.TP
+${\fIparameter\fP\fB:?\fP\fIword\fP}
+\fBDisplay Error if Null or Unset\fP.
+If
+.I parameter
+is null or unset, the expansion of \fIword\fP (or a message to that effect
+if
+.I word
+is not present) is written to the standard error and the shell, if it
+is not interactive, exits.  Otherwise, the value of \fIparameter\fP is
+substituted.
+.TP
+${\fIparameter\fP\fB:+\fP\fIword\fP}
+\fBUse Alternate Value\fP.
+If
+.I parameter
+is null or unset, nothing is substituted, otherwise the expansion of
+.I word
+is substituted.
+.TP
+${\fIparameter\fP\fB:\fP\fIoffset\fP}
+.PD 0
+.TP
+${\fIparameter\fP\fB:\fP\fIoffset\fP\fB:\fP\fIlength\fP}
+.PD
+\fBSubstring Expansion\fP.
+Expands to up to \fIlength\fP characters of the value of \fIparameter\fP
+starting at the character specified by \fIoffset\fP.
+If \fIparameter\fP is \fB@\fP, an indexed array subscripted by
+\fB@\fP or \fB*\fP, or an associative array name, the results differ as
+described below.
+If \fIlength\fP is omitted, expands to the substring of the value of
+\fIparameter\fP starting at the character specified by \fIoffset\fP
+and extending to the end of the value.
+\fIlength\fP and \fIoffset\fP are arithmetic expressions (see
+.SM
+.B
+ARITHMETIC EVALUATION
+below).
+.sp 1
+If \fIoffset\fP evaluates to a number less than zero, the value
+is used as an offset in characters
+from the end of the value of \fIparameter\fP.
+If \fIlength\fP evaluates to a number less than zero,
+it is interpreted as an offset in characters
+from the end of the value of \fIparameter\fP rather than
+a number of characters, and the expansion is the characters between
+\fIoffset\fP 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 \fB:-\fP expansion.
+.sp 1
+If \fIparameter\fP is \fB@\fP, the result is \fIlength\fP positional
+parameters beginning at \fIoffset\fP.
+A negative \fIoffset\fP 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 expansion error if \fIlength\fP evaluates to a number less than
+zero.
+.sp 1
+If \fIparameter\fP is an indexed array name subscripted by @ or *,
+the result is the \fIlength\fP
+members of the array beginning with ${\fIparameter\fP[\fIoffset\fP]}.
+A negative \fIoffset\fP is taken relative to one greater than the maximum
+index of the specified array.
+It is an expansion error if \fIlength\fP evaluates to a number less than
+zero.
+.sp 1
+Substring expansion applied to an associative array produces undefined
+results.
+.sp 1
+Substring indexing is zero-based unless the positional parameters 
+are used, in which case the indexing starts at 1 by default.
+If \fIoffset\fP is 0, and the positional parameters are used, \fB$0\fP is
+prefixed to the list.
+.TP
+${\fB!\fP\fIprefix\fP\fB*\fP}
+.PD 0
+.TP
+${\fB!\fP\fIprefix\fP\fB@\fP}
+.PD
+\fBNames matching prefix\fP.
+Expands to the names of variables whose names begin with \fIprefix\fP,
+separated by the first character of the
+.SM
+.B IFS
+special variable.
+When \fI@\fP is used and the expansion appears within double quotes, each
+variable name expands to a separate word.
+.TP
+${\fB!\fP\fIname\fP[\fI@\fP]}
+.PD 0
+.TP
+${\fB!\fP\fIname\fP[\fI*\fP]}
+.PD
+\fBList of array keys\fP.
+If \fIname\fP is an array variable, expands to the list of array indices
+(keys) assigned in \fIname\fP.
+If \fIname\fP is not an array, expands to 0 if \fIname\fP is set and null
+otherwise.
+When \fI@\fP is used and the expansion appears within double quotes, each
+key expands to a separate word.
+.TP
+${\fB#\fP\fIparameter\fP}
+\fBParameter length\fP.
+The length in characters of the value of \fIparameter\fP is substituted.
+If
+.I parameter
+is
+.B *
+or 
+.BR @ ,
+the value substituted is the number of positional parameters.
+If
+.I parameter
+is an array name subscripted by
+.B *
+or
+.BR @ ,
+the value substituted is the number of elements in the array.
+If
+.I parameter
+is an indexed array name subscripted by a negative number, that number is
+interpreted as relative to one greater than the maximum index of
+\fIparameter\fP, so negative indices count back from the end of the
+array, and an index of \-1 references the last element.
+.TP
+${\fIparameter\fP\fB#\fP\fIword\fP}
+.PD 0
+.TP
+${\fIparameter\fP\fB##\fP\fIword\fP}
+.PD
+\fBRemove matching prefix pattern\fP.
+The 
+.I word
+is expanded to produce a pattern just as in pathname
+expansion.  If the pattern matches the beginning of
+the value of
+.IR parameter ,
+then the result of the expansion is the expanded value of
+.I parameter
+with the shortest matching pattern (the ``\fB#\fP'' case) or the
+longest matching pattern (the ``\fB##\fP'' case) deleted.
+If
+.I parameter
+is
+.B @
+or
+.BR * ,
+the pattern removal operation is applied to each positional
+parameter in turn, and the expansion is the resultant list.
+If
+.I parameter
+is an array variable subscripted with
+.B @
+or
+.BR * ,
+the pattern removal operation is applied to each member of the
+array in turn, and the expansion is the resultant list.
+.TP
+${\fIparameter\fP\fB%\fP\fIword\fP}
+.PD 0
+.TP
+${\fIparameter\fP\fB%%\fP\fIword\fP}
+.PD
+\fBRemove matching suffix pattern\fP.
+The \fIword\fP is expanded to produce a pattern just as in
+pathname expansion.
+If the pattern matches a trailing portion of the expanded value of
+.IR parameter ,
+then the result of the expansion is the expanded value of
+.I parameter
+with the shortest matching pattern (the ``\fB%\fP'' case) or the
+longest matching pattern (the ``\fB%%\fP'' case) deleted.
+If
+.I parameter
+is
+.B @
+or
+.BR * ,
+the pattern removal operation is applied to each positional
+parameter in turn, and the expansion is the resultant list.
+If
+.I parameter
+is an array variable subscripted with
+.B @
+or
+.BR * ,
+the pattern removal operation is applied to each member of the
+array in turn, and the expansion is the resultant list.
+.TP
+${\fIparameter\fP\fB/\fP\fIpattern\fP\fB/\fP\fIstring\fP}
+\fBPattern substitution\fP.
+The \fIpattern\fP is expanded to produce a pattern just as in
+pathname expansion.
+\fIParameter\fP is expanded and the longest match of \fIpattern\fP
+against its value is replaced with \fIstring\fP.
+If \fIpattern\fP begins with \fB/\fP, all matches of \fIpattern\fP are
+replaced with \fIstring\fP.  Normally only the first match is replaced.
+If \fIpattern\fP begins with \fB#\fP, it must match at the beginning
+of the expanded value of \fIparameter\fP.
+If \fIpattern\fP begins with \fB%\fP, it must match at the end
+of the expanded value of \fIparameter\fP.
+If \fIstring\fP is null, matches of \fIpattern\fP are deleted
+and the \fB/\fP following \fIpattern\fP may be omitted.
+If
+.I parameter
+is
+.B @
+or
+.BR * ,
+the substitution operation is applied to each positional
+parameter in turn, and the expansion is the resultant list.
+If
+.I parameter
+is an array variable subscripted with
+.B @
+or
+.BR * ,
+the substitution operation is applied to each member of the
+array in turn, and the expansion is the resultant list.
+.TP
+${\fIparameter\fP\fB^\fP\fIpattern\fP}
+.PD 0
+.TP
+${\fIparameter\fP\fB^^\fP\fIpattern\fP}
+.TP
+${\fIparameter\fP\fB,\fP\fIpattern\fP}
+.TP
+${\fIparameter\fP\fB,,\fP\fIpattern\fP}
+.PD
+\fBCase modification\fP.
+This expansion modifies the case of alphabetic characters in \fIparameter\fP.
+The \fIpattern\fP is expanded to produce a pattern just as in
+pathname expansion.
+Each character in the expanded value of \fIparameter\fP is tested against
+\fIpattern\fP, and, if it matches the pattern, its case is converted.
+The pattern should not attempt to match more than one character.
+The \fB^\fP operator converts lowercase letters matching \fIpattern\fP
+to uppercase; the \fB,\fP operator converts matching uppercase letters
+to lowercase.
+The \fB^^\fP and \fB,,\fP expansions convert each matched character in the
+expanded value; the \fB^\fP and \fB,\fP expansions match and convert only
+the first character in the expanded value.
+If \fIpattern\fP is omitted, it is treated like a \fB?\fP, which matches
+every character.
+If
+.I parameter
+is
+.B @
+or
+.BR * ,
+the case modification operation is applied to each positional
+parameter in turn, and the expansion is the resultant list.
+If
+.I parameter
+is an array variable subscripted with
+.B @
+or
+.BR * ,
+the case modification operation is applied to each member of the
+array in turn, and the expansion is the resultant list.
+.SS Command Substitution
+.PP
+\fICommand substitution\fP allows the output of a command to replace
+the command name.  There are two forms:
+.RS
+.PP
+\fB$(\fP\fIcommand\fP\|\fB)\fP
+.RE
+or
+.RS
+\fB\`\fP\fIcommand\fP\fB\`\fP
+.RE
+.PP
+.B Bash
+performs the expansion by executing \fIcommand\fP and
+replacing the command 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 \fB$(cat \fIfile\fP)\fR can be replaced by
+the equivalent but faster \fB$(< \fIfile\fP)\fR.
+.PP
+When the old-style backquote form of substitution is used,
+backslash retains its literal meaning except when followed by
+.BR $ ,
+.BR \` ,
+or
+.BR \e .
+The first backquote not preceded by a backslash terminates the
+command substitution.
+When using the $(\^\fIcommand\fP\|) form, all characters between the
+parentheses make up the command; none are treated specially.
+.PP
+Command substitutions may be nested.  To nest when using the backquoted form,
+escape the inner backquotes with backslashes.
+.PP
+If the substitution appears within double quotes, word splitting and
+pathname expansion are not performed on the results.
+.SS Arithmetic Expansion
+.PP
+Arithmetic expansion allows the evaluation of an arithmetic expression
+and the substitution of the result.  The format for arithmetic expansion is:
+.RS
+.PP
+\fB$((\fP\fIexpression\fP\fB))\fP
+.RE
+.PP
+The
+.I expression
+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,
+command substitution, and quote removal.
+The result is treated as the arithmetic expression to be evaluated.
+Arithmetic expansions may be nested.
+.PP
+The evaluation is performed according to the rules listed below under
+.SM
+.BR "ARITHMETIC EVALUATION" .
+If
+.I expression
+is invalid,
+.B bash
+prints a message indicating failure and no substitution occurs.
+.SS Process Substitution
+.PP
+\fIProcess substitution\fP is supported on systems that support named
+pipes (\fIFIFOs\fP) or the \fB/dev/fd\fP method of naming open files.
+It takes the form of
+\fB<(\fP\fIlist\^\fP\fB)\fP
+or
+\fB>(\fP\fIlist\^\fP\fB)\fP.
+The process \fIlist\fP is run with its input or output connected to a
+\fIFIFO\fP or some file in \fB/dev/fd\fP.  The name of this file is
+passed as an argument to the current command as the result of the
+expansion.  If the \fB>(\fP\fIlist\^\fP\fB)\fP form is used, writing to
+the file will provide input for \fIlist\fP.  If the
+\fB<(\fP\fIlist\^\fP\fB)\fP form is used, the file passed as an
+argument should be read to obtain the output of \fIlist\fP.
+.PP
+When available, process substitution is performed
+simultaneously with parameter and variable expansion, 
+command substitution,
+and arithmetic expansion.
+.SS Word Splitting
+.PP
+The shell scans the results of
+parameter expansion,
+command substitution,
+and
+arithmetic expansion
+that did not occur within double quotes for
+.IR "word splitting" .
+.PP
+The shell treats each character of
+.SM
+.B IFS
+as a delimiter, and splits the results of the other
+expansions into words on these characters.  If
+.SM
+.B IFS
+is unset, or its
+value is exactly
+.BR <space><tab><newline> ,
+the default, then
+sequences of
+.BR <space> ,
+.BR <tab> ,
+and
+.B <newline>
+at the beginning and end of the results of the previous
+expansions are ignored, and
+any sequence of
+.SM
+.B IFS
+characters not at the beginning or end serves to delimit words.
+If
+.SM
+.B IFS
+has a value other than the default, then sequences of
+the whitespace characters
+.B space
+and
+.B tab
+are ignored at the beginning and end of the
+word, as long as the whitespace character is in the
+value of
+.SM
+.BR IFS
+(an
+.SM
+.B IFS
+whitespace character).
+Any character in
+.SM
+.B IFS
+that is not
+.SM
+.B IFS
+whitespace, along with any adjacent
+.SM
+.B IFS
+whitespace characters, delimits a field.
+A sequence of
+.SM
+.B IFS
+whitespace characters is also treated as a delimiter.
+If the value of
+.SM
+.B IFS
+is null, no word splitting occurs.
+.PP
+Explicit null arguments (\^\f3"\^"\fP or \^\f3\(aq\^\(aq\fP\^) 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 double quotes, a
+null argument results and is retained.
+.PP
+Note that if no expansion occurs, no splitting
+is performed.
+.SS Pathname Expansion
+.PP
+After word splitting,
+unless the
+.B \-f
+option has been set,
+.B bash
+scans each word for the characters
+.BR * ,
+.BR ? ,
+and
+.BR [ .
+If one of these characters appears, then the word is
+regarded as a
+.IR pattern ,
+and replaced with an alphabetically sorted list of
+filenames matching the pattern
+(see
+.SM
+.B "Pattern Matching"
+below).
+If no matching filenames are found,
+and the shell option
+.B nullglob
+is not enabled, the word is left unchanged.
+If the 
+.B nullglob
+option is set, and no matches are found,
+the word is removed.
+If the
+.B failglob
+shell option is set, and no matches are found, an error message
+is printed and the command is not executed.
+If the shell option
+.B nocaseglob
+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 ``.''
+at the start of a name or immediately following a slash
+must be matched explicitly, unless the shell option
+.B dotglob
+is set.
+When matching a pathname, the slash character must always be
+matched explicitly.
+In other cases, the
+.B ``.''
+character is not treated specially.
+See the description of
+.B shopt
+below under
+.SM
+.B SHELL BUILTIN COMMANDS
+for a description of the
+.BR nocaseglob ,
+.BR nullglob ,
+.BR failglob ,
+and
+.B dotglob
+shell options.
+.PP
+The
+.SM
+.B GLOBIGNORE
+shell variable may be used to restrict the set of filenames matching a
+.IR pattern .
+If
+.SM
+.B GLOBIGNORE
+is set, each matching filename that also matches one of the patterns in
+.SM
+.B GLOBIGNORE
+is removed from the list of matches.
+The filenames
+.B ``.''
+and
+.B ``..''
+are always ignored when
+.SM
+.B GLOBIGNORE
+is set and not null.  However, setting
+.SM
+.B GLOBIGNORE
+to a non-null value has the effect of enabling the
+.B dotglob
+shell option, so all other filenames beginning with a
+.B ``.''
+will match.
+To get the old behavior of ignoring filenames beginning with a
+.BR ``.'' ,
+make
+.B ``.*''
+one of the patterns in
+.SM
+.BR GLOBIGNORE .
+The
+.B dotglob
+option is disabled when
+.SM
+.B GLOBIGNORE
+is unset.
+.PP
+\fBPattern Matching\fP
+.PP
+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 must be quoted if
+they are to be matched literally.
+.PP
+The special pattern characters have the following meanings:
+.PP
+.PD 0
+.RS
+.TP
+.B *
+Matches any string, including the null string.
+When the \fBglobstar\fP shell option is enabled, and \fB*\fP is used in
+a pathname expansion context, two adjacent \fB*\fPs used as a single
+pattern will match all files and zero or more directories and
+subdirectories.
+If followed by a \fB/\fP, two adjacent \fB*\fPs will match only directories
+and subdirectories.
+.TP
+.B ?
+Matches any single character.
+.TP
+.B [...]
+Matches any one of the enclosed characters.  A pair of characters
+separated by a hyphen denotes a
+\fIrange expression\fP;
+any character that falls between those two characters, 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 character not enclosed is matched.
+The sorting order of characters in range expressions is determined by
+the current locale and the values of the
+.SM
+.B LC_COLLATE
+or
+.SM
+.B LC_ALL
+shell variables, if set.
+To obtain the traditional interpretation of range expressions, where
+.B [a\-d]
+is equivalent to
+.BR [abcd] ,
+set value of the
+.B LC_ALL
+shell variable to
+.BR C ,
+or enable the
+.B globasciiranges
+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.
+.br
+.if t .sp 0.5
+.if n .sp 1
+Within
+.B [
+and
+.BR ] ,
+\fIcharacter classes\fP can be specified using the syntax
+\fB[:\fP\fIclass\fP\fB:]\fP, where \fIclass\fP is one of the
+following classes defined in the POSIX standard:
+.PP
+.RS
+.B
+.if n alnum alpha ascii blank cntrl digit graph lower print punct space upper word xdigit
+.if t alnum   alpha   ascii   blank   cntrl   digit   graph   lower   print   punct   space   upper   word   xdigit
+.br
+A character class matches any character belonging to that class.
+The \fBword\fP character class matches letters, digits, and the character _.
+.br
+.if t .sp 0.5
+.if n .sp 1
+Within
+.B [
+and 
+.BR ] ,
+an \fIequivalence class\fP can be specified using the syntax
+\fB[=\fP\fIc\fP\fB=]\fP, which matches all characters with the
+same collation weight (as defined by the current locale) as
+the character \fIc\fP.
+.br
+.if t .sp 0.5
+.if n .sp 1
+Within
+.B [
+and 
+.BR ] ,
+the syntax \fB[.\fP\fIsymbol\fP\fB.]\fP matches the collating symbol
+\fIsymbol\fP.
+.RE
+.RE
+.PD
+.PP
+If the \fBextglob\fP shell option is enabled using the \fBshopt\fP
+builtin, several extended pattern matching operators are recognized.
+In the following description, a \fIpattern-list\fP is a list of one
+or more patterns separated by a \fB|\fP.
+Composite patterns may be formed using one or more of the following
+sub-patterns:
+.sp 1
+.PD 0
+.RS
+.TP
+\fB?(\fP\^\fIpattern-list\^\fP\fB)\fP
+Matches zero or one occurrence of the given patterns
+.TP
+\fB*(\fP\^\fIpattern-list\^\fP\fB)\fP
+Matches zero or more occurrences of the given patterns
+.TP
+\fB+(\fP\^\fIpattern-list\^\fP\fB)\fP
+Matches one or more occurrences of the given patterns
+.TP
+\fB@(\fP\^\fIpattern-list\^\fP\fB)\fP
+Matches one of the given patterns
+.TP
+\fB!(\fP\^\fIpattern-list\^\fP\fB)\fP
+Matches anything except one of the given patterns
+.RE
+.PD
+.SS Quote Removal
+.PP
+After the preceding expansions, all unquoted occurrences of the
+characters
+.BR \e ,
+.BR \(aq ,
+and \^\f3"\fP\^ that did not result from one of the above
+expansions are removed.
+.SH REDIRECTION
+Before a command is executed, its input and output
+may be
+.I redirected
+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
+operators may precede or appear anywhere within a
+.I simple command
+or may follow a
+.IR command .
+Redirections are processed in the order they appear, from
+left to right.
+.PP
+Each redirection that may be preceded by a file descriptor number
+may instead be preceded by a word of the form {\fIvarname\fP}.
+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 \fIvarname\fP.
+If >&- or <&- is preceded
+by {\fIvarname\fP}, the value of \fIvarname\fP defines the file
+descriptor to close.
+.PP
+In the following descriptions, if the file descriptor number is
+omitted, and the first character of the redirection operator is
+.BR < ,
+the redirection refers to the standard input (file descriptor
+0).  If the first character of the redirection operator is
+.BR > ,
+the redirection refers to the standard output (file descriptor
+1).
+.PP
+The word following the redirection operator in the following
+descriptions, 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 bash
+reports an error.
+.PP
+Note that the order of redirections is significant.  For example, 
+the command
+.RS
+.PP
+ls \fB>\fP dirlist 2\fB>&\fP1
+.RE
+.PP
+directs both standard output and standard error to the file 
+.IR dirlist ,
+while the command
+.RS
+.PP
+ls 2\fB>&\fP1 \fB>\fP dirlist
+.RE
+.PP
+directs only the standard output to file
+.IR dirlist ,
+because the standard error was duplicated from the standard output
+before the standard output was redirected to
+.IR dirlist .
+.PP
+\fBBash\fP handles several filenames specially when they are used in
+redirections, as described in the following table:
+.RS
+.PP
+.PD 0
+.TP
+.B /dev/fd/\fIfd\fP
+If \fIfd\fP is a valid integer, file descriptor \fIfd\fP is duplicated.
+.TP
+.B /dev/stdin
+File descriptor 0 is duplicated.
+.TP
+.B /dev/stdout
+File descriptor 1 is duplicated.
+.TP
+.B /dev/stderr
+File descriptor 2 is duplicated.
+.TP
+.B /dev/tcp/\fIhost\fP/\fIport\fP
+If \fIhost\fP is a valid hostname or Internet address, and \fIport\fP
+is an integer port number or service name, \fBbash\fP attempts to open
+the corresponding TCP socket.
+.TP
+.B /dev/udp/\fIhost\fP/\fIport\fP
+If \fIhost\fP is a valid hostname or Internet address, and \fIport\fP
+is an integer port number or service name, \fBbash\fP attempts to open
+the corresponding UDP socket.
+.PD
+.RE
+.PP
+A failure to open or create a file causes the redirection to fail.
+.PP
+Redirections using file descriptors greater than 9 should be used with
+care, as they may conflict with file descriptors the shell uses
+internally.
+.SS Redirecting Input
+.PP
+Redirection of input causes the file whose name results from
+the expansion of
+.I word
+to be opened for reading on file descriptor
+.IR n ,
+or the standard input (file descriptor 0) if
+.I n
+is not specified.
+.PP
+The general format for redirecting input is:
+.RS
+.PP
+[\fIn\fP]\fB<\fP\fIword\fP
+.RE
+.SS Redirecting Output
+.PP
+Redirection of output causes the file whose name results from
+the expansion of
+.I word
+to be opened for writing on file descriptor
+.IR n ,
+or the standard output (file descriptor 1) if
+.I n
+is not specified.  If the file does not exist it is created;
+if it does exist it is truncated to zero size.
+.PP
+The general format for redirecting output is:
+.RS
+.PP
+[\fIn\fP]\fB>\fP\fIword\fP
+.RE
+.PP
+If the redirection operator is
+.BR > ,
+and the
+.B noclobber
+option to the
+.B set
+builtin has been enabled, the redirection will fail if the file
+whose name results from the expansion of \fIword\fP exists and is
+a regular file.
+If the redirection operator is
+.BR >| ,
+or the redirection operator is
+.B >
+and the
+.B noclobber
+option to the
+.B set
+builtin command is not enabled, the redirection is attempted even
+if the file named by \fIword\fP exists.
+.SS Appending Redirected Output
+.PP
+Redirection of output in this fashion
+causes the file whose name results from
+the expansion of
+.I word
+to be opened for appending on file descriptor
+.IR n ,
+or the standard output (file descriptor 1) if
+.I n
+is not specified.  If the file does not exist it is created.
+.PP
+The general format for appending output is:
+.RS
+.PP
+[\fIn\fP]\fB>>\fP\fIword\fP
+.RE
+.PP
+.SS Redirecting Standard Output and Standard Error
+.PP
+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
+.IR word .
+.PP
+There are two formats for redirecting standard output and
+standard error:
+.RS
+.PP
+\fB&>\fP\fIword\fP
+.RE
+and
+.RS
+\fB>&\fP\fIword\fP
+.RE
+.PP
+Of the two forms, the first is preferred.
+This is semantically equivalent to
+.RS
+.PP
+\fB>\fP\fIword\fP 2\fB>&\fP1
+.RE
+.PP
+When using the second form, \fIword\fP may not expand to a number or
+\fB\-\fP.  If it does, other redirection operators apply
+(see \fBDuplicating File Descriptors\fP below) for compatibility
+reasons.
+.SS Appending Standard Output and Standard Error
+.PP
+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
+.IR word .
+.PP
+The format for appending standard output and standard error is:
+.RS
+.PP
+\fB&>>\fP\fIword\fP
+.RE
+.PP
+This is semantically equivalent to
+.RS
+.PP
+\fB>>\fP\fIword\fP 2\fB>&\fP1
+.RE
+.PP
+(see \fBDuplicating File Descriptors\fP below).
+.SS Here Documents
+.PP
+This type of redirection instructs the shell to read input from the
+current source until a line containing only
+.I delimiter
+(with no trailing blanks)
+is seen.  All of
+the lines read up to that point are then used as the standard
+input for a command.
+.PP
+The format of here-documents is:
+.RS
+.PP
+.nf
+\fB<<\fP[\fB\-\fP]\fIword\fP
+        \fIhere-document\fP
+\fIdelimiter\fP
+.fi
+.RE
+.PP
+No parameter and variable expansion, command substitution,
+arithmetic expansion, or pathname expansion is performed on
+.IR word .
+If any characters in
+.I word
+are quoted, the
+.I delimiter
+is the result of quote removal on
+.IR word ,
+and the lines in the here-document are not expanded.
+If \fIword\fP is unquoted,
+all lines of the here-document are subjected to
+parameter expansion, command substitution, and arithmetic expansion,
+the character sequence
+.B \e<newline>
+is ignored, and
+.B \e
+must be used to quote the characters
+.BR \e ,
+.BR $ ,
+and
+.BR \` .
+.PP
+If the redirection operator is
+.BR <<\- ,
+then all leading tab characters are stripped from input lines and the
+line containing
+.IR delimiter .
+This allows
+here-documents within shell scripts to be indented in a
+natural fashion.
+.SS "Here Strings"
+A variant of here documents, the format is:
+.RS
+.PP
+.nf
+\fB<<<\fP\fIword\fP
+.fi
+.RE
+.PP
+The \fIword\fP undergoes
+brace expansion, tilde expansion, parameter and variable expansion,
+command substitution, arithmetic expansion, and quote removal.
+Pathname expansion and word splitting are not performed.
+The result is supplied as a single string to the command on its
+standard input.
+.SS "Duplicating File Descriptors"
+.PP
+The redirection operator
+.RS
+.PP
+[\fIn\fP]\fB<&\fP\fIword\fP
+.RE
+.PP
+is used to duplicate input file descriptors.
+If
+.I word
+expands to one or more digits, the file descriptor denoted by
+.I n
+is made to be a copy of that file descriptor.
+If the digits in
+.I word
+do not specify a file descriptor open for input, a redirection error occurs.
+If
+.I word
+evaluates to
+.BR \- ,
+file descriptor
+.I n
+is closed.  If
+.I n
+is not specified, the standard input (file descriptor 0) is used.
+.PP
+The operator
+.RS
+.PP
+[\fIn\fP]\fB>&\fP\fIword\fP
+.RE
+.PP
+is used similarly to duplicate output file descriptors.  If
+.I n
+is not specified, the standard output (file descriptor 1) is used.
+If the digits in
+.I word
+do not specify a file descriptor open for output, a redirection error occurs.
+If
+.I word
+evaluates to
+.BR \- ,
+file descriptor
+.I n
+is closed.
+As a special case, if \fIn\fP is omitted, and \fIword\fP does not
+expand to one or more digits or \fB\-\fP, the standard output and standard
+error are redirected as described previously.
+.SS "Moving File Descriptors"
+.PP
+The redirection operator
+.RS
+.PP
+[\fIn\fP]\fB<&\fP\fIdigit\fP\fB\-\fP
+.RE
+.PP
+moves the file descriptor \fIdigit\fP to file descriptor
+.IR n ,
+or the standard input (file descriptor 0) if \fIn\fP is not specified.
+\fIdigit\fP is closed after being duplicated to \fIn\fP.
+.PP
+Similarly, the redirection operator
+.RS
+.PP
+[\fIn\fP]\fB>&\fP\fIdigit\fP\fB\-\fP
+.RE
+.PP
+moves the file descriptor \fIdigit\fP to file descriptor
+.IR n ,
+or the standard output (file descriptor 1) if \fIn\fP is not specified.
+.SS "Opening File Descriptors for Reading and Writing"
+.PP
+The redirection operator
+.RS
+.PP
+[\fIn\fP]\fB<>\fP\fIword\fP
+.RE
+.PP
+causes the file whose name is the expansion of
+.I word
+to be opened for both reading and writing on file descriptor
+.IR n ,
+or on file descriptor 0 if
+.I n
+is not specified.  If the file does not exist, it is created.
+.SH ALIASES
+\fIAliases\fP 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
+.B alias
+and
+.B unalias
+builtin commands (see
+.SM
+.B SHELL BUILTIN COMMANDS
+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 \fB/\fP, \fB$\fP, \fB\`\fP, and \fB=\fP and
+any of the shell \fImetacharacters\fP 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
+.B ls
+to
+.BR "ls \-F" ,
+for instance, and
+.B bash
+does not try to recursively expand the replacement text.
+If the last character of the alias value is a
+.IR blank ,
+then the next command
+word following the alias is also checked for alias expansion.
+.PP
+Aliases are created and listed with the
+.B alias
+command, and removed with the
+.B unalias
+command.
+.PP
+There is no mechanism for using arguments in the replacement text.
+If arguments are needed, a shell function should be used (see
+.SM
+.B FUNCTIONS
+below).
+.PP
+Aliases are not expanded when the shell is not interactive, unless
+the
+.B expand_aliases
+shell option is set using
+.B shopt
+(see the description of
+.B shopt
+under
+.SM
+\fBSHELL BUILTIN COMMANDS\fP
+below).
+.PP
+The rules concerning the definition and use of aliases are
+somewhat confusing.
+.B Bash
+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 compound command.  As a consequence, aliases
+defined in a function are not available until after that
+function is executed.  To be safe, always put
+alias definitions on a separate line, and do not use
+.B alias
+in compound commands.
+.PP
+For almost every purpose, aliases are superseded by
+shell functions.
+.SH FUNCTIONS
+A shell function, defined as described above under
+.SM
+.BR "SHELL GRAMMAR" ,
+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 positional parameters
+during its execution.
+The special parameter
+.B #
+is updated to reflect the change.  Special parameter \fB0\fP
+is unchanged.
+The first element of the
+.SM
+.B FUNCNAME
+variable is set to the name of the function while the function
+is executing.
+.PP
+All other aspects of the shell execution
+environment are identical between a function and its caller
+with these exceptions:  the
+.SM
+.B DEBUG
+and
+.B RETURN
+traps (see the description of the
+.B trap
+builtin under
+.SM
+.B SHELL BUILTIN COMMANDS
+below) are not inherited unless the function has been given the
+\fBtrace\fP attribute (see the description of the
+.SM
+.B declare
+builtin below) or the
+\fB\-o functrace\fP shell option has been enabled with
+the \fBset\fP builtin
+(in which case all functions inherit the \fBDEBUG\fP and \fBRETURN\fP traps),
+and the
+.SM
+.B ERR
+trap is not inherited unless the \fB\-o errtrace\fP shell option has
+been enabled.
+.PP
+Variables local to the function may be declared with the
+.B local
+builtin command.  Ordinarily, variables and their values
+are shared between the function and its caller.
+.PP
+The \fBFUNCNEST\fP variable, if set to a numeric value greater
+than 0, defines a maximum function nesting level.  Function
+invocations that exceed the limit cause the entire command to
+abort.
+.PP
+If the builtin command
+.B return
+is executed in a function, the function completes and
+execution resumes with the next command after the function
+call.
+Any command associated with the \fBRETURN\fP 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 values they had prior to the function's
+execution.
+.PP
+Function names and definitions may be listed with the
+.B \-f
+option to the
+.B declare
+or
+.B typeset
+builtin commands.  The
+.B \-F
+option to
+.B declare
+or
+.B typeset
+will list the function names only
+(and optionally the source file and line number, if the \fBextdebug\fP
+shell option is enabled).
+Functions may be exported so that subshells
+automatically have them defined with the
+.B \-f
+option to the 
+.B export
+builtin.
+A function definition may be deleted using the \fB\-f\fP option to
+the
+.B unset
+builtin.
+Note that shell functions and variables with the same name may result
+in multiple identically-named entries in the environment passed to the
+shell's children.
+Care should be taken in cases where this may cause a problem.
+.PP
+Functions may be recursive.
+The \fBFUNCNEST\fP variable may be used to limit the depth of the
+function call stack and restrict the number of function invocations.
+By default, no limit is imposed on the number of recursive calls.
+.SH "ARITHMETIC EVALUATION"
+The shell allows arithmetic expressions to be evaluated, under
+certain circumstances (see the \fBlet\fP and \fBdeclare\fP builtin
+commands and \fBArithmetic Expansion\fP).
+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.
+.PP
+.PD 0
+.TP
+.B \fIid\fP++ \fIid\fP\-\-
+variable post-increment and post-decrement
+.TP
+.B ++\fIid\fP \-\-\fIid\fP
+variable pre-increment and pre-decrement
+.TP
+.B \- +
+unary minus and plus
+.TP
+.B ! ~
+logical and bitwise negation
+.TP
+.B **
+exponentiation
+.TP
+.B * / %
+multiplication, division, remainder
+.TP
+.B + \-
+addition, subtraction
+.TP
+.B << >>
+left and right bitwise shifts
+.TP
+.B <= >= < >
+comparison
+.TP
+.B == !=
+equality and inequality
+.TP
+.B &
+bitwise AND
+.TP
+.B ^
+bitwise exclusive OR
+.TP
+.B |
+bitwise OR
+.TP
+.B &&
+logical AND
+.TP
+.B ||
+logical OR
+.TP
+.B \fIexpr\fP?\fIexpr\fP:\fIexpr\fP
+conditional operator
+.TP
+.B = *= /= %= += \-= <<= >>= &= ^= |=
+assignment
+.TP
+.B \fIexpr1\fP , \fIexpr2\fP
+comma
+.PD
+.PP
+Shell variables are allowed as operands; parameter expansion is
+performed 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 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
+\fIinteger\fP attribute using \fBdeclare -i\fP is assigned a value.
+A null value evaluates to 0.
+A shell variable need not have its \fIinteger\fP attribute
+turned on to be used in an expression.
+.PP
+Constants with a leading 0 are interpreted as octal numbers.
+A leading 0x or 0X denotes hexadecimal.
+Otherwise, numbers take the form [\fIbase#\fP]n, where the optional \fIbase\fP
+is a decimal number between 2 and 64 representing the arithmetic
+base, and \fIn\fP is a number in that base.
+If \fIbase#\fP is omitted, then base 10 is used.
+When specifying \fIn\fP,
+the digits greater< than 9 are represented by the lowercase letters,
+the uppercase letters, @, and _, in that order.
+If \fIbase\fP is less than or equal to 36, lowercase and uppercase
+letters may be used interchangeably to represent numbers between 10
+and 35.
+.PP
+Operators are evaluated in order of precedence.  Sub-expressions in
+parentheses are evaluated first and may override the precedence
+rules above.
+.SH "CONDITIONAL EXPRESSIONS"
+Conditional expressions are used by the \fB[[\fP compound command and
+the \fBtest\fP and \fB[\fP builtin commands to test file attributes
+and perform string and arithmetic comparisons.
+Expressions are formed from the following unary or binary primaries.
+If any \fIfile\fP argument to one of the primaries is of the form
+\fI/dev/fd/n\fP, then file descriptor \fIn\fP is checked.
+If the \fIfile\fP argument to one of the primaries is one of
+\fI/dev/stdin\fP, \fI/dev/stdout\fP, or \fI/dev/stderr\fP, file
+descriptor 0, 1, or 2, respectively, is checked.
+.PP
+Unless otherwise specified, primaries that operate on files follow symbolic
+links and operate on the target of the link, rather than the link itself.
+.if t .sp 0.5
+.if n .sp 1
+When used with \fB[[\fP, the \fB<\fP and \fB>\fP operators sort
+lexicographically using the current locale.
+The \fBtest\fP command sorts using ASCII ordering.
+.sp 1
+.PD 0
+.TP
+.B \-a \fIfile\fP
+True if \fIfile\fP exists.
+.TP
+.B \-b \fIfile\fP
+True if \fIfile\fP exists and is a block special file.
+.TP
+.B \-c \fIfile\fP
+True if \fIfile\fP exists and is a character special file.
+.TP
+.B \-d \fIfile\fP
+True if \fIfile\fP exists and is a directory.
+.TP
+.B \-e \fIfile\fP
+True if \fIfile\fP exists.
+.TP
+.B \-f \fIfile\fP
+True if \fIfile\fP exists and is a regular file.
+.TP
+.B \-g \fIfile\fP
+True if \fIfile\fP exists and is set-group-id.
+.TP
+.B \-h \fIfile\fP
+True if \fIfile\fP exists and is a symbolic link.
+.TP
+.B \-k \fIfile\fP
+True if \fIfile\fP exists and its ``sticky'' bit is set.
+.TP
+.B \-p \fIfile\fP
+True if \fIfile\fP exists and is a named pipe (FIFO).
+.TP
+.B \-r \fIfile\fP
+True if \fIfile\fP exists and is readable.
+.TP
+.B \-s \fIfile\fP
+True if \fIfile\fP exists and has a size greater than zero.
+.TP
+.B \-t \fIfd\fP
+True if file descriptor
+.I fd
+is open and refers to a terminal.
+.TP
+.B \-u \fIfile\fP
+True if \fIfile\fP exists and its set-user-id bit is set.
+.TP
+.B \-w \fIfile\fP
+True if \fIfile\fP exists and is writable.
+.TP
+.B \-x \fIfile\fP
+True if \fIfile\fP exists and is executable.
+.TP
+.B \-G \fIfile\fP
+True if \fIfile\fP exists and is owned by the effective group id.
+.TP
+.B \-L \fIfile\fP
+True if \fIfile\fP exists and is a symbolic link.
+.TP
+.B \-N \fIfile\fP
+True if \fIfile\fP exists and has been modified since it was last read.
+.TP
+.B \-O \fIfile\fP
+True if \fIfile\fP exists and is owned by the effective user id.
+.TP
+.B \-S \fIfile\fP
+True if \fIfile\fP exists and is a socket.
+.TP
+\fIfile1\fP \fB\-ef\fP \fIfile2\fP
+True if \fIfile1\fP and \fIfile2\fP refer to the same device and
+inode numbers.
+.TP
+\fIfile1\fP \-\fBnt\fP \fIfile2\fP
+True if \fIfile1\fP is newer (according to modification date) than \fIfile2\fP,
+or if \fIfile1\fP exists and \fPfile2\fP does not.
+.TP
+\fIfile1\fP \-\fBot\fP \fIfile2\fP
+True if \fIfile1\fP is older than \fIfile2\fP, or if \fIfile2\fP exists
+and \fIfile1\fP does not.
+.TP
+.B \-o \fIoptname\fP
+True if the shell option
+.I optname
+is enabled.
+See the list of options under the description of the
+.B \-o
+option to the
+.B set
+builtin below.
+.TP
+.B \-v \fIvarname\fP
+True if the shell variable
+.I varname
+is set (has been assigned a value).
+.TP
+.B \-R \fIvarname\fP
+True if the shell variable
+.I varname
+is set and is a name reference.
+.TP
+.B \-z \fIstring\fP
+True if the length of \fIstring\fP is zero.
+.TP
+\fIstring\fP
+.PD 0
+.TP
+.B \-n \fIstring\fP
+.PD
+True if the length of
+.I string
+is non-zero.
+.TP
+\fIstring1\fP \fB==\fP \fIstring2\fP
+.PD 0
+.TP
+\fIstring1\fP \fB=\fP \fIstring2\fP
+.PD
+True if the strings are equal.  \fB=\fP should be used
+with the \fBtest\fP command for POSIX conformance.
+When used with the \fB[[\fP command, this performs pattern matching as
+described above (\fBCompound Commands\fP).
+.TP
+\fIstring1\fP \fB!=\fP \fIstring2\fP
+True if the strings are not equal.
+.TP
+\fIstring1\fP \fB<\fP \fIstring2\fP
+True if \fIstring1\fP sorts before \fIstring2\fP lexicographically.
+.TP
+\fIstring1\fP \fB>\fP \fIstring2\fP
+True if \fIstring1\fP sorts after \fIstring2\fP lexicographically.
+.TP
+.I \fIarg1\fP \fBOP\fP \fIarg2\fP
+.SM
+.B OP
+is one of
+.BR \-eq ,
+.BR \-ne ,
+.BR \-lt ,
+.BR \-le ,
+.BR \-gt ,
+or
+.BR \-ge .
+These arithmetic binary operators return true if \fIarg1\fP
+is equal to, not equal to, less than, less than or equal to,
+greater than, or greater than or equal to \fIarg2\fP, respectively.
+.I Arg1
+and
+.I arg2
+may be positive or negative integers.
+.PD
+.SH "SIMPLE COMMAND EXPANSION"
+When a simple command is executed, the shell performs the following
+expansions, assignments, and redirections, from left to right.
+.IP 1.
+The words that the parser has marked as variable assignments (those
+preceding the command name) and redirections are saved for later
+processing.
+.IP 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.
+.IP 3.
+Redirections are performed as described above under
+.SM
+.BR REDIRECTION .
+.IP 4.
+The text after the \fB=\fP in each variable assignment undergoes tilde
+expansion, parameter expansion, command substitution, arithmetic expansion,
+and quote removal before being assigned to the variable.
+.PP
+If no command name results, the variable assignments affect the current
+shell environment.  Otherwise, the variables are added to the environment
+of the executed command and do not affect the current shell environment.
+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.
+.PP
+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.
+.PP
+If there is a command name left after expansion, execution proceeds as
+described below.  Otherwise, the command exits.  If one of the expansions
+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.
+.SH "COMMAND EXECUTION"
+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.
+.PP
+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
+.SM
+.BR FUNCTIONS .
+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.
+.PP
+If the name is neither a shell function nor a builtin,
+and contains no slashes,
+.B bash
+searches each element of the
+.SM
+.B PATH
+for a directory containing an executable file by that name.
+.B Bash
+uses a hash table to remember the full pathnames of executable
+files (see
+.B hash
+under
+.SM
+.B "SHELL BUILTIN COMMANDS"
+below).
+A full search of the directories in
+.SM
+.B PATH
+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 \fBcommand_not_found_handle\fP.
+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
+message and returns an exit status of 127.
+.PP
+If the search is successful, or if the command name contains
+one or more slashes, the shell executes the named program in a
+separate execution environment.
+Argument 0 is set to the name given, and the remaining arguments
+to the command are set to the arguments given, if any.
+.PP
+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 \fIshell script\fP, 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
+.B hash
+below under
+.SM
+\fBSHELL BUILTIN COMMANDS\fP)
+are retained by the child.
+.PP
+If the program is a file beginning with
+.BR #! ,
+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 executable 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 the command
+arguments, if any.
+.SH COMMAND EXECUTION ENVIRONMENT
+The shell has an \fIexecution environment\fP, which consists of the
+following:
+.IP \(bu
+open files inherited by the shell at invocation, as modified by
+redirections supplied to the \fBexec\fP builtin
+.IP \(bu
+the current working directory as set by \fBcd\fP, \fBpushd\fP, or
+\fBpopd\fP, or inherited by the shell at invocation
+.IP \(bu
+the file creation mode mask as set by \fBumask\fP or inherited from
+the shell's parent
+.IP \(bu
+current traps set by \fBtrap\fP
+.IP \(bu
+shell parameters that are set by variable assignment or with \fBset\fP
+or inherited from the shell's parent in the environment
+.IP \(bu
+shell functions defined during execution or inherited from the shell's
+parent in the environment
+.IP \(bu
+options enabled at invocation (either by default or with command-line
+arguments) or by \fBset\fP
+.IP \(bu
+options enabled by \fBshopt\fP
+.IP \(bu
+shell aliases defined with \fBalias\fP
+.IP \(bu
+various process IDs, including those of background jobs, the value
+of \fB$$\fP, and the value of
+.SM
+.B PPID
+.PP
+When a simple command other than a builtin or shell function
+is to be executed, it
+is invoked in a separate execution environment that consists of
+the following.  Unless otherwise noted, the values are inherited
+from the shell.
+.if n .sp 1
+.IP \(bu
+the shell's open files, plus any modifications and additions specified
+by redirections to the command
+.IP \(bu
+the current working directory
+.IP \(bu
+the file creation mode mask
+.IP \(bu
+shell variables and functions marked for export, along with variables
+exported for the command, passed in the environment
+.IP \(bu
+traps caught by the shell are reset to the values inherited from the
+shell's parent, and traps ignored by the shell are ignored
+.PP
+A command invoked in this separate environment cannot affect the
+shell's execution environment. 
+.PP
+Command substitution, commands grouped with parentheses,
+and asynchronous commands are invoked in a
+subshell environment that is a duplicate of the shell environment,
+except that traps caught by the shell are reset to the values
+that the shell inherited from its parent at invocation.  Builtin
+commands that are invoked as part of a pipeline are also executed in a
+subshell environment.  Changes made to the subshell environment
+cannot affect the shell's execution environment.
+.PP
+Subshells spawned to execute command substitutions inherit the value of
+the \fB\-e\fP option from the parent shell.  When not in \fIposix\fP mode,
+\fBbash\fP clears the \fB\-e\fP option in such subshells.
+.PP
+If a command is followed by a \fB&\fP and job control is not active, the
+default standard input for the command is the empty file \fI/dev/null\fP.
+Otherwise, the invoked command inherits the file descriptors of the calling
+shell as modified by redirections.
+.SH ENVIRONMENT
+When a program is invoked it is given an array of strings
+called the
+.IR environment .
+This is a list of 
+\fIname\fP\-\fIvalue\fP pairs, of the form
+.IR "name\fR=\fPvalue" .
+.PP
+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
+.I export
+to child processes.  Executed commands inherit the environment.
+The
+.B export
+and
+.B declare \-x
+commands allow parameters and functions to be added to and
+deleted from the environment.  If the value of a parameter
+in the environment 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 modified in the shell,
+less any pairs removed by the
+.B unset
+command, plus any additions via the
+.B export
+and
+.B declare \-x
+commands.
+.PP
+The environment for any
+.I simple command
+or function may be augmented temporarily by prefixing it with
+parameter assignments, as described above in
+.SM
+.BR PARAMETERS .
+These assignment statements affect only the environment seen
+by that command.
+.PP
+If the 
+.B \-k
+option is set (see the
+.B set
+builtin command below), then
+.I all
+parameter assignments are placed in the environment for a command,
+not just those that precede the command name.
+.PP
+When
+.B bash
+invokes an external command, the variable
+.B _
+is set to the full filename of the command and passed to that
+command in its environment.
+.SH "EXIT STATUS"
+.PP
+The exit status of an executed command is the value returned by the
+\fIwaitpid\fP system call or equivalent function.  Exit statuses
+fall between 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.
+.PP
+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 signal \fIN\fP, \fBbash\fP uses
+the value of 128+\fIN\fP as the exit status.
+.PP
+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.
+.PP
+If a command fails because of an error during expansion or redirection,
+the exit status is greater than zero.
+.PP
+Shell builtin commands return a status of 0 (\fItrue\fP) if
+successful, and non-zero (\fIfalse\fP) if an error occurs
+while they execute. 
+All builtins return an exit status of 2 to indicate incorrect usage.
+.PP
+\fBBash\fP itself 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 \fBexit\fP builtin
+command below.
+.SH SIGNALS
+When \fBbash\fP is interactive, in the absence of any traps, it ignores
+.SM
+.B SIGTERM
+(so that \fBkill 0\fP does not kill an interactive shell),
+and
+.SM
+.B SIGINT
+is caught and handled (so that the \fBwait\fP builtin is interruptible).
+In all cases, \fBbash\fP ignores
+.SM
+.BR SIGQUIT .
+If job control is in effect,
+.B bash
+ignores
+.SM
+.BR SIGTTIN ,
+.SM
+.BR SIGTTOU ,
+and
+.SM
+.BR SIGTSTP .
+.PP
+Non-builtin commands run by \fBbash\fP have signal handlers
+set to the values inherited by the shell from its parent.
+When job control is not in effect, asynchronous commands
+ignore
+.SM
+.B SIGINT
+and
+.SM
+.B SIGQUIT
+in addition to these inherited handlers.
+Commands run as a result of command substitution ignore the
+keyboard-generated job control signals
+.SM
+.BR SIGTTIN ,
+.SM
+.BR SIGTTOU ,
+and
+.SM
+.BR SIGTSTP .
+.PP
+The shell exits by default upon receipt of a
+.SM
+.BR SIGHUP .
+Before exiting, an interactive shell resends the
+.SM
+.B SIGHUP
+to all jobs, running or stopped.
+Stopped jobs are sent
+.SM
+.B SIGCONT
+to ensure that they receive the
+.SM
+.BR SIGHUP .
+To prevent the shell from
+sending the signal to a particular job, it should be removed from the
+jobs table with the 
+.B disown
+builtin (see
+.SM
+.B "SHELL BUILTIN COMMANDS"
+below) or marked 
+to not receive
+.SM
+.B SIGHUP
+using
+.BR "disown \-h" .
+.PP
+If the
+.B huponexit
+shell option has been set with
+.BR shopt ,
+.B bash
+sends a 
+.SM
+.B SIGHUP
+to all jobs when an interactive login shell exits.
+.PP
+If \fBbash\fP 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 command completes. 
+When \fBbash\fP is waiting for an asynchronous command via the \fBwait\fP
+builtin, the reception of a signal for which a trap has been set will
+cause the \fBwait\fP builtin to return immediately with an exit status
+greater than 128, immediately after which the trap is executed.
+.SH "JOB CONTROL"
+.I Job control
+refers to the ability to selectively stop (\fIsuspend\fP)
+the execution of processes and continue (\fIresume\fP)
+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 driver and
+.BR bash .
+.PP
+The shell associates a
+.I job
+with each pipeline.  It keeps a table of currently executing
+jobs, which may be listed with the
+.B jobs
+command.  When
+.B bash
+starts a job asynchronously (in the
+.IR background ),
+it prints a line that looks like:
+.RS
+.PP
+[1] 25647
+.RE
+.PP
+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 Bash
+uses the
+.I job
+abstraction as the basis for job control.
+.PP
+To facilitate the implementation of the user interface to job
+control, the operating system maintains the notion of a \fIcurrent terminal
+process group ID\fP.  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
+.SM
+.BR SIGINT .
+These processes are said to be in the
+.IR foreground .
+.I Background
+processes are those whose process group ID differs from the terminal's;
+such processes are immune to keyboard-generated signals.
+Only foreground processes are allowed to read from or, if the
+user so specifies with \f(CWstty tostop\fP, write to the
+terminal.
+Background processes which attempt to read from (write to when
+\f(CWstty tostop\fP is in effect) the
+terminal are sent a 
+.SM
+.B SIGTTIN (SIGTTOU)
+signal by the kernel's terminal driver, 
+which, unless caught, suspends the process.
+.PP
+If the operating system on which
+.B bash
+is running supports
+job control,
+.B bash
+contains facilities to use it.
+Typing the
+.I suspend
+character (typically
+.BR ^Z ,
+Control-Z) while a process is running
+causes that process to be stopped and returns control to 
+.BR bash .
+Typing the
+.I "delayed suspend"
+character (typically
+.BR ^Y ,
+Control-Y) causes the process to be stopped when it
+attempts to read input from the terminal, and control to
+be returned to
+.BR bash .
+The user may then manipulate the state of this job, using the
+.B bg
+command to continue it in the background, the
+.B fg
+command to continue it in the foreground, or
+the
+.B kill
+command to kill it.  A \fB^Z\fP takes effect immediately,
+and has the additional side effect of causing pending output
+and typeahead to be discarded.
+.PP
+There are a number of ways to refer to a job in the shell.
+The character
+.B %
+introduces a job specification (\fIjobspec\fP).  Job number
+.I n
+may be referred to as
+.BR %n .
+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 %ce
+refers to a stopped
+.B ce
+job.  If a prefix matches more than one job,
+.B bash
+reports an error.  Using
+.BR %?ce ,
+on the other hand, refers to any job containing the string
+.B ce
+in its command line.  If the substring matches more than one job,
+.B bash
+reports an error.  The symbols
+.B %%
+and
+.B %+
+refer to the shell's notion of the
+.IR "current job" ,
+which is the last job stopped while it was in
+the foreground or started in the background.
+The 
+.I "previous job"
+may be referenced using
+.BR %\- .
+If there is only a single job, \fB%+\fP and \fB%\-\fP can both be used
+to refer to that job.
+In output pertaining to jobs (e.g., the output of the
+.B jobs
+command), the current job is always flagged with a
+.BR + ,
+and the previous job with a
+.BR \- .
+A single % (with no accompanying job specification) also refers to the
+current job.
+.PP
+Simply naming a job can be used to bring it into the
+foreground:
+.B %1
+is a synonym for
+\fB``fg %1''\fP,
+bringing job 1 from the background into the foreground.
+Similarly,
+.B ``%1 &''
+resumes job 1 in the background, equivalent to
+\fB``bg %1''\fP.
+.PP
+The shell learns immediately whenever a job changes state.
+Normally,
+.B bash
+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
+option to the
+.B set
+builtin command
+is enabled,
+.B bash
+reports such changes immediately.
+Any trap on
+.SM
+.B SIGCHLD
+is executed for each child that exits.
+.PP
+If an attempt to exit
+.B bash
+is made while jobs are stopped (or, if the \fBcheckjobs\fP shell option has
+been enabled using the \fBshopt\fP builtin, running), the shell prints a
+warning message, and, if the \fBcheckjobs\fP option is enabled, lists the
+jobs and their statuses.
+The
+.B jobs
+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.
+.SH PROMPTING
+When executing interactively, 
+.B bash
+displays the primary prompt
+.SM
+.B PS1
+when it is ready to read a command, and the secondary prompt
+.SM
+.B PS2
+when it needs more input to complete a command.
+.B Bash
+allows these prompt strings to be customized by inserting a number of
+backslash-escaped special characters that are decoded as follows:
+.RS
+.PD 0
+.TP
+.B \ea
+an ASCII bell character (07)
+.TP
+.B \ed
+the date in "Weekday Month Date" format (e.g., "Tue May 26")
+.TP
+.B \eD{\fIformat\fP}
+the \fIformat\fP is passed to \fIstrftime\fP(3) and the result is inserted
+into the prompt string; an empty \fIformat\fP results in a locale-specific
+time representation.  The braces are required
+.TP
+.B \ee
+an ASCII escape character (033)
+.TP
+.B \eh
+the hostname up to the first `.'
+.TP
+.B \eH
+the hostname
+.TP
+.B \ej
+the number of jobs currently managed by the shell
+.TP
+.B \el
+the basename of the shell's terminal device name
+.TP
+.B \en
+newline
+.TP
+.B \er
+carriage return
+.TP
+.B \es
+the name of the shell, the basename of
+.B $0
+(the portion following the final slash)
+.TP
+.B \et
+the current time in 24-hour HH:MM:SS format
+.TP
+.B \eT
+the current time in 12-hour HH:MM:SS format
+.TP
+.B \e@
+the current time in 12-hour am/pm format
+.TP
+.B \eA
+the current time in 24-hour HH:MM format
+.TP
+.B \eu
+the username of the current user
+.TP
+.B \ev
+the version of \fBbash\fP (e.g., 2.00)
+.TP
+.B \eV
+the release of \fBbash\fP, version + patch level (e.g., 2.00.0)
+.TP
+.B \ew
+the current working directory, with
+.SM
+.B $HOME
+abbreviated with a tilde
+(uses the value of the
+.SM
+.B PROMPT_DIRTRIM
+variable)
+.TP
+.B \eW
+the basename of the current working directory, with
+.SM
+.B $HOME
+abbreviated with a tilde
+.TP
+.B \e!
+the history number of this command
+.TP
+.B \e#
+the command number of this command
+.TP
+.B \e$
+if the effective UID is 0, a
+.BR # ,
+otherwise a
+.B $
+.TP
+.B \e\fInnn\fP
+the character corresponding to the octal number \fInnn\fP
+.TP
+.B \e\e
+a backslash
+.TP
+.B \e[
+begin a sequence of non-printing characters, which could be used to
+embed a terminal control sequence into the prompt
+.TP
+.B \e]
+end a sequence of non-printing characters
+.PD
+.RE
+.PP
+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
+.SM
+.B HISTORY
+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 substitution, arithmetic
+expansion, and quote removal, subject to the value of the
+.B promptvars
+shell option (see the description of the
+.B shopt
+command under
+.SM
+.B "SHELL BUILTIN COMMANDS"
+below).
+.SH READLINE
+This is the library that handles reading input when using an interactive
+shell, unless the
+.B \-\-noediting
+option is given at shell invocation.
+Line editing is also used when using the \fB\-e\fP option to the
+\fBread\fP 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 emacs
+or
+.B \-o vi
+options to the
+.B set
+builtin (see
+.SM
+.B SHELL BUILTIN COMMANDS
+below).
+To turn off line editing after the shell is running, use the
+.B +o emacs
+or
+.B +o vi
+options to the
+.B set
+builtin.
+.SS "Readline Notation"
+.PP
+In this section, the Emacs-style notation is used to denote
+keystrokes.  Control keys are denoted by C\-\fIkey\fR, e.g., C\-n
+means Control\-N.  Similarly, 
+.I meta
+keys are denoted by M\-\fIkey\fR, so M\-x means Meta\-X.  (On keyboards
+without a 
+.I meta
+key, M\-\fIx\fP means ESC \fIx\fP, i.e., press the Escape key
+then the
+.I x
+key.  This makes ESC the \fImeta prefix\fP.
+The combination M\-C\-\fIx\fP means ESC\-Control\-\fIx\fP,
+or press the Escape key
+then hold the Control key while pressing the
+.I x
+key.)
+.PP
+Readline commands may be given numeric
+.IR arguments ,
+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., \fBkill\-line\fP) causes that command to act in a
+backward direction. 
+Commands whose behavior with arguments deviates from this are noted
+below.
+.PP
+When a command is described as \fIkilling\fP text, the text
+deleted is saved for possible future retrieval
+(\fIyanking\fP).  The killed text is saved in a
+\fIkill ring\fP.  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.
+.SS "Readline Initialization"
+.PP
+Readline is customized by putting commands in an initialization
+file (the \fIinputrc\fP file).
+The name of this file is taken from the value of the
+.SM
+.B INPUTRC
+variable.  If that variable is unset, the default is
+.IR ~/.inputrc .
+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 \fB#\fP are comments.
+Lines beginning with a \fB$\fP indicate conditional constructs.
+Other lines denote key bindings and variable settings.
+.PP
+The default key-bindings may be changed with an
+.I inputrc 
+file.
+Other programs that use this library may add their own commands
+and bindings.
+.PP
+For example, placing
+.RS
+.PP
+M\-Control\-u: universal\-argument
+.RE
+or
+.RS
+C\-Meta\-u: universal\-argument
+.RE
+into the 
+.I inputrc
+would make M\-C\-u execute the readline command
+.IR universal\-argument .
+.PP
+The following symbolic character names are recognized:
+.IR RUBOUT ,
+.IR DEL ,
+.IR ESC ,
+.IR LFD ,
+.IR NEWLINE ,
+.IR RET ,
+.IR RETURN ,
+.IR SPC ,
+.IR SPACE ,
+and
+.IR TAB .
+.PP
+In addition to command names, readline allows keys to be bound
+to a string that is inserted when the key is pressed (a \fImacro\fP).
+.SS "Readline Key Bindings"
+.PP
+The syntax for controlling key bindings in the
+.I inputrc
+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 specified in one of two ways:
+as a symbolic key name, possibly with \fIMeta\-\fP or \fIControl\-\fP
+prefixes, or as a key sequence.
+.PP
+When using the form \fBkeyname\fP:\^\fIfunction\-name\fP or \fImacro\fP,
+.I keyname
+is the name of a key spelled out in English.  For example:
+.sp
+.RS
+Control-u: universal\-argument
+.br
+Meta-Rubout: backward-kill-word
+.br
+Control-o: "> output"
+.RE
+.LP
+In the above example,
+.I C\-u
+is bound to the function
+.BR universal\-argument ,
+.I M\-DEL
+is bound to the function
+.BR backward\-kill\-word ,
+and
+.I C\-o
+is bound to run the macro
+expressed on the right hand side (that is, to insert the text
+.if t \f(CW> output\fP
+.if n ``> output''
+into the line).
+.PP
+In the second form, \fB"keyseq"\fP:\^\fIfunction\-name\fP or \fImacro\fP,
+.B keyseq
+differs from
+.B keyname
+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.
+.sp
+.RS
+"\eC\-u": universal\-argument
+.br
+"\eC\-x\eC\-r": re\-read\-init\-file
+.br
+"\ee[11~": "Function Key 1"
+.RE
+.PP
+In this example,
+.I C\-u
+is again bound to the function
+.BR universal\-argument .
+.I "C\-x C\-r"
+is bound to the function
+.BR re\-read\-init\-file ,
+and 
+.I "ESC [ 1 1 ~"
+is bound to insert the text
+.if t \f(CWFunction Key 1\fP.
+.if n ``Function Key 1''.
+.PP
+The full set of GNU Emacs style escape sequences is
+.RS
+.PD 0
+.TP
+.B \eC\-
+control prefix
+.TP
+.B \eM\-
+meta prefix
+.TP
+.B \ee
+an escape character
+.TP
+.B \e\e
+backslash
+.TP
+.B \e"
+literal "
+.TP
+.B \e\(aq
+literal \(aq
+.RE
+.PD
+.PP
+In addition to the GNU Emacs style escape sequences, a second
+set of backslash escapes is available:
+.RS
+.PD 0
+.TP
+.B \ea
+alert (bell)
+.TP
+.B \eb
+backspace
+.TP
+.B \ed
+delete
+.TP
+.B \ef
+form feed
+.TP
+.B \en
+newline
+.TP
+.B \er
+carriage return
+.TP
+.B \et
+horizontal tab
+.TP
+.B \ev
+vertical tab
+.TP
+.B \e\fInnn\fP
+the eight-bit character whose value is the octal value \fInnn\fP
+(one to three digits)
+.TP
+.B \ex\fIHH\fP
+the eight-bit character whose value is the hexadecimal value \fIHH\fP
+(one or two hex digits)
+.RE
+.PD
+.PP
+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 function name.
+In the macro body, the backslash escapes described above are expanded.
+Backslash will quote any other character in the macro text,
+including " and \(aq.
+.PP
+.B Bash
+allows the current readline key bindings to be displayed or modified
+with the
+.B bind
+builtin command.  The editing mode may be switched during interactive
+use by using the
+.B \-o
+option to the
+.B set
+builtin command (see
+.SM
+.B SHELL BUILTIN COMMANDS
+below).
+.SS "Readline Variables"
+.PP
+Readline has variables that can be used to further customize its
+behavior.  A variable may be set in the
+.I inputrc
+file with a statement of the form
+.RS
+.PP
+\fBset\fP \fIvariable\-name\fP \fIvalue\fP
+.RE
+.PP
+Except where noted, readline variables can take the values
+.B On
+or
+.B Off
+(without regard to case).
+Unrecognized variable names are ignored.
+When a variable value is read, empty or null values, "on" (case-insensitive),
+and "1" are equivalent to \fBOn\fP.  All other values are equivalent to
+\fBOff\fP.
+The variables and their default values are:
+.PP
+.PD 0
+.TP
+.B bell\-style (audible)
+Controls what happens when readline wants to ring the terminal bell.
+If set to \fBnone\fP, readline never rings the bell.  If set to
+\fBvisible\fP, readline uses a visible bell if one is available.
+If set to \fBaudible\fP, readline attempts to ring the terminal's bell.
+.TP
+.B bind\-tty\-special\-chars (On)
+If set to \fBOn\fP, readline attempts to bind the control characters
+treated specially by the kernel's terminal driver to their readline
+equivalents.
+.TP
+.B colored\-stats (Off)
+If set to \fBOn\fP, readline displays possible completions using different
+colors to indicate their file type.     
+The color definitions are taken from the value of the \fBLS_COLORS\fP
+environment variable.
+.TP
+.B comment\-begin (``#'')
+The string that is inserted when the readline
+.B insert\-comment
+command is executed.
+This command is bound to
+.B M\-#
+in emacs mode and to
+.B #
+in vi command mode.
+.TP
+.B completion\-ignore\-case (Off)
+If set to \fBOn\fP, readline performs filename matching and completion
+in a case\-insensitive fashion.
+.TP
+.B completion\-prefix\-display\-length (0)
+The length in characters of the common prefix of a list of possible
+completions that is displayed without modification.  When set to a
+value greater than zero, common prefixes longer than this value are
+replaced with an ellipsis when displaying possible completions.
+.TP
+.B completion\-query\-items (100)
+This determines when the user is queried about viewing
+the number of possible completions
+generated by the \fBpossible\-completions\fP 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 simply listed
+on the terminal.
+.TP
+.B convert\-meta (On)
+If set to \fBOn\fP, 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 \fImeta prefix\fP).
+.TP
+.B disable\-completion (Off)
+If set to \fBOn\fP, readline will inhibit word completion.  Completion
+characters will be inserted into the line as if they had been
+mapped to \fBself-insert\fP.
+.TP
+.B editing\-mode (emacs)
+Controls whether readline begins with a set of key bindings similar
+to \fIEmacs\fP or \fIvi\fP.
+.B editing\-mode
+can be set to either
+.B emacs
+or
+.BR vi .
+.TP
+.B echo\-control\-characters (On)
+When set to \fBOn\fP, on operating systems that indicate they support it,
+readline echoes a character corresponding to a signal generated from the
+keyboard.
+.TP
+.B enable\-keypad (Off)
+When set to \fBOn\fP, readline will try to enable the application
+keypad when it is called.  Some systems need this to enable the
+arrow keys.
+.TP
+.B enable\-meta\-key (On)
+When set to \fBOn\fP, 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.
+.TP
+.B expand\-tilde (Off)
+If set to \fBOn\fP, tilde expansion is performed when readline
+attempts word completion.
+.TP
+.B history\-preserve\-point (Off)
+If set to \fBOn\fP, the history code attempts to place point at the
+same location on each history line retrieved with \fBprevious-history\fP
+or \fBnext-history\fP.
+.TP
+.B history\-size (0)
+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 number of history entries is not limited.
+.TP
+.B horizontal\-scroll\-mode (Off)
+When set to \fBOn\fP, 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 new line.
+.TP
+.B input\-meta (Off)
+If set to \fBOn\fP, 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
+.B meta\-flag
+is a synonym for this variable.
+.TP
+.B isearch\-terminators (``C\-[C\-J'')
+The string of characters that should terminate an incremental
+search without subsequently executing the character as a command.
+If this variable has not been given a value, the characters
+\fIESC\fP and \fIC\-J\fP will terminate an incremental search.
+.TP
+.B keymap (emacs)
+Set the current readline keymap.  The set of valid keymap names is
+\fIemacs, emacs\-standard, emacs\-meta, emacs\-ctlx, vi,
+vi\-command\fP, and
+.IR vi\-insert .
+\fIvi\fP is equivalent to \fIvi\-command\fP; \fIemacs\fP is
+equivalent to \fIemacs\-standard\fP.  The default value is
+.IR emacs ;
+the value of
+.B editing\-mode
+also affects the default keymap.
+.TP
+.B keyseq\-timeout (500)
+Specifies the duration \fIreadline\fP 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, \fIreadline\fP will use the shorter
+but complete key sequence.
+The value is specified in milliseconds, so a value of 1000 means that
+\fIreadline\fP 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, \fIreadline\fP will wait until another key is pressed to
+decide which key sequence to complete.
+.TP
+.B mark\-directories (On)
+If set to \fBOn\fP, completed directory names have a slash
+appended.
+.TP
+.B mark\-modified\-lines (Off)
+If set to \fBOn\fP, history lines that have been modified are displayed
+with a preceding asterisk (\fB*\fP).
+.TP
+.B mark\-symlinked\-directories (Off)
+If set to \fBOn\fP, completed names which are symbolic links to directories
+have a slash appended (subject to the value of
+\fBmark\-directories\fP).
+.TP
+.B match\-hidden\-files (On)
+This variable, when set to \fBOn\fP, causes readline to match files whose
+names begin with a `.' (hidden files) when performing filename 
+completion.
+If set to \fBOff\fP, the leading `.' must be
+supplied by the user in the filename to be completed.
+.TP
+.B menu\-complete\-display\-prefix (Off)
+If set to \fBOn\fP, menu completion displays the common prefix of the
+list of possible completions (which may be empty) before cycling through
+the list.
+.TP
+.B output\-meta (Off)
+If set to \fBOn\fP, readline will display characters with the
+eighth bit set directly rather than as a meta-prefixed escape
+sequence.
+.TP
+.B page\-completions (On)
+If set to \fBOn\fP, readline uses an internal \fImore\fP-like pager
+to display a screenful of possible completions at a time.
+.TP
+.B print\-completions\-horizontally (Off)
+If set to \fBOn\fP, readline will display completions with matches
+sorted horizontally in alphabetical order, rather than down the screen.
+.TP 
+.B revert\-all\-at\-newline (Off)
+If set to \fBOn\fP, readline will undo all changes to history lines 
+before returning when \fBaccept\-line\fP is executed.  By default,
+history lines may be modified and retain individual undo lists across
+calls to \fBreadline\fP.
+.TP
+.B show\-all\-if\-ambiguous (Off)
+This alters the default behavior of the completion functions.  If
+set to
+.BR On ,
+words which have more than one possible completion cause the
+matches to be listed immediately instead of ringing the bell.
+.TP
+.B show\-all\-if\-unmodified (Off)
+This alters the default behavior of the completion functions in
+a fashion similar to \fBshow\-all\-if\-ambiguous\fP.
+If set to
+.BR On ,
+words which have more than one possible completion without any
+possible partial completion (the possible completions don't share
+a common prefix) cause the matches to be listed immediately instead
+of ringing the bell.
+.TP
+.B show\-mode\-in\-prompt (Off)
+If set to \fBOn\fP, add a character to the beginning of the prompt
+indicating the editing mode: emacs (@), vi command (:) or vi
+insertion (+).
+.TP
+.B skip\-completed\-text (Off)
+If set to \fBOn\fP, 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.
+.TP
+.B visible\-stats (Off)
+If set to \fBOn\fP, a character denoting a file's type as reported
+by \fIstat\fP(2) is appended to the filename when listing possible
+completions.
+.PD
+.SS "Readline Conditional Constructs"
+.PP
+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.
+.IP \fB$if\fP
+The 
+.B $if
+construct allows bindings to be made based on the
+editing 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.
+.RS
+.IP \fBmode\fP
+The \fBmode=\fP form of the \fB$if\fP directive is used to test
+whether readline is in emacs or vi mode.
+This may be used in conjunction
+with the \fBset keymap\fP command, for instance, to set bindings in
+the \fIemacs\-standard\fP and \fIemacs\-ctlx\fP keymaps only if
+readline is starting out in emacs mode.
+.IP \fBterm\fP
+The \fBterm=\fP 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 terminal and the portion
+of the terminal name before the first \fB\-\fP.  This allows
+.I sun
+to match both
+.I sun
+and
+.IR sun\-cmd ,
+for instance.
+.IP \fBapplication\fP
+The \fBapplication\fP construct is used to include
+application-specific settings.  Each program using the readline
+library sets the \fIapplication name\fP, 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 \fBbash\fP:
+.sp 1
+.RS
+.nf
+\fB$if\fP Bash
+# Quote the current or previous word
+"\eC\-xq": "\eeb\e"\eef\e""
+\fB$endif\fP
+.fi
+.RE
+.RE
+.IP \fB$endif\fP
+This command, as seen in the previous example, terminates an
+\fB$if\fP command.
+.IP \fB$else\fP
+Commands in this branch of the \fB$if\fP directive are executed if
+the test fails.
+.IP \fB$include\fP
+This directive takes a single filename as an argument and reads commands
+and bindings from that file.  For example, the following directive
+would read \fI/etc/inputrc\fP:
+.sp 1
+.RS
+.nf
+\fB$include\fP \^ \fI/etc/inputrc\fP
+.fi
+.RE
+.SS Searching
+.PP
+Readline provides commands for searching through the command history
+(see
+.SM
+.B HISTORY
+below) for lines containing a specified string.
+There are two search modes:
+.I incremental
+and
+.IR non-incremental .
+.PP
+Incremental searches begin before the user has finished typing the
+search string.
+As each character of the search string is typed, readline 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 \fBisearch-terminators\fP
+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
+search string becomes the current line.
+.PP
+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 \fInewline\fP will terminate the search and accept
+the line, thereby executing the command from the history list.
+.PP
+Readline remembers the last incremental search string.  If two
+Control-Rs are typed without any intervening characters defining a
+new search string, any remembered search string is used.
+.PP
+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.
+.SS "Readline Command Names"
+.PP
+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 accompanying key sequence are unbound by default.
+In the following descriptions, \fIpoint\fP refers to the current cursor
+position, and \fImark\fP refers to a cursor position saved by the
+\fBset\-mark\fP command.
+The text between the point and mark is referred to as the \fIregion\fP.
+.SS Commands for Moving
+.PP
+.PD 0
+.TP
+.B beginning\-of\-line (C\-a)
+Move to the start of the current line.
+.TP
+.B end\-of\-line (C\-e)
+Move to the end of the line.
+.TP
+.B forward\-char (C\-f)
+Move forward a character.
+.TP
+.B backward\-char (C\-b)
+Move back a character.
+.TP
+.B forward\-word (M\-f)
+Move forward to the end of the next word.  Words are composed of
+alphanumeric characters (letters and digits).
+.TP
+.B backward\-word (M\-b)
+Move back to the start of the current or previous word.
+Words are composed of alphanumeric characters (letters and digits).
+.TP
+.B shell\-forward\-word
+Move forward to the end of the next word.
+Words are delimited by non-quoted shell metacharacters.
+.TP
+.B shell\-backward\-word
+Move back to the start of the current or previous word.
+Words are delimited by non-quoted shell metacharacters.
+.TP
+.B clear\-screen (C\-l)
+Clear the screen leaving the current line at the top of the screen.
+With an argument, refresh the current line without clearing the
+screen.
+.TP
+.B redraw\-current\-line
+Refresh the current line.
+.PD
+.SS Commands for Manipulating the History
+.PP
+.PD 0
+.TP
+.B accept\-line (Newline, Return)
+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
+.SM
+.B HISTCONTROL
+variable.  If the line is a modified history
+line, then restore the history line to its original state.
+.TP
+.B previous\-history (C\-p)
+Fetch the previous command from the history list, moving back in
+the list.
+.TP
+.B next\-history (C\-n)
+Fetch the next command from the history list, moving forward in the
+list.
+.TP
+.B beginning\-of\-history (M\-<)
+Move to the first line in the history.
+.TP
+.B end\-of\-history (M\->)
+Move to the end of the input history, i.e., the line currently being
+entered.
+.TP
+.B reverse\-search\-history (C\-r)
+Search backward starting at the current line and moving `up' through
+the history as necessary.  This is an incremental search.
+.TP
+.B forward\-search\-history (C\-s)
+Search forward starting at the current line and moving `down' through
+the history as necessary.  This is an incremental search.
+.TP
+.B non\-incremental\-reverse\-search\-history (M\-p)
+Search backward through the history starting at the current line
+using a non-incremental search for a string supplied by the user.
+.TP
+.B non\-incremental\-forward\-search\-history (M\-n)
+Search forward through the history using a non-incremental search for
+a string supplied by the user.
+.TP
+.B history\-search\-forward
+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.
+.TP
+.B history\-search\-backward
+Search backward through the history for the string of characters
+between the start of the current line and the point.
+This is a non-incremental search.
+.TP
+.B yank\-nth\-arg (M\-C\-y)
+Insert the first argument to the previous command (usually
+the second word on the previous line) at point.
+With an argument
+.IR n ,
+insert the \fIn\fPth word from the previous command (the words
+in the previous command begin with word 0).  A negative argument
+inserts the \fIn\fPth word from the end of the previous command.
+Once the argument \fIn\fP is computed, the argument is extracted
+as if the "!\fIn\fP" history expansion had been specified.
+.TP
+.B
+yank\-last\-arg (M\-.\^, M\-_\^)
+Insert the last argument to the previous command (the last word of
+the previous history entry).
+With a numeric argument, behave exactly like \fByank\-nth\-arg\fP.
+Successive calls to \fByank\-last\-arg\fP 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 (back or forward).
+The history expansion facilities are used to extract the last word,
+as if the "!$" history expansion had been specified.
+.TP
+.B shell\-expand\-line (M\-C\-e)
+Expand the line as the shell does.  This
+performs alias and history expansion as well as all of the shell
+word expansions.  See
+.SM
+.B HISTORY EXPANSION
+below for a description of history expansion.
+.TP
+.B history\-expand\-line (M\-^)
+Perform history expansion on the current line.
+See
+.SM
+.B HISTORY EXPANSION
+below for a description of history expansion.
+.TP
+.B magic\-space
+Perform history expansion on the current line and insert a space.
+See
+.SM
+.B HISTORY EXPANSION
+below for a description of history expansion.
+.TP
+.B alias\-expand\-line
+Perform alias expansion on the current line.
+See
+.SM
+.B ALIASES
+above for a description of alias expansion.
+.TP
+.B history\-and\-alias\-expand\-line
+Perform history and alias expansion on the current line.
+.TP
+.B insert\-last\-argument (M\-.\^, M\-_\^)
+A synonym for \fByank\-last\-arg\fP.
+.TP
+.B operate\-and\-get\-next (C\-o)
+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.
+.TP
+.B edit\-and\-execute\-command (C\-xC\-e)
+Invoke an editor on the current command line, and execute the result as shell
+commands.
+\fBBash\fP attempts to invoke
+.SM
+.BR $VISUAL ,
+.SM
+.BR $EDITOR ,
+and \fIemacs\fP as the editor, in that order.
+.PD
+.SS Commands for Changing Text
+.PP
+.PD 0
+.TP
+.B delete\-char (C\-d)
+Delete the character at point.  If point is at the
+beginning of the line, there are no characters in the line, and
+the last character typed was not bound to \fBdelete\-char\fP,
+then return
+.SM
+.BR EOF .
+.TP
+.B backward\-delete\-char (Rubout)
+Delete the character behind the cursor.  When given a numeric argument,
+save the deleted text on the kill ring.
+.TP
+.B forward\-backward\-delete\-char
+Delete the character under the cursor, unless the cursor is at the
+end of the line, in which case the character behind the cursor is
+deleted.
+.TP
+.B quoted\-insert (C\-q, C\-v)
+Add the next character typed to the line verbatim.  This is
+how to insert characters like \fBC\-q\fP, for example.
+.TP
+.B tab\-insert (C\-v TAB)
+Insert a tab character.
+.TP
+.B self\-insert (a,\ b,\ A,\ 1,\ !,\ ...)
+Insert the character typed.
+.TP
+.B transpose\-chars (C\-t)
+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.
+.TP
+.B transpose\-words (M\-t)
+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.   
+.TP
+.B upcase\-word (M\-u)
+Uppercase the current (or following) word.  With a negative argument,
+uppercase the previous word, but do not move point.
+.TP
+.B downcase\-word (M\-l)
+Lowercase the current (or following) word.  With a negative argument,
+lowercase the previous word, but do not move point.
+.TP
+.B capitalize\-word (M\-c)
+Capitalize the current (or following) word.  With a negative argument,
+capitalize the previous word, but do not move point.
+.TP
+.B overwrite\-mode
+Toggle overwrite mode.  With an explicit positive numeric argument,
+switches to overwrite mode.  With an explicit non-positive numeric
+argument, switches to insert mode.  This command affects only
+\fBemacs\fP mode; \fBvi\fP mode does overwrite differently.
+Each call to \fIreadline()\fP starts in insert mode.
+In overwrite mode, characters bound to \fBself\-insert\fP replace   
+the text at point rather than pushing the text to the right.
+Characters bound to \fBbackward\-delete\-char\fP replace the character
+before point with a space.  By default, this command is unbound.
+.PD
+.SS Killing and Yanking
+.PP
+.PD 0
+.TP
+.B kill\-line (C\-k)
+Kill the text from point to the end of the line.
+.TP
+.B backward\-kill\-line (C\-x Rubout)
+Kill backward to the beginning of the line.
+.TP
+.B unix\-line\-discard (C\-u)
+Kill backward from point to the beginning of the line.
+The killed text is saved on the kill-ring.
+.\" There is no real difference between this and backward-kill-line
+.TP
+.B kill\-whole\-line
+Kill all characters on the current line, no matter where point is.
+.TP
+.B kill\-word  (M\-d)
+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 \fBforward\-word\fP.
+.TP
+.B backward\-kill\-word (M\-Rubout)
+Kill the word behind point.
+Word boundaries are the same as those used by \fBbackward\-word\fP.
+.TP
+.B shell\-kill\-word  (M\-d)
+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 \fBshell\-forward\-word\fP.
+.TP
+.B shell\-backward\-kill\-word (M\-Rubout)
+Kill the word behind point.
+Word boundaries are the same as those used by \fBshell\-backward\-word\fP.
+.TP
+.B unix\-word\-rubout (C\-w)
+Kill the word behind point, using white space as a word boundary.
+The killed text is saved on the kill-ring.
+.TP
+.B unix\-filename\-rubout
+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.
+.TP
+.B delete\-horizontal\-space (M\-\e)
+Delete all spaces and tabs around point.
+.TP
+.B kill\-region
+Kill the text in the current region.
+.TP
+.B copy\-region\-as\-kill
+Copy the text in the region to the kill buffer.
+.TP
+.B copy\-backward\-word
+Copy the word before point to the kill buffer.
+The word boundaries are the same as \fBbackward\-word\fP.
+.TP
+.B copy\-forward\-word
+Copy the word following point to the kill buffer.
+The word boundaries are the same as \fBforward\-word\fP.
+.TP
+.B yank (C\-y)
+Yank the top of the kill ring into the buffer at point.
+.TP
+.B yank\-pop (M\-y)
+Rotate the kill ring, and yank the new top.  Only works following
+.B yank
+or
+.BR yank\-pop .
+.PD
+.SS Numeric Arguments
+.PP
+.PD 0
+.TP
+.B digit\-argument (M\-0, M\-1, ..., M\-\-)
+Add this digit to the argument already accumulating, or start a new
+argument.  M\-\- starts a negative argument.
+.TP
+.B universal\-argument
+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 followed by digits, executing
+.B universal\-argument
+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 argument count four, a second time makes the
+argument count sixteen, and so on.
+.PD
+.SS Completing
+.PP
+.PD 0
+.TP
+.B complete (TAB)
+Attempt to perform completion on the text before point.
+.B Bash
+attempts completion treating the text as a variable (if the
+text begins with \fB$\fP), username (if the text begins with
+\fB~\fP), hostname (if the text begins with \fB@\fP), or
+command (including aliases and functions) in turn.  If none
+of these produces a match, filename completion is attempted.
+.TP
+.B possible\-completions (M\-?)
+List the possible completions of the text before point.
+.TP
+.B insert\-completions (M\-*)
+Insert all completions of the text before point
+that would have been generated by
+\fBpossible\-completions\fP.
+.TP
+.B menu\-complete
+Similar to \fBcomplete\fP, but replaces the word to be completed
+with a single match from the list of possible completions.
+Repeated execution of \fBmenu\-complete\fP 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 \fBbell\-style\fP)
+and the original text is restored.
+An argument of \fIn\fP moves \fIn\fP 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 \fBTAB\fP, but is unbound
+by default.
+.TP
+.B menu\-complete\-backward
+Identical to \fBmenu\-complete\fP, but moves backward through the list
+of possible completions, as if \fBmenu\-complete\fP had been given a
+negative argument.  This command is unbound by default.
+.TP
+.B delete\-char\-or\-list
+Deletes the character under the cursor if not at the beginning or
+end of the line (like \fBdelete\-char\fP).
+If at the end of the line, behaves identically to
+\fBpossible\-completions\fP.
+This command is unbound by default.
+.TP
+.B complete\-filename (M\-/)
+Attempt filename completion on the text before point.
+.TP
+.B possible\-filename\-completions (C\-x /)
+List the possible completions of the text before point,
+treating it as a filename.
+.TP
+.B complete\-username (M\-~)
+Attempt completion on the text before point, treating
+it as a username.
+.TP
+.B possible\-username\-completions (C\-x ~)
+List the possible completions of the text before point,
+treating it as a username.
+.TP
+.B complete\-variable (M\-$)
+Attempt completion on the text before point, treating
+it as a shell variable.
+.TP
+.B possible\-variable\-completions (C\-x $)
+List the possible completions of the text before point,
+treating it as a shell variable.
+.TP
+.B complete\-hostname (M\-@)
+Attempt completion on the text before point, treating
+it as a hostname.
+.TP
+.B possible\-hostname\-completions (C\-x @)
+List the possible completions of the text before point,
+treating it as a hostname.
+.TP
+.B complete\-command (M\-!)
+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.
+.TP
+.B possible\-command\-completions (C\-x !)
+List the possible completions of the text before point,
+treating it as a command name.
+.TP
+.B dynamic\-complete\-history (M\-TAB)
+Attempt completion on the text before point, comparing
+the text against lines from the history list for possible
+completion matches.
+.TP
+.B dabbrev\-expand
+Attempt menu completion on the text before point, comparing
+the text against lines from the history list for possible
+completion matches.
+.TP
+.B complete\-into\-braces (M\-{)
+Perform filename completion and insert the list of possible completions
+enclosed within braces so the list is available to the shell (see
+.B Brace Expansion
+above).
+.PD
+.SS Keyboard Macros
+.PP
+.PD 0
+.TP
+.B start\-kbd\-macro (C\-x (\^)
+Begin saving the characters typed into the current keyboard macro.
+.TP
+.B end\-kbd\-macro (C\-x )\^)
+Stop saving the characters typed into the current keyboard macro
+and store the definition.
+.TP
+.B call\-last\-kbd\-macro (C\-x e)
+Re-execute the last keyboard macro defined, by making the characters
+in the macro appear as if typed at the keyboard.
+.B print\-last\-kbd\-macro ()
+Print the last keyboard macro defined in a format suitable for the
+\fIinputrc\fP file.
+.PD
+.SS Miscellaneous
+.PP
+.PD 0
+.TP
+.B re\-read\-init\-file (C\-x C\-r)
+Read in the contents of the \fIinputrc\fP file, and incorporate
+any bindings or variable assignments found there.
+.TP
+.B abort (C\-g)
+Abort the current editing command and
+ring the terminal's bell (subject to the setting of
+.BR bell\-style ).
+.TP
+.B do\-uppercase\-version (M\-a, M\-b, M\-\fIx\fP, ...)
+If the metafied character \fIx\fP is lowercase, run the command
+that is bound to the corresponding uppercase character.
+.TP
+.B prefix\-meta (ESC)
+Metafy the next character typed.
+.SM
+.B ESC
+.B f
+is equivalent to
+.BR Meta\-f .
+.TP
+.B undo (C\-_, C\-x C\-u)
+Incremental undo, separately remembered for each line.
+.TP
+.B revert\-line (M\-r)
+Undo all changes made to this line.  This is like executing the
+.B undo
+command enough times to return the line to its initial state.
+.TP
+.B tilde\-expand (M\-&)
+Perform tilde expansion on the current word.
+.TP
+.B set\-mark (C\-@, M\-<space>)
+Set the mark to the point.  If a
+numeric argument is supplied, the mark is set to that position.
+.TP
+.B exchange\-point\-and\-mark (C\-x C\-x)
+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.
+.TP
+.B character\-search (C\-])
+A character is read and point is moved to the next occurrence of that
+character.  A negative count searches for previous occurrences.
+.TP
+.B character\-search\-backward (M\-C\-])
+A character is read and point is moved to the previous occurrence of that
+character.  A negative count searches for subsequent occurrences.
+.TP
+.B skip\-csi\-sequence
+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 "\e[", 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\-[.
+.TP
+.B insert\-comment (M\-#)
+Without a numeric argument, the value of the readline
+.B comment\-begin
+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 \fBcomment\-begin\fP, the value is inserted, otherwise
+the characters in \fBcomment\-begin\fP are deleted from the beginning of 
+the line.
+In either case, the line is accepted as if a newline had been typed.
+The default value of
+\fBcomment\-begin\fP 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.
+.TP
+.B glob\-complete\-word (M\-g)
+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.
+.TP
+.B glob\-expand\-word (C\-x *)
+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.
+.TP
+.B glob\-list\-expansions (C\-x g)
+The list of expansions that would have been generated by
+.B glob\-expand\-word
+is displayed, and the line is redrawn.
+If a numeric argument is supplied, an asterisk is appended before
+pathname expansion.
+.TP
+.B dump\-functions
+Print all of the functions and their key bindings 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
+of an \fIinputrc\fP file.
+.TP
+.B dump\-variables
+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
+of an \fIinputrc\fP file.
+.TP
+.B dump\-macros
+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 \fIinputrc\fP file.
+.TP
+.B display\-shell\-version (C\-x C\-v)
+Display version information about the current instance of
+.BR bash .
+.PD
+.SS Programmable Completion
+.PP
+When word completion is attempted for an argument to a command for
+which a completion specification (a \fIcompspec\fP) has been defined
+using the \fBcomplete\fP builtin (see
+.SM
+.B "SHELL BUILTIN COMMANDS"
+below), the programmable completion facilities are invoked.
+.PP
+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 \fB\-E\fP option to \fBcomplete\fP 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 with
+the \fB\-D\fP option to \fBcomplete\fP is used as the default.
+.PP
+Once a compspec has been found, it is used to generate the list of
+matching words.
+If a compspec is not found, the default \fBbash\fP completion as
+described above under \fBCompleting\fP is performed.
+.PP
+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
+or
+.B \-d
+option is used for filename or directory name completion, the shell
+variable
+.SM
+.B FIGNORE
+is used to filter the matches.
+.PP
+Any completions specified by a pathname expansion pattern to the
+\fB\-G\fP option are generated next.
+The words generated by the pattern need not match the word
+being completed.
+The
+.SM
+.B GLOBIGNORE
+shell variable is not used to filter the matches, but the
+.SM
+.B FIGNORE
+variable is used.
+.PP
+Next, the string specified as the argument to the \fB\-W\fP option
+is considered.
+The string is first split using the characters in the
+.SM
+.B IFS
+special 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 
+.SM
+.BR EXPANSION .
+The results are split using the rules described above under
+\fBWord Splitting\fP.
+The results of the expansion are prefix-matched against the word being
+completed, and the matching words become the possible completions.
+.PP
+After these matches have been generated, any shell function or command
+specified with the \fB\-F\fP and \fB\-C\fP options is invoked.
+When the command or function is invoked, the
+.SM
+.BR COMP_LINE ,
+.SM
+.BR COMP_POINT ,
+.SM
+.BR COMP_KEY ,
+and
+.SM
+.B COMP_TYPE
+variables are assigned values as described above under
+\fBShell Variables\fP.
+If a shell function is being invoked, the 
+.SM
+.B COMP_WORDS
+and
+.SM
+.B COMP_CWORD
+variables are also set.
+When the function or command is invoked,
+the first argument (\fB$1\fP) is the name of the command whose arguments are
+being completed,
+the second argument (\fB$2\fP) is the word being completed,
+and the third argument (\fB$3\fP) is the word preceding the word being
+completed on the current command line.
+No filtering of the generated completions against the word being completed
+is performed; the function or command has complete freedom in generating
+the matches.
+.PP
+Any function specified with \fB\-F\fP is invoked first.
+The function may use any of the shell facilities, including the
+\fBcompgen\fP builtin described below, to generate the matches.
+It must put the possible completions in the
+.SM
+.B COMPREPLY
+array variable, one per array element.
+.PP
+Next, any command specified with the \fB\-C\fP option is invoked
+in an environment 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.
+.PP
+After all of the possible completions are generated, any filter
+specified with the \fB\-X\fP option is applied to the list.
+The filter is a pattern as used for pathname expansion; a \fB&\fP
+in the pattern is replaced with the text of the word being completed.
+A literal \fB&\fP 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 \fB!\fP negates the pattern; in this case any completion
+not matching the pattern will be removed.
+.PP
+Finally, any prefix and suffix specified with the \fB\-P\fP and \fB\-S\fP
+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.
+.PP
+If the previously-applied actions do not generate any matches, and the
+\fB\-o dirnames\fP option was supplied to \fBcomplete\fP when the
+compspec was defined, directory name completion is attempted.
+.PP
+If the \fB\-o plusdirs\fP option was supplied to \fBcomplete\fP when the
+compspec was defined, directory name completion is attempted and any
+matches are added to the results of the other actions.
+.PP
+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 \fBbash\fP completions are not attempted, and the readline
+default of filename completion is disabled.
+If the \fB\-o bashdefault\fP option was supplied to \fBcomplete\fP when
+the compspec was defined, the \fBbash\fP default completions are attempted
+if the compspec generates no matches.
+If the \fB\-o default\fP option was supplied to \fBcomplete\fP when the
+compspec was defined, readline's default completion will be performed
+if the compspec (and, if attempted, the default \fBbash\fP completions)
+generate no matches.
+.PP
+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 \fBmark\-directories\fP readline variable, regardless
+of the setting of the \fBmark-symlinked\-directories\fP readline variable.
+.PP
+There is some support for dynamically modifying completions.  This is
+most useful when used in combination with a default completion specified
+with \fBcomplete -D\fP.
+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 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 than
+being loaded all at once.
+.PP
+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:
+.PP
+\f(CW_completion_loader()
+.br
+{
+.br
+       . "/etc/bash_completion.d/$1.sh" >/dev/null 2>&1 && return 124
+.br
+}
+.br
+complete -D -F _completion_loader
+.br
+\fP
+.SH HISTORY
+When the
+.B \-o history
+option to the
+.B set
+builtin is enabled, the shell provides access to the
+\fIcommand history\fP,
+the list of commands previously typed.
+The value of the
+.SM
+.B HISTSIZE
+variable is used as the
+number of commands to save in a history list.
+The text of the last
+.SM
+.B HISTSIZE
+commands (default 500) is saved.  The shell
+stores each command in the history list prior to parameter and
+variable expansion (see
+.SM
+.B EXPANSION
+above) but after history expansion is performed, subject to the
+values of the shell variables
+.SM
+.B HISTIGNORE
+and
+.SM
+.BR HISTCONTROL .
+.PP
+On startup, the history is initialized from the file named by
+the variable
+.SM
+.B HISTFILE
+(default \fI~/.bash_history\fP).
+The file named by the value of
+.SM
+.B HISTFILE
+is truncated, if necessary, to contain no more than
+the number of lines specified by the value of
+.SM
+.BR HISTFILESIZE .
+If \fBHISTFILESIZE\fP 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 followed immediately
+by a digit are interpreted as timestamps for the preceding history line.
+These timestamps are optionally displayed depending on the value of the
+.SM
+.B HISTTIMEFORMAT
+variable.
+When a shell with history enabled exits, the last
+.SM
+.B $HISTSIZE
+lines are copied from the history list to
+.SM
+.BR $HISTFILE .
+If the
+.B histappend
+shell option is enabled
+(see the description of
+.B shopt
+under
+.SM
+.B "SHELL BUILTIN COMMANDS"
+below), the lines are appended to the history file,
+otherwise the history file is overwritten.
+If
+.SM
+.B HISTFILE
+is unset, or if the history file is unwritable, the history is
+not saved.
+If the
+.SM
+.B HISTTIMEFORMAT
+variable is set, time stamps are written to the history file, marked
+with the history comment character, so
+they may be preserved across shell sessions.
+This uses the history comment character to distinguish timestamps from
+other history lines.
+After saving the history, the history file is truncated
+to contain no more than
+.SM
+.B HISTFILESIZE
+lines.  If
+.SM
+.B HISTFILESIZE
+is unset, or set to null, a non-numeric value,
+or a numeric value less than zero, the history file is not truncated.
+.PP
+The builtin command
+.B fc
+(see
+.SM
+.B SHELL BUILTIN COMMANDS
+below) may be used to list or edit and re-execute a portion of
+the history list.
+The
+.B history
+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.
+.PP
+The shell allows control over which commands are saved on the history
+list.  The
+.SM
+.B HISTCONTROL
+and
+.SM
+.B HISTIGNORE
+variables may be set to cause the shell to save only a subset of the
+commands entered.
+The
+.B cmdhist
+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
+.B lithist
+shell option causes the shell to save the command with embedded newlines
+instead of semicolons.  See the description of the
+.B shopt
+builtin below under
+.SM
+.B "SHELL BUILTIN COMMANDS"
+for information on setting and unsetting shell options.
+.SH "HISTORY EXPANSION"
+.PP
+The shell supports a history expansion feature that
+is similar to the history expansion in
+.BR csh.
+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
+option to the
+.B set
+builtin command (see
+.SM
+.B SHELL BUILTIN COMMANDS
+below).  Non-interactive shells do not perform history expansion
+by default.
+.PP
+History expansions introduce words from the history list into
+the input 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.
+.PP
+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 \fIevent\fP,
+and the portions of that line that are acted upon are \fIwords\fP.
+Various \fImodifiers\fP are available to manipulate the selected words.
+The line is broken into words in the same fashion as when reading input,
+so that several \fImetacharacter\fP-separated words surrounded by
+quotes are considered one word.
+History expansions are introduced by the appearance of the
+history expansion character, which is \^\fB!\fP\^ by default.
+Only backslash (\^\fB\e\fP\^) and single quotes can quote
+the history expansion character.
+.PP
+Several characters inhibit history expansion if found immediately
+following the history expansion character, even if it is unquoted:
+space, tab, newline, carriage return, and \fB=\fP.
+If the \fBextglob\fP shell option is enabled, \fB(\fP will also
+inhibit expansion.
+.PP
+Several shell options settable with the
+.B shopt
+builtin may be used to tailor the behavior of history expansion.
+If the
+.B histverify
+shell option is enabled (see the description of the
+.B shopt
+builtin below), and
+.B readline
+is being used, history substitutions are not immediately passed to
+the shell parser.
+Instead, the expanded line is reloaded into the
+.B readline
+editing buffer for further modification.
+If
+.B readline
+is being used, and the
+.B histreedit
+shell option is enabled, a failed history substitution will be reloaded
+into the
+.B readline
+editing buffer for correction.
+The
+.B \-p
+option to the
+.B history
+builtin command may be used to see what a history expansion will
+do before using it.
+The
+.B \-s
+option to the
+.B history
+builtin may be used to add commands to the end of the history list
+without actually executing them, so that they are available for
+subsequent recall.
+.PP
+The shell allows control of the various characters used by the
+history expansion mechanism (see the description of
+.B histchars
+above under
+.BR "Shell Variables" ).
+The shell uses
+the history comment character to mark history timestamps when
+writing the history file.
+.SS Event Designators
+.PP
+An event designator is a reference to a command line entry in the
+history list.
+Unless the reference is absolute, events are relative to the current
+position in the history list.
+.PP
+.PD 0
+.TP
+.B !
+Start a history substitution, except when followed by a
+.BR blank ,
+newline, carriage return, =
+or ( (when the \fBextglob\fP shell option is enabled using
+the \fBshopt\fP builtin).
+.TP
+.B !\fIn\fR
+Refer to command line
+.IR n .
+.TP
+.B !\-\fIn\fR
+Refer to the current command minus
+.IR n .
+.TP
+.B !!
+Refer to the previous command.  This is a synonym for `!\-1'.
+.TP
+.B !\fIstring\fR
+Refer to the most recent command preceding the current position in the
+history list starting with
+.IR string .
+.TP
+.B !?\fIstring\fR\fB[?]\fR
+Refer to the most recent command preceding the current position in the
+history list containing
+.IR string .
+The trailing \fB?\fP may be omitted if
+.I string
+is followed immediately by a newline.
+.TP
+.B \d\s+2^\s-2\u\fIstring1\fP\d\s+2^\s-2\u\fIstring2\fP\d\s+2^\s-2\u
+Quick substitution.  Repeat the previous command, replacing
+.I string1
+with
+.IR string2 .
+Equivalent to
+``!!:s/\fIstring1\fP/\fIstring2\fP/''
+(see \fBModifiers\fP below).
+.TP
+.B !#
+The entire command line typed so far.
+.PD
+.SS Word Designators
+.PP
+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
+.BR ^ ,
+.BR $ ,
+.BR * ,
+.BR \- ,
+or
+.BR % .
+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 separated by single spaces.
+.PP
+.PD 0
+.TP
+.B 0 (zero)
+The zeroth word.  For the shell, this is the command
+word.
+.TP
+.I n
+The \fIn\fRth word.
+.TP
+.B ^
+The first argument.  That is, word 1.
+.TP
+.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.
+.TP
+.B %
+The word matched by the most recent `?\fIstring\fR?' search.
+.TP
+.I x\fB\-\fPy
+A range of words; `\-\fIy\fR' abbreviates `0\-\fIy\fR'.
+.TP
+.B *
+All of the words but the zeroth.  This is a synonym
+for `\fI1\-$\fP'.  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.
+.TP
+.B x*
+Abbreviates \fIx\-$\fP.
+.TP
+.B x\-
+Abbreviates \fIx\-$\fP like \fBx*\fP, but omits the last word.
+.PD
+.PP
+If a word designator is supplied without an event specification, the
+previous command is used as the event.
+.SS Modifiers
+.PP
+After the optional word designator, there may appear a sequence of
+one or more of the following modifiers, each preceded by a `:'.
+.PP
+.PD 0
+.PP
+.TP
+.B h
+Remove a trailing filename component, leaving only the head.
+.TP
+.B t
+Remove all leading filename components, leaving the tail.
+.TP
+.B r
+Remove a trailing suffix of the form \fI.xxx\fP, leaving the
+basename.
+.TP
+.B e
+Remove all but the trailing suffix.
+.TP
+.B p
+Print the new command but do not execute it.
+.TP
+.B q
+Quote the substituted words, escaping further substitutions.
+.TP
+.B x
+Quote the substituted words as with
+.BR q ,
+but break into words at
+.B blanks
+and newlines.
+.TP
+.B s/\fIold\fP/\fInew\fP/
+Substitute
+.I new
+for the first occurrence of
+.I old
+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
+.I old
+and
+.I new
+with a single backslash.  If & appears in
+.IR new ,
+it is replaced by
+.IR old .
+A single backslash will quote the &.  If
+.I old
+is null, it is set to the last
+.I old
+substituted, or, if no previous history substitutions took place,
+the last
+.I string
+in a
+.B !?\fIstring\fR\fB[?]\fR
+search.
+.TP
+.B &
+Repeat the previous substitution.
+.TP
+.B g
+Cause changes to be applied over the entire event line.  This is
+used in conjunction with `\fB:s\fP' (e.g., `\fB:gs/\fIold\fP/\fInew\fP/\fR')
+or `\fB:&\fP'.  If used with
+`\fB:s\fP', 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 \fBa\fP may be used as a synonym for \fBg\fP.
+.TP
+.B G
+Apply the following `\fBs\fP' modifier once to each word in the event line.
+.PD
+.SH "SHELL BUILTIN COMMANDS"
+.\" start of bash_builtins
+.zZ
+.PP
+Unless otherwise noted, each builtin command documented in this
+section as accepting options preceded by
+.B \-
+accepts
+.B \-\-
+to signify the end of the options.
+The \fB:\fP, \fBtrue\fP, \fBfalse\fP, and \fBtest\fP builtins
+do not accept options and do not treat \fB\-\-\fP specially.
+The \fBexit\fP, \fBlogout\fP, \fBbreak\fP, \fBcontinue\fP, \fBlet\fP,
+and \fBshift\fP builtins accept and process arguments beginning with
+\fB\-\fP without requiring \fB\-\-\fP.
+Other builtins that accept arguments but are not specified as accepting
+options interpret arguments beginning with \fB\-\fP as invalid options and
+require \fB\-\-\fP to prevent this interpretation.
+.sp .5
+.PD 0
+.TP
+\fB:\fP [\fIarguments\fP]
+.PD
+No effect; the command does nothing beyond expanding
+.I arguments
+and performing any specified
+redirections.  A zero exit code is returned.
+.TP
+\fB .\| \fP \fIfilename\fP [\fIarguments\fP]
+.PD 0
+.TP
+\fBsource\fP \fIfilename\fP [\fIarguments\fP]
+.PD
+Read and execute commands from
+.I filename
+in the current
+shell environment and return the exit status of the last command
+executed from
+.IR filename .
+If
+.I filename
+does not contain a slash, filenames in
+.SM
+.B PATH
+are used to find the directory containing
+.IR filename .
+The file searched for in
+.SM
+.B PATH
+need not be executable.
+When \fBbash\fP is not in \fIposix mode\fP, the current directory is
+searched if no file is found in
+.SM
+.BR PATH .
+If the
+.B sourcepath
+option to the
+.B shopt
+builtin command is turned off, the
+.SM
+.B PATH
+is not searched.
+If any \fIarguments\fP are supplied, they become the positional
+parameters when \fIfilename\fP 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
+.I filename
+is not found or cannot be read.
+.TP
+\fBalias\fP [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
+\fBAlias\fP with no arguments or with the
+.B \-p
+option prints the list of aliases in the form
+\fBalias\fP \fIname\fP=\fIvalue\fP on standard output.
+When arguments are supplied, an alias is defined for
+each \fIname\fP whose \fIvalue\fP is given.
+A trailing space in  \fIvalue\fP causes the next word to be
+checked for alias substitution when the alias is expanded.
+For each \fIname\fP in the argument list for which no \fIvalue\fP
+is supplied, the name and value of the alias is printed.
+\fBAlias\fP returns true unless a \fIname\fP is given for which
+no alias has been defined.
+.TP
+\fBbg\fP [\fIjobspec\fP ...]
+Resume each suspended job \fIjobspec\fP in the background, as if it
+had been started with
+.BR & .
+If
+.I jobspec
+is not present, the shell's notion of the \fIcurrent job\fP is used.
+.B bg
+.I jobspec
+returns 0 unless run when job control is disabled or, when run with
+job control enabled, any specified \fIjobspec\fP was not found
+or was started without job control.
+.TP
+\fBbind\fP [\fB\-m\fP \fIkeymap\fP] [\fB\-lpsvPSVX\fP]
+.PD 0
+.TP
+\fBbind\fP [\fB\-m\fP \fIkeymap\fP] [\fB\-q\fP \fIfunction\fP] [\fB\-u\fP \fIfunction\fP] [\fB\-r\fP \fIkeyseq\fP]
+.TP
+\fBbind\fP [\fB\-m\fP \fIkeymap\fP] \fB\-f\fP \fIfilename\fP
+.TP
+\fBbind\fP [\fB\-m\fP \fIkeymap\fP] \fB\-x\fP \fIkeyseq\fP:\fIshell\-command\fP
+.TP
+\fBbind\fP [\fB\-m\fP \fIkeymap\fP] \fIkeyseq\fP:\fIfunction\-name\fP
+.TP
+\fBbind\fP \fIreadline\-command\fP
+.PD
+Display current
+.B readline
+key and function bindings, bind a key sequence to a
+.B readline
+function or macro, or set a
+.B readline
+variable.
+Each non-option argument is a command as it would appear in
+.IR .inputrc ,
+but each binding or command must be passed as a separate argument;
+e.g., '"\eC\-x\eC\-r": re\-read\-init\-file'.
+Options, if supplied, have the following meanings:
+.RS
+.PD 0
+.TP
+.B \-m \fIkeymap\fP
+Use
+.I keymap
+as the keymap to be affected by the subsequent bindings.
+Acceptable
+.I keymap
+names are
+\fIemacs, emacs\-standard, emacs\-meta, emacs\-ctlx, vi,
+vi\-move, vi\-command\fP, and
+.IR vi\-insert .
+\fIvi\fP is equivalent to \fIvi\-command\fP; \fIemacs\fP is
+equivalent to \fIemacs\-standard\fP.
+.TP
+.B \-l
+List the names of all \fBreadline\fP functions.
+.TP
+.B \-p
+Display \fBreadline\fP function names and bindings in such a way
+that they can be re-read.
+.TP
+.B \-P
+List current \fBreadline\fP function names and bindings.
+.TP
+.B \-s
+Display \fBreadline\fP key sequences bound to macros and the strings
+they output in such a way that they can be re-read.
+.TP
+.B \-S
+Display \fBreadline\fP key sequences bound to macros and the strings
+they output.
+.TP
+.B \-v
+Display \fBreadline\fP variable names and values in such a way that they
+can be re-read.
+.TP
+.B \-V
+List current \fBreadline\fP variable names and values.
+.TP
+.B \-f \fIfilename\fP
+Read key bindings from \fIfilename\fP.
+.TP
+.B \-q \fIfunction\fP
+Query about which keys invoke the named \fIfunction\fP.
+.TP
+.B \-u \fIfunction\fP
+Unbind all keys bound to the named \fIfunction\fP.
+.TP
+.B \-r \fIkeyseq\fP
+Remove any current binding for \fIkeyseq\fP.
+.TP
+.B \-x \fIkeyseq\fP:\fIshell\-command\fP
+Cause \fIshell\-command\fP to be executed whenever \fIkeyseq\fP is
+entered.
+When \fIshell\-command\fP is executed, the shell sets the
+.SM
+.B READLINE_LINE
+variable to the contents of the \fBreadline\fP line buffer and the
+.SM
+.B READLINE_POINT
+variable to the current location of the insertion point.
+If the executed command changes the value of
+.SM
+.B READLINE_LINE
+or
+.SM
+.BR READLINE_POINT ,
+those new values will be reflected in the editing state.
+.TP
+.B \-X
+List all key sequences bound to shell commands and the associated commands
+in a format that can be reused as input.
+.PD
+.PP
+The return value is 0 unless an unrecognized option is given or an
+error occurred.
+.RE
+.TP
+\fBbreak\fP [\fIn\fP]
+Exit from within a
+.BR for ,
+.BR while ,
+.BR until ,
+or
+.B select
+loop.  If \fIn\fP is specified, break \fIn\fP levels.
+.I n
+must be \(>= 1.  If
+.I n
+is greater than the number of enclosing loops, all enclosing loops
+are exited.
+The return value is 0 unless \fIn\fP is not greater than or equal to 1.
+.TP
+\fBbuiltin\fP \fIshell\-builtin\fP [\fIarguments\fP]
+Execute the specified shell builtin, passing it
+.IR arguments ,
+and return its exit status.
+This is useful when defining a
+function whose name is the same as a shell builtin,
+retaining the functionality of the builtin within the function.
+The \fBcd\fP builtin is commonly redefined this way.
+The return status is false if
+.I shell\-builtin
+is not a shell builtin command.
+.TP
+\fBcaller\fP [\fIexpr\fP]
+Returns the context of any active subroutine call (a shell function or
+a script executed with the \fB.\fP or \fBsource\fP builtins).
+Without \fIexpr\fP, \fBcaller\fP displays the line number and source
+filename of the current subroutine call.
+If a non-negative integer is supplied as \fIexpr\fP, \fBcaller\fP 
+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 subroutine
+call or \fIexpr\fP does not correspond to a valid position in the
+call stack.
+.TP
+\fBcd\fP [\fB\-L\fP|[\fB\-P\fP [\fB\-e\fP]]] [\fIdir\fP]
+Change the current directory to \fIdir\fP.
+if \fIdir\fP is not supplied, the value of the
+.SM
+.B HOME
+shell variable is the default.
+Any additional arguments following \fIdir\fP are ignored.
+The variable
+.SM
+.B CDPATH
+defines the search path for the directory containing
+.IR dir :
+each directory name in
+.SM
+.B CDPATH
+is searched for \fIdir\fP.
+Alternative directory names in
+.SM
+.B CDPATH
+are separated by a colon (:).  A null directory name in
+.SM
+.B CDPATH
+is the same as the current directory, i.e., ``\fB.\fP''.  If
+.I dir
+begins with a slash (/),
+then
+.SM
+.B CDPATH
+is not used. The
+.B \-P
+option causes \fBcd\fP to use the physical directory structure
+by resolving symbolic links while traversing \fIdir\fP and
+before processing instances of \fI..\fP in \fIdir\fP (see also the
+.B \-P
+option to the
+.B set
+builtin command); the
+.B \-L
+option forces symbolic links to be followed by resolving the link
+after processing instances of \fI..\fP in \fIdir\fP.
+If \fI..\fP appears in \fIdir\fP, it is processed by removing the
+immediately previous pathname component from \fIdir\fP, back to a slash
+or the beginning of \fIdir\fP.
+If the
+.B \-e
+option is supplied with
+.BR \-P ,
+and the current working directory cannot be successfully determined
+after a successful directory change, \fBcd\fP will return an unsuccessful
+status.
+An argument of
+.B \-
+is converted to
+.SM
+.B $OLDPWD
+before the directory change is attempted.
+If a non-empty directory name from
+.SM
+.B CDPATH
+is used, or if
+\fB\-\fP 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 changed;
+false otherwise.
+.TP
+\fBcommand\fP [\fB\-pVv\fP] \fIcommand\fP [\fIarg\fP ...]
+Run
+.I command
+with
+.I args
+suppressing the normal shell function lookup. Only builtin
+commands or commands found in the
+.SM
+.B PATH
+are executed.  If the
+.B \-p
+option is given, the search for
+.I command
+is performed using a default value for
+.SM
+.B PATH
+that is guaranteed to find all of the standard utilities.
+If either the
+.B \-V
+or
+.B \-v
+option is supplied, a description of
+.I command
+is printed.  The
+.B \-v
+option causes a single word indicating the command or filename
+used to invoke
+.I command
+to be displayed; the
+.B \-V
+option produces a more verbose description.
+If the
+.B \-V
+or
+.B \-v
+option is supplied, the exit status is 0 if
+.I command
+was found, and 1 if not.  If neither option is supplied and
+an error occurred or
+.I command
+cannot be found, the exit status is 127.  Otherwise, the exit status of the
+.B command
+builtin is the exit status of
+.IR command .
+.TP
+\fBcompgen\fP [\fIoption\fP] [\fIword\fP]
+Generate possible completion matches for \fIword\fP according to
+the \fIoption\fPs, which may be any option accepted by the
+.B complete
+builtin with the exception of \fB\-p\fP and \fB\-r\fP, and write
+the matches to the standard output.
+When using the \fB\-F\fP or \fB\-C\fP options, the various shell variables
+set by the programmable completion facilities, while available, will not
+have useful values.
+.sp 1
+The matches will be generated in the same way as if the programmable
+completion code had generated them directly from a completion specification
+with the same flags.
+If \fIword\fP is specified, only those completions matching \fIword\fP
+will be displayed.
+.sp 1
+The return value is true unless an invalid option is supplied, or no
+matches were generated.
+.TP
+\fBcomplete\fP [\fB\-abcdefgjksuv\fP] [\fB\-o\fP \fIcomp-option\fP] [\fB\-DE\fP] [\fB\-A\fP \fIaction\fP] [\fB\-G\fP \fIglobpat\fP] [\fB\-W\fP \fIwordlist\fP] [\fB\-F\fP \fIfunction\fP] [\fB\-C\fP \fIcommand\fP]
+.br
+[\fB\-X\fP \fIfilterpat\fP] [\fB\-P\fP \fIprefix\fP] [\fB\-S\fP \fIsuffix\fP] \fIname\fP [\fIname ...\fP]
+.PD 0
+.TP
+\fBcomplete\fP \fB\-pr\fP [\fB\-DE\fP] [\fIname\fP ...]
+.PD
+Specify how arguments to each \fIname\fP should be completed.
+If the \fB\-p\fP option 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 \fB\-r\fP option removes a completion specification for
+each \fIname\fP, or, if no \fIname\fPs are supplied, all
+completion specifications.
+The \fB\-D\fP 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 \fB\-E\fP option indicates that the remaining options and actions should
+apply to ``empty'' command completion; that is, completion attempted on a
+blank line.
+.sp 1
+The process of applying these completion specifications when word completion
+is attempted is described above under \fBProgrammable Completion\fP.
+.sp 1
+Other options, if specified, have the following meanings.
+The arguments to the \fB\-G\fP, \fB\-W\fP, and \fB\-X\fP options
+(and, if necessary, the \fB\-P\fP and \fB\-S\fP options)
+should be quoted to protect them from expansion before the
+.B complete
+builtin is invoked.
+.RS
+.PD 0
+.TP 8
+\fB\-o\fP \fIcomp-option\fP
+The \fIcomp-option\fP controls several aspects of the compspec's behavior
+beyond the simple generation of completions.
+\fIcomp-option\fP may be one of:
+.RS
+.TP 8
+.B bashdefault
+Perform the rest of the default \fBbash\fP completions if the compspec
+generates no matches.
+.TP 8
+.B default
+Use readline's default filename completion if the compspec generates
+no matches.
+.TP 8
+.B dirnames
+Perform directory name completion if the compspec generates no matches.
+.TP 8
+.B filenames
+Tell readline that the compspec generates filenames, so it can perform any
+filename\-specific processing (like adding a slash to directory names,
+quoting special characters, or suppressing trailing spaces).
+Intended to be used with shell functions.
+.TP 8
+.B noquote
+Tell readline not to quote the completed words if they are filenames
+(quoting filenames is the default).
+.TP 8
+.B nospace
+Tell readline not to append a space (the default) to words completed at
+the end of the line.
+.TP 8
+.B plusdirs
+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.
+.RE
+.TP 8
+\fB\-A\fP \fIaction\fP
+The \fIaction\fP may be one of the following to generate a list of possible
+completions:
+.RS
+.TP 8
+.B alias
+Alias names.  May also be specified as \fB\-a\fP.
+.TP 8
+.B arrayvar
+Array variable names.
+.TP 8
+.B binding
+\fBReadline\fP key binding names.
+.TP 8
+.B builtin
+Names of shell builtin commands.  May also be specified as \fB\-b\fP.
+.TP 8
+.B command
+Command names.  May also be specified as \fB\-c\fP.
+.TP 8
+.B directory
+Directory names.  May also be specified as \fB\-d\fP.
+.TP 8
+.B disabled
+Names of disabled shell builtins.
+.TP 8
+.B enabled
+Names of enabled shell builtins.
+.TP 8
+.B export
+Names of exported shell variables.  May also be specified as \fB\-e\fP.
+.TP 8
+.B file
+File names.  May also be specified as \fB\-f\fP.
+.TP 8
+.B function
+Names of shell functions.
+.TP 8
+.B group
+Group names.  May also be specified as \fB\-g\fP.
+.TP 8
+.B helptopic
+Help topics as accepted by the \fBhelp\fP builtin.
+.TP 8
+.B hostname
+Hostnames, as taken from the file specified by the
+.SM
+.B HOSTFILE
+shell variable.
+.TP 8
+.B job
+Job names, if job control is active.  May also be specified as \fB\-j\fP.
+.TP 8
+.B keyword
+Shell reserved words.  May also be specified as \fB\-k\fP.
+.TP 8
+.B running
+Names of running jobs, if job control is active.
+.TP 8
+.B service
+Service names.  May also be specified as \fB\-s\fP.
+.TP 8
+.B setopt
+Valid arguments for the \fB\-o\fP option to the \fBset\fP builtin.
+.TP 8
+.B shopt
+Shell option names as accepted by the \fBshopt\fP builtin.
+.TP 8
+.B signal
+Signal names.
+.TP 8
+.B stopped
+Names of stopped jobs, if job control is active.
+.TP 8
+.B user
+User names.  May also be specified as \fB\-u\fP.
+.TP 8
+.B variable
+Names of all shell variables.  May also be specified as \fB\-v\fP.
+.RE
+.TP 8
+\fB\-C\fP \fIcommand\fP
+\fIcommand\fP is executed in a subshell environment, and its output is
+used as the possible completions.
+.TP 8
+\fB\-F\fP \fIfunction\fP
+The shell function \fIfunction\fP is executed in the current shell
+environment.
+When the function is executed,
+the first argument (\fB$1\fP) is the name of the command whose arguments are
+being completed,
+the second argument (\fB$2\fP) is the word being completed,
+and the third argument (\fB$3\fP) 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
+.SM
+.B COMPREPLY
+array variable.
+.TP 8
+\fB\-G\fP \fIglobpat\fP
+The pathname expansion pattern \fIglobpat\fP is expanded to generate
+the possible completions.
+.TP 8
+\fB\-P\fP \fIprefix\fP
+\fIprefix\fP is added at the beginning of each possible completion
+after all other options have been applied.
+.TP 8
+\fB\-S\fP \fIsuffix\fP
+\fIsuffix\fP is appended to each possible completion
+after all other options have been applied.
+.TP 8
+\fB\-W\fP \fIwordlist\fP
+The \fIwordlist\fP is split using the characters in the
+.SM
+.B IFS
+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 completed.
+.TP 8
+\fB\-X\fP \fIfilterpat\fP
+\fIfilterpat\fP is a pattern as used for pathname expansion.
+It is applied to the list of possible completions generated by the
+preceding options and arguments, and each completion matching
+\fIfilterpat\fP is removed from the list.
+A leading \fB!\fP in \fIfilterpat\fP negates the pattern; in this
+case, any completion not matching \fIfilterpat\fP is removed.
+.PD
+.PP
+The return value is true unless an invalid option is supplied, an option
+other than \fB\-p\fP or \fB\-r\fP is supplied without a \fIname\fP
+argument, an attempt is made to remove a completion specification for
+a \fIname\fP for which no specification exists, or
+an error occurs adding a completion specification.
+.RE
+.TP
+\fBcompopt\fP [\fB\-o\fP \fIoption\fP] [\fB\-DE\fP] [\fB+o\fP \fIoption\fP] [\fIname\fP]
+Modify completion options for each \fIname\fP according to the
+\fIoption\fPs, or for the
+currently-executing completion if no \fIname\fPs are supplied.
+If no \fIoption\fPs are given, display the completion options for each
+\fIname\fP or the current completion.
+The possible values of \fIoption\fP are those valid for the \fBcomplete\fP
+builtin described above.
+The \fB\-D\fP 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 \fB\-E\fP option indicates that the remaining options should
+apply to ``empty'' command completion; that is, completion attempted on a
+blank line.
+.sp 1
+The return value is true unless an invalid option is supplied, an attempt
+is made to modify the options for a \fIname\fP for which no completion
+specification exists, or an output error occurs.
+.TP
+\fBcontinue\fP [\fIn\fP]
+Resume the next iteration of the enclosing
+.BR for ,
+.BR while ,
+.BR until ,
+or
+.B select
+loop.
+If
+.I n
+is specified, resume at the \fIn\fPth enclosing loop.
+.I n
+must be \(>= 1.  If
+.I n
+is greater than the number of enclosing loops, the last enclosing loop
+(the ``top-level'' loop) is resumed.
+The return value is 0 unless \fIn\fP is not greater than or equal to 1.
+.TP
+\fBdeclare\fP [\fB\-aAfFgilnrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
+.PD 0
+.TP
+\fBtypeset\fP [\fB\-aAfFgilnrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
+.PD
+Declare variables and/or give them attributes.
+If no \fIname\fPs are given then display the values of variables.
+The
+.B \-p
+option will display the attributes and values of each
+.IR name .
+When
+.B \-p
+is used with \fIname\fP arguments, additional options are ignored.
+When
+.B \-p
+is supplied without \fIname\fP 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 \fB\-p\fP, \fBdeclare\fP will display
+the attributes and values of all shell variables.  The \fB\-f\fP option
+will restrict the display to shell functions.
+The
+.B \-F
+option inhibits the display of function definitions; only the
+function name and attributes are printed.
+If the \fBextdebug\fP shell option is enabled using \fBshopt\fP,
+the source file name and line number where the function is defined
+are displayed as well.  The
+.B \-F
+option implies
+.BR \-f .
+The
+.B \-g
+option forces variables to be created or modified at the global scope,
+even when \fBdeclare\fP is executed in a shell function.
+It is ignored in all other cases.
+The following options can
+be used to restrict output to variables with the specified attribute or
+to give variables attributes:
+.RS
+.PD 0
+.TP
+.B \-a
+Each \fIname\fP is an indexed array variable (see
+.B Arrays
+above).
+.TP
+.B \-A
+Each \fIname\fP is an associative array variable (see
+.B Arrays
+above).
+.TP
+.B \-f
+Use function names only.
+.TP
+.B \-i
+The variable is treated as an integer; arithmetic evaluation (see
+.SM
+.B "ARITHMETIC EVALUATION"
+above) is performed when the variable is assigned a value.
+.TP
+.B \-l
+When the variable is assigned a value, all upper-case characters are
+converted to lower-case.
+The upper-case attribute is disabled.
+.TP
+.B \-n
+Give each \fIname\fP the \fInameref\fP attribute, making
+it a name reference to another variable.
+That other variable is defined by the value of \fIname\fP.
+All references and assignments to \fIname\fP, except for changing the
+\fB\-n\fP attribute itself, are performed on the variable referenced by
+\fIname\fP's value.
+The \fB\-n\fP attribute cannot be applied to array variables.
+.TP
+.B \-r
+Make \fIname\fPs readonly.  These names cannot then be assigned values
+by subsequent assignment statements or unset.
+.TP
+.B \-t
+Give each \fIname\fP the \fItrace\fP attribute.
+Traced functions inherit the \fBDEBUG\fP and \fBRETURN\fP traps from
+the calling shell.
+The trace attribute has no special meaning for variables.
+.TP
+.B \-u
+When the variable is assigned a value, all lower-case characters are
+converted to upper-case.
+The lower-case attribute is disabled.
+.TP
+.B \-x
+Mark \fIname\fPs for export to subsequent commands via the environment.
+.PD
+.PP
+Using `+' instead of `\-'
+turns off the attribute instead,
+with the exceptions that \fB+a\fP
+may not be used to destroy an array variable and \fB+r\fP will not
+remove the readonly attribute.
+When used in a function,
+.B declare
+and
+.B typeset
+make each
+\fIname\fP local, as with the
+.B local
+command,
+unless the \fB\-g\fP option is supplied.
+If a variable name is followed by =\fIvalue\fP, the value of
+the variable is set to \fIvalue\fP.
+The return value is 0 unless an invalid option is encountered,
+an attempt is made to define a function using
+.if n ``\-f foo=bar'',
+.if t \f(CW\-f foo=bar\fP,
+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
+.B Arrays
+above), one of the \fInames\fP is not a valid shell variable name,
+an attempt is made to turn off readonly 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 \fB\-f\fP.
+.RE
+.TP
+.B dirs [\fB\-clpv\fP] [+\fIn\fP] [\-\fIn\fP]
+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 
+.B pushd
+command; the
+.B popd
+command removes entries from the list.
+.RS
+.PD 0
+.TP
+.B \-c
+Clears the directory stack by deleting all of the entries.
+.TP
+.B \-l
+Produces a listing using full pathnames;
+the default listing format uses a tilde to denote the home directory.
+.TP
+.B \-p
+Print the directory stack with one entry per line.
+.TP
+.B \-v
+Print the directory stack with one entry per line,
+prefixing each entry with its index in the stack.
+.TP
+\fB+\fP\fIn\fP
+Displays the \fIn\fPth entry counting from the left of the list
+shown by
+.B dirs
+when invoked without options, starting with zero.
+.TP
+\fB\-\fP\fIn\fP
+Displays the \fIn\fPth entry counting from the right of the list
+shown by
+.B dirs
+when invoked without options, starting with zero.
+.PD
+.PP
+The return value is 0 unless an
+invalid option is supplied or \fIn\fP indexes beyond the end
+of the directory stack.
+.RE
+.TP
+\fBdisown\fP [\fB\-ar\fP] [\fB\-h\fP] [\fIjobspec\fP ...]
+Without options, remove each
+.I jobspec
+from the table of active jobs.
+If
+.I jobspec
+is not present, and neither \fB\-a\fP nor \fB\-r\fP is supplied,
+the shell's notion of the \fIcurrent job\fP is used.
+If the \fB\-h\fP option is given, each
+.I jobspec
+is not removed from the table, but is marked so that
+.SM
+.B SIGHUP
+is not sent to the job if the shell receives a
+.SM
+.BR SIGHUP .
+If no
+.I jobspec
+is present, and neither the
+.B \-a
+nor the
+.B \-r
+option is supplied, the \fIcurrent job\fP is used.
+If no
+.I jobspec
+is supplied, the
+.B \-a
+option means to remove or mark all jobs; the
+.B \-r
+option without a
+.I jobspec
+argument restricts operation to running jobs.
+The return value is 0 unless a
+.I jobspec
+does not specify a valid job.
+.TP
+\fBecho\fP [\fB\-neE\fP] [\fIarg\fP ...]
+Output the \fIarg\fPs, separated by spaces, followed by a newline.
+The return status is 0 unless a write error occurs.
+If \fB\-n\fP is specified, the trailing newline is
+suppressed.  If the \fB\-e\fP option is given, interpretation of
+the following backslash-escaped characters is enabled.  The
+.B \-E
+option disables the interpretation of these escape characters,
+even on systems where they are interpreted by default.
+The \fBxpg_echo\fP shell option may be used to
+dynamically determine whether or not \fBecho\fP expands these
+escape characters by default.
+.B echo
+does not interpret \fB\-\-\fP to mean the end of options.
+.B echo
+interprets the following escape sequences:
+.RS
+.PD 0
+.TP
+.B \ea
+alert (bell)
+.TP
+.B \eb
+backspace
+.TP
+.B \ec
+suppress further output
+.TP
+.B \ee
+.TP
+.B \eE
+an escape character
+.TP
+.B \ef
+form feed
+.TP
+.B \en
+new line
+.TP
+.B \er
+carriage return
+.TP
+.B \et
+horizontal tab
+.TP
+.B \ev
+vertical tab
+.TP
+.B \e\e
+backslash
+.TP
+.B \e0\fInnn\fP
+the eight-bit character whose value is the octal value \fInnn\fP
+(zero to three octal digits)
+.TP
+.B \ex\fIHH\fP
+the eight-bit character whose value is the hexadecimal value \fIHH\fP
+(one or two hex digits)
+.TP
+.B \eu\fIHHHH\fP
+the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value
+\fIHHHH\fP (one to four hex digits)
+.TP
+.B \eU\fIHHHHHHHH\fP
+the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value
+\fIHHHHHHHH\fP (one to eight hex digits)
+.PD
+.RE
+.TP
+\fBenable\fP [\fB\-a\fP] [\fB\-dnps\fP] [\fB\-f\fP \fIfilename\fP] [\fIname\fP ...]
+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 \fB\-n\fP is used, each \fIname\fP
+is disabled; otherwise,
+\fInames\fP are enabled.  For example, to use the
+.B test
+binary found via the
+.SM
+.B PATH
+instead of the shell builtin version, run
+.if t \f(CWenable -n test\fP.
+.if n ``enable -n test''.
+The
+.B \-f
+option means to load the new builtin command
+.I name
+from shared object
+.IR filename ,
+on systems that support dynamic loading.  The
+.B \-d
+option will delete a builtin previously loaded with
+.BR \-f .
+If no \fIname\fP arguments are given, or if the
+.B \-p
+option is supplied, a list of shell builtins is printed.
+With no other option arguments, the list consists of all enabled
+shell builtins.
+If \fB\-n\fP is supplied, only disabled builtins are printed.
+If \fB\-a\fP is supplied, the list printed includes all builtins, with an
+indication of whether or not each is enabled.
+If \fB\-s\fP is supplied, the output is restricted to the POSIX
+\fIspecial\fP builtins.
+The return value is 0 unless a
+.I name
+is not a shell builtin or there is an error loading a new builtin
+from a shared object.
+.TP
+\fBeval\fP [\fIarg\fP ...]
+The \fIarg\fPs are read and concatenated together into a single
+command.  This command is then read and executed by the shell, and
+its exit status is returned as the value of
+.BR eval .
+If there are no
+.IR args ,
+or only null arguments,
+.B eval
+returns 0.
+.TP
+\fBexec\fP [\fB\-cl\fP] [\fB\-a\fP \fIname\fP] [\fIcommand\fP [\fIarguments\fP]]
+If
+.I command
+is specified, it replaces the shell.
+No new process is created.  The
+.I arguments
+become the arguments to \fIcommand\fP.
+If the
+.B \-l
+option is supplied,
+the shell places a dash at the beginning of the zeroth argument passed to 
+.IR command .
+This is what
+.IR login (1)
+does.  The
+.B \-c
+option causes
+.I command
+to be executed with an empty environment.  If
+.B \-a
+is supplied, the shell passes
+.I name
+as the zeroth argument to the executed command.
+If
+.I command
+cannot be executed for some reason, a non-interactive shell exits,
+unless the
+.B execfail
+shell option
+is enabled.  In that case, it returns failure.
+An interactive shell returns failure if the file cannot be executed.
+If
+.I command
+is not specified, any redirections take effect in the current shell,
+and the return status is 0.  If there is a redirection error, the
+return status is 1.
+.TP
+\fBexit\fP [\fIn\fP]
+Cause the shell to exit
+with a status of \fIn\fP.  If
+.I n
+is omitted, the exit status
+is that of the last command executed.
+A trap on
+.SM
+.B EXIT
+is executed before the shell terminates.
+.TP
+\fBexport\fP [\fB\-fn\fP\^] [\fIname\fP[=\fIword\fP]] ...
+.PD 0
+.TP
+.B export \-p
+.PD
+The supplied
+.I names
+are marked for automatic export to the environment of
+subsequently executed commands.  If the 
+.B \-f
+option is given,
+the 
+.I names
+refer to functions.
+If no
+.I names
+are given, or if the
+.B \-p
+option is supplied, a list
+of names of all exported variables is printed.
+The
+.B \-n
+option causes the export property to be removed from each
+\fIname\fP.
+If a variable name is followed by =\fIword\fP, the value of
+the variable is set to \fIword\fP.
+.B export
+returns an exit status of 0 unless an invalid option is
+encountered,
+one of the \fInames\fP is not a valid shell variable name, or
+.B \-f
+is supplied with a
+.I name
+that is not a function.
+.TP
+\fBfc\fP [\fB\-e\fP \fIename\fP] [\fB\-lnr\fP] [\fIfirst\fP] [\fIlast\fP]
+.PD 0
+.TP
+\fBfc\fP \fB\-s\fP [\fIpat\fP=\fIrep\fP] [\fIcmd\fP]
+.PD
+The first form selects a range of commands from
+.I first
+to
+.I last
+from the history list and displays or edits and re-executes them.
+.I First
+and
+.I last
+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 
+.I last
+is not specified it is set to
+the current command for listing (so that
+.if n ``fc \-l \-10''
+.if t \f(CWfc \-l \-10\fP
+prints the last 10 commands) and to
+.I first
+otherwise.
+If
+.I first
+is not specified it is set to the previous
+command for editing and \-16 for listing.
+.sp 1
+The
+.B \-n
+option suppresses
+the command numbers when listing.  The
+.B \-r
+option reverses the order of
+the commands.  If the
+.B \-l
+option is given,
+the commands are listed on
+standard output.  Otherwise, the editor given by
+.I ename
+is invoked
+on a file containing those commands.  If
+.I ename
+is not given, the
+value of the
+.SM
+.B FCEDIT
+variable is used, and
+the value of
+.SM
+.B EDITOR
+if
+.SM
+.B FCEDIT
+is not set.  If neither variable is set,
+.FN vi
+is used.  When editing is complete, the edited commands are
+echoed and executed.
+.sp 1
+In the second form, \fIcommand\fP is re-executed after each instance
+of \fIpat\fP is replaced by \fIrep\fP.
+\fICommand\fP is intepreted the same as \fIfirst\fP above.
+A useful alias to use with this is
+.if n ``r="fc -s"'',
+.if t \f(CWr='fc \-s'\fP,
+so that typing
+.if n ``r cc''
+.if t \f(CWr cc\fP
+runs the last command beginning with
+.if n ``cc''
+.if t \f(CWcc\fP
+and typing
+.if n ``r''
+.if t \f(CWr\fP
+re-executes the last command.
+.sp 1
+If the first form is used, the return value is 0 unless an invalid
+option is encountered or
+.I first
+or
+.I last
+specify history lines out of range.
+If the
+.B \-e
+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-executed, unless
+.I cmd
+does not specify a valid history line, in which case
+.B fc
+returns failure.
+.TP
+\fBfg\fP [\fIjobspec\fP]
+Resume
+.I jobspec
+in the foreground, and make it the current job.
+If
+.I jobspec
+is not present, the shell's notion of the \fIcurrent job\fP 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
+.I jobspec
+does not specify a valid job or
+.I jobspec
+specifies a job that was started without job control.
+.TP
+\fBgetopts\fP \fIoptstring\fP \fIname\fP [\fIargs\fP]
+.B getopts
+is used by shell procedures to parse positional parameters.
+.I optstring
+contains the option characters to be recognized; 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,
+.B getopts
+places the next option in the shell variable
+.IR name ,
+initializing
+.I name
+if it does not exist,
+and the index of the next argument to be processed into the
+variable
+.SM
+.BR OPTIND .
+.SM
+.B OPTIND
+is initialized to 1 each time the shell or a shell script
+is invoked.  When an option requires an argument,
+.B getopts
+places that argument into the variable
+.SM
+.BR OPTARG .
+The shell does not reset
+.SM
+.B OPTIND
+automatically; it must be manually reset between multiple
+calls to
+.B getopts
+within the same shell invocation if a new set of parameters
+is to be used.
+.sp 1
+When the end of options is encountered, \fBgetopts\fP exits with a
+return value greater than zero.
+.SM
+.B OPTIND
+is set to the index of the first non-option argument,
+and \fIname\fP is set to ?.
+.sp 1
+.B getopts
+normally parses the positional parameters, but if more arguments are
+given in
+.IR args ,
+.B getopts
+parses those instead.
+.sp 1
+.B getopts
+can report errors in two ways.  If the first character of
+.I optstring
+is a colon,
+.I silent
+error reporting is used.  In normal operation, diagnostic messages
+are printed when invalid options or missing option arguments are
+encountered.
+If the variable
+.SM
+.B OPTERR
+is set to 0, no error messages will be displayed, even if the first
+character of 
+.I optstring
+is not a colon.
+.sp 1
+If an invalid option is seen,
+.B getopts
+places ? into
+.I name
+and, if not silent,
+prints an error message and unsets
+.SM
+.BR OPTARG .
+If
+.B getopts
+is silent,
+the option character found is placed in
+.SM
+.B OPTARG
+and no diagnostic message is printed.
+.sp 1
+If a required argument is not found, and
+.B getopts
+is not silent,
+a question mark (\^\fB?\fP\^) is placed in
+.IR name ,
+.SM
+.B OPTARG
+is unset, and a diagnostic message is printed.
+If
+.B getopts
+is silent, then a colon (\^\fB:\fP\^) is placed in
+.I name
+and
+.SM
+.B OPTARG
+is set to the option character found.
+.sp 1
+.B getopts
+returns true if an option, specified or unspecified, is found.
+It returns false if the end of options is encountered or an
+error occurs.
+.TP
+\fBhash\fP [\fB\-lr\fP] [\fB\-p\fP \fIfilename\fP] [\fB\-dt\fP] [\fIname\fP]
+Each time \fBhash\fP is invoked,
+the full pathname of the command 
+.I name
+is determined by searching
+the directories in
+.B $PATH
+and remembered.  Any previously-remembered pathname is discarded.
+If the
+.B \-p
+option is supplied, no path search is performed, and
+.I filename
+is used as the full filename of the command.
+The
+.B \-r
+option causes the shell to forget all
+remembered locations.
+The
+.B \-d
+option causes the shell to forget the remembered location of each \fIname\fP.
+If the
+.B \-t
+option is supplied, the full pathname to which each \fIname\fP corresponds
+is printed.  If multiple \fIname\fP arguments are supplied with \fB\-t\fP,
+the \fIname\fP is printed before the hashed full pathname.
+The
+.B \-l
+option causes output to be displayed in a format that may be reused as input.
+If no arguments are given, or if only \fB\-l\fP is supplied,
+information about remembered commands is printed.
+The return status is true unless a
+.I name
+is not found or an invalid option is supplied.
+.TP
+\fBhelp\fP [\fB\-dms\fP] [\fIpattern\fP]
+Display helpful information about builtin commands.  If
+.I pattern
+is specified,
+.B help
+gives detailed help on all commands matching
+.IR pattern ;
+otherwise help for all the builtins and shell control structures
+is printed.
+.RS
+.PD 0
+.TP
+.B \-d
+Display a short description of each \fIpattern\fP
+.TP
+.B \-m
+Display the description of each \fIpattern\fP in a manpage-like format
+.TP
+.B \-s
+Display only a short usage synopsis for each \fIpattern\fP
+.PD
+.PP
+The return status is 0 unless no command matches
+.IR pattern .
+.RE
+.TP
+\fBhistory [\fIn\fP]
+.PD 0
+.TP
+\fBhistory\fP \fB\-c\fP
+.TP
+\fBhistory \-d\fP \fIoffset\fP
+.TP
+\fBhistory\fP \fB\-anrw\fP [\fIfilename\fP]
+.TP
+\fBhistory\fP \fB\-p\fP \fIarg\fP [\fIarg ...\fP]
+.TP
+\fBhistory\fP \fB\-s\fP \fIarg\fP [\fIarg ...\fP]
+.PD
+With no options, display the command
+history list with line numbers.  Lines listed
+with a 
+.B *
+have been modified.  An argument of
+.I n
+lists only the last
+.I n
+lines.
+If the shell variable
+.SM
+.B HISTTIMEFORMAT
+is set and not null,
+it is used as a format string for \fIstrftime\fP(3) to display
+the time stamp associated with each displayed history entry.
+No intervening blank is printed between the formatted time stamp
+and the history line.
+If \fIfilename\fP is supplied, it is used as the
+name of the history file; if not, the value of
+.SM
+.B HISTFILE
+is used.  Options, if supplied, have the following meanings:
+.RS
+.PD 0
+.TP
+.B \-c
+Clear the history list by deleting all the entries.
+.TP
+\fB\-d\fP \fIoffset\fP
+Delete the history entry at position \fIoffset\fP.
+.TP
+.B \-a
+Append the ``new'' history lines (history lines entered since the
+beginning of the current \fBbash\fP session) to the history file.
+.TP
+.B \-n
+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 \fBbash\fP session.
+.TP
+.B \-r
+Read the contents of the history file
+and append them to the current history list.
+.TP
+.B \-w
+Write the current history list to the history file, overwriting the
+history file's contents.
+.TP
+.B \-p
+Perform history substitution on the following \fIargs\fP and display
+the result on the standard output.
+Does not store the results in the history list.
+Each \fIarg\fP must be quoted to disable normal history expansion.
+.TP
+.B \-s
+Store the
+.I args
+in the history list as a single entry.  The last command in the
+history list is removed before the
+.I args
+are added.
+.PD
+.PP
+If the
+.SM
+.B HISTTIMEFORMAT
+variable is set, the time stamp information
+associated with each history entry is written to the history 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
+\fIoffset\fP is supplied as an argument to \fB\-d\fP, or the
+history expansion supplied as an argument to \fB\-p\fP fails.
+.RE
+.TP
+\fBjobs\fP [\fB\-lnprs\fP] [ \fIjobspec\fP ... ]
+.PD 0
+.TP
+\fBjobs\fP \fB\-x\fP \fIcommand\fP [ \fIargs\fP ... ]
+.PD
+The first form lists the active jobs.  The options have the following
+meanings:
+.RS
+.PD 0
+.TP
+.B \-l
+List process IDs
+in addition to the normal information.
+.TP
+.B \-n
+Display information only about jobs that have changed status since
+the user was last notified of their status.
+.TP
+.B \-p
+List only the process ID of the job's process group
+leader.
+.TP
+.B \-r
+Display only running jobs.
+.TP
+.B \-s
+Display only stopped jobs.
+.PD
+.PP
+If
+.I jobspec
+is given, output is restricted to information about that job.
+The return status is 0 unless an invalid option is encountered
+or an invalid
+.I jobspec
+is supplied.
+.PP
+If the
+.B \-x
+option is supplied,
+.B jobs
+replaces any
+.I jobspec
+found in
+.I command
+or
+.I args
+with the corresponding process group ID, and executes
+.I command
+passing it
+.IR args ,
+returning its exit status.
+.RE
+.TP
+\fBkill\fP [\fB\-s\fP \fIsigspec\fP | \fB\-n\fP \fIsignum\fP | \fB\-\fP\fIsigspec\fP] [\fIpid\fP | \fIjobspec\fP] ...
+.PD 0
+.TP
+\fBkill\fP \fB\-l\fP [\fIsigspec\fP | \fIexit_status\fP]
+.PD
+Send the signal named by
+.I sigspec
+or
+.I signum
+to the processes named by
+.I pid
+or
+.IR jobspec .
+.I sigspec
+is either a case-insensitive signal name such as
+.SM
+.B SIGKILL
+(with or without the
+.SM
+.B SIG
+prefix) or a signal number;
+.I signum
+is a signal number.
+If
+.I sigspec
+is not present, then
+.SM
+.B SIGTERM
+is assumed.
+An argument of
+.B \-l
+lists the signal names.
+If any arguments are supplied when
+.B \-l
+is given, the names of the signals corresponding to the arguments are
+listed, and the return status is 0.
+The \fIexit_status\fP argument to
+.B \-l
+is a number specifying either a signal number or the exit status of
+a process terminated by a signal.
+.B kill
+returns true if at least one signal was successfully sent, or false
+if an error occurs or an invalid option is encountered.
+.TP
+\fBlet\fP \fIarg\fP [\fIarg\fP ...]
+Each
+.I arg
+is an arithmetic expression to be evaluated (see
+.SM
+.B "ARITHMETIC EVALUATION"
+above).
+If the last
+.I arg
+evaluates to 0,
+.B let
+returns 1; 0 is returned otherwise.
+.TP
+\fBlocal\fP [\fIoption\fP] [\fIname\fP[=\fIvalue\fP] ...]
+For each argument, a local variable named
+.I name 
+is created, and assigned
+.IR value .
+The \fIoption\fP can be any of the options accepted by \fBdeclare\fP.
+When
+.B local
+is used within a function, it causes the variable
+.I name
+to have a visible scope restricted to that function and its children.
+With no operands,
+.B local
+writes a list of local variables to the standard output.  It is
+an error to use
+.B local
+when not within a function.  The return status is 0 unless
+.B local
+is used outside a function, an invalid
+.I name
+is supplied, or
+\fIname\fP is a readonly variable.
+.TP
+.B logout
+Exit a login shell.
+.TP
+\fBmapfile\fP [\fB\-n\fP \fIcount\fP] [\fB\-O\fP \fIorigin\fP] [\fB\-s\fP \fIcount\fP] [\fB\-t\fP] [\fB\-u\fP \fIfd\fP] [\fB\-C\fP \fIcallback\fP] [\fB\-c\fP \fIquantum\fP] [\fIarray\fP]
+.PD 0
+.TP
+\fBreadarray\fP [\fB\-n\fP \fIcount\fP] [\fB\-O\fP \fIorigin\fP] [\fB\-s\fP \fIcount\fP] [\fB\-t\fP] [\fB\-u\fP \fIfd\fP] [\fB\-C\fP \fIcallback\fP] [\fB\-c\fP \fIquantum\fP] [\fIarray\fP]
+.PD
+Read lines from the standard input into the indexed array variable
+.IR array ,
+or from file descriptor 
+.IR fd
+if the 
+.B \-u
+option is supplied.
+The variable
+.SM
+.B MAPFILE
+is the default \fIarray\fP.
+Options, if supplied, have the following meanings:
+.RS
+.PD 0
+.TP
+.B \-n
+Copy at most
+.I count
+lines.  If \fIcount\fP is 0, all lines are copied.
+.TP
+.B \-O
+Begin assigning to
+.I array
+at index
+.IR origin .
+The default index is 0.
+.TP
+.B \-s
+Discard the first \fIcount\fP lines read.
+.TP
+.B \-t
+Remove a trailing newline from each line read.
+.TP
+.B \-u
+Read lines from file descriptor \fIfd\fP instead of the standard input.
+.TP
+.B \-C
+Evaluate
+.I callback
+each time \fIquantum\fP lines are read.  The \fB\-c\fP option specifies
+.IR quantum .
+.TP
+.B \-c
+Specify the number of lines read between each call to
+.IR callback .
+.PD
+.PP
+If
+.B \-C
+is specified without 
+.BR \-c ,
+the default quantum is 5000.
+When \fIcallback\fP is evaluated, it is supplied the index of the next
+array element to be assigned and the line to be assigned to that element
+as additional arguments.
+\fIcallback\fP is evaluated after the line is read but before the 
+array element is assigned.
+.PP
+If not supplied with an explicit origin, \fBmapfile\fP will clear \fIarray\fP
+before assigning to it.
+.PP
+\fBmapfile\fP returns successfully unless an invalid option or option
+argument is supplied, \fIarray\fP is invalid or unassignable, or if
+\fIarray\fP is not an indexed array.
+.RE
+.TP
+\fBpopd\fP [\-\fBn\fP] [+\fIn\fP] [\-\fIn\fP]
+Removes entries from the directory stack.  With no arguments,
+removes the top directory from the stack, and performs a
+.B cd
+to the new top directory.
+Arguments, if supplied, have the following meanings:
+.RS
+.PD 0
+.TP
+.B \-n
+Suppresses the normal change of directory when removing directories
+from the stack, so that only the stack is manipulated.
+.TP
+\fB+\fP\fIn\fP
+Removes the \fIn\fPth entry counting from the left of the list
+shown by
+.BR dirs ,
+starting with zero.  For example:
+.if n ``popd +0''
+.if t \f(CWpopd +0\fP
+removes the first directory,
+.if n ``popd +1''
+.if t \f(CWpopd +1\fP
+the second.
+.TP
+\fB\-\fP\fIn\fP
+Removes the \fIn\fPth entry counting from the right of the list
+shown by
+.BR dirs ,
+starting with zero.  For example:
+.if n ``popd -0''
+.if t \f(CWpopd -0\fP
+removes the last directory,
+.if n ``popd -1''
+.if t \f(CWpopd -1\fP
+the next to last.
+.PD
+.PP
+If the
+.B popd
+command is successful, a 
+.B dirs
+is performed as well, and the return status is 0.
+.B popd
+returns false if an invalid option is encountered, the directory stack
+is empty, a non-existent directory stack entry is specified, or the
+directory change fails.
+.RE
+.TP
+\fBprintf\fP [\fB\-v\fP \fIvar\fP] \fIformat\fP [\fIarguments\fP]
+Write the formatted \fIarguments\fP to the standard output under the
+control of the \fIformat\fP.
+The \fB\-v\fP option causes the output to be assigned to the variable
+\fIvar\fP rather than being printed to the standard output.
+.sp 1
+The \fIformat\fP is a character string which contains three types of objects:
+plain characters, which are simply copied to standard output, character
+escape sequences, which are converted and copied to the standard output, and
+format specifications, each of which causes printing of the next successive
+\fIargument\fP.
+In addition to the standard \fIprintf\fP(1) format specifications,
+\fBprintf\fP interprets the following extensions:
+.RS
+.PD 0
+.TP
+.B %b
+causes
+\fBprintf\fP to expand backslash escape sequences in the corresponding
+\fIargument\fP (except that \fB\ec\fP terminates output, backslashes in
+\fB\e\(aq\fP, \fB\e"\fP, and \fB\e?\fP are not removed, and octal escapes
+beginning with \fB\e0\fP may contain up to four digits).
+.TP
+.B %q
+causes \fBprintf\fP to output the corresponding
+\fIargument\fP in a format that can be reused as shell input.
+.TP
+.B %(\fIdatefmt\fP)T
+causes \fBprintf\fP to output the date-time string resulting from using
+\fIdatefmt\fP as a format string for \fIstrftime\fP(3).
+The corresponding \fIargument\fP is an integer representing the number of
+seconds since the epoch.
+Two special argument values may be used: -1 represents the current
+time, and -2 represents the time the shell was invoked.
+If no argument is specified, conversion behaves as if -1 had been given.
+This is an exception to the usual \fBprintf\fP behavior.
+.PD
+.PP
+Arguments to non-string format specifiers are treated as C constants,
+except that a leading plus or minus sign is allowed, and if the leading
+character is a single or double quote, the value is the ASCII value of
+the following character.
+.PP
+The \fIformat\fP is reused as necessary to consume all of the \fIarguments\fP.
+If the \fIformat\fP requires more \fIarguments\fP than are supplied, the
+extra format specifications behave as if a zero value or null string, as
+appropriate, had been supplied.
+The return value is zero on success, non-zero on failure.
+.RE
+.TP
+\fBpushd\fP [\fB\-n\fP] [+\fIn\fP] [\-\fIn\fP]
+.PD 0
+.TP
+\fBpushd\fP [\fB\-n\fP] [\fIdir\fP]
+.PD
+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, if supplied, have the following meanings:
+.RS
+.PD 0
+.TP
+.B \-n
+Suppresses the normal change of directory when adding directories
+to the stack, so that only the stack is manipulated.
+.TP
+\fB+\fP\fIn\fP
+Rotates the stack so that the \fIn\fPth directory
+(counting from the left of the list shown by
+.BR dirs ,
+starting with zero)
+is at the top.
+.TP
+\fB\-\fP\fIn\fP
+Rotates the stack so that the \fIn\fPth directory
+(counting from the right of the list shown by
+.BR dirs ,
+starting with zero) is at the top.
+.TP
+.I dir
+Adds
+.I dir
+to the directory stack at the top, making it the
+new current working directory as if it had been supplied as the argument
+to the \fBcd\fP builtin.
+.PD
+.PP
+If the
+.B pushd
+command is successful, a 
+.B dirs
+is performed as well.
+If the first form is used,
+.B pushd
+returns 0 unless the cd to
+.I dir
+fails.  With the second form,
+.B pushd
+returns 0 unless the directory stack is empty,
+a non-existent directory stack element is specified,
+or the directory change to the specified new current directory
+fails.
+.RE
+.TP
+\fBpwd\fP [\fB\-LP\fP]
+Print the absolute pathname of the current working directory.
+The pathname printed contains no symbolic links if the
+.B \-P
+option is supplied or the 
+.B \-o physical
+option to the
+.B set
+builtin command is enabled.
+If the
+.B \-L
+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.
+.TP
+\fBread\fP [\fB\-ers\fP] [\fB\-a\fP \fIaname\fP] [\fB\-d\fP \fIdelim\fP] [\fB\-i\fP \fItext\fP] [\fB\-n\fP \fInchars\fP] [\fB\-N\fP \fInchars\fP] [\fB\-p\fP \fIprompt\fP] [\fB\-t\fP \fItimeout\fP] [\fB\-u\fP \fIfd\fP] [\fIname\fP ...]
+One line is read from the standard input, or from the file descriptor
+\fIfd\fP supplied as an argument to the \fB\-u\fP option, and the first word
+is assigned to the first
+.IR name ,
+the second word to the second
+.IR name ,
+and so on, with leftover words and their intervening separators assigned
+to the last
+.IR name .
+If there are fewer words read from the input stream than names,
+the remaining names are assigned empty values.
+The characters in 
+.SM
+.B IFS
+are used to split the line into words using the same rules the shell
+uses for expansion (described above under \fBWord Splitting\fP).
+The backslash character (\fB\e\fP) may be used to remove any special
+meaning for the next character read and for line continuation.
+Options, if supplied, have the following meanings:
+.RS
+.PD 0
+.TP
+.B \-a \fIaname\fP
+The words are assigned to sequential indices
+of the array variable
+.IR aname ,
+starting at 0.
+.I aname
+is unset before any new values are assigned.
+Other \fIname\fP arguments are ignored.
+.TP
+.B \-d \fIdelim\fP
+The first character of \fIdelim\fP is used to terminate the input line,
+rather than newline.
+.TP
+.B \-e
+If the standard input
+is coming from a terminal,
+.B readline
+(see
+.SM
+.B READLINE
+above) is used to obtain the line.
+Readline uses the current (or default, if line editing was not previously
+active) editing settings.
+.TP
+.B \-i \fItext\fP
+If
+.B readline
+is being used to read the line, \fItext\fP is placed into the editing
+buffer before editing begins.
+.TP
+.B \-n \fInchars\fP
+\fBread\fP returns after reading \fInchars\fP characters rather than
+waiting for a complete line of input, but honor a delimiter if fewer
+than \fInchars\fP characters are read before the delimiter.
+.TP
+.B \-N \fInchars\fP
+\fBread\fP returns after reading exactly \fInchars\fP characters rather
+than waiting for a complete line of input, unless EOF is encountered or
+\fBread\fP times out.
+Delimiter characters encountered in the input are
+not treated specially and do not cause \fBread\fP to return until
+\fInchars\fP characters are read.
+.TP
+.B \-p \fIprompt\fP
+Display \fIprompt\fP on standard error, without a
+trailing newline, before attempting to read any input.  The prompt
+is displayed only if input is coming from a terminal.
+.TP
+.B \-r
+Backslash does not act as an escape character.
+The backslash is considered to be part of the line.
+In particular, a backslash-newline pair may not be used as a line
+continuation.
+.TP
+.B \-s
+Silent mode.  If input is coming from a terminal, characters are
+not echoed.
+.TP
+.B \-t \fItimeout\fP
+Cause \fBread\fP to time out and return failure if a complete line of
+input (or a specified number of characters)
+is not read within \fItimeout\fP seconds.
+\fItimeout\fP may be a decimal number with a fractional portion following
+the decimal point.
+This option is only effective if \fBread\fP is reading input from a
+terminal, pipe, or other special file; it has no effect when reading
+from regular files.
+If \fBread\fP times out, \fBread\fP saves any partial input read into
+the specified variable \fIname\fP.
+If \fItimeout\fP is 0, \fBread\fP returns immediately, without trying to
+read any data.  The exit status is 0 if input is available on
+the specified file descriptor, non-zero otherwise.
+The exit status is greater than 128 if the timeout is exceeded.
+.TP
+.B \-u \fIfd\fP
+Read input from file descriptor \fIfd\fP.
+.PD
+.PP
+If no
+.I names
+are supplied, the line read is assigned to the variable
+.SM
+.BR REPLY .
+The return code is zero, unless end-of-file is encountered, \fBread\fP
+times out (in which case the return code is greater than 128),
+a variable assignment error (such as assigning to a readonly variable) occurs,
+or an invalid file descriptor is supplied as the argument to \fB\-u\fP.
+.RE
+.TP
+\fBreadonly\fP [\fB\-aAf\fP] [\fB\-p\fP] [\fIname\fP[=\fIword\fP] ...]
+.PD
+The given
+\fInames\fP are marked readonly; the values of these
+.I names
+may not be changed by subsequent assignment.
+If the
+.B \-f
+option is supplied, the functions corresponding to the
+\fInames\fP are so
+marked.
+The
+.B \-a
+option restricts the variables to indexed arrays; the
+.B \-A
+option restricts the variables to associative arrays.
+If both options are supplied,
+.B \-A
+takes precedence.
+If no
+.I name
+arguments are given, or if the
+.B \-p
+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
+option causes output to be displayed in a format that
+may be reused as input.
+If a variable name is followed by =\fIword\fP, the value of
+the variable is set to \fIword\fP.
+The return status is 0 unless an invalid option is encountered,
+one of the
+.I names
+is not a valid shell variable name, or
+.B \-f
+is supplied with a
+.I name
+that is not a function.
+.TP
+\fBreturn\fP [\fIn\fP]
+Causes a function to stop executing and return the value specified by
+.I n
+to its caller.
+If 
+.I n
+is omitted, the return status is that of the last command
+executed in the function body.  If
+.B return
+is used outside a function,
+but during execution of a script by the 
+.B .
+(\fBsource\fP) command, it causes the shell to stop executing
+that script and return either
+.I n
+or the exit status of the last command executed within the
+script as the exit status of the script.
+If \fIn\fP is supplied, the return value is its least significant
+8 bits.
+The return status is non-zero if
+.B return
+is supplied a non-numeric argument, or
+is used outside a
+function and not during execution of a script by \fB.\fP\^ or \fBsource\fP.
+Any command associated with the \fBRETURN\fP trap is executed
+before execution resumes after the function or script.
+.TP
+\fBset\fP [\fB\-\-abefhkmnptuvxBCEHPT\fP] [\fB\-o\fP \fIoption\-name\fP] [\fIarg\fP ...]
+.PD 0
+.TP
+\fBset\fP [\fB+abefhkmnptuvxBCEHPT\fP] [\fB+o\fP \fIoption\-name\fP] [\fIarg\fP ...]
+.PD
+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 cannot be reset.
+In \fIposix\fP 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 values for the positional parameters and are assigned, in order, to 
+.BR $1 ,
+.BR $2 ,
+.B ...
+.BR $\fIn\fP .
+Options, if specified, have the following meanings:
+.RS
+.PD 0
+.TP 8
+.B \-a
+Automatically mark variables and functions which are modified or
+created for export to the environment of subsequent commands.
+.TP 8
+.B \-b
+Report the status of terminated background jobs
+immediately, rather than before the next primary prompt.  This is
+effective only when job control is enabled.
+.TP 8
+.B \-e
+Exit immediately if a
+\fIpipeline\fP (which may consist of a single \fIsimple command\fP),
+a \fIlist\fP,
+or a \fIcompound command\fP
+(see
+.SM
+.B SHELL GRAMMAR
+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
+.B while
+or
+.B until
+keyword, 
+part of the test following the
+.B if
+or
+.B elif
+reserved words, part of any command executed in a
+.B &&
+or
+.B ||
+list except the command following the final \fB&&\fP or \fB||\fP,
+any command in a pipeline but the last,
+or if the command's return value is
+being inverted with
+.BR ! .
+If a compound command other than a subshell
+returns a non-zero status because a command failed
+while \fB\-e\fP was being ignored, the shell does not exit.
+A trap on \fBERR\fP, if set, is executed before the shell exits.
+This option applies to the shell environment and each subshell environment
+separately (see
+.SM
+.B "COMMAND EXECUTION ENVIRONMENT"
+above), and may cause
+subshells to exit before executing all the commands in the subshell.
+.if t .sp 0.5
+.if n .sp 1
+If a compound command or shell function executes in a context
+where \fB\-e\fP is being ignored,
+none of the commands executed within the compound command or function body
+will be affected by the \fB\-e\fP setting, even if \fB\-e\fP is set
+and a command returns a failure status.
+If a compound command or shell function sets \fB\-e\fP while executing in
+a context where \fB\-e\fP is ignored, that setting will not have any
+effect until the compound command or the command containing the function
+call completes.
+.TP 8
+.B \-f
+Disable pathname expansion.
+.TP 8 
+.B \-h
+Remember the location of commands as they are looked up for execution.
+This is enabled by default.
+.TP 8
+.B \-k
+All arguments in the form of assignment statements
+are placed in the environment for a command, not just
+those that precede the command name.
+.TP 8
+.B \-m
+Monitor mode.  Job control is enabled.  This option is on
+by default for interactive shells on systems that support
+it (see
+.SM
+.B JOB CONTROL
+above).
+All processes run in a separate process group.
+When a background job completes, the shell prints a line
+containing its exit status.
+.TP 8
+.B \-n
+Read commands but do not execute them.  This may be used to 
+check a shell script for syntax errors.  This is ignored by
+interactive shells.
+.TP 8
+.B \-o \fIoption\-name\fP
+The \fIoption\-name\fP can be one of the following:
+.RS
+.TP 8
+.B allexport
+Same as
+.BR \-a .
+.TP 8
+.B braceexpand
+Same as
+.BR \-B .
+.TP 8
+.B emacs
+Use an emacs-style command line editing interface.  This is enabled
+by default when the shell is interactive, unless the shell is started
+with the
+.B \-\-noediting
+option.
+This also affects the editing interface used for \fBread \-e\fP.
+.TP 8
+.B errexit
+Same as
+.BR \-e .
+.TP 8
+.B errtrace
+Same as
+.BR \-E .
+.TP 8
+.B functrace
+Same as
+.BR \-T .
+.TP 8
+.B hashall
+Same as
+.BR \-h .
+.TP 8
+.B histexpand
+Same as
+.BR \-H .
+.TP 8
+.B history
+Enable command history, as described above under
+.SM
+.BR HISTORY .
+This option is on by default in interactive shells.
+.TP 8
+.B ignoreeof
+The effect is as if the shell command
+.if t \f(CWIGNOREEOF=10\fP
+.if n ``IGNOREEOF=10''
+had been executed
+(see
+.B Shell Variables
+above).
+.TP 8
+.B keyword
+Same as
+.BR \-k .
+.TP 8
+.B monitor
+Same as
+.BR \-m .
+.TP 8
+.B noclobber
+Same as
+.BR \-C .
+.TP 8
+.B noexec
+Same as
+.BR \-n .
+.TP 8
+.B noglob
+Same as
+.BR \-f .
+.TP 8
+.B nolog
+Currently ignored.
+.TP 8
+.B notify
+Same as
+.BR \-b .
+.TP 8
+.B nounset
+Same as
+.BR \-u .
+.TP 8
+.B onecmd
+Same as
+.BR \-t .
+.TP 8
+.B physical
+Same as
+.BR \-P .
+.TP 8
+.B pipefail
+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.
+.TP 8
+.B posix
+Change the behavior of
+.B bash
+where the default operation differs
+from the POSIX standard to match the standard (\fIposix mode\fP).
+See
+.SM
+.B "SEE ALSO"
+below for a reference to a document that details how posix mode affects
+bash's behavior.
+.TP 8
+.B privileged
+Same as
+.BR \-p .
+.TP 8
+.B verbose
+Same as
+.BR \-v .
+.TP 8
+.B vi
+Use a vi-style command line editing interface.
+This also affects the editing interface used for \fBread \-e\fP.
+.TP 8
+.B xtrace
+Same as
+.BR \-x .
+.sp .5
+.PP
+If
+.B \-o
+is supplied with no \fIoption\-name\fP, the values of the current options are
+printed.
+If
+.B +o
+is supplied with no \fIoption\-name\fP, a series of
+.B set
+commands to recreate the current option settings is displayed on
+the standard output.
+.RE
+.TP 8
+.B \-p
+Turn on
+.I privileged
+mode.  In this mode, the
+.SM
+.B $ENV
+and
+.SM
+.B $BASH_ENV
+files are not processed, shell functions are not inherited from the
+environment, and the
+.SM
+.BR SHELLOPTS ,
+.SM
+.BR BASHOPTS ,
+.SM
+.BR CDPATH ,
+and
+.SM
+.B GLOBIGNORE
+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 \fB\-p\fP option is not supplied, these actions
+are taken and the effective user id is set to the real user id.
+If the \fB\-p\fP option is supplied 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.
+.TP 8
+.B \-t
+Exit after reading and executing one command.
+.TP 8
+.B \-u
+Treat unset variables and parameters other than the special
+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.
+.TP 8
+.B \-v
+Print shell input lines as they are read.
+.TP 8
+.B \-x
+After expanding each \fIsimple command\fP,
+\fBfor\fP command, \fBcase\fP command, \fBselect\fP command, or
+arithmetic \fBfor\fP command, display the expanded value of
+.SM
+.BR PS4 ,
+followed by the command and its expanded arguments
+or associated word list.
+.TP 8
+.B \-B
+The shell performs brace expansion (see
+.B Brace Expansion
+above).  This is on by default.
+.TP 8
+.B \-C
+If set,
+.B bash
+does not overwrite an existing file with the
+.BR > ,
+.BR >& ,
+and
+.B <>
+redirection operators.  This may be overridden when 
+creating output files by using the redirection operator
+.B >|
+instead of
+.BR > .
+.TP 8
+.B \-E
+If set, any trap on \fBERR\fP is inherited by shell functions, command
+substitutions, and commands executed in a subshell environment.
+The \fBERR\fP trap is normally not inherited in such cases.
+.TP 8
+.B \-H
+Enable
+.B !
+style history substitution.  This option is on by
+default when the shell is interactive.
+.TP 8
+.B \-P
+If set, the shell does not resolve symbolic links when executing
+commands such as
+.B cd
+that change the current working directory.  It uses the
+physical directory structure instead.  By default,
+.B bash
+follows the logical chain of directories when performing commands
+which change the current directory.
+.TP 8
+.B \-T
+If set, any traps on \fBDEBUG\fP and \fBRETURN\fP are inherited by shell
+functions, command substitutions, and commands executed in a
+subshell environment.
+The \fBDEBUG\fP and \fBRETURN\fP traps are normally not inherited
+in such cases.
+.TP 8
+.B \-\-
+If no arguments follow this option, then the positional parameters are
+unset.  Otherwise, the positional parameters are set to the
+\fIarg\fPs, even if some of them begin with a
+.BR \- .
+.TP 8
+.B \-
+Signal the end of options, cause all remaining \fIarg\fPs to be
+assigned to the positional parameters.  The
+.B \-x
+and
+.B \-v
+options are turned off.
+If there are no \fIarg\fPs,
+the positional parameters remain unchanged.
+.PD
+.PP
+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
+.BR $\- .
+The return status is always true unless an invalid option is encountered.
+.RE
+.TP
+\fBshift\fP [\fIn\fP]
+The positional parameters from \fIn\fP+1 ... are renamed to
+.B $1
+.B ....
+Parameters represented by the numbers \fB$#\fP
+down to \fB$#\fP\-\fIn\fP+1 are unset.
+.I n
+must be a non-negative number less than or equal to \fB$#\fP.
+If
+.I n
+is 0, no parameters are changed.
+If
+.I n 
+is not given, it is assumed to be 1.
+If
+.I n
+is greater than \fB$#\fP, the positional parameters are not changed.
+The return status is greater than zero if
+.I n
+is greater than
+.B $#
+or less than zero; otherwise 0.
+.TP
+\fBshopt\fP [\fB\-pqsu\fP] [\fB\-o\fP] [\fIoptname\fP ...]
+Toggle the values of variables controlling optional shell behavior.
+With no options, or with the
+.B \-p
+option, a list of all settable options is displayed, with
+an indication of whether or not each is set.
+The \fB\-p\fP option causes output to be displayed in a form that
+may be reused as input.
+Other options have the following meanings:
+.RS
+.PD 0
+.TP
+.B \-s
+Enable (set) each \fIoptname\fP.
+.TP
+.B \-u
+Disable (unset) each \fIoptname\fP.
+.TP
+.B \-q
+Suppresses normal output (quiet mode); the return status indicates
+whether the \fIoptname\fP is set or unset.
+If multiple \fIoptname\fP arguments are given with
+.BR \-q ,
+the return status is zero if all \fIoptnames\fP are enabled; non-zero
+otherwise.
+.TP
+.B \-o
+Restricts the values of \fIoptname\fP to be those defined for the
+.B \-o
+option to the
+.B set
+builtin.
+.PD
+.PP
+If either
+.B \-s
+or
+.B \-u
+is used with no \fIoptname\fP arguments,
+.B shopt
+shows only those options which are set or unset, respectively.
+Unless otherwise noted, the \fBshopt\fP options are disabled (unset)
+by default.
+.PP
+The return status when listing options is zero if all \fIoptnames\fP
+are enabled, non-zero otherwise.  When setting or unsetting options,
+the return status is zero unless an \fIoptname\fP is not a valid shell
+option.
+.PP
+The list of \fBshopt\fP options is:
+.if t .sp .5v
+.if n .sp 1v
+.PD 0
+.TP 8
+.B autocd
+If set, a command name that is the name of a directory is executed as if
+it were the argument to the \fBcd\fP command.
+This option is only used by interactive shells.
+.TP 8
+.B cdable_vars
+If set, an argument to the
+.B cd
+builtin command that
+is not a directory is assumed to be the name of a variable whose
+value is the directory to change to.
+.TP 8
+.B cdspell
+If set, minor errors in the spelling of a directory component in a
+.B cd
+command will be corrected.
+The errors checked for are transposed characters,
+a missing character, and one character too many.
+If a correction is found, the corrected filename is printed,
+and the command proceeds.
+This option is only used by interactive shells.
+.TP 8
+.B checkhash
+If set, \fBbash\fP checks that a command found in the hash
+table exists before trying to execute it.  If a hashed command no
+longer exists, a normal path search is performed.
+.TP 8
+.B checkjobs
+If set, \fBbash\fP lists the status of any stopped and running 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
+.SM
+.B "JOB CONTROL"
+above).  The shell always
+postpones exiting if any jobs are stopped.
+.TP 8
+.B checkwinsize
+If set, \fBbash\fP checks the window size after each command
+and, if necessary, updates the values of
+.SM
+.B LINES
+and
+.SM
+.BR COLUMNS .
+.TP 8
+.B cmdhist
+If set,
+.B bash
+attempts to save all lines of a multiple-line
+command in the same history entry.  This allows
+easy re-editing of multi-line commands.
+.TP 8
+.B compat31
+If set,
+.B bash
+changes its behavior to that of version 3.1 with respect to quoted
+arguments to the \fB[[\fP conditional command's \fB=~\fP operator
+and locale-specific string comparison when using the \fB[[\fP
+conditional command's \fB<\fP and \fB>\fP operators.
+Bash versions prior to bash-4.1 use ASCII collation and
+.IR strcmp (3);
+bash-4.1 and later use the current locale's collation sequence and
+.IR strcoll (3).
+.TP 8
+.B compat32
+If set,
+.B bash
+changes its behavior to that of version 3.2 with respect to
+locale-specific string comparison when using the \fB[[\fP
+conditional command's \fB<\fP and \fB>\fP operators (see previous item).
+.TP 8
+.B compat40
+If set,
+.B bash
+changes its behavior to that of version 4.0 with respect to locale-specific
+string comparison when using the \fB[[\fP
+conditional command's \fB<\fP and \fB>\fP operators (see description of
+\fBcompat31\fP)
+and the effect of interrupting a command list.
+Bash versions 4.0 and later interrupt the list as if the shell received the
+interrupt; previous versions continue with the next command in the list.
+.TP 8
+.B compat41
+If set,
+.BR bash ,
+when in \fIposix\fP mode, treats a single quote in a double-quoted
+parameter expansion as a special character.  The single quotes must match
+(an even number) 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.
+.TP 8
+.B compat42
+If set,
+.B bash
+does not process the replacement string in the pattern substitution word
+expansion using quote removal.
+.TP 8
+.B complete_fullquote
+If set,
+.B bash
+quotes all shell metacharacters in filenames and directory names when
+performing completion.
+If not set,
+.B bash
+removes metacharacters such as the dollar 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 backslashes to quote completed
+filenames.
+This variable is set by default, which is the default bash behavior in
+versions through 4.2.
+.TP 8
+.B direxpand
+If set,
+.B bash
+replaces directory names with the results of word expansion when performing
+filename completion.  This changes the contents of the readline editing
+buffer.
+If not set,
+.B bash
+attempts to preserve what the user typed.
+.TP 8
+.B dirspell
+If set,
+.B bash
+attempts spelling correction on directory names during word completion
+if the directory name initially supplied does not exist.
+.TP 8
+.B dotglob
+If set, 
+.B bash
+includes filenames beginning with a `.' in the results of pathname
+expansion.
+.TP 8
+.B execfail
+If set, a non-interactive shell will not exit if
+it cannot execute the file specified as an argument to the
+.B exec
+builtin command.  An interactive shell does not exit if
+.B exec
+fails.
+.TP 8
+.B expand_aliases
+If set, aliases are expanded as described above under
+.SM
+.BR ALIASES .
+This option is enabled by default for interactive shells.
+.TP 8
+.B extdebug
+If set, behavior intended for use by debuggers is enabled:
+.RS
+.TP
+.B 1.
+The \fB\-F\fP option to the \fBdeclare\fP builtin displays the source
+file name and line number corresponding to each function name supplied
+as an argument.
+.TP
+.B 2.
+If the command run by the \fBDEBUG\fP trap returns a non-zero value, the
+next command is skipped and not executed.
+.TP
+.B 3.
+If the command run by the \fBDEBUG\fP trap returns a value of 2, and the
+shell is executing in a subroutine (a shell function or a shell script
+executed by the \fB.\fP or \fBsource\fP builtins), a call to
+\fBreturn\fP is simulated.
+.TP
+.B 4.
+.SM
+.B BASH_ARGC
+and
+.SM
+.B BASH_ARGV
+are updated as described in their descriptions above.
+.TP
+.B 5.
+Function tracing is enabled:  command substitution, shell functions, and
+subshells invoked with \fB(\fP \fIcommand\fP \fB)\fP inherit the
+\fBDEBUG\fP and \fBRETURN\fP traps.
+.TP
+.B 6.
+Error tracing is enabled:  command substitution, shell functions, and
+subshells invoked with \fB(\fP \fIcommand\fP \fB)\fP inherit the
+\fBERR\fP trap.
+.RE
+.TP 8
+.B extglob
+If set, the extended pattern matching features described above under
+\fBPathname Expansion\fP are enabled.
+.TP 8
+.B extquote
+If set, \fB$\fP\(aq\fIstring\fP\(aq and \fB$\fP"\fIstring\fP" quoting is
+performed within \fB${\fP\fIparameter\fP\fB}\fP expansions
+enclosed in double quotes.  This option is enabled by default.
+.TP 8
+.B failglob
+If set, patterns which fail to match filenames during pathname expansion
+result in an expansion error.
+.TP 8
+.B force_fignore
+If set, the suffixes specified by the
+.SM
+.B FIGNORE
+shell variable
+cause words to be ignored when performing word completion even if
+the ignored words are the only possible completions.
+See
+.SM
+\fBSHELL VARIABLES\fP
+above for a description of
+.SM
+.BR FIGNORE .
+This option is enabled by default.
+.TP 8
+.B globasciiranges
+If set, range expressions used in pattern matching bracket expressions (see
+.SM
+.B Pattern Matching
+above) behave as if in the traditional C locale when performing
+comparisons.  That is, the current locale's collating sequence
+is not taken into account, so
+.B b
+will not collate between
+.B A
+and
+.BR B ,
+and upper-case and lower-case ASCII characters will collate together.
+.TP 8
+.B globstar
+If set, the pattern \fB**\fP used in a pathname expansion context will
+match all files and zero or more directories and subdirectories.
+If the pattern is followed by a \fB/\fP, only directories and
+subdirectories match.
+.TP 8
+.B gnu_errfmt
+If set, shell error messages are written in the standard GNU error
+message format.
+.TP 8
+.B histappend
+If set, the history list is appended to the file named by the value
+of the
+.SM
+.B HISTFILE
+variable when the shell exits, rather than overwriting the file.
+.TP 8
+.B histreedit
+If set, and
+.B readline
+is being used, a user is given the opportunity to re-edit a
+failed history substitution.
+.TP 8
+.B histverify
+If set, and 
+.B readline
+is being used, the results of history substitution are not immediately
+passed to the shell parser.  Instead, the resulting line is loaded into
+the \fBreadline\fP editing buffer, allowing further modification.
+.TP 8
+.B hostcomplete
+If set, and
+.B readline
+is being used, \fBbash\fP will attempt to perform hostname completion when a
+word containing a \fB@\fP is being completed (see
+.B Completing
+under
+.SM
+.B READLINE
+above).
+This is enabled by default.
+.TP 8
+.B huponexit
+If set, \fBbash\fP will send
+.SM
+.B SIGHUP
+to all jobs when an interactive login shell exits.
+.TP 8
+.B interactive_comments
+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
+.SM
+.B COMMENTS
+above).  This option is enabled by default.
+.TP 8
+.B lastpipe
+If set, and job control is not active, the shell runs the last command of
+a pipeline not executed in the background in the current shell environment.
+.TP 8
+.B lithist
+If set, and the
+.B cmdhist
+option is enabled, multi-line commands are saved to the history with
+embedded newlines rather than using semicolon separators where possible.
+.TP 8
+.B login_shell
+The shell sets this option if it is started as a login shell (see
+.SM
+.B "INVOCATION"
+above).
+The value may not be changed.
+.TP 8
+.B mailwarn
+If set, and a file that \fBbash\fP is checking for mail has been  
+accessed since the last time it was checked, the message ``The mail in
+\fImailfile\fP has been read'' is displayed.
+.TP 8
+.B no_empty_cmd_completion
+If set, and
+.B readline
+is being used,
+.B bash
+will not attempt to search the
+.SM
+.B PATH
+for possible completions when
+completion is attempted on an empty line.
+.TP 8
+.B nocaseglob
+If set,
+.B bash
+matches filenames in a case\-insensitive fashion when performing pathname
+expansion (see
+.B Pathname Expansion
+above).
+.TP 8
+.B nocasematch
+If set,
+.B bash
+matches patterns in a case\-insensitive fashion when performing matching
+while executing \fBcase\fP or \fB[[\fP conditional commands.
+.TP 8
+.B nullglob
+If set,
+.B bash
+allows patterns which match no
+files (see
+.B Pathname Expansion
+above)
+to expand to a null string, rather than themselves.
+.TP 8
+.B progcomp
+If set, the programmable completion facilities (see
+\fBProgrammable Completion\fP above) are enabled.
+This option is enabled by default.
+.TP 8
+.B promptvars
+If set, prompt strings undergo
+parameter expansion, command substitution, arithmetic
+expansion, and quote removal after being expanded as described in
+.SM
+.B PROMPTING
+above.  This option is enabled by default.
+.TP 8
+.B restricted_shell
+The shell sets this option if it is started in restricted mode (see
+.SM
+.B "RESTRICTED SHELL"
+below).
+The value may not be changed.
+This is not reset when the startup files are executed, allowing
+the startup files to discover whether or not a shell is restricted.
+.TP 8
+.B shift_verbose
+If set, the
+.B shift
+builtin prints an error message when the shift count exceeds the
+number of positional parameters.
+.TP 8
+.B sourcepath
+If set, the
+\fBsource\fP (\fB.\fP) builtin uses the value of
+.SM
+.B PATH
+to find the directory containing the file supplied as an argument.
+This option is enabled by default.
+.TP 8
+.B xpg_echo
+If set, the \fBecho\fP builtin expands backslash-escape sequences
+by default.
+.RE
+.PD
+.TP
+\fBsuspend\fP [\fB\-f\fP]
+Suspend the execution of this shell until it receives a
+.SM
+.B SIGCONT
+signal.  A login shell cannot be suspended; the
+.B \-f
+option can be used to override this and force the suspension.
+The return status is 0 unless the shell is a login shell and
+.B \-f
+is not supplied, or if job control is not enabled.
+.TP
+\fBtest\fP \fIexpr\fP
+.PD 0
+.TP
+\fB[\fP \fIexpr\fP \fB]\fP
+Return a status of 0 (true) or 1 (false) depending on
+the evaluation of the conditional expression
+.IR expr .
+Each operator and operand must be a separate argument.
+Expressions are composed of the primaries described above under
+.SM
+.BR "CONDITIONAL EXPRESSIONS" .
+\fBtest\fP does not accept any options, nor does it accept and ignore
+an argument of \fB\-\-\fP as signifying the end of options.
+.if t .sp 0.5
+.if n .sp 1
+Expressions may be combined using the following operators, listed
+in decreasing order of precedence.
+The evaluation depends on the number of arguments; see below.
+Operator precedence is used when there are five or more arguments.
+.RS
+.PD 0
+.TP
+.B ! \fIexpr\fP
+True if
+.I expr
+is false.
+.TP
+.B ( \fIexpr\fP )
+Returns the value of \fIexpr\fP.
+This may be used to override the normal precedence of operators.
+.TP
+\fIexpr1\fP \-\fBa\fP \fIexpr2\fP
+True if both
+.I expr1
+and
+.I expr2
+are true.
+.TP
+\fIexpr1\fP \-\fBo\fP \fIexpr2\fP
+True if either
+.I expr1
+or
+.I expr2
+is true.
+.PD
+.PP
+\fBtest\fP and \fB[\fP evaluate conditional
+expressions using a set of rules based on the number of arguments.
+.if t .sp 0.5
+.if n .sp 1
+.PD 0
+.TP
+0 arguments
+The expression is false.
+.TP
+1 argument
+The expression is true if and only if the argument is not null.
+.TP
+2 arguments
+If the first argument is \fB!\fP, the expression is true if and
+only if the second argument is null.
+If the first argument is one of the unary conditional operators listed above
+under
+.SM
+.BR "CONDITIONAL EXPRESSIONS" ,
+the expression is true if the unary test is true.
+If the first argument is not a valid unary conditional operator, the expression
+is false.
+.TP
+3 arguments
+The following conditions are applied in the order listed.
+If the second argument is one of the binary conditional operators listed above
+under
+.SM
+.BR "CONDITIONAL EXPRESSIONS" ,
+the result of the expression is the result of the binary test using
+the first and third arguments as operands.
+The \fB\-a\fP and \fB\-o\fP operators are considered binary operators
+when there are three arguments.  
+If the first argument is \fB!\fP, the value is the negation of
+the two-argument test using the second and third arguments.
+If the first argument is exactly \fB(\fP and the third argument is
+exactly \fB)\fP, the result is the one-argument test of the second
+argument.
+Otherwise, the expression is false.
+.TP
+4 arguments
+If the first argument is \fB!\fP, the result is the negation of
+the three-argument expression composed of the remaining arguments.
+Otherwise, the expression is parsed and evaluated according to 
+precedence using the rules listed above.
+.TP
+5 or more arguments
+The expression is parsed and evaluated according to precedence
+using the rules listed above.
+.if t .sp 0.5
+.if n .sp 1
+.LP
+When used with \fBtest\fP or \fB[\fP, the \fB<\fP and \fB>\fP operators
+sort lexicographically using ASCII ordering.
+.RE
+.PD
+.TP
+.B times
+Print the accumulated user and system times for the shell and
+for processes run from the shell.  The return status is 0.
+.TP
+\fBtrap\fP [\fB\-lp\fP] [[\fIarg\fP] \fIsigspec\fP ...]
+The command
+.I arg
+is to be read and executed when the shell receives
+signal(s)
+.IR sigspec .
+If
+.I arg
+is absent (and there is a single \fIsigspec\fP) or
+.BR \- ,
+each specified signal is
+reset to its original disposition (the value it had
+upon entrance to the shell).
+If 
+.I arg
+is the null string the signal specified by each
+.I sigspec
+is ignored by the shell and by the commands it invokes.
+If
+.I arg
+is not present and
+.B \-p
+has been supplied, then the trap commands associated with each
+.I sigspec
+are displayed.
+If no arguments are supplied or if only
+.B \-p
+is given,
+.B trap
+prints the list of commands associated with each signal.
+The
+.B \-l
+option causes the shell to print a list of signal names and
+their corresponding numbers.
+Each
+.I sigspec
+is either
+a signal name defined in <\fIsignal.h\fP>, or a signal number.
+Signal names are case insensitive and the
+.SM
+.B SIG
+prefix is optional.
+.if t .sp 0.5
+.if n .sp 1
+If a
+.I sigspec
+is
+.SM
+.B EXIT
+(0) the command
+.I arg
+is executed on exit from the shell.
+If a
+.I sigspec
+is
+.SM
+.BR DEBUG ,
+the command
+.I arg
+is executed before every \fIsimple command\fP, \fIfor\fP command,
+\fIcase\fP command, \fIselect\fP command, every arithmetic \fIfor\fP
+command, and before the first command executes in a shell function (see
+.SM
+.B SHELL GRAMMAR
+above).
+Refer to the description of the \fBextdebug\fP option to the
+\fBshopt\fP builtin for details of its effect on the \fBDEBUG\fP trap.
+If a
+.I sigspec
+is
+.SM
+.BR RETURN ,
+the command
+.I arg
+is executed each time a shell function or a script executed with
+the \fB.\fP or \fBsource\fP builtins finishes executing.
+.if t .sp 0.5
+.if n .sp 1
+If a
+.I sigspec
+is
+.SM
+.BR ERR ,
+the command
+.I arg
+is executed whenever a 
+a pipeline (which may consist of a single simple
+command), a list, or a compound command returns a 
+non\-zero exit status,
+subject to the following conditions.
+The
+.SM
+.B ERR
+trap is not executed if the failed
+command is part of the command list immediately following a
+.B while
+or
+.B until
+keyword, 
+part of the test in an
+.I if
+statement, part of a command executed in a
+.B &&
+or
+.B ||
+list except the command following the final \fB&&\fP or \fB||\fP,
+any command in a pipeline but the last,
+or if the command's return value is
+being inverted using
+.BR ! .
+These are the same conditions obeyed by the \fBerrexit\fP (\fB\-e\fP) option.
+.if t .sp 0.5
+.if n .sp 1
+Signals ignored upon entry to the shell cannot be trapped or reset.
+Trapped signals that are not being ignored are reset to their original
+values in a subshell or subshell environment when one is created.
+The return status is false if any
+.I sigspec
+is invalid; otherwise
+.B trap
+returns true.
+.TP
+\fBtype\fP [\fB\-aftpP\fP] \fIname\fP [\fIname\fP ...]
+With no options, 
+indicate how each
+.I name
+would be interpreted if used as a command name.
+If the
+.B \-t
+option is used,
+.B type
+prints a string which is one of
+.IR alias ,
+.IR keyword ,
+.IR function ,
+.IR builtin ,
+or
+.I file 
+if
+.I name
+is an alias, shell reserved word, function, builtin, or disk file,
+respectively.
+If the
+.I name
+is not found, then nothing is printed, and an exit status of false
+is returned.
+If the
+.B \-p
+option is used,
+.B type
+either returns the name of the disk file
+that would be executed if
+.I name
+were specified as a command name,
+or nothing if
+.if t \f(CWtype -t name\fP
+.if n ``type -t name''
+would not return
+.IR file .
+The
+.B \-P
+option forces a
+.SM
+.B PATH
+search for each \fIname\fP, even if
+.if t \f(CWtype -t name\fP
+.if n ``type -t name''
+would not return
+.IR file .
+If a command is hashed,
+.B \-p
+and
+.B \-P
+print the hashed value, which is not necessarily the file that appears
+first in 
+.SM
+.BR PATH .
+If the
+.B \-a
+option is used, 
+.B type
+prints all of the places that contain
+an executable named 
+.IR name .
+This includes aliases and functions,
+if and only if the 
+.B \-p
+option is not also used.
+The table of hashed commands is not consulted
+when using
+.BR \-a .
+The
+.B \-f
+option suppresses shell function lookup, as with the \fBcommand\fP builtin.
+.B type
+returns true if all of the arguments are found, false if
+any are not found.
+.TP
+\fBulimit\fP [\fB\-HSTabcdefilmnpqrstuvx\fP [\fIlimit\fP]]
+Provides control over the resources available to the shell and to
+processes started by it, on systems that allow such control.
+The \fB\-H\fP and \fB\-S\fP options specify that the hard or soft limit is
+set for the given resource.
+A hard limit cannot be increased by a non-root user once it is set;
+a soft limit may be increased up to the value of the hard limit.
+If neither \fB\-H\fP nor \fB\-S\fP is specified, both the soft and hard
+limits are set.
+The value of
+.I limit
+can be a number in the unit specified for the resource
+or one of the special values
+.BR hard ,
+.BR soft ,
+or
+.BR unlimited ,
+which stand for the current hard limit, the current soft limit, and
+no limit, respectively.
+If
+.I limit
+is omitted, the current value of the soft limit of the resource is
+printed, unless the \fB\-H\fP option is given.  When more than one
+resource is specified, the limit name and unit are printed before the value.
+Other options are interpreted as follows:
+.RS
+.PD 0
+.TP
+.B \-a
+All current limits are reported
+.TP
+.B \-b
+The maximum socket buffer size
+.TP
+.B \-c
+The maximum size of core files created
+.TP
+.B \-d
+The maximum size of a process's data segment
+.TP
+.B \-e
+The maximum scheduling priority ("nice")
+.TP
+.B \-f
+The maximum size of files written by the shell and its children
+.TP
+.B \-i
+The maximum number of pending signals
+.TP
+.B \-l
+The maximum size that may be locked into memory
+.TP
+.B \-m
+The maximum resident set size (many systems do not honor this limit)
+.TP
+.B \-n
+The maximum number of open file descriptors (most systems do not
+allow this value to be set)
+.TP
+.B \-p
+The pipe size in 512-byte blocks (this may not be set)
+.TP
+.B \-q
+The maximum number of bytes in POSIX message queues
+.TP
+.B \-r
+The maximum real-time scheduling priority
+.TP
+.B \-s
+The maximum stack size
+.TP
+.B \-t
+The maximum amount of cpu time in seconds
+.TP
+.B \-u
+The maximum number of processes available to a single user
+.TP
+.B \-v
+The maximum amount of virtual memory available to the shell and, on
+some systems, to its children
+.TP
+.B \-x
+The maximum number of file locks
+.TP
+.B \-T
+The maximum number of threads
+.PD
+.PP
+If
+.I limit
+is given, and the
+.B \-a
+option is not used,
+\fIlimit\fP is the new value of the specified resource.
+If no option is given, then
+.B \-f
+is assumed.  Values are in 1024-byte increments, except for
+.BR \-t ,
+which is in seconds;
+.BR \-p ,
+which is in units of 512-byte blocks;
+and
+.BR \-T ,
+.BR \-b ,
+.BR \-n ,
+and
+.BR \-u ,
+which are unscaled values.
+The return status is 0 unless an invalid option or argument is supplied,
+or an error occurs while setting a new limit.
+.RE
+.TP
+\fBumask\fP [\fB\-p\fP] [\fB\-S\fP] [\fImode\fP]
+The user file-creation mask is set to 
+.IR mode .
+If
+.I mode
+begins with a digit, it
+is interpreted as an octal number; otherwise
+it is interpreted as a symbolic mode mask similar
+to that accepted by
+.IR chmod (1).
+If
+.I mode
+is omitted, the current value of the mask is printed.
+The
+.B \-S
+option causes the mask to be printed in symbolic form; the
+default output is an octal number.
+If the
+.B \-p
+option is supplied, and
+.I mode
+is omitted, the output is in a form that may be reused as input.
+The return status is 0 if the mode was successfully changed or if
+no \fImode\fP argument was supplied, and false otherwise.
+.TP
+\fBunalias\fP [\-\fBa\fP] [\fIname\fP ...]
+Remove each \fIname\fP from the list of defined aliases.  If
+.B \-a
+is supplied, all alias definitions are removed.  The return
+value is true unless a supplied
+.I name
+is not a defined alias.
+.TP
+\fBunset\fP [\-\fBfv\fP] [\-\fBn\fP] [\fIname\fP ...]
+For each
+.IR name ,
+remove the corresponding variable or function.
+If the
+.B \-v
+option is given, each
+.I name
+refers to a shell variable, and that variable is removed.
+Read-only variables may not be unset.
+If
+.B \-f
+is specified, each
+.I name
+refers to a shell function, and the function definition
+is removed.
+If the
+.B \-n
+option is supplied, and \fIname\fP is a variable with the \fInameref\fP
+attribute, \fIname\fP will be unset rather than the variable it
+references.
+\fB\-n\fP has no effect if the \fB\-f\fP option is supplied.
+If no options are supplied, each \fIname\fP refers to a variable; if
+there is no variable by that name, any function with that name is
+unset.
+Each unset variable or function is removed from the environment
+passed to subsequent commands.
+If any of
+.SM
+.BR COMP_WORDBREAKS ,
+.SM
+.BR RANDOM ,
+.SM
+.BR SECONDS ,
+.SM
+.BR LINENO ,
+.SM
+.BR HISTCMD ,
+.SM
+.BR FUNCNAME ,
+.SM
+.BR GROUPS ,
+or
+.SM
+.B DIRSTACK
+are unset, they lose their special properties, even if they are
+subsequently reset.  The exit status is true unless a
+.I name
+is readonly.
+.TP
+\fBwait\fP [\fB\--n\fP] [\fIn ...\fP]
+Wait for each specified process and return its termination status.
+Each
+.I n
+may be a process
+ID or a job specification; if a job spec is given, all processes
+in that job's pipeline are waited for.  If
+.I n
+is not given, all currently active child processes
+are waited for, and the return status is zero.
+If the \fB\--n\fP option is supplied, \fBwait\fP waits for any job to
+terminate and returns its exit status.
+If
+.I n
+specifies a non-existent process or job, the return status is
+127.  Otherwise, the return status is the exit status of the last
+process or job waited for.
+.\" bash_builtins
+.if \n(zZ=1 .ig zZ
+.SH "RESTRICTED SHELL"
+.\" rbash.1
+.zY
+.PP
+If
+.B bash
+is started with the name
+.BR rbash ,
+or the
+.B \-r
+option is supplied at invocation,
+the shell becomes restricted.
+A restricted shell is used to
+set up an environment more controlled than the standard shell.
+It behaves identically to
+.B bash
+with the exception that the following are disallowed or not performed:
+.IP \(bu
+changing directories with \fBcd\fP
+.IP \(bu
+setting or unsetting the values of
+.SM
+.BR SHELL ,
+.SM
+.BR PATH ,
+.SM
+.BR ENV ,
+or
+.SM
+.B BASH_ENV
+.IP \(bu
+specifying command names containing
+.B /
+.IP \(bu
+specifying a filename containing a
+.B /
+as an argument to the
+.B .
+builtin command
+.IP \(bu
+specifying a filename containing a slash as an argument to the
+.B \-p
+option to the
+.B hash
+builtin command
+.IP \(bu
+importing function definitions from the shell environment at startup
+.IP \(bu
+parsing the value of
+.SM
+.B SHELLOPTS
+from the shell environment at startup
+.IP \(bu
+redirecting output using the >, >|, <>, >&, &>, and >> redirection operators
+.IP \(bu
+using the
+.B exec
+builtin command to replace the shell with another command
+.IP \(bu
+adding or deleting builtin commands with the
+.B \-f
+and
+.B \-d
+options to the
+.B enable
+builtin command
+.IP \(bu
+using the \fBenable\fP builtin command to enable disabled shell builtins
+.IP \(bu
+specifying the
+.B \-p
+option to the
+.B command
+builtin command
+.IP \(bu
+turning off restricted mode with
+\fBset +r\fP or \fBset +o restricted\fP.
+.PP
+These restrictions are enforced after any startup files are read.
+.PP
+.ie \n(zY=1 When a command that is found to be a shell script is executed,
+.el \{ When a command that is found to be a shell script is executed
+(see
+.SM
+.B "COMMAND EXECUTION"
+above),
+\}
+.B rbash
+turns off any restrictions in the shell spawned to execute the
+script.
+.\" end of rbash.1
+.if \n(zY=1 .ig zY
+.SH "SEE ALSO"
+.PD 0
+.TP
+\fIBash Reference Manual\fP, Brian Fox and Chet Ramey
+.TP
+\fIThe Gnu Readline Library\fP, Brian Fox and Chet Ramey
+.TP
+\fIThe Gnu History Library\fP, Brian Fox and Chet Ramey
+.TP
+\fIPortable Operating System Interface (POSIX) Part 2: Shell and Utilities\fP, IEEE --
+http://pubs.opengroup.org/onlinepubs/9699919799/
+.TP
+http://tiswww.case.edu/~chet/bash/POSIX -- a description of posix mode
+.TP
+\fIsh\fP(1), \fIksh\fP(1), \fIcsh\fP(1)
+.TP
+\fIemacs\fP(1), \fIvi\fP(1)
+.TP
+\fIreadline\fP(3)
+.PD
+.SH FILES
+.PD 0
+.TP
+.FN /bin/bash
+The \fBbash\fP executable
+.TP
+.FN /etc/profile
+The systemwide initialization file, executed for login shells
+.TP
+.FN ~/.bash_profile
+The personal initialization file, executed for login shells
+.TP
+.FN ~/.bashrc
+The individual per-interactive-shell startup file
+.TP
+.FN ~/.bash_logout
+The individual login shell cleanup file, executed when a login shell exits
+.TP
+.FN ~/.inputrc
+Individual \fIreadline\fP initialization file
+.PD
+.SH AUTHORS
+Brian Fox, Free Software Foundation
+.br
+bfox@gnu.org
+.PP
+Chet Ramey, Case Western Reserve University
+.br
+chet.ramey@case.edu
+.SH BUG REPORTS
+If you find a bug in
+.B bash,
+you should report it.  But first, you should
+make sure that it really is a bug, and that it appears in the latest
+version of
+.BR bash .
+The latest version is always available from
+\fIftp://ftp.gnu.org/pub/gnu/bash/\fP.
+.PP
+Once you have determined that a bug actually exists, use the
+.I bashbug
+command to submit a bug report.
+If you have a fix, you are encouraged to mail that as well!
+Suggestions and `philosophical' bug reports may be mailed
+to \fIbug-bash@gnu.org\fP or posted to the Usenet
+newsgroup
+.BR gnu.bash.bug .
+.PP
+ALL bug reports should include:
+.PP
+.PD 0
+.TP 20
+The version number of \fBbash\fR
+.TP
+The hardware and operating system
+.TP
+The compiler used to compile
+.TP
+A description of the bug behaviour
+.TP
+A short script or `recipe' which exercises the bug
+.PD
+.PP
+.I bashbug
+inserts the first three items automatically into the template
+it provides for filing a bug report.
+.PP
+Comments and bug reports concerning
+this manual page should be directed to
+.IR chet.ramey@case.edu .
+.SH BUGS
+.PP
+It's too big and too slow.
+.PP
+There are some subtle differences between 
+.B bash
+and traditional versions of
+.BR sh ,
+mostly because of the
+.SM
+.B POSIX
+specification.
+.PP
+Aliases are confusing in some uses.
+.PP
+Shell builtin commands and functions are not stoppable/restartable.
+.PP
+Compound commands and command sequences of the form `a ; b ; c'
+are not handled gracefully when process suspension is attempted.
+When a process is stopped, the shell immediately executes the next
+command in the sequence.
+It suffices to place the sequence of commands between
+parentheses to force it into a subshell, which may be stopped as
+a unit.
+.PP
+Array variables may not (yet) be exported.
+.PP
+There may be only one active coprocess at a time.
+.zZ
+.zY
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
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 5edc08aa0e661b73c88fc6f1b61dce3089bd54b0..bbcffa6fa11fcda38b1bc62b8867bd6ca1af5cde 100644 (file)
@@ -39,6 +39,7 @@
 #include <shmbchar.h>
 #include <shmbutil.h>
 #include <chartypes.h>
+#include <typemax.h>
 
 #include <glob/strmatch.h>
 
 
 extern char *substring __P((char *, int, int));
 
+#ifndef UCHAR_MAX
+#  define UCHAR_MAX    TYPE_MAXIMUM(unsigned char)
+#endif
+
 #if defined (HANDLE_MULTIBYTE)
 static wchar_t
 cval (s, i)
@@ -141,8 +146,10 @@ sh_modcase (string, pat, flags)
       if (iswalnum (wc) == 0)
        {
          inword = 0;
+#if 0
          ADVANCE_CHAR (ret, end, start);
          continue;
+#endif
        }
 
       if (pat)
@@ -203,8 +210,11 @@ sh_modcase (string, pat, flags)
       else
        nop = flags;
 
-      if (MB_CUR_MAX == 1 || is_basic ((int)wc))
+      /* Need to check UCHAR_MAX since wc may have already been converted to a
+        wide character by cval() */
+      if (MB_CUR_MAX == 1 || (wc <= UCHAR_MAX && is_basic ((int)wc)))
        {
+singlebyte:
          switch (nop)
          {
          default:
@@ -221,7 +231,10 @@ sh_modcase (string, pat, flags)
        {
          m = mbrtowc (&wc, string + start, end - start, &state);
          if (MB_INVALIDCH (m))
-           wc = (wchar_t)string[start];
+           {
+             wc = (unsigned char)string[start];
+             goto singlebyte;
+           }
          else if (MB_NULLWCH (m))
            wc = L'\0';
          switch (nop)
diff --git a/lib/sh/casemod.c~ b/lib/sh/casemod.c~
new file mode 100644 (file)
index 0000000..64e251e
--- /dev/null
@@ -0,0 +1,265 @@
+/* casemod.c -- functions to change case of strings */
+
+/* Copyright (C) 2008,2009 Free Software Foundation, Inc.
+
+   This file is part of GNU Bash, the Bourne Again SHell.
+
+   Bash is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   Bash is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with Bash.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#if defined (HAVE_CONFIG_H)
+#  include <config.h>
+#endif
+
+#if defined (HAVE_UNISTD_H)
+#  include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <stdc.h>
+
+#include <bashansi.h>
+#include <bashintl.h>
+#include <bashtypes.h>
+
+#include <stdio.h>
+#include <ctype.h>
+#include <xmalloc.h>
+
+#include <shmbchar.h>
+#include <shmbutil.h>
+#include <chartypes.h>
+#include <typemax.h>
+
+#include <glob/strmatch.h>
+
+#define _to_wupper(wc) (iswlower (wc) ? towupper (wc) : (wc))
+#define _to_wlower(wc) (iswupper (wc) ? towlower (wc) : (wc))
+
+#if !defined (HANDLE_MULTIBYTE)
+#  define cval(s, i)   ((s)[(i)])
+#  define iswalnum(c)  (isalnum(c))
+#  define TOGGLE(x)    (ISUPPER (x) ? tolower (x) : (TOUPPER (x)))
+#else
+#  define TOGGLE(x)    (iswupper (x) ? towlower (x) : (_to_wupper(x)))
+#endif
+
+/* These must agree with the defines in externs.h */
+#define CASE_NOOP      0x0000
+#define CASE_LOWER     0x0001
+#define CASE_UPPER     0x0002
+#define CASE_CAPITALIZE        0x0004
+#define CASE_UNCAP     0x0008
+#define CASE_TOGGLE    0x0010
+#define CASE_TOGGLEALL 0x0020
+#define CASE_UPFIRST   0x0040
+#define CASE_LOWFIRST  0x0080
+
+#define CASE_USEWORDS  0x1000          /* modify behavior to act on words in passed string */
+
+extern char *substring __P((char *, int, int));
+
+#ifndef UCHAR_MAX
+#  define UCHAR_MAX    TYPE_MAXIMUM(unsigned char)
+#endif
+
+#if defined (HANDLE_MULTIBYTE)
+static wchar_t
+cval (s, i)
+     char *s;
+     int i;
+{
+  size_t tmp;
+  wchar_t wc;
+  int l;
+  mbstate_t mps;  
+
+  if (MB_CUR_MAX == 1 || is_basic (s[i]))
+    return ((wchar_t)s[i]);
+  l = strlen (s);
+  if (i >= (l - 1))
+    return ((wchar_t)s[i]);
+  memset (&mps, 0, sizeof (mbstate_t));
+  tmp = mbrtowc (&wc, s + i, l - i, &mps);
+  if (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp))
+    return ((wchar_t)s[i]);
+  return wc;  
+}
+#endif
+
+/* Modify the case of characters in STRING matching PAT based on the value of
+   FLAGS.  If PAT is null, modify the case of each character */
+char *
+sh_modcase (string, pat, flags)
+     const char *string;
+     char *pat;
+     int flags;
+{
+  int start, next, end;
+  int inword, c, nc, nop, match, usewords;
+  char *ret, *s;
+  wchar_t wc;
+#if defined (HANDLE_MULTIBYTE)
+  wchar_t nwc;
+  char mb[MB_LEN_MAX+1];
+  int mlen;
+  size_t m;
+  mbstate_t state;
+#endif
+
+  if (string == 0 || *string == 0)
+    {
+      ret = (char *)xmalloc (1);
+      ret[0] = '\0';
+      return ret;
+    }
+
+#if defined (HANDLE_MULTIBYTE)
+  memset (&state, 0, sizeof (mbstate_t));
+#endif
+
+  start = 0;
+  end = strlen (string);
+
+  ret = (char *)xmalloc (end + 1);
+  strcpy (ret, string);
+
+  /* See if we are supposed to split on alphanumerics and operate on each word */
+  usewords = (flags & CASE_USEWORDS);
+  flags &= ~CASE_USEWORDS;
+
+  inword = 0;
+  while (start < end)
+    {
+      wc = cval (ret, start);
+
+      if (iswalnum (wc) == 0)
+       {
+         inword = 0;
+#if 0
+         ADVANCE_CHAR (ret, end, start);
+         continue;
+#endif
+       }
+
+      if (pat)
+       {
+         next = start;
+         ADVANCE_CHAR (ret, end, next);
+         s = substring (ret, start, next);
+         match = strmatch (pat, s, FNM_EXTMATCH) != FNM_NOMATCH;
+         free (s);
+         if (match == 0)
+            {
+              start = next;
+              inword = 1;
+              continue;
+            }
+       }
+
+      /* XXX - for now, the toggling operators work on the individual
+        words in the string, breaking on alphanumerics.  Should I
+        leave the capitalization operators to do that also? */
+      if (flags == CASE_CAPITALIZE)
+       {
+         if (usewords)
+           nop = inword ? CASE_LOWER : CASE_UPPER;
+         else
+           nop = (start > 0) ? CASE_LOWER : CASE_UPPER;
+         inword = 1;
+       }
+      else if (flags == CASE_UNCAP)
+       {
+         if (usewords)
+           nop = inword ? CASE_UPPER : CASE_LOWER;
+         else
+           nop = (start > 0) ? CASE_UPPER : CASE_LOWER;
+         inword = 1;
+       }
+      else if (flags == CASE_UPFIRST)
+       {
+         if (usewords)
+           nop = inword ? CASE_NOOP : CASE_UPPER;
+         else
+           nop = (start > 0) ? CASE_NOOP : CASE_UPPER;
+         inword = 1;
+       }
+      else if (flags == CASE_LOWFIRST)
+       {
+         if (usewords)
+           nop = inword ? CASE_NOOP : CASE_LOWER;
+         else
+           nop = (start > 0) ? CASE_NOOP : CASE_LOWER;
+         inword = 1;
+       }
+      else if (flags == CASE_TOGGLE)
+       {
+         nop = inword ? CASE_NOOP : CASE_TOGGLE;
+         inword = 1;
+       }
+      else
+       nop = flags;
+
+      /* Need to check UCHAR_MAX since wc may have already been converted to a
+        wide character by cval() */
+      if (MB_CUR_MAX == 1 || (wc <= UCHAR_MAX && is_basic ((int)wc)))
+       {
+singlebyte:
+         switch (nop)
+         {
+         default:
+         case CASE_NOOP:  nc = wc; break;
+         case CASE_UPPER:  nc = TOUPPER (wc); break;
+         case CASE_LOWER:  nc = TOLOWER (wc); break;
+         case CASE_TOGGLEALL:
+         case CASE_TOGGLE: nc = TOGGLE (wc); break;
+         }
+         ret[start] = nc;
+       }
+#if defined (HANDLE_MULTIBYTE)
+      else
+       {
+         m = mbrtowc (&wc, string + start, end - start, &state);
+         if (MB_INVALIDCH (m))
+           {
+             wc = (wchar_t)string[start];
+             goto singlebyte;
+           }
+         else if (MB_NULLWCH (m))
+           wc = L'\0';
+         switch (nop)
+         {
+         default:
+         case CASE_NOOP:  nwc = wc; break;
+         case CASE_UPPER:  nwc = _to_wupper (wc); break;
+         case CASE_LOWER:  nwc = _to_wlower (wc); break;
+         case CASE_TOGGLEALL:
+         case CASE_TOGGLE: nwc = TOGGLE (wc); break;
+         }
+         if  (nwc != wc)       /*  just skip unchanged characters */
+           {
+             mlen = wcrtomb (mb, nwc, &state);
+             if (mlen > 0)
+               mb[mlen] = '\0';
+             /* Assume the same width */
+             strncpy (ret + start, mb, mlen);
+           }
+       }
+#endif
+
+      /*  This assumes that the upper and lower case versions are the same width. */
+      ADVANCE_CHAR (ret, end, start);
+    }
+
+  return ret;
+}
diff --git a/parse.y b/parse.y
index 58e1fc524717c442ff7fa7992574afc70ceb40d0..d301193e0f81b4db0c0e7303b24b5f1d18476574 100644 (file)
--- a/parse.y
+++ b/parse.y
@@ -5886,6 +5886,7 @@ parse_compound_assignment (retlenp)
 {
   WORD_LIST *wl, *rl;
   int tok, orig_line_number, orig_token_size, orig_last_token, assignok;
+  int peekc;
   char *saved_token, *ret;
 
   saved_token = token;
diff --git a/parse.y~ b/parse.y~
new file mode 100644 (file)
index 0000000..67ea7fd
--- /dev/null
+++ b/parse.y~
@@ -0,0 +1,6165 @@
+/* parse.y - Yacc grammar for bash. */
+
+/* Copyright (C) 1989-2012 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 "bashansi.h"
+
+#include "filecntl.h"
+
+#if defined (HAVE_UNISTD_H)
+#  include <unistd.h>
+#endif
+
+#if defined (HAVE_LOCALE_H)
+#  include <locale.h>
+#endif
+
+#include <stdio.h>
+#include "chartypes.h"
+#include <signal.h>
+
+#include "memalloc.h"
+
+#include "bashintl.h"
+
+#define NEED_STRFTIME_DECL     /* used in externs.h */
+
+#include "shell.h"
+#include "typemax.h"           /* SIZE_MAX if needed */
+#include "trap.h"
+#include "flags.h"
+#include "parser.h"
+#include "mailcheck.h"
+#include "test.h"
+#include "builtins.h"
+#include "builtins/common.h"
+#include "builtins/builtext.h"
+
+#include "shmbutil.h"
+
+#if defined (READLINE)
+#  include "bashline.h"
+#  include <readline/readline.h>
+#endif /* READLINE */
+
+#if defined (HISTORY)
+#  include "bashhist.h"
+#  include <readline/history.h>
+#endif /* HISTORY */
+
+#if defined (JOB_CONTROL)
+#  include "jobs.h"
+#endif /* JOB_CONTROL */
+
+#if defined (ALIAS)
+#  include "alias.h"
+#else
+typedef void *alias_t;
+#endif /* ALIAS */
+
+#if defined (PROMPT_STRING_DECODE)
+#  ifndef _MINIX
+#    include <sys/param.h>
+#  endif
+#  include <time.h>
+#  if defined (TM_IN_SYS_TIME)
+#    include <sys/types.h>
+#    include <sys/time.h>
+#  endif /* TM_IN_SYS_TIME */
+#  include "maxpath.h"
+#endif /* PROMPT_STRING_DECODE */
+
+#define RE_READ_TOKEN  -99
+#define NO_EXPANSION   -100
+
+#ifdef DEBUG
+#  define YYDEBUG 1
+#else
+#  define YYDEBUG 0
+#endif
+
+#if defined (HANDLE_MULTIBYTE)
+#  define last_shell_getc_is_singlebyte \
+       ((shell_input_line_index > 1) \
+               ? shell_input_line_property[shell_input_line_index - 1] \
+               : 1)
+#  define MBTEST(x)    ((x) && last_shell_getc_is_singlebyte)
+#else
+#  define last_shell_getc_is_singlebyte        1
+#  define MBTEST(x)    ((x))
+#endif
+
+#if defined (EXTENDED_GLOB)
+extern int extended_glob;
+#endif
+
+extern int eof_encountered;
+extern int no_line_editing, running_under_emacs;
+extern int current_command_number;
+extern int sourcelevel, parse_and_execute_level;
+extern int posixly_correct;
+extern int last_command_exit_value;
+extern pid_t last_command_subst_pid;
+extern char *shell_name, *current_host_name;
+extern char *dist_version;
+extern int patch_level;
+extern int dump_translatable_strings, dump_po_strings;
+extern sh_builtin_func_t *last_shell_builtin, *this_shell_builtin;
+#if defined (BUFFERED_INPUT)
+extern int bash_input_fd_changed;
+#endif
+
+extern int errno;
+/* **************************************************************** */
+/*                                                                 */
+/*                 "Forward" declarations                          */
+/*                                                                 */
+/* **************************************************************** */
+
+#ifdef DEBUG
+static void debug_parser __P((int));
+#endif
+
+static int yy_getc __P((void));
+static int yy_ungetc __P((int));
+
+#if defined (READLINE)
+static int yy_readline_get __P((void));
+static int yy_readline_unget __P((int));
+#endif
+
+static int yy_string_get __P((void));
+static int yy_string_unget __P((int));
+static void rewind_input_string __P((void));
+static int yy_stream_get __P((void));
+static int yy_stream_unget __P((int));
+
+static int shell_getc __P((int));
+static void shell_ungetc __P((int));
+static void discard_until __P((int));
+
+#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
+static void push_string __P((char *, int, alias_t *));
+static void pop_string __P((void));
+static void free_string_list __P((void));
+#endif
+
+static char *read_a_line __P((int));
+
+static int reserved_word_acceptable __P((int));
+static int yylex __P((void));
+static int alias_expand_token __P((char *));
+static int time_command_acceptable __P((void));
+static int special_case_tokens __P((char *));
+static int read_token __P((int));
+static char *parse_matched_pair __P((int, int, int, int *, int));
+static char *parse_comsub __P((int, int, int, int *, int));
+#if defined (ARRAY_VARS)
+static char *parse_compound_assignment __P((int *));
+#endif
+#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
+static int parse_dparen __P((int));
+static int parse_arith_cmd __P((char **, int));
+#endif
+#if defined (COND_COMMAND)
+static void cond_error __P((void));
+static COND_COM *cond_expr __P((void));
+static COND_COM *cond_or __P((void));
+static COND_COM *cond_and __P((void));
+static COND_COM *cond_term __P((void));
+static int cond_skip_newlines __P((void));
+static COMMAND *parse_cond_command __P((void));
+#endif
+#if defined (ARRAY_VARS)
+static int token_is_assignment __P((char *, int));
+static int token_is_ident __P((char *, int));
+#endif
+static int read_token_word __P((int));
+static void discard_parser_constructs __P((int));
+
+static char *error_token_from_token __P((int));
+static char *error_token_from_text __P((void));
+static void print_offending_line __P((void));
+static void report_syntax_error __P((char *));
+
+static void handle_eof_input_unit __P((void));
+static void prompt_again __P((void));
+#if 0
+static void reset_readline_prompt __P((void));
+#endif
+static void print_prompt __P((void));
+
+#if defined (HANDLE_MULTIBYTE)
+static void set_line_mbstate __P((void));
+static char *shell_input_line_property = NULL;
+#else
+#  define set_line_mbstate()
+#endif
+
+extern int yyerror __P((const char *));
+
+#ifdef DEBUG
+extern int yydebug;
+#endif
+
+/* Default prompt strings */
+char *primary_prompt = PPROMPT;
+char *secondary_prompt = SPROMPT;
+
+/* PROMPT_STRING_POINTER points to one of these, never to an actual string. */
+char *ps1_prompt, *ps2_prompt;
+
+/* Handle on the current prompt string.  Indirectly points through
+   ps1_ or ps2_prompt. */
+char **prompt_string_pointer = (char **)NULL;
+char *current_prompt_string;
+
+/* Non-zero means we expand aliases in commands. */
+int expand_aliases = 0;
+
+/* If non-zero, the decoded prompt string undergoes parameter and
+   variable substitution, command substitution, arithmetic substitution,
+   string expansion, process substitution, and quote removal in
+   decode_prompt_string. */
+int promptvars = 1;
+
+/* If non-zero, $'...' and $"..." are expanded when they appear within
+   a ${...} expansion, even when the expansion appears within double
+   quotes. */
+int extended_quote = 1;
+
+/* The number of lines read from input while creating the current command. */
+int current_command_line_count;
+
+/* The number of lines in a command saved while we run parse_and_execute */
+int saved_command_line_count;
+
+/* The token that currently denotes the end of parse. */
+int shell_eof_token;
+
+/* The token currently being read. */
+int current_token;
+
+/* The current parser state. */
+int parser_state;
+
+/* Variables to manage the task of reading here documents, because we need to
+   defer the reading until after a complete command has been collected. */
+static REDIRECT *redir_stack[10];
+int need_here_doc;
+
+/* Where shell input comes from.  History expansion is performed on each
+   line when the shell is interactive. */
+static char *shell_input_line = (char *)NULL;
+static size_t shell_input_line_index;
+static size_t shell_input_line_size;   /* Amount allocated for shell_input_line. */
+static size_t shell_input_line_len;    /* strlen (shell_input_line) */
+
+/* Either zero or EOF. */
+static int shell_input_line_terminator;
+
+/* The line number in a script on which a function definition starts. */
+static int function_dstart;
+
+/* The line number in a script on which a function body starts. */
+static int function_bstart;
+
+/* The line number in a script at which an arithmetic for command starts. */
+static int arith_for_lineno;
+
+/* The decoded prompt string.  Used if READLINE is not defined or if
+   editing is turned off.  Analogous to current_readline_prompt. */
+static char *current_decoded_prompt;
+
+/* The last read token, or NULL.  read_token () uses this for context
+   checking. */
+static int last_read_token;
+
+/* The token read prior to last_read_token. */
+static int token_before_that;
+
+/* The token read prior to token_before_that. */
+static int two_tokens_ago;
+
+static int global_extglob;
+
+/* The line number in a script where the word in a `case WORD', `select WORD'
+   or `for WORD' begins.  This is a nested command maximum, since the array
+   index is decremented after a case, select, or for command is parsed. */
+#define MAX_CASE_NEST  128
+static int word_lineno[MAX_CASE_NEST];
+static int word_top = -1;
+
+/* If non-zero, it is the token that we want read_token to return
+   regardless of what text is (or isn't) present to be read.  This
+   is reset by read_token.  If token_to_read == WORD or
+   ASSIGNMENT_WORD, yylval.word should be set to word_desc_to_read. */
+static int token_to_read;
+static WORD_DESC *word_desc_to_read;
+
+static REDIRECTEE source;
+static REDIRECTEE redir;
+
+static char compound_assignment_error;
+%}
+
+%union {
+  WORD_DESC *word;             /* the word that we read. */
+  int number;                  /* the number that we read. */
+  WORD_LIST *word_list;
+  COMMAND *command;
+  REDIRECT *redirect;
+  ELEMENT element;
+  PATTERN_LIST *pattern;
+}
+
+/* Reserved words.  Members of the first group are only recognized
+   in the case that they are preceded by a list_terminator.  Members
+   of the second group are for [[...]] commands.  Members of the
+   third group are recognized only under special circumstances. */
+%token IF THEN ELSE ELIF FI CASE ESAC FOR SELECT WHILE UNTIL DO DONE FUNCTION COPROC
+%token COND_START COND_END COND_ERROR
+%token IN BANG TIME TIMEOPT TIMEIGN
+
+/* More general tokens. yylex () knows how to make these. */
+%token <word> WORD ASSIGNMENT_WORD REDIR_WORD
+%token <number> NUMBER
+%token <word_list> ARITH_CMD ARITH_FOR_EXPRS
+%token <command> COND_CMD
+%token AND_AND OR_OR GREATER_GREATER LESS_LESS LESS_AND LESS_LESS_LESS
+%token GREATER_AND SEMI_SEMI SEMI_AND SEMI_SEMI_AND
+%token LESS_LESS_MINUS AND_GREATER AND_GREATER_GREATER LESS_GREATER
+%token GREATER_BAR BAR_AND
+
+/* The types that the various syntactical units return. */
+
+%type <command> inputunit command pipeline pipeline_command
+%type <command> list list0 list1 compound_list simple_list simple_list1
+%type <command> simple_command shell_command
+%type <command> for_command select_command case_command group_command
+%type <command> arith_command
+%type <command> cond_command
+%type <command> arith_for_command
+%type <command> coproc
+%type <command> function_def function_body if_command elif_clause subshell
+%type <redirect> redirection redirection_list
+%type <element> simple_command_element
+%type <word_list> word_list pattern
+%type <pattern> pattern_list case_clause_sequence case_clause
+%type <number> timespec
+%type <number> list_terminator
+
+%start inputunit
+
+%left '&' ';' '\n' yacc_EOF
+%left AND_AND OR_OR
+%right '|' BAR_AND
+%%
+
+inputunit:     simple_list simple_list_terminator
+                       {
+                         /* Case of regular command.  Discard the error
+                            safety net,and return the command just parsed. */
+                         global_command = $1;
+                         eof_encountered = 0;
+                         /* discard_parser_constructs (0); */
+                         if (parser_state & PST_CMDSUBST)
+                           parser_state |= PST_EOFTOKEN;
+                         YYACCEPT;
+                       }
+       |       '\n'
+                       {
+                         /* Case of regular command, but not a very
+                            interesting one.  Return a NULL command. */
+                         global_command = (COMMAND *)NULL;
+                         if (parser_state & PST_CMDSUBST)
+                           parser_state |= PST_EOFTOKEN;
+                         YYACCEPT;
+                       }
+       |       error '\n'
+                       {
+                         /* Error during parsing.  Return NULL command. */
+                         global_command = (COMMAND *)NULL;
+                         eof_encountered = 0;
+                         /* discard_parser_constructs (1); */
+                         if (interactive && parse_and_execute_level == 0)
+                           {
+                             YYACCEPT;
+                           }
+                         else
+                           {
+                             YYABORT;
+                           }
+                       }
+       |       yacc_EOF
+                       {
+                         /* Case of EOF seen by itself.  Do ignoreeof or
+                            not. */
+                         global_command = (COMMAND *)NULL;
+                         handle_eof_input_unit ();
+                         YYACCEPT;
+                       }
+       ;
+
+word_list:     WORD
+                       { $$ = make_word_list ($1, (WORD_LIST *)NULL); }
+       |       word_list WORD
+                       { $$ = make_word_list ($2, $1); }
+       ;
+
+redirection:   '>' WORD
+                       {
+                         source.dest = 1;
+                         redir.filename = $2;
+                         $$ = make_redirection (source, r_output_direction, redir, 0);
+                       }
+       |       '<' WORD
+                       {
+                         source.dest = 0;
+                         redir.filename = $2;
+                         $$ = make_redirection (source, r_input_direction, redir, 0);
+                       }
+       |       NUMBER '>' WORD
+                       {
+                         source.dest = $1;
+                         redir.filename = $3;
+                         $$ = make_redirection (source, r_output_direction, redir, 0);
+                       }
+       |       NUMBER '<' WORD
+                       {
+                         source.dest = $1;
+                         redir.filename = $3;
+                         $$ = make_redirection (source, r_input_direction, redir, 0);
+                       }
+       |       REDIR_WORD '>' WORD
+                       {
+                         source.filename = $1;
+                         redir.filename = $3;
+                         $$ = make_redirection (source, r_output_direction, redir, REDIR_VARASSIGN);
+                       }
+       |       REDIR_WORD '<' WORD
+                       {
+                         source.filename = $1;
+                         redir.filename = $3;
+                         $$ = make_redirection (source, r_input_direction, redir, REDIR_VARASSIGN);
+                       }
+       |       GREATER_GREATER WORD
+                       {
+                         source.dest = 1;
+                         redir.filename = $2;
+                         $$ = make_redirection (source, r_appending_to, redir, 0);
+                       }
+       |       NUMBER GREATER_GREATER WORD
+                       {
+                         source.dest = $1;
+                         redir.filename = $3;
+                         $$ = make_redirection (source, r_appending_to, redir, 0);
+                       }
+       |       REDIR_WORD GREATER_GREATER WORD
+                       {
+                         source.filename = $1;
+                         redir.filename = $3;
+                         $$ = make_redirection (source, r_appending_to, redir, REDIR_VARASSIGN);
+                       }
+       |       GREATER_BAR WORD
+                       {
+                         source.dest = 1;
+                         redir.filename = $2;
+                         $$ = make_redirection (source, r_output_force, redir, 0);
+                       }
+       |       NUMBER GREATER_BAR WORD
+                       {
+                         source.dest = $1;
+                         redir.filename = $3;
+                         $$ = make_redirection (source, r_output_force, redir, 0);
+                       }
+       |       REDIR_WORD GREATER_BAR WORD
+                       {
+                         source.filename = $1;
+                         redir.filename = $3;
+                         $$ = make_redirection (source, r_output_force, redir, REDIR_VARASSIGN);
+                       }
+       |       LESS_GREATER WORD
+                       {
+                         source.dest = 0;
+                         redir.filename = $2;
+                         $$ = make_redirection (source, r_input_output, redir, 0);
+                       }
+       |       NUMBER LESS_GREATER WORD
+                       {
+                         source.dest = $1;
+                         redir.filename = $3;
+                         $$ = make_redirection (source, r_input_output, redir, 0);
+                       }
+       |       REDIR_WORD LESS_GREATER WORD
+                       {
+                         source.filename = $1;
+                         redir.filename = $3;
+                         $$ = make_redirection (source, r_input_output, redir, REDIR_VARASSIGN);
+                       }
+       |       LESS_LESS WORD
+                       {
+                         source.dest = 0;
+                         redir.filename = $2;
+                         $$ = make_redirection (source, r_reading_until, redir, 0);
+                         redir_stack[need_here_doc++] = $$;
+                       }
+       |       NUMBER LESS_LESS WORD
+                       {
+                         source.dest = $1;
+                         redir.filename = $3;
+                         $$ = make_redirection (source, r_reading_until, redir, 0);
+                         redir_stack[need_here_doc++] = $$;
+                       }
+       |       REDIR_WORD LESS_LESS WORD
+                       {
+                         source.filename = $1;
+                         redir.filename = $3;
+                         $$ = make_redirection (source, r_reading_until, redir, REDIR_VARASSIGN);
+                         redir_stack[need_here_doc++] = $$;
+                       }
+       |       LESS_LESS_MINUS WORD
+                       {
+                         source.dest = 0;
+                         redir.filename = $2;
+                         $$ = make_redirection (source, r_deblank_reading_until, redir, 0);
+                         redir_stack[need_here_doc++] = $$;
+                       }
+       |       NUMBER LESS_LESS_MINUS WORD
+                       {
+                         source.dest = $1;
+                         redir.filename = $3;
+                         $$ = make_redirection (source, r_deblank_reading_until, redir, 0);
+                         redir_stack[need_here_doc++] = $$;
+                       }
+       |       REDIR_WORD  LESS_LESS_MINUS WORD
+                       {
+                         source.filename = $1;
+                         redir.filename = $3;
+                         $$ = make_redirection (source, r_deblank_reading_until, redir, REDIR_VARASSIGN);
+                         redir_stack[need_here_doc++] = $$;
+                       }
+       |       LESS_LESS_LESS WORD
+                       {
+                         source.dest = 0;
+                         redir.filename = $2;
+                         $$ = make_redirection (source, r_reading_string, redir, 0);
+                       }
+       |       NUMBER LESS_LESS_LESS WORD
+                       {
+                         source.dest = $1;
+                         redir.filename = $3;
+                         $$ = make_redirection (source, r_reading_string, redir, 0);
+                       }
+       |       REDIR_WORD LESS_LESS_LESS WORD
+                       {
+                         source.filename = $1;
+                         redir.filename = $3;
+                         $$ = make_redirection (source, r_reading_string, redir, REDIR_VARASSIGN);
+                       }
+       |       LESS_AND NUMBER
+                       {
+                         source.dest = 0;
+                         redir.dest = $2;
+                         $$ = make_redirection (source, r_duplicating_input, redir, 0);
+                       }
+       |       NUMBER LESS_AND NUMBER
+                       {
+                         source.dest = $1;
+                         redir.dest = $3;
+                         $$ = make_redirection (source, r_duplicating_input, redir, 0);
+                       }
+       |       REDIR_WORD LESS_AND NUMBER
+                       {
+                         source.filename = $1;
+                         redir.dest = $3;
+                         $$ = make_redirection (source, r_duplicating_input, redir, REDIR_VARASSIGN);
+                       }
+       |       GREATER_AND NUMBER
+                       {
+                         source.dest = 1;
+                         redir.dest = $2;
+                         $$ = make_redirection (source, r_duplicating_output, redir, 0);
+                       }
+       |       NUMBER GREATER_AND NUMBER
+                       {
+                         source.dest = $1;
+                         redir.dest = $3;
+                         $$ = make_redirection (source, r_duplicating_output, redir, 0);
+                       }
+       |       REDIR_WORD GREATER_AND NUMBER
+                       {
+                         source.filename = $1;
+                         redir.dest = $3;
+                         $$ = make_redirection (source, r_duplicating_output, redir, REDIR_VARASSIGN);
+                       }
+       |       LESS_AND WORD
+                       {
+                         source.dest = 0;
+                         redir.filename = $2;
+                         $$ = make_redirection (source, r_duplicating_input_word, redir, 0);
+                       }
+       |       NUMBER LESS_AND WORD
+                       {
+                         source.dest = $1;
+                         redir.filename = $3;
+                         $$ = make_redirection (source, r_duplicating_input_word, redir, 0);
+                       }
+       |       REDIR_WORD LESS_AND WORD
+                       {
+                         source.filename = $1;
+                         redir.filename = $3;
+                         $$ = make_redirection (source, r_duplicating_input_word, redir, REDIR_VARASSIGN);
+                       }
+       |       GREATER_AND WORD
+                       {
+                         source.dest = 1;
+                         redir.filename = $2;
+                         $$ = make_redirection (source, r_duplicating_output_word, redir, 0);
+                       }
+       |       NUMBER GREATER_AND WORD
+                       {
+                         source.dest = $1;
+                         redir.filename = $3;
+                         $$ = make_redirection (source, r_duplicating_output_word, redir, 0);
+                       }
+       |       REDIR_WORD GREATER_AND WORD
+                       {
+                         source.filename = $1;
+                         redir.filename = $3;
+                         $$ = make_redirection (source, r_duplicating_output_word, redir, REDIR_VARASSIGN);
+                       }
+       |       GREATER_AND '-'
+                       {
+                         source.dest = 1;
+                         redir.dest = 0;
+                         $$ = make_redirection (source, r_close_this, redir, 0);
+                       }
+       |       NUMBER GREATER_AND '-'
+                       {
+                         source.dest = $1;
+                         redir.dest = 0;
+                         $$ = make_redirection (source, r_close_this, redir, 0);
+                       }
+       |       REDIR_WORD GREATER_AND '-'
+                       {
+                         source.filename = $1;
+                         redir.dest = 0;
+                         $$ = make_redirection (source, r_close_this, redir, REDIR_VARASSIGN);
+                       }
+       |       LESS_AND '-'
+                       {
+                         source.dest = 0;
+                         redir.dest = 0;
+                         $$ = make_redirection (source, r_close_this, redir, 0);
+                       }
+       |       NUMBER LESS_AND '-'
+                       {
+                         source.dest = $1;
+                         redir.dest = 0;
+                         $$ = make_redirection (source, r_close_this, redir, 0);
+                       }
+       |       REDIR_WORD LESS_AND '-'
+                       {
+                         source.filename = $1;
+                         redir.dest = 0;
+                         $$ = make_redirection (source, r_close_this, redir, REDIR_VARASSIGN);
+                       }
+       |       AND_GREATER WORD
+                       {
+                         source.dest = 1;
+                         redir.filename = $2;
+                         $$ = make_redirection (source, r_err_and_out, redir, 0);
+                       }
+       |       AND_GREATER_GREATER WORD
+                       {
+                         source.dest = 1;
+                         redir.filename = $2;
+                         $$ = make_redirection (source, r_append_err_and_out, redir, 0);
+                       }
+       ;
+
+simple_command_element: WORD
+                       { $$.word = $1; $$.redirect = 0; }
+       |       ASSIGNMENT_WORD
+                       { $$.word = $1; $$.redirect = 0; }
+       |       redirection
+                       { $$.redirect = $1; $$.word = 0; }
+       ;
+
+redirection_list: redirection
+                       {
+                         $$ = $1;
+                       }
+       |       redirection_list redirection
+                       {
+                         register REDIRECT *t;
+
+                         for (t = $1; t->next; t = t->next)
+                           ;
+                         t->next = $2;
+                         $$ = $1;
+                       }
+       ;
+
+simple_command:        simple_command_element
+                       { $$ = make_simple_command ($1, (COMMAND *)NULL); }
+       |       simple_command simple_command_element
+                       { $$ = make_simple_command ($2, $1); }
+       ;
+
+command:       simple_command
+                       { $$ = clean_simple_command ($1); }
+       |       shell_command
+                       { $$ = $1; }
+       |       shell_command redirection_list
+                       {
+                         COMMAND *tc;
+
+                         tc = $1;
+                         if (tc->redirects)
+                           {
+                             register REDIRECT *t;
+                             for (t = tc->redirects; t->next; t = t->next)
+                               ;
+                             t->next = $2;
+                           }
+                         else
+                           tc->redirects = $2;
+                         $$ = $1;
+                       }
+       |       function_def
+                       { $$ = $1; }
+       |       coproc
+                       { $$ = $1; }
+       ;
+
+shell_command: for_command
+                       { $$ = $1; }
+       |       case_command
+                       { $$ = $1; }
+       |       WHILE compound_list DO compound_list DONE
+                       { $$ = make_while_command ($2, $4); }
+       |       UNTIL compound_list DO compound_list DONE
+                       { $$ = make_until_command ($2, $4); }
+       |       select_command
+                       { $$ = $1; }
+       |       if_command
+                       { $$ = $1; }
+       |       subshell
+                       { $$ = $1; }
+       |       group_command
+                       { $$ = $1; }
+       |       arith_command
+                       { $$ = $1; }
+       |       cond_command
+                       { $$ = $1; }
+       |       arith_for_command
+                       { $$ = $1; }
+       ;
+
+for_command:   FOR WORD newline_list DO compound_list DONE
+                       {
+                         $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
+                         if (word_top > 0) word_top--;
+                       }
+       |       FOR WORD newline_list '{' compound_list '}'
+                       {
+                         $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
+                         if (word_top > 0) word_top--;
+                       }
+       |       FOR WORD ';' newline_list DO compound_list DONE
+                       {
+                         $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
+                         if (word_top > 0) word_top--;
+                       }
+       |       FOR WORD ';' newline_list '{' compound_list '}'
+                       {
+                         $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
+                         if (word_top > 0) word_top--;
+                       }
+       |       FOR WORD newline_list IN word_list list_terminator newline_list DO compound_list DONE
+                       {
+                         $$ = make_for_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
+                         if (word_top > 0) word_top--;
+                       }
+       |       FOR WORD newline_list IN word_list list_terminator newline_list '{' compound_list '}'
+                       {
+                         $$ = make_for_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
+                         if (word_top > 0) word_top--;
+                       }
+       |       FOR WORD newline_list IN list_terminator newline_list DO compound_list DONE
+                       {
+                         $$ = make_for_command ($2, (WORD_LIST *)NULL, $8, word_lineno[word_top]);
+                         if (word_top > 0) word_top--;
+                       }
+       |       FOR WORD newline_list IN list_terminator newline_list '{' compound_list '}'
+                       {
+                         $$ = make_for_command ($2, (WORD_LIST *)NULL, $8, word_lineno[word_top]);
+                         if (word_top > 0) word_top--;
+                       }
+       ;
+
+arith_for_command:     FOR ARITH_FOR_EXPRS list_terminator newline_list DO compound_list DONE
+                               {
+                                 $$ = make_arith_for_command ($2, $6, arith_for_lineno);
+                                 if (word_top > 0) word_top--;
+                               }
+       |               FOR ARITH_FOR_EXPRS list_terminator newline_list '{' compound_list '}'
+                               {
+                                 $$ = make_arith_for_command ($2, $6, arith_for_lineno);
+                                 if (word_top > 0) word_top--;
+                               }
+       |               FOR ARITH_FOR_EXPRS DO compound_list DONE
+                               {
+                                 $$ = make_arith_for_command ($2, $4, arith_for_lineno);
+                                 if (word_top > 0) word_top--;
+                               }
+       |               FOR ARITH_FOR_EXPRS '{' compound_list '}'
+                               {
+                                 $$ = make_arith_for_command ($2, $4, arith_for_lineno);
+                                 if (word_top > 0) word_top--;
+                               }
+       ;
+
+select_command:        SELECT WORD newline_list DO list DONE
+                       {
+                         $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
+                         if (word_top > 0) word_top--;
+                       }
+       |       SELECT WORD newline_list '{' list '}'
+                       {
+                         $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
+                         if (word_top > 0) word_top--;
+                       }
+       |       SELECT WORD ';' newline_list DO list DONE
+                       {
+                         $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
+                         if (word_top > 0) word_top--;
+                       }
+       |       SELECT WORD ';' newline_list '{' list '}'
+                       {
+                         $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
+                         if (word_top > 0) word_top--;
+                       }
+       |       SELECT WORD newline_list IN word_list list_terminator newline_list DO list DONE
+                       {
+                         $$ = make_select_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
+                         if (word_top > 0) word_top--;
+                       }
+       |       SELECT WORD newline_list IN word_list list_terminator newline_list '{' list '}'
+                       {
+                         $$ = make_select_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
+                         if (word_top > 0) word_top--;
+                       }
+       ;
+
+case_command:  CASE WORD newline_list IN newline_list ESAC
+                       {
+                         $$ = make_case_command ($2, (PATTERN_LIST *)NULL, word_lineno[word_top]);
+                         if (word_top > 0) word_top--;
+                       }
+       |       CASE WORD newline_list IN case_clause_sequence newline_list ESAC
+                       {
+                         $$ = make_case_command ($2, $5, word_lineno[word_top]);
+                         if (word_top > 0) word_top--;
+                       }
+       |       CASE WORD newline_list IN case_clause ESAC
+                       {
+                         $$ = make_case_command ($2, $5, word_lineno[word_top]);
+                         if (word_top > 0) word_top--;
+                       }
+       ;
+
+function_def:  WORD '(' ')' newline_list function_body
+                       { $$ = make_function_def ($1, $5, function_dstart, function_bstart); }
+
+       |       FUNCTION WORD '(' ')' newline_list function_body
+                       { $$ = make_function_def ($2, $6, function_dstart, function_bstart); }
+
+       |       FUNCTION WORD newline_list function_body
+                       { $$ = make_function_def ($2, $4, function_dstart, function_bstart); }
+       ;
+
+function_body: shell_command
+                       { $$ = $1; }
+       |       shell_command redirection_list
+                       {
+                         COMMAND *tc;
+
+                         tc = $1;
+                         /* According to Posix.2 3.9.5, redirections
+                            specified after the body of a function should
+                            be attached to the function and performed when
+                            the function is executed, not as part of the
+                            function definition command. */
+                         /* XXX - I don't think it matters, but we might
+                            want to change this in the future to avoid
+                            problems differentiating between a function
+                            definition with a redirection and a function
+                            definition containing a single command with a
+                            redirection.  The two are semantically equivalent,
+                            though -- the only difference is in how the
+                            command printing code displays the redirections. */
+                         if (tc->redirects)
+                           {
+                             register REDIRECT *t;
+                             for (t = tc->redirects; t->next; t = t->next)
+                               ;
+                             t->next = $2;
+                           }
+                         else
+                           tc->redirects = $2;
+                         $$ = $1;
+                       }
+       ;
+
+subshell:      '(' compound_list ')'
+                       {
+                         $$ = make_subshell_command ($2);
+                         $$->flags |= CMD_WANT_SUBSHELL;
+                       }
+       ;
+
+coproc:                COPROC shell_command
+                       {
+                         $$ = make_coproc_command ("COPROC", $2);
+                         $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
+                       }
+       |       COPROC shell_command redirection_list
+                       {
+                         COMMAND *tc;
+
+                         tc = $2;
+                         if (tc->redirects)
+                           {
+                             register REDIRECT *t;
+                             for (t = tc->redirects; t->next; t = t->next)
+                               ;
+                             t->next = $3;
+                           }
+                         else
+                           tc->redirects = $3;
+                         $$ = make_coproc_command ("COPROC", $2);
+                         $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
+                       }
+       |       COPROC WORD shell_command
+                       {
+                         $$ = make_coproc_command ($2->word, $3);
+                         $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
+                       }
+       |       COPROC WORD shell_command redirection_list
+                       {
+                         COMMAND *tc;
+
+                         tc = $3;
+                         if (tc->redirects)
+                           {
+                             register REDIRECT *t;
+                             for (t = tc->redirects; t->next; t = t->next)
+                               ;
+                             t->next = $4;
+                           }
+                         else
+                           tc->redirects = $4;
+                         $$ = make_coproc_command ($2->word, $3);
+                         $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
+                       }
+       |       COPROC simple_command
+                       {
+                         $$ = make_coproc_command ("COPROC", clean_simple_command ($2));
+                         $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
+                       }
+       ;
+
+if_command:    IF compound_list THEN compound_list FI
+                       { $$ = make_if_command ($2, $4, (COMMAND *)NULL); }
+       |       IF compound_list THEN compound_list ELSE compound_list FI
+                       { $$ = make_if_command ($2, $4, $6); }
+       |       IF compound_list THEN compound_list elif_clause FI
+                       { $$ = make_if_command ($2, $4, $5); }
+       ;
+
+
+group_command: '{' compound_list '}'
+                       { $$ = make_group_command ($2); }
+       ;
+
+arith_command: ARITH_CMD
+                       { $$ = make_arith_command ($1); }
+       ;
+
+cond_command:  COND_START COND_CMD COND_END
+                       { $$ = $2; }
+       ; 
+
+elif_clause:   ELIF compound_list THEN compound_list
+                       { $$ = make_if_command ($2, $4, (COMMAND *)NULL); }
+       |       ELIF compound_list THEN compound_list ELSE compound_list
+                       { $$ = make_if_command ($2, $4, $6); }
+       |       ELIF compound_list THEN compound_list elif_clause
+                       { $$ = make_if_command ($2, $4, $5); }
+       ;
+
+case_clause:   pattern_list
+       |       case_clause_sequence pattern_list
+                       { $2->next = $1; $$ = $2; }
+       ;
+
+pattern_list:  newline_list pattern ')' compound_list
+                       { $$ = make_pattern_list ($2, $4); }
+       |       newline_list pattern ')' newline_list
+                       { $$ = make_pattern_list ($2, (COMMAND *)NULL); }
+       |       newline_list '(' pattern ')' compound_list
+                       { $$ = make_pattern_list ($3, $5); }
+       |       newline_list '(' pattern ')' newline_list
+                       { $$ = make_pattern_list ($3, (COMMAND *)NULL); }
+       ;
+
+case_clause_sequence:  pattern_list SEMI_SEMI
+                       { $$ = $1; }
+       |       case_clause_sequence pattern_list SEMI_SEMI
+                       { $2->next = $1; $$ = $2; }
+       |       pattern_list SEMI_AND
+                       { $1->flags |= CASEPAT_FALLTHROUGH; $$ = $1; }
+       |       case_clause_sequence pattern_list SEMI_AND
+                       { $2->flags |= CASEPAT_FALLTHROUGH; $2->next = $1; $$ = $2; }
+       |       pattern_list SEMI_SEMI_AND
+                       { $1->flags |= CASEPAT_TESTNEXT; $$ = $1; }
+       |       case_clause_sequence pattern_list SEMI_SEMI_AND
+                       { $2->flags |= CASEPAT_TESTNEXT; $2->next = $1; $$ = $2; }      
+       ;
+
+pattern:       WORD
+                       { $$ = make_word_list ($1, (WORD_LIST *)NULL); }
+       |       pattern '|' WORD
+                       { $$ = make_word_list ($3, $1); }
+       ;
+
+/* A list allows leading or trailing newlines and
+   newlines as operators (equivalent to semicolons).
+   It must end with a newline or semicolon.
+   Lists are used within commands such as if, for, while.  */
+
+list:          newline_list list0
+                       {
+                         $$ = $2;
+                         if (need_here_doc)
+                           gather_here_documents ();
+                        }
+       ;
+
+compound_list: list
+       |       newline_list list1
+                       {
+                         $$ = $2;
+                       }
+       ;
+
+list0:         list1 '\n' newline_list
+       |       list1 '&' newline_list
+                       {
+                         if ($1->type == cm_connection)
+                           $$ = connect_async_list ($1, (COMMAND *)NULL, '&');
+                         else
+                           $$ = command_connect ($1, (COMMAND *)NULL, '&');
+                       }
+       |       list1 ';' newline_list
+
+       ;
+
+list1:         list1 AND_AND newline_list list1
+                       { $$ = command_connect ($1, $4, AND_AND); }
+       |       list1 OR_OR newline_list list1
+                       { $$ = command_connect ($1, $4, OR_OR); }
+       |       list1 '&' newline_list list1
+                       {
+                         if ($1->type == cm_connection)
+                           $$ = connect_async_list ($1, $4, '&');
+                         else
+                           $$ = command_connect ($1, $4, '&');
+                       }
+       |       list1 ';' newline_list list1
+                       { $$ = command_connect ($1, $4, ';'); }
+       |       list1 '\n' newline_list list1
+                       { $$ = command_connect ($1, $4, ';'); }
+       |       pipeline_command
+                       { $$ = $1; }
+       ;
+
+simple_list_terminator:        '\n'
+       |       yacc_EOF
+       ;
+
+list_terminator:'\n'
+               { $$ = '\n'; }
+       |       ';'
+               { $$ = ';'; }
+       |       yacc_EOF
+               { $$ = yacc_EOF; }
+       ;
+
+newline_list:
+       |       newline_list '\n'
+       ;
+
+/* A simple_list is a list that contains no significant newlines
+   and no leading or trailing newlines.  Newlines are allowed
+   only following operators, where they are not significant.
+
+   This is what an inputunit consists of.  */
+
+simple_list:   simple_list1
+                       {
+                         $$ = $1;
+                         if (need_here_doc)
+                           gather_here_documents ();
+                         if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token)
+                           {
+                             global_command = $1;
+                             eof_encountered = 0;
+                             rewind_input_string ();
+                             YYACCEPT;
+                           }
+                       }
+       |       simple_list1 '&'
+                       {
+                         if ($1->type == cm_connection)
+                           $$ = connect_async_list ($1, (COMMAND *)NULL, '&');
+                         else
+                           $$ = command_connect ($1, (COMMAND *)NULL, '&');
+                         if (need_here_doc)
+                           gather_here_documents ();
+                         if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token)
+                           {
+                             global_command = $1;
+                             eof_encountered = 0;
+                             rewind_input_string ();
+                             YYACCEPT;
+                           }
+                       }
+       |       simple_list1 ';'
+                       {
+                         $$ = $1;
+                         if (need_here_doc)
+                           gather_here_documents ();
+                         if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token)
+                           {
+                             global_command = $1;
+                             eof_encountered = 0;
+                             rewind_input_string ();
+                             YYACCEPT;
+                           }
+                       }
+       ;
+
+simple_list1:  simple_list1 AND_AND newline_list simple_list1
+                       { $$ = command_connect ($1, $4, AND_AND); }
+       |       simple_list1 OR_OR newline_list simple_list1
+                       { $$ = command_connect ($1, $4, OR_OR); }
+       |       simple_list1 '&' simple_list1
+                       {
+                         if ($1->type == cm_connection)
+                           $$ = connect_async_list ($1, $3, '&');
+                         else
+                           $$ = command_connect ($1, $3, '&');
+                       }
+       |       simple_list1 ';' simple_list1
+                       { $$ = command_connect ($1, $3, ';'); }
+
+       |       pipeline_command
+                       { $$ = $1; }
+       ;
+
+pipeline_command: pipeline
+                       { $$ = $1; }                    
+       |       BANG pipeline_command
+                       {
+                         if ($2)
+                           $2->flags ^= CMD_INVERT_RETURN;     /* toggle */
+                         $$ = $2;
+                       }
+       |       timespec pipeline_command
+                       {
+                         if ($2)
+                           $2->flags |= $1;
+                         $$ = $2;
+                       }
+       |       timespec list_terminator
+                       {
+                         ELEMENT x;
+
+                         /* Boy, this is unclean.  `time' by itself can
+                            time a null command.  We cheat and push a
+                            newline back if the list_terminator was a newline
+                            to avoid the double-newline problem (one to
+                            terminate this, one to terminate the command) */
+                         x.word = 0;
+                         x.redirect = 0;
+                         $$ = make_simple_command (x, (COMMAND *)NULL);
+                         $$->flags |= $1;
+                         /* XXX - let's cheat and push a newline back */
+                         if ($2 == '\n')
+                           token_to_read = '\n';
+                       }
+       |       BANG list_terminator
+                       {
+                         ELEMENT x;
+
+                         /* This is just as unclean.  Posix says that `!'
+                            by itself should be equivalent to `false'.
+                            We cheat and push a
+                            newline back if the list_terminator was a newline
+                            to avoid the double-newline problem (one to
+                            terminate this, one to terminate the command) */
+                         x.word = 0;
+                         x.redirect = 0;
+                         $$ = make_simple_command (x, (COMMAND *)NULL);
+                         $$->flags |= CMD_INVERT_RETURN;
+                         /* XXX - let's cheat and push a newline back */
+                         if ($2 == '\n')
+                           token_to_read = '\n';
+                       }
+       ;
+
+pipeline:      pipeline '|' newline_list pipeline
+                       { $$ = command_connect ($1, $4, '|'); }
+       |       pipeline BAR_AND newline_list pipeline
+                       {
+                         /* Make cmd1 |& cmd2 equivalent to cmd1 2>&1 | cmd2 */
+                         COMMAND *tc;
+                         REDIRECTEE rd, sd;
+                         REDIRECT *r;
+
+                         tc = $1->type == cm_simple ? (COMMAND *)$1->value.Simple : $1;
+                         sd.dest = 2;
+                         rd.dest = 1;
+                         r = make_redirection (sd, r_duplicating_output, rd, 0);
+                         if (tc->redirects)
+                           {
+                             register REDIRECT *t;
+                             for (t = tc->redirects; t->next; t = t->next)
+                               ;
+                             t->next = r;
+                           }
+                         else
+                           tc->redirects = r;
+
+                         $$ = command_connect ($1, $4, '|');
+                       }
+       |       command
+                       { $$ = $1; }
+       ;
+
+timespec:      TIME
+                       { $$ = CMD_TIME_PIPELINE; }
+       |       TIME TIMEOPT
+                       { $$ = CMD_TIME_PIPELINE|CMD_TIME_POSIX; }
+       |       TIME TIMEOPT TIMEIGN
+                       { $$ = CMD_TIME_PIPELINE|CMD_TIME_POSIX; }
+       ;
+%%
+
+/* Initial size to allocate for tokens, and the
+   amount to grow them by. */
+#define TOKEN_DEFAULT_INITIAL_SIZE 496
+#define TOKEN_DEFAULT_GROW_SIZE 512
+
+/* Should we call prompt_again? */
+#define SHOULD_PROMPT() \
+  (interactive && (bash_input.type == st_stdin || bash_input.type == st_stream))
+
+#if defined (ALIAS)
+#  define expanding_alias() (pushed_string_list && pushed_string_list->expander)
+#else
+#  define expanding_alias() 0
+#endif
+
+/* Global var is non-zero when end of file has been reached. */
+int EOF_Reached = 0;
+
+#ifdef DEBUG
+static void
+debug_parser (i)
+     int i;
+{
+#if YYDEBUG != 0
+  yydebug = i;
+#endif
+}
+#endif
+
+/* yy_getc () returns the next available character from input or EOF.
+   yy_ungetc (c) makes `c' the next character to read.
+   init_yy_io (get, unget, type, location) makes the function GET the
+   installed function for getting the next character, makes UNGET the
+   installed function for un-getting a character, sets the type of stream
+   (either string or file) from TYPE, and makes LOCATION point to where
+   the input is coming from. */
+
+/* Unconditionally returns end-of-file. */
+int
+return_EOF ()
+{
+  return (EOF);
+}
+
+/* Variable containing the current get and unget functions.
+   See ./input.h for a clearer description. */
+BASH_INPUT bash_input;
+
+/* Set all of the fields in BASH_INPUT to NULL.  Free bash_input.name if it
+   is non-null, avoiding a memory leak. */
+void
+initialize_bash_input ()
+{
+  bash_input.type = st_none;
+  FREE (bash_input.name);
+  bash_input.name = (char *)NULL;
+  bash_input.location.file = (FILE *)NULL;
+  bash_input.location.string = (char *)NULL;
+  bash_input.getter = (sh_cget_func_t *)NULL;
+  bash_input.ungetter = (sh_cunget_func_t *)NULL;
+}
+
+/* Set the contents of the current bash input stream from
+   GET, UNGET, TYPE, NAME, and LOCATION. */
+void
+init_yy_io (get, unget, type, name, location)
+     sh_cget_func_t *get;
+     sh_cunget_func_t *unget;
+     enum stream_type type;
+     const char *name;
+     INPUT_STREAM location;
+{
+  bash_input.type = type;
+  FREE (bash_input.name);
+  bash_input.name = name ? savestring (name) : (char *)NULL;
+
+  /* XXX */
+#if defined (CRAY)
+  memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location));
+#else
+  bash_input.location = location;
+#endif
+  bash_input.getter = get;
+  bash_input.ungetter = unget;
+}
+
+char *
+yy_input_name ()
+{
+  return (bash_input.name ? bash_input.name : "stdin");
+}
+
+/* Call this to get the next character of input. */
+static int
+yy_getc ()
+{
+  return (*(bash_input.getter)) ();
+}
+
+/* Call this to unget C.  That is, to make C the next character
+   to be read. */
+static int
+yy_ungetc (c)
+     int c;
+{
+  return (*(bash_input.ungetter)) (c);
+}
+
+#if defined (BUFFERED_INPUT)
+#ifdef INCLUDE_UNUSED
+int
+input_file_descriptor ()
+{
+  switch (bash_input.type)
+    {
+    case st_stream:
+      return (fileno (bash_input.location.file));
+    case st_bstream:
+      return (bash_input.location.buffered_fd);
+    case st_stdin:
+    default:
+      return (fileno (stdin));
+    }
+}
+#endif
+#endif /* BUFFERED_INPUT */
+
+/* **************************************************************** */
+/*                                                                 */
+/*               Let input be read from readline ().               */
+/*                                                                 */
+/* **************************************************************** */
+
+#if defined (READLINE)
+char *current_readline_prompt = (char *)NULL;
+char *current_readline_line = (char *)NULL;
+int current_readline_line_index = 0;
+
+static int
+yy_readline_get ()
+{
+  SigHandler *old_sigint;
+  int line_len;
+  unsigned char c;
+
+  if (!current_readline_line)
+    {
+      if (!bash_readline_initialized)
+       initialize_readline ();
+
+#if defined (JOB_CONTROL)
+      if (job_control)
+       give_terminal_to (shell_pgrp, 0);
+#endif /* JOB_CONTROL */
+
+      old_sigint = (SigHandler *)IMPOSSIBLE_TRAP_HANDLER;
+      if (signal_is_ignored (SIGINT) == 0)
+       {
+         /* interrupt_immediately++; */
+         old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
+       }
+
+      current_readline_line = readline (current_readline_prompt ?
+                                         current_readline_prompt : "");
+
+      CHECK_TERMSIG;
+      if (signal_is_ignored (SIGINT) == 0)
+       {
+         /* interrupt_immediately--; */
+         if (old_sigint != IMPOSSIBLE_TRAP_HANDLER)
+           set_signal_handler (SIGINT, old_sigint);
+       }
+
+#if 0
+      /* Reset the prompt to the decoded value of prompt_string_pointer. */
+      reset_readline_prompt ();
+#endif
+
+      if (current_readline_line == 0)
+       return (EOF);
+
+      current_readline_line_index = 0;
+      line_len = strlen (current_readline_line);
+
+      current_readline_line = (char *)xrealloc (current_readline_line, 2 + line_len);
+      current_readline_line[line_len++] = '\n';
+      current_readline_line[line_len] = '\0';
+    }
+
+  if (current_readline_line[current_readline_line_index] == 0)
+    {
+      free (current_readline_line);
+      current_readline_line = (char *)NULL;
+      return (yy_readline_get ());
+    }
+  else
+    {
+      c = current_readline_line[current_readline_line_index++];
+      return (c);
+    }
+}
+
+static int
+yy_readline_unget (c)
+     int c;
+{
+  if (current_readline_line_index && current_readline_line)
+    current_readline_line[--current_readline_line_index] = c;
+  return (c);
+}
+
+void
+with_input_from_stdin ()
+{
+  INPUT_STREAM location;
+
+  if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0)
+    {
+      location.string = current_readline_line;
+      init_yy_io (yy_readline_get, yy_readline_unget,
+                 st_stdin, "readline stdin", location);
+    }
+}
+
+#else  /* !READLINE */
+
+void
+with_input_from_stdin ()
+{
+  with_input_from_stream (stdin, "stdin");
+}
+#endif /* !READLINE */
+
+/* **************************************************************** */
+/*                                                                 */
+/*   Let input come from STRING.  STRING is zero terminated.       */
+/*                                                                 */
+/* **************************************************************** */
+
+static int
+yy_string_get ()
+{
+  register char *string;
+  register unsigned char c;
+
+  string = bash_input.location.string;
+
+  /* If the string doesn't exist, or is empty, EOF found. */
+  if (string && *string)
+    {
+      c = *string++;
+      bash_input.location.string = string;
+      return (c);
+    }
+  else
+    return (EOF);
+}
+
+static int
+yy_string_unget (c)
+     int c;
+{
+  *(--bash_input.location.string) = c;
+  return (c);
+}
+
+void
+with_input_from_string (string, name)
+     char *string;
+     const char *name;
+{
+  INPUT_STREAM location;
+
+  location.string = string;
+  init_yy_io (yy_string_get, yy_string_unget, st_string, name, location);
+}
+
+/* Count the number of characters we've consumed from bash_input.location.string
+   and read into shell_input_line, but have not returned from shell_getc.
+   That is the true input location.  Rewind bash_input.location.string by
+   that number of characters, so it points to the last character actually
+   consumed by the parser. */
+static void
+rewind_input_string ()
+{
+  int xchars;
+
+  /* number of unconsumed characters in the input -- XXX need to take newlines
+     into account, e.g., $(...\n) */
+  xchars = shell_input_line_len - shell_input_line_index;
+  if (bash_input.location.string[-1] == '\n')
+    xchars++;
+
+  /* XXX - how to reflect bash_input.location.string back to string passed to
+     parse_and_execute or xparse_dolparen?  xparse_dolparen needs to know how
+     far into the string we parsed.  parse_and_execute knows where bash_input.
+     location.string is, and how far from orig_string that is -- that's the
+     number of characters the command consumed. */
+
+  /* bash_input.location.string - xchars should be where we parsed to */
+  /* need to do more validation on xchars value for sanity -- test cases. */
+  bash_input.location.string -= xchars;
+}
+
+/* **************************************************************** */
+/*                                                                 */
+/*                  Let input come from STREAM.                    */
+/*                                                                 */
+/* **************************************************************** */
+
+/* These two functions used to test the value of the HAVE_RESTARTABLE_SYSCALLS
+   define, and just use getc/ungetc if it was defined, but since bash
+   installs its signal handlers without the SA_RESTART flag, some signals
+   (like SIGCHLD, SIGWINCH, etc.) received during a read(2) will not cause
+   the read to be restarted.  We need to restart it ourselves. */
+
+static int
+yy_stream_get ()
+{
+  int result;
+
+  result = EOF;
+  if (bash_input.location.file)
+    {
+#if 0
+      if (interactive)
+       interrupt_immediately++;
+#endif
+
+      /* XXX - don't need terminate_immediately; getc_with_restart checks
+        for terminating signals itself if read returns < 0 */
+      result = getc_with_restart (bash_input.location.file);
+
+#if 0
+      if (interactive)
+       interrupt_immediately--;
+#endif
+    }
+  return (result);
+}
+
+static int
+yy_stream_unget (c)
+     int c;
+{
+  return (ungetc_with_restart (c, bash_input.location.file));
+}
+
+void
+with_input_from_stream (stream, name)
+     FILE *stream;
+     const char *name;
+{
+  INPUT_STREAM location;
+
+  location.file = stream;
+  init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location);
+}
+
+typedef struct stream_saver {
+  struct stream_saver *next;
+  BASH_INPUT bash_input;
+  int line;
+#if defined (BUFFERED_INPUT)
+  BUFFERED_STREAM *bstream;
+#endif /* BUFFERED_INPUT */
+} STREAM_SAVER;
+
+/* The globally known line number. */
+int line_number = 0;
+
+/* The line number offset set by assigning to LINENO.  Not currently used. */
+int line_number_base = 0;
+
+#if defined (COND_COMMAND)
+static int cond_lineno;
+static int cond_token;
+#endif
+
+STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
+
+void
+push_stream (reset_lineno)
+     int reset_lineno;
+{
+  STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
+
+  xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT));
+
+#if defined (BUFFERED_INPUT)
+  saver->bstream = (BUFFERED_STREAM *)NULL;
+  /* If we have a buffered stream, clear out buffers[fd]. */
+  if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
+    saver->bstream = set_buffered_stream (bash_input.location.buffered_fd,
+                                         (BUFFERED_STREAM *)NULL);
+#endif /* BUFFERED_INPUT */
+
+  saver->line = line_number;
+  bash_input.name = (char *)NULL;
+  saver->next = stream_list;
+  stream_list = saver;
+  EOF_Reached = 0;
+  if (reset_lineno)
+    line_number = 0;
+}
+
+void
+pop_stream ()
+{
+  if (!stream_list)
+    EOF_Reached = 1;
+  else
+    {
+      STREAM_SAVER *saver = stream_list;
+
+      EOF_Reached = 0;
+      stream_list = stream_list->next;
+
+      init_yy_io (saver->bash_input.getter,
+                 saver->bash_input.ungetter,
+                 saver->bash_input.type,
+                 saver->bash_input.name,
+                 saver->bash_input.location);
+
+#if defined (BUFFERED_INPUT)
+      /* If we have a buffered stream, restore buffers[fd]. */
+      /* If the input file descriptor was changed while this was on the
+        save stack, update the buffered fd to the new file descriptor and
+        re-establish the buffer <-> bash_input fd correspondence. */
+      if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
+       {
+         if (bash_input_fd_changed)
+           {
+             bash_input_fd_changed = 0;
+             if (default_buffered_input >= 0)
+               {
+                 bash_input.location.buffered_fd = default_buffered_input;
+                 saver->bstream->b_fd = default_buffered_input;
+                 SET_CLOSE_ON_EXEC (default_buffered_input);
+               }
+           }
+         /* XXX could free buffered stream returned as result here. */
+         set_buffered_stream (bash_input.location.buffered_fd, saver->bstream);
+       }
+#endif /* BUFFERED_INPUT */
+
+      line_number = saver->line;
+
+      FREE (saver->bash_input.name);
+      free (saver);
+    }
+}
+
+/* Return 1 if a stream of type TYPE is saved on the stack. */
+int
+stream_on_stack (type)
+     enum stream_type type;
+{
+  register STREAM_SAVER *s;
+
+  for (s = stream_list; s; s = s->next)
+    if (s->bash_input.type == type)
+      return 1;
+  return 0;
+}
+
+/* Save the current token state and return it in a malloced array. */
+int *
+save_token_state ()
+{
+  int *ret;
+
+  ret = (int *)xmalloc (4 * sizeof (int));
+  ret[0] = last_read_token;
+  ret[1] = token_before_that;
+  ret[2] = two_tokens_ago;
+  ret[3] = current_token;
+  return ret;
+}
+
+void
+restore_token_state (ts)
+     int *ts;
+{
+  if (ts == 0)
+    return;
+  last_read_token = ts[0];
+  token_before_that = ts[1];
+  two_tokens_ago = ts[2];
+  current_token = ts[3];
+}
+
+/*
+ * This is used to inhibit alias expansion and reserved word recognition
+ * inside case statement pattern lists.  A `case statement pattern list' is:
+ *
+ *     everything between the `in' in a `case word in' and the next ')'
+ *     or `esac'
+ *     everything between a `;;' and the next `)' or `esac'
+ */
+
+#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
+
+#define END_OF_ALIAS 0
+
+/*
+ * Pseudo-global variables used in implementing token-wise alias expansion.
+ */
+
+/*
+ * Pushing and popping strings.  This works together with shell_getc to
+ * implement alias expansion on a per-token basis.
+ */
+
+typedef struct string_saver {
+  struct string_saver *next;
+  int expand_alias;  /* Value to set expand_alias to when string is popped. */
+  char *saved_line;
+#if defined (ALIAS)
+  alias_t *expander;   /* alias that caused this line to be pushed. */
+#endif
+  size_t saved_line_size, saved_line_index;
+  int saved_line_terminator;
+} STRING_SAVER;
+
+STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL;
+
+/*
+ * Push the current shell_input_line onto a stack of such lines and make S
+ * the current input.  Used when expanding aliases.  EXPAND is used to set
+ * the value of expand_next_token when the string is popped, so that the
+ * word after the alias in the original line is handled correctly when the
+ * alias expands to multiple words.  TOKEN is the token that was expanded
+ * into S; it is saved and used to prevent infinite recursive expansion.
+ */
+static void
+push_string (s, expand, ap)
+     char *s;
+     int expand;
+     alias_t *ap;
+{
+  STRING_SAVER *temp = (STRING_SAVER *)xmalloc (sizeof (STRING_SAVER));
+
+  temp->expand_alias = expand;
+  temp->saved_line = shell_input_line;
+  temp->saved_line_size = shell_input_line_size;
+  temp->saved_line_index = shell_input_line_index;
+  temp->saved_line_terminator = shell_input_line_terminator;
+#if defined (ALIAS)
+  temp->expander = ap;
+#endif
+  temp->next = pushed_string_list;
+  pushed_string_list = temp;
+
+#if defined (ALIAS)
+  if (ap)
+    ap->flags |= AL_BEINGEXPANDED;
+#endif
+
+  shell_input_line = s;
+  shell_input_line_size = strlen (s);
+  shell_input_line_index = 0;
+  shell_input_line_terminator = '\0';
+#if 0
+  parser_state &= ~PST_ALEXPNEXT;      /* XXX */
+#endif
+
+  set_line_mbstate ();
+}
+
+/*
+ * Make the top of the pushed_string stack be the current shell input.
+ * Only called when there is something on the stack.  Called from shell_getc
+ * when it thinks it has consumed the string generated by an alias expansion
+ * and needs to return to the original input line.
+ */
+static void
+pop_string ()
+{
+  STRING_SAVER *t;
+
+  FREE (shell_input_line);
+  shell_input_line = pushed_string_list->saved_line;
+  shell_input_line_index = pushed_string_list->saved_line_index;
+  shell_input_line_size = pushed_string_list->saved_line_size;
+  shell_input_line_terminator = pushed_string_list->saved_line_terminator;
+
+  if (pushed_string_list->expand_alias)
+    parser_state |= PST_ALEXPNEXT;
+  else
+    parser_state &= ~PST_ALEXPNEXT;
+
+  t = pushed_string_list;
+  pushed_string_list = pushed_string_list->next;
+
+#if defined (ALIAS)
+  if (t->expander)
+    t->expander->flags &= ~AL_BEINGEXPANDED;
+#endif
+
+  free ((char *)t);
+
+  set_line_mbstate ();
+}
+
+static void
+free_string_list ()
+{
+  register STRING_SAVER *t, *t1;
+
+  for (t = pushed_string_list; t; )
+    {
+      t1 = t->next;
+      FREE (t->saved_line);
+#if defined (ALIAS)
+      if (t->expander)
+       t->expander->flags &= ~AL_BEINGEXPANDED;
+#endif
+      free ((char *)t);
+      t = t1;
+    }
+  pushed_string_list = (STRING_SAVER *)NULL;
+}
+
+#endif /* ALIAS || DPAREN_ARITHMETIC */
+
+void
+free_pushed_string_input ()
+{
+#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
+  free_string_list ();
+#endif
+}
+
+/* Return a line of text, taken from wherever yylex () reads input.
+   If there is no more input, then we return NULL.  If REMOVE_QUOTED_NEWLINE
+   is non-zero, we remove unquoted \<newline> pairs.  This is used by
+   read_secondary_line to read here documents. */
+static char *
+read_a_line (remove_quoted_newline)
+     int remove_quoted_newline;
+{
+  static char *line_buffer = (char *)NULL;
+  static int buffer_size = 0;
+  int indx, c, peekc, pass_next;
+
+#if defined (READLINE)
+  if (no_line_editing && SHOULD_PROMPT ())
+#else
+  if (SHOULD_PROMPT ())
+#endif
+    print_prompt ();
+
+  pass_next = indx = 0;
+  while (1)
+    {
+      /* Allow immediate exit if interrupted during input. */
+      QUIT;
+
+      c = yy_getc ();
+
+      /* Ignore null bytes in input. */
+      if (c == 0)
+       {
+#if 0
+         internal_warning ("read_a_line: ignored null byte in input");
+#endif
+         continue;
+       }
+
+      /* If there is no more input, then we return NULL. */
+      if (c == EOF)
+       {
+         if (interactive && bash_input.type == st_stream)
+           clearerr (stdin);
+         if (indx == 0)
+           return ((char *)NULL);
+         c = '\n';
+       }
+
+      /* `+2' in case the final character in the buffer is a newline. */
+      RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128);
+
+      /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a
+        here document with an unquoted delimiter.  In this case,
+        the line will be expanded as if it were in double quotes.
+        We allow a backslash to escape the next character, but we
+        need to treat the backslash specially only if a backslash
+        quoting a backslash-newline pair appears in the line. */
+      if (pass_next)
+       {
+         line_buffer[indx++] = c;
+         pass_next = 0;
+       }
+      else if (c == '\\' && remove_quoted_newline)
+       {
+         QUIT;
+         peekc = yy_getc ();
+         if (peekc == '\n')
+           {
+             line_number++;
+             continue; /* Make the unquoted \<newline> pair disappear. */
+           }
+         else
+           {
+             yy_ungetc (peekc);
+             pass_next = 1;
+             line_buffer[indx++] = c;          /* Preserve the backslash. */
+           }
+       }
+      else
+       line_buffer[indx++] = c;
+
+      if (c == '\n')
+       {
+         line_buffer[indx] = '\0';
+         return (line_buffer);
+       }
+    }
+}
+
+/* Return a line as in read_a_line (), but insure that the prompt is
+   the secondary prompt.  This is used to read the lines of a here
+   document.  REMOVE_QUOTED_NEWLINE is non-zero if we should remove
+   newlines quoted with backslashes while reading the line.  It is
+   non-zero unless the delimiter of the here document was quoted. */
+char *
+read_secondary_line (remove_quoted_newline)
+     int remove_quoted_newline;
+{
+  char *ret;
+  int n, c;
+
+  prompt_string_pointer = &ps2_prompt;
+  if (SHOULD_PROMPT())
+    prompt_again ();
+  ret = read_a_line (remove_quoted_newline);
+#if defined (HISTORY)
+  if (ret && remember_on_history && (parser_state & PST_HEREDOC))
+    {
+      /* To make adding the the here-document body right, we need to rely
+        on history_delimiting_chars() returning \n for the first line of
+        the here-document body and the null string for the second and
+        subsequent lines, so we avoid double newlines.
+        current_command_line_count == 2 for the first line of the body. */
+
+      current_command_line_count++;
+      maybe_add_history (ret);
+    }
+#endif /* HISTORY */
+  return ret;
+}
+
+/* **************************************************************** */
+/*                                                                 */
+/*                             YYLEX ()                            */
+/*                                                                 */
+/* **************************************************************** */
+
+/* Reserved words.  These are only recognized as the first word of a
+   command. */
+STRING_INT_ALIST word_token_alist[] = {
+  { "if", IF },
+  { "then", THEN },
+  { "else", ELSE },
+  { "elif", ELIF },
+  { "fi", FI },
+  { "case", CASE },
+  { "esac", ESAC },
+  { "for", FOR },
+#if defined (SELECT_COMMAND)
+  { "select", SELECT },
+#endif
+  { "while", WHILE },
+  { "until", UNTIL },
+  { "do", DO },
+  { "done", DONE },
+  { "in", IN },
+  { "function", FUNCTION },
+#if defined (COMMAND_TIMING)
+  { "time", TIME },
+#endif
+  { "{", '{' },
+  { "}", '}' },
+  { "!", BANG },
+#if defined (COND_COMMAND)
+  { "[[", COND_START },
+  { "]]", COND_END },
+#endif
+#if defined (COPROCESS_SUPPORT)
+  { "coproc", COPROC },
+#endif
+  { (char *)NULL, 0}
+};
+
+/* other tokens that can be returned by read_token() */
+STRING_INT_ALIST other_token_alist[] = {
+  /* Multiple-character tokens with special values */
+  { "--", TIMEIGN },
+  { "-p", TIMEOPT },
+  { "&&", AND_AND },
+  { "||", OR_OR },
+  { ">>", GREATER_GREATER },
+  { "<<", LESS_LESS },
+  { "<&", LESS_AND },
+  { ">&", GREATER_AND },
+  { ";;", SEMI_SEMI },
+  { ";&", SEMI_AND },
+  { ";;&", SEMI_SEMI_AND },
+  { "<<-", LESS_LESS_MINUS },
+  { "<<<", LESS_LESS_LESS },
+  { "&>", AND_GREATER },
+  { "&>>", AND_GREATER_GREATER },
+  { "<>", LESS_GREATER },
+  { ">|", GREATER_BAR },
+  { "|&", BAR_AND },
+  { "EOF", yacc_EOF },
+  /* Tokens whose value is the character itself */
+  { ">", '>' },
+  { "<", '<' },
+  { "-", '-' },
+  { "{", '{' },
+  { "}", '}' },
+  { ";", ';' },
+  { "(", '(' },
+  { ")", ')' },
+  { "|", '|' },
+  { "&", '&' },
+  { "newline", '\n' },
+  { (char *)NULL, 0}
+};
+
+/* others not listed here:
+       WORD                    look at yylval.word
+       ASSIGNMENT_WORD         look at yylval.word
+       NUMBER                  look at yylval.number
+       ARITH_CMD               look at yylval.word_list
+       ARITH_FOR_EXPRS         look at yylval.word_list
+       COND_CMD                look at yylval.command
+*/
+
+/* These are used by read_token_word, but appear up here so that shell_getc
+   can use them to decide when to add otherwise blank lines to the history. */
+
+/* The primary delimiter stack. */
+struct dstack dstack = {  (char *)NULL, 0, 0 };
+
+/* A temporary delimiter stack to be used when decoding prompt strings.
+   This is needed because command substitutions in prompt strings (e.g., PS2)
+   can screw up the parser's quoting state. */
+static struct dstack temp_dstack = { (char *)NULL, 0, 0 };
+
+/* Macro for accessing the top delimiter on the stack.  Returns the
+   delimiter or zero if none. */
+#define current_delimiter(ds) \
+  (ds.delimiter_depth ? ds.delimiters[ds.delimiter_depth - 1] : 0)
+
+#define push_delimiter(ds, character) \
+  do \
+    { \
+      if (ds.delimiter_depth + 2 > ds.delimiter_space) \
+       ds.delimiters = (char *)xrealloc \
+         (ds.delimiters, (ds.delimiter_space += 10) * sizeof (char)); \
+      ds.delimiters[ds.delimiter_depth] = character; \
+      ds.delimiter_depth++; \
+    } \
+  while (0)
+
+#define pop_delimiter(ds)      ds.delimiter_depth--
+
+/* Return the next shell input character.  This always reads characters
+   from shell_input_line; when that line is exhausted, it is time to
+   read the next line.  This is called by read_token when the shell is
+   processing normal command input. */
+
+/* This implements one-character lookahead/lookbehind across physical input
+   lines, to avoid something being lost because it's pushed back with
+   shell_ungetc when we're at the start of a line. */
+static int eol_ungetc_lookahead = 0;
+
+static int
+shell_getc (remove_quoted_newline)
+     int remove_quoted_newline;
+{
+  register int i;
+  int c, truncating;
+  unsigned char uc;
+
+  QUIT;
+
+  if (sigwinch_received)
+    {
+      sigwinch_received = 0;
+      get_new_window_size (0, (int *)0, (int *)0);
+    }
+      
+  if (eol_ungetc_lookahead)
+    {
+      c = eol_ungetc_lookahead;
+      eol_ungetc_lookahead = 0;
+      return (c);
+    }
+
+#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
+  /* If shell_input_line[shell_input_line_index] == 0, but there is
+     something on the pushed list of strings, then we don't want to go
+     off and get another line.  We let the code down below handle it. */
+
+  if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
+                           (pushed_string_list == (STRING_SAVER *)NULL)))
+#else /* !ALIAS && !DPAREN_ARITHMETIC */
+  if (!shell_input_line || !shell_input_line[shell_input_line_index])
+#endif /* !ALIAS && !DPAREN_ARITHMETIC */
+    {
+      line_number++;
+
+      /* Let's not let one really really long line blow up memory allocation */
+      if (shell_input_line && shell_input_line_size >= 32768)
+       {
+         free (shell_input_line);
+         shell_input_line = 0;
+         shell_input_line_size = 0;
+       }
+
+    restart_read:
+
+      /* Allow immediate exit if interrupted during input. */
+      QUIT;
+
+      i = truncating = 0;
+      shell_input_line_terminator = 0;
+
+      /* If the shell is interatctive, but not currently printing a prompt
+         (interactive_shell && interactive == 0), we don't want to print
+         notifies or cleanup the jobs -- we want to defer it until we do
+         print the next prompt. */
+      if (interactive_shell == 0 || SHOULD_PROMPT())
+       {
+#if defined (JOB_CONTROL)
+      /* This can cause a problem when reading a command as the result
+        of a trap, when the trap is called from flush_child.  This call
+        had better not cause jobs to disappear from the job table in
+        that case, or we will have big trouble. */
+         notify_and_cleanup ();
+#else /* !JOB_CONTROL */
+         cleanup_dead_jobs ();
+#endif /* !JOB_CONTROL */
+       }
+
+#if defined (READLINE)
+      if (no_line_editing && SHOULD_PROMPT())
+#else
+      if (SHOULD_PROMPT())
+#endif
+       print_prompt ();
+
+      if (bash_input.type == st_stream)
+       clearerr (stdin);
+
+      while (1)
+       {
+         c = yy_getc ();
+
+         /* Allow immediate exit if interrupted during input. */
+         QUIT;
+
+         if (c == '\0')
+           {
+#if 0
+             internal_warning ("shell_getc: ignored null byte in input");
+#endif
+             continue;
+           }
+
+         /* Theoretical overflow */
+         /* If we can't put 256 bytes more into the buffer, allocate
+            everything we can and fill it as full as we can. */
+         /* XXX - we ignore rest of line using `truncating' flag */
+         if (shell_input_line_size > (SIZE_MAX - 256))
+           {
+             size_t n;
+
+             n = SIZE_MAX - i; /* how much more can we put into the buffer? */
+             if (n <= 2)       /* we have to save 1 for the newline added below */
+               {
+                 if (truncating == 0)
+                   internal_warning("shell_getc: shell_input_line_size (%zu) exceeds SIZE_MAX (%llu): line truncated", shell_input_line_size, SIZE_MAX);
+                 shell_input_line[i] = '\0';
+                 truncating = 1;
+               }
+             if (shell_input_line_size < SIZE_MAX)
+               {
+                 shell_input_line_size = SIZE_MAX;
+                 shell_input_line = xrealloc (shell_input_line, shell_input_line_size);
+               }
+           }
+         else
+           RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
+
+         if (c == EOF)
+           {
+             if (bash_input.type == st_stream)
+               clearerr (stdin);
+
+             if (i == 0)
+               shell_input_line_terminator = EOF;
+
+             shell_input_line[i] = '\0';
+             break;
+           }
+
+         if (truncating == 0 || c == '\n')
+           shell_input_line[i++] = c;
+
+         if (c == '\n')
+           {
+             shell_input_line[--i] = '\0';
+             current_command_line_count++;
+             break;
+           }
+       }
+
+      shell_input_line_index = 0;
+      shell_input_line_len = i;                /* == strlen (shell_input_line) */
+
+      set_line_mbstate ();
+
+#if defined (HISTORY)
+      if (remember_on_history && shell_input_line && shell_input_line[0])
+       {
+         char *expansions;
+#  if defined (BANG_HISTORY)
+         int old_hist;
+
+         /* If the current delimiter is a single quote, we should not be
+            performing history expansion, even if we're on a different
+            line from the original single quote. */
+         old_hist = history_expansion_inhibited;
+         if (current_delimiter (dstack) == '\'')
+           history_expansion_inhibited = 1;
+#  endif
+         expansions = pre_process_line (shell_input_line, 1, 1);
+#  if defined (BANG_HISTORY)
+         history_expansion_inhibited = old_hist;
+#  endif
+         if (expansions != shell_input_line)
+           {
+             free (shell_input_line);
+             shell_input_line = expansions;
+             shell_input_line_len = shell_input_line ?
+                                       strlen (shell_input_line) : 0;
+             if (shell_input_line_len == 0)
+               current_command_line_count--;
+
+             /* We have to force the xrealloc below because we don't know
+                the true allocated size of shell_input_line anymore. */
+             shell_input_line_size = shell_input_line_len;
+
+             set_line_mbstate ();
+           }
+       }
+      /* Try to do something intelligent with blank lines encountered while
+        entering multi-line commands.  XXX - this is grotesque */
+      else if (remember_on_history && shell_input_line &&
+              shell_input_line[0] == '\0' &&
+              current_command_line_count > 1)
+       {
+         if (current_delimiter (dstack))
+           /* We know shell_input_line[0] == 0 and we're reading some sort of
+              quoted string.  This means we've got a line consisting of only
+              a newline in a quoted string.  We want to make sure this line
+              gets added to the history. */
+           maybe_add_history (shell_input_line);
+         else
+           {
+             char *hdcs;
+             hdcs = history_delimiting_chars (shell_input_line);
+             if (hdcs && hdcs[0] == ';')
+               maybe_add_history (shell_input_line);
+           }
+       }
+
+#endif /* HISTORY */
+
+      if (shell_input_line)
+       {
+         /* Lines that signify the end of the shell's input should not be
+            echoed. */
+         if (echo_input_at_read && (shell_input_line[0] ||
+                                    shell_input_line_terminator != EOF))
+           fprintf (stderr, "%s\n", shell_input_line);
+       }
+      else
+       {
+         shell_input_line_size = 0;
+         prompt_string_pointer = &current_prompt_string;
+         if (SHOULD_PROMPT ())
+           prompt_again ();
+         goto restart_read;
+       }
+
+      /* Add the newline to the end of this string, iff the string does
+        not already end in an EOF character.  */
+      if (shell_input_line_terminator != EOF)
+       {
+         if (shell_input_line_size < SIZE_MAX && shell_input_line_len > shell_input_line_size - 3)
+           shell_input_line = (char *)xrealloc (shell_input_line,
+                                       1 + (shell_input_line_size += 2));
+
+         shell_input_line[shell_input_line_len] = '\n';
+         shell_input_line[shell_input_line_len + 1] = '\0';
+
+         set_line_mbstate ();
+       }
+    }
+
+next_alias_char:
+  uc = shell_input_line[shell_input_line_index];
+
+  if (uc)
+    shell_input_line_index++;
+
+#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
+  /* If UC is NULL, we have reached the end of the current input string.  If
+     pushed_string_list is non-empty, it's time to pop to the previous string
+     because we have fully consumed the result of the last alias expansion.
+     Do it transparently; just return the next character of the string popped
+     to. */
+pop_alias:
+  if (uc == 0 && (pushed_string_list != (STRING_SAVER *)NULL))
+    {
+      pop_string ();
+      uc = shell_input_line[shell_input_line_index];
+      if (uc)
+       shell_input_line_index++;
+    }
+#endif /* ALIAS || DPAREN_ARITHMETIC */
+
+  if MBTEST(uc == '\\' && remove_quoted_newline && shell_input_line[shell_input_line_index] == '\n')
+    {
+       if (SHOULD_PROMPT ())
+         prompt_again ();
+       line_number++;
+       /* What do we do here if we're expanding an alias whose definition
+          includes an escaped newline?  If that's the last character in the
+          alias expansion, we just pop the pushed string list (recall that
+          we inhibit the appending of a space in mk_alexpansion() if newline
+          is the last character).  If it's not the last character, we need
+          to consume the quoted newline and move to the next character in
+          the expansion. */
+#if defined (ALIAS)
+       if (expanding_alias () && shell_input_line[shell_input_line_index+1] == '\0')
+         {
+           uc = 0;
+           goto pop_alias;
+         }
+       else if (expanding_alias () && shell_input_line[shell_input_line_index+1] != '\0')
+         {
+           shell_input_line_index++;   /* skip newline */
+           goto next_alias_char;       /* and get next character */
+         }
+       else
+#endif 
+         goto restart_read;
+    }
+
+  if (uc == 0 && shell_input_line_terminator == EOF)
+    return ((shell_input_line_index != 0) ? '\n' : EOF);
+
+  return (uc);
+}
+
+/* Put C back into the input for the shell.  This might need changes for
+   HANDLE_MULTIBYTE around EOLs.  Since we (currently) never push back a
+   character different than we read, shell_input_line_property doesn't need
+   to change when manipulating shell_input_line.  The define for
+   last_shell_getc_is_singlebyte should take care of it, though. */
+static void
+shell_ungetc (c)
+     int c;
+{
+  if (shell_input_line && shell_input_line_index)
+    shell_input_line[--shell_input_line_index] = c;
+  else
+    eol_ungetc_lookahead = c;
+}
+
+#ifdef INCLUDE_UNUSED
+/* Back the input pointer up by one, effectively `ungetting' a character. */
+static void
+shell_ungetchar ()
+{
+  if (shell_input_line && shell_input_line_index)
+    shell_input_line_index--;
+}
+#endif
+
+/* Discard input until CHARACTER is seen, then push that character back
+   onto the input stream. */
+static void
+discard_until (character)
+     int character;
+{
+  int c;
+
+  while ((c = shell_getc (0)) != EOF && c != character)
+    ;
+
+  if (c != EOF)
+    shell_ungetc (c);
+}
+
+void
+execute_variable_command (command, vname)
+     char *command, *vname;
+{
+  char *last_lastarg;
+  sh_parser_state_t ps;
+
+  save_parser_state (&ps);
+  last_lastarg = get_string_value ("_");
+  if (last_lastarg)
+    last_lastarg = savestring (last_lastarg);
+
+  parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST);
+
+  restore_parser_state (&ps);
+  bind_variable ("_", last_lastarg, 0);
+  FREE (last_lastarg);
+
+  if (token_to_read == '\n')   /* reset_parser was called */
+    token_to_read = 0;
+}
+
+/* Place to remember the token.  We try to keep the buffer
+   at a reasonable size, but it can grow. */
+static char *token = (char *)NULL;
+
+/* Current size of the token buffer. */
+static int token_buffer_size;
+
+/* Command to read_token () explaining what we want it to do. */
+#define READ 0
+#define RESET 1
+#define prompt_is_ps1 \
+      (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
+
+/* Function for yyparse to call.  yylex keeps track of
+   the last two tokens read, and calls read_token.  */
+static int
+yylex ()
+{
+  if (interactive && (current_token == 0 || current_token == '\n'))
+    {
+      /* Before we print a prompt, we might have to check mailboxes.
+        We do this only if it is time to do so. Notice that only here
+        is the mail alarm reset; nothing takes place in check_mail ()
+        except the checking of mail.  Please don't change this. */
+      if (prompt_is_ps1 && parse_and_execute_level == 0 && time_to_check_mail ())
+       {
+         check_mail ();
+         reset_mail_timer ();
+       }
+
+      /* Avoid printing a prompt if we're not going to read anything, e.g.
+        after resetting the parser with read_token (RESET). */
+      if (token_to_read == 0 && SHOULD_PROMPT ())
+       prompt_again ();
+    }
+
+  two_tokens_ago = token_before_that;
+  token_before_that = last_read_token;
+  last_read_token = current_token;
+  current_token = read_token (READ);
+
+  if ((parser_state & PST_EOFTOKEN) && current_token == shell_eof_token)
+    {
+      current_token = yacc_EOF;
+      if (bash_input.type == st_string)
+       rewind_input_string ();
+    }
+  parser_state &= ~PST_EOFTOKEN;
+
+  return (current_token);
+}
+
+/* When non-zero, we have read the required tokens
+   which allow ESAC to be the next one read. */
+static int esacs_needed_count;
+
+void
+gather_here_documents ()
+{
+  int r;
+
+  r = 0;
+  while (need_here_doc)
+    {
+      parser_state |= PST_HEREDOC;
+      make_here_document (redir_stack[r++], line_number);
+      parser_state &= ~PST_HEREDOC;
+      need_here_doc--;
+    }
+}
+
+/* When non-zero, an open-brace used to create a group is awaiting a close
+   brace partner. */
+static int open_brace_count;
+
+#define command_token_position(token) \
+  (((token) == ASSIGNMENT_WORD) || (parser_state&PST_REDIRLIST) || \
+   ((token) != SEMI_SEMI && (token) != SEMI_AND && (token) != SEMI_SEMI_AND && reserved_word_acceptable(token)))
+
+#define assignment_acceptable(token) \
+  (command_token_position(token) && ((parser_state & PST_CASEPAT) == 0))
+
+/* Check to see if TOKEN is a reserved word and return the token
+   value if it is. */
+#define CHECK_FOR_RESERVED_WORD(tok) \
+  do { \
+    if (!dollar_present && !quoted && \
+       reserved_word_acceptable (last_read_token)) \
+      { \
+       int i; \
+       for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
+         if (STREQ (tok, word_token_alist[i].word)) \
+           { \
+             if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
+               break; \
+             if (word_token_alist[i].token == TIME && time_command_acceptable () == 0) \
+               break; \
+             if (word_token_alist[i].token == ESAC) \
+               parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
+             else if (word_token_alist[i].token == CASE) \
+               parser_state |= PST_CASESTMT; \
+             else if (word_token_alist[i].token == COND_END) \
+               parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \
+             else if (word_token_alist[i].token == COND_START) \
+               parser_state |= PST_CONDCMD; \
+             else if (word_token_alist[i].token == '{') \
+               open_brace_count++; \
+             else if (word_token_alist[i].token == '}' && open_brace_count) \
+               open_brace_count--; \
+             return (word_token_alist[i].token); \
+           } \
+      } \
+  } while (0)
+
+#if defined (ALIAS)
+
+    /* OK, we have a token.  Let's try to alias expand it, if (and only if)
+       it's eligible.
+
+       It is eligible for expansion if EXPAND_ALIASES is set, and
+       the token is unquoted and the last token read was a command
+       separator (or expand_next_token is set), and we are currently
+       processing an alias (pushed_string_list is non-empty) and this
+       token is not the same as the current or any previously
+       processed alias.
+
+       Special cases that disqualify:
+        In a pattern list in a case statement (parser_state & PST_CASEPAT). */
+
+static char *
+mk_alexpansion (s)
+     char *s;
+{
+  int l;
+  char *r;
+
+  l = strlen (s);
+  r = xmalloc (l + 2);
+  strcpy (r, s);
+  /* If the last character in the alias is a newline, don't add a trailing
+     space to the expansion.  Works with shell_getc above. */
+  if (r[l - 1] != ' ' && r[l - 1] != '\n')
+    r[l++] = ' ';
+  r[l] = '\0';
+  return r;
+}
+
+static int
+alias_expand_token (tokstr)
+     char *tokstr;
+{
+  char *expanded;
+  alias_t *ap;
+
+  if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) &&
+       (parser_state & PST_CASEPAT) == 0)
+    {
+      ap = find_alias (tokstr);
+
+      /* Currently expanding this token. */
+      if (ap && (ap->flags & AL_BEINGEXPANDED))
+       return (NO_EXPANSION);
+
+      /* mk_alexpansion puts an extra space on the end of the alias expansion,
+         so the lookahead by the parser works right.  If this gets changed,
+         make sure the code in shell_getc that deals with reaching the end of
+         an expanded alias is changed with it. */
+      expanded = ap ? mk_alexpansion (ap->value) : (char *)NULL;
+
+      if (expanded)
+       {
+         push_string (expanded, ap->flags & AL_EXPANDNEXT, ap);
+         return (RE_READ_TOKEN);
+       }
+      else
+       /* This is an eligible token that does not have an expansion. */
+       return (NO_EXPANSION);
+    }
+  return (NO_EXPANSION);
+}
+#endif /* ALIAS */
+
+static int
+time_command_acceptable ()
+{
+#if defined (COMMAND_TIMING)
+  int i;
+
+  if (posixly_correct && shell_compatibility_level > 41)
+    {
+      /* Quick check of the rest of the line to find the next token.  If it
+        begins with a `-', Posix says to not return `time' as the token.
+        This was interp 267. */
+      i = shell_input_line_index;
+      while (i < shell_input_line_len && (shell_input_line[i] == ' ' || shell_input_line[i] == '\t'))
+        i++;
+      if (shell_input_line[i] == '-')
+       return 0;
+    }
+
+  switch (last_read_token)
+    {
+    case 0:
+    case ';':
+    case '\n':
+    case AND_AND:
+    case OR_OR:
+    case '&':
+    case DO:
+    case THEN:
+    case ELSE:
+    case '{':          /* } */
+    case '(':          /* ) */
+    case BANG:         /* ! time pipeline */
+    case TIME:         /* time time pipeline */
+    case TIMEOPT:      /* time -p time pipeline */
+    case TIMEIGN:      /* time -p -- ... */
+      return 1;
+    default:
+      return 0;
+    }
+#else
+  return 0;
+#endif /* COMMAND_TIMING */
+}
+
+/* Handle special cases of token recognition:
+       IN is recognized if the last token was WORD and the token
+       before that was FOR or CASE or SELECT.
+
+       DO is recognized if the last token was WORD and the token
+       before that was FOR or SELECT.
+
+       ESAC is recognized if the last token caused `esacs_needed_count'
+       to be set
+
+       `{' is recognized if the last token as WORD and the token
+       before that was FUNCTION, or if we just parsed an arithmetic
+       `for' command.
+
+       `}' is recognized if there is an unclosed `{' present.
+
+       `-p' is returned as TIMEOPT if the last read token was TIME.
+       `--' is returned as TIMEIGN if the last read token was TIMEOPT.
+
+       ']]' is returned as COND_END if the parser is currently parsing
+       a conditional expression ((parser_state & PST_CONDEXPR) != 0)
+
+       `time' is returned as TIME if and only if it is immediately
+       preceded by one of `;', `\n', `||', `&&', or `&'.
+*/
+
+static int
+special_case_tokens (tokstr)
+     char *tokstr;
+{
+  if ((last_read_token == WORD) &&
+#if defined (SELECT_COMMAND)
+      ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
+#else
+      ((token_before_that == FOR) || (token_before_that == CASE)) &&
+#endif
+      (tokstr[0] == 'i' && tokstr[1] == 'n' && tokstr[2] == 0))
+    {
+      if (token_before_that == CASE)
+       {
+         parser_state |= PST_CASEPAT;
+         esacs_needed_count++;
+       }
+      return (IN);
+    }
+
+  if (last_read_token == WORD &&
+#if defined (SELECT_COMMAND)
+      (token_before_that == FOR || token_before_that == SELECT) &&
+#else
+      (token_before_that == FOR) &&
+#endif
+      (tokstr[0] == 'd' && tokstr[1] == 'o' && tokstr[2] == '\0'))
+    return (DO);
+
+  /* Ditto for ESAC in the CASE case.
+     Specifically, this handles "case word in esac", which is a legal
+     construct, certainly because someone will pass an empty arg to the
+     case construct, and we don't want it to barf.  Of course, we should
+     insist that the case construct has at least one pattern in it, but
+     the designers disagree. */
+  if (esacs_needed_count)
+    {
+      esacs_needed_count--;
+      if (STREQ (tokstr, "esac"))
+       {
+         parser_state &= ~PST_CASEPAT;
+         return (ESAC);
+       }
+    }
+
+  /* The start of a shell function definition. */
+  if (parser_state & PST_ALLOWOPNBRC)
+    {
+      parser_state &= ~PST_ALLOWOPNBRC;
+      if (tokstr[0] == '{' && tokstr[1] == '\0')               /* } */
+       {
+         open_brace_count++;
+         function_bstart = line_number;
+         return ('{');                                 /* } */
+       }
+    }
+
+  /* We allow a `do' after a for ((...)) without an intervening
+     list_terminator */
+  if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == 'd' && tokstr[1] == 'o' && !tokstr[2])
+    return (DO);
+  if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == '{' && tokstr[1] == '\0')     /* } */
+    {
+      open_brace_count++;
+      return ('{');                    /* } */
+    }
+
+  if (open_brace_count && reserved_word_acceptable (last_read_token) && tokstr[0] == '}' && !tokstr[1])
+    {
+      open_brace_count--;              /* { */
+      return ('}');
+    }
+
+#if defined (COMMAND_TIMING)
+  /* Handle -p after `time'. */
+  if (last_read_token == TIME && tokstr[0] == '-' && tokstr[1] == 'p' && !tokstr[2])
+    return (TIMEOPT);
+  /* Handle -- after `time -p'. */
+  if (last_read_token == TIMEOPT && tokstr[0] == '-' && tokstr[1] == '-' && !tokstr[2])
+    return (TIMEIGN);
+#endif
+
+#if defined (COND_COMMAND) /* [[ */
+  if ((parser_state & PST_CONDEXPR) && tokstr[0] == ']' && tokstr[1] == ']' && tokstr[2] == '\0')
+    return (COND_END);
+#endif
+
+  return (-1);
+}
+
+/* Called from shell.c when Control-C is typed at top level.  Or
+   by the error rule at top level. */
+void
+reset_parser ()
+{
+  dstack.delimiter_depth = 0;  /* No delimiters found so far. */
+  open_brace_count = 0;
+
+#if defined (EXTENDED_GLOB)
+  /* Reset to global value of extended glob */
+  if (parser_state & PST_EXTPAT)
+    extended_glob = global_extglob;
+#endif
+
+  parser_state = 0;
+
+#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
+  if (pushed_string_list)
+    free_string_list ();
+#endif /* ALIAS || DPAREN_ARITHMETIC */
+
+  if (shell_input_line)
+    {
+      free (shell_input_line);
+      shell_input_line = (char *)NULL;
+      shell_input_line_size = shell_input_line_index = 0;
+    }
+
+  FREE (word_desc_to_read);
+  word_desc_to_read = (WORD_DESC *)NULL;
+
+  current_token = '\n';                /* XXX */
+  last_read_token = '\n';
+  token_to_read = '\n';
+}
+
+/* Read the next token.  Command can be READ (normal operation) or
+   RESET (to normalize state). */
+static int
+read_token (command)
+     int command;
+{
+  int character;               /* Current character. */
+  int peek_char;               /* Temporary look-ahead character. */
+  int result;                  /* The thing to return. */
+
+  if (command == RESET)
+    {
+      reset_parser ();
+      return ('\n');
+    }
+
+  if (token_to_read)
+    {
+      result = token_to_read;
+      if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
+       {
+         yylval.word = word_desc_to_read;
+         word_desc_to_read = (WORD_DESC *)NULL;
+       }
+      token_to_read = 0;
+      return (result);
+    }
+
+#if defined (COND_COMMAND)
+  if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD)
+    {
+      cond_lineno = line_number;
+      parser_state |= PST_CONDEXPR;
+      yylval.command = parse_cond_command ();
+      if (cond_token != COND_END)
+       {
+         cond_error ();
+         return (-1);
+       }
+      token_to_read = COND_END;
+      parser_state &= ~(PST_CONDEXPR|PST_CONDCMD);
+      return (COND_CMD);
+    }
+#endif
+
+#if defined (ALIAS)
+  /* This is a place to jump back to once we have successfully expanded a
+     token with an alias and pushed the string with push_string () */
+ re_read_token:
+#endif /* ALIAS */
+
+  /* Read a single word from input.  Start by skipping blanks. */
+  while ((character = shell_getc (1)) != EOF && shellblank (character))
+    ;
+
+  if (character == EOF)
+    {
+      EOF_Reached = 1;
+      return (yacc_EOF);
+    }
+
+  if MBTEST(character == '#' && (!interactive || interactive_comments))
+    {
+      /* A comment.  Discard until EOL or EOF, and then return a newline. */
+      discard_until ('\n');
+      shell_getc (0);
+      character = '\n';        /* this will take the next if statement and return. */
+    }
+
+  if (character == '\n')
+    {
+      /* If we're about to return an unquoted newline, we can go and collect
+        the text of any pending here document. */
+      if (need_here_doc)
+       gather_here_documents ();
+
+#if defined (ALIAS)
+      parser_state &= ~PST_ALEXPNEXT;
+#endif /* ALIAS */
+
+      parser_state &= ~PST_ASSIGNOK;
+
+      return (character);
+    }
+
+  if (parser_state & PST_REGEXP)
+    goto tokword;
+
+  /* Shell meta-characters. */
+  if MBTEST(shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
+    {
+#if defined (ALIAS)
+      /* Turn off alias tokenization iff this character sequence would
+        not leave us ready to read a command. */
+      if (character == '<' || character == '>')
+       parser_state &= ~PST_ALEXPNEXT;
+#endif /* ALIAS */
+
+      parser_state &= ~PST_ASSIGNOK;
+
+      peek_char = shell_getc (1);
+      if (character == peek_char)
+       {
+         switch (character)
+           {
+           case '<':
+             /* If '<' then we could be at "<<" or at "<<-".  We have to
+                look ahead one more character. */
+             peek_char = shell_getc (1);
+             if MBTEST(peek_char == '-')
+               return (LESS_LESS_MINUS);
+             else if MBTEST(peek_char == '<')
+               return (LESS_LESS_LESS);
+             else
+               {
+                 shell_ungetc (peek_char);
+                 return (LESS_LESS);
+               }
+
+           case '>':
+             return (GREATER_GREATER);
+
+           case ';':
+             parser_state |= PST_CASEPAT;
+#if defined (ALIAS)
+             parser_state &= ~PST_ALEXPNEXT;
+#endif /* ALIAS */
+
+             peek_char = shell_getc (1);
+             if MBTEST(peek_char == '&')
+               return (SEMI_SEMI_AND);
+             else
+               {
+                 shell_ungetc (peek_char);
+                 return (SEMI_SEMI);
+               }
+
+           case '&':
+             return (AND_AND);
+
+           case '|':
+             return (OR_OR);
+
+#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
+           case '(':           /* ) */
+             result = parse_dparen (character);
+             if (result == -2)
+               break;
+             else
+               return result;
+#endif
+           }
+       }
+      else if MBTEST(character == '<' && peek_char == '&')
+       return (LESS_AND);
+      else if MBTEST(character == '>' && peek_char == '&')
+       return (GREATER_AND);
+      else if MBTEST(character == '<' && peek_char == '>')
+       return (LESS_GREATER);
+      else if MBTEST(character == '>' && peek_char == '|')
+       return (GREATER_BAR);
+      else if MBTEST(character == '&' && peek_char == '>')
+       {
+         peek_char = shell_getc (1);
+         if MBTEST(peek_char == '>')
+           return (AND_GREATER_GREATER);
+         else
+           {
+             shell_ungetc (peek_char);
+             return (AND_GREATER);
+           }
+       }
+      else if MBTEST(character == '|' && peek_char == '&')
+       return (BAR_AND);
+      else if MBTEST(character == ';' && peek_char == '&')
+       {
+         parser_state |= PST_CASEPAT;
+#if defined (ALIAS)
+         parser_state &= ~PST_ALEXPNEXT;
+#endif /* ALIAS */
+         return (SEMI_AND);
+       }
+
+      shell_ungetc (peek_char);
+
+      /* If we look like we are reading the start of a function
+        definition, then let the reader know about it so that
+        we will do the right thing with `{'. */
+      if MBTEST(character == ')' && last_read_token == '(' && token_before_that == WORD)
+       {
+         parser_state |= PST_ALLOWOPNBRC;
+#if defined (ALIAS)
+         parser_state &= ~PST_ALEXPNEXT;
+#endif /* ALIAS */
+         function_dstart = line_number;
+       }
+
+      /* case pattern lists may be preceded by an optional left paren.  If
+        we're not trying to parse a case pattern list, the left paren
+        indicates a subshell. */
+      if MBTEST(character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */
+       parser_state |= PST_SUBSHELL;
+      /*(*/
+      else if MBTEST((parser_state & PST_CASEPAT) && character == ')')
+       parser_state &= ~PST_CASEPAT;
+      /*(*/
+      else if MBTEST((parser_state & PST_SUBSHELL) && character == ')')
+       parser_state &= ~PST_SUBSHELL;
+
+#if defined (PROCESS_SUBSTITUTION)
+      /* Check for the constructs which introduce process substitution.
+        Shells running in `posix mode' don't do process substitution. */
+      if MBTEST(posixly_correct || ((character != '>' && character != '<') || peek_char != '(')) /*)*/
+#endif /* PROCESS_SUBSTITUTION */
+       return (character);
+    }
+
+  /* Hack <&- (close stdin) case.  Also <&N- (dup and close). */
+  if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
+    return (character);
+
+tokword:
+  /* Okay, if we got this far, we have to read a word.  Read one,
+     and then check it against the known ones. */
+  result = read_token_word (character);
+#if defined (ALIAS)
+  if (result == RE_READ_TOKEN)
+    goto re_read_token;
+#endif
+  return result;
+}
+
+/*
+ * Match a $(...) or other grouping construct.  This has to handle embedded
+ * quoted strings ('', ``, "") and nested constructs.  It also must handle
+ * reprompting the user, if necessary, after reading a newline, and returning
+ * correct error values if it reads EOF.
+ */
+#define P_FIRSTCLOSE   0x0001
+#define P_ALLOWESC     0x0002
+#define P_DQUOTE       0x0004
+#define P_COMMAND      0x0008  /* parsing a command, so look for comments */
+#define P_BACKQUOTE    0x0010  /* parsing a backquoted command substitution */
+#define P_ARRAYSUB     0x0020  /* parsing a [...] array subscript for assignment */
+#define P_DOLBRACE     0x0040  /* parsing a ${...} construct */
+
+/* Lexical state while parsing a grouping construct or $(...). */
+#define LEX_WASDOL     0x001
+#define LEX_CKCOMMENT  0x002
+#define LEX_INCOMMENT  0x004
+#define LEX_PASSNEXT   0x008
+#define LEX_RESWDOK    0x010
+#define LEX_CKCASE     0x020
+#define LEX_INCASE     0x040
+#define LEX_INHEREDOC  0x080
+#define LEX_HEREDELIM  0x100           /* reading here-doc delimiter */
+#define LEX_STRIPDOC   0x200           /* <<- strip tabs from here doc delim */
+#define LEX_INWORD     0x400
+
+#define COMSUB_META(ch)                ((ch) == ';' || (ch) == '&' || (ch) == '|')
+
+#define CHECK_NESTRET_ERROR() \
+  do { \
+    if (nestret == &matched_pair_error) \
+      { \
+       free (ret); \
+       return &matched_pair_error; \
+      } \
+  } while (0)
+
+#define APPEND_NESTRET() \
+  do { \
+    if (nestlen) \
+      { \
+       RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64); \
+       strcpy (ret + retind, nestret); \
+       retind += nestlen; \
+      } \
+  } while (0)
+
+static char matched_pair_error;
+
+static char *
+parse_matched_pair (qc, open, close, lenp, flags)
+     int qc;   /* `"' if this construct is within double quotes */
+     int open, close;
+     int *lenp, flags;
+{
+  int count, ch, tflags;
+  int nestlen, ttranslen, start_lineno;
+  char *ret, *nestret, *ttrans;
+  int retind, retsize, rflags;
+  int dolbrace_state;
+
+  dolbrace_state = (flags & P_DOLBRACE) ? DOLBRACE_PARAM : 0;
+
+/*itrace("parse_matched_pair[%d]: open = %c close = %c flags = %d", line_number, open, close, flags);*/
+  count = 1;
+  tflags = 0;
+
+  if ((flags & P_COMMAND) && qc != '`' && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0)
+    tflags |= LEX_CKCOMMENT;
+
+  /* RFLAGS is the set of flags we want to pass to recursive calls. */
+  rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE);
+
+  ret = (char *)xmalloc (retsize = 64);
+  retind = 0;
+
+  start_lineno = line_number;
+  while (count)
+    {
+      ch = shell_getc (qc != '\'' && (tflags & (LEX_PASSNEXT)) == 0);
+
+      if (ch == EOF)
+       {
+         free (ret);
+         parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
+         EOF_Reached = 1;      /* XXX */
+         return (&matched_pair_error);
+       }
+
+      /* Possible reprompting. */
+      if (ch == '\n' && SHOULD_PROMPT ())
+       prompt_again ();
+
+      /* Don't bother counting parens or doing anything else if in a comment
+        or part of a case statement */
+      if (tflags & LEX_INCOMMENT)
+       {
+         /* Add this character. */
+         RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
+         ret[retind++] = ch;
+
+         if (ch == '\n')
+           tflags &= ~LEX_INCOMMENT;
+
+         continue;
+       }
+
+      /* Not exactly right yet, should handle shell metacharacters, too.  If
+        any changes are made to this test, make analogous changes to subst.c:
+        extract_delimited_string(). */
+      else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || shellblank (ret[retind - 1])))
+       tflags |= LEX_INCOMMENT;
+
+      if (tflags & LEX_PASSNEXT)               /* last char was backslash */
+       {
+         tflags &= ~LEX_PASSNEXT;
+         if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
+           {
+             if (retind > 0)
+               retind--;       /* swallow previously-added backslash */
+             continue;
+           }
+
+         RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
+         if MBTEST(ch == CTLESC)
+           ret[retind++] = CTLESC;
+         ret[retind++] = ch;
+         continue;
+       }
+      /* If we're reparsing the input (e.g., from parse_string_to_word_list),
+        we've already prepended CTLESC to single-quoted results of $'...'.
+        We may want to do this for other CTLESC-quoted characters in
+        reparse, too. */
+      else if MBTEST((parser_state & PST_REPARSE) && open == '\'' && (ch == CTLESC || ch == CTLNUL))
+       {
+         RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
+         ret[retind++] = ch;
+         continue;
+       }
+      else if MBTEST(ch == CTLESC || ch == CTLNUL)     /* special shell escapes */
+       {
+         RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
+         ret[retind++] = CTLESC;
+         ret[retind++] = ch;
+         continue;
+       }
+      else if MBTEST(ch == close)              /* ending delimiter */
+       count--;
+      /* handle nested ${...} specially. */
+      else if MBTEST(open != close && (tflags & LEX_WASDOL) && open == '{' && ch == open) /* } */
+       count++;
+      else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && ch == open)      /* nested begin */
+       count++;
+
+      /* Add this character. */
+      RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
+      ret[retind++] = ch;
+
+      /* If we just read the ending character, don't bother continuing. */
+      if (count == 0)
+       break;
+
+      if (open == '\'')                        /* '' inside grouping construct */
+       {
+         if MBTEST((flags & P_ALLOWESC) && ch == '\\')
+           tflags |= LEX_PASSNEXT;
+         continue;
+       }
+
+      if MBTEST(ch == '\\')                    /* backslashes */
+       tflags |= LEX_PASSNEXT;
+
+      /* Based on which dolstate is currently in (param, op, or word),
+        decide what the op is.  We're really only concerned if it's % or
+        #, so we can turn on a flag that says whether or not we should
+        treat single quotes as special when inside a double-quoted
+        ${...}. This logic must agree with subst.c:extract_dollar_brace_string
+        since they share the same defines. */
+      /* FLAG POSIX INTERP 221 */
+      if (flags & P_DOLBRACE)
+        {
+          /* ${param%[%]word} */
+         if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '%' && retind > 1)
+           dolbrace_state = DOLBRACE_QUOTE;
+          /* ${param#[#]word} */
+         else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '#' && retind > 1)
+           dolbrace_state = DOLBRACE_QUOTE;
+          /* ${param/[/]pat/rep} */
+         else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '/' && retind > 1)
+           dolbrace_state = DOLBRACE_QUOTE2;   /* XXX */
+          /* ${param^[^]pat} */
+         else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '^' && retind > 1)
+           dolbrace_state = DOLBRACE_QUOTE;
+          /* ${param,[,]pat} */
+         else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == ',' && retind > 1)
+           dolbrace_state = DOLBRACE_QUOTE;
+         else if MBTEST(dolbrace_state == DOLBRACE_PARAM && strchr ("#%^,~:-=?+/", ch) != 0)
+           dolbrace_state = DOLBRACE_OP;
+         else if MBTEST(dolbrace_state == DOLBRACE_OP && strchr ("#%^,~:-=?+/", ch) == 0)
+           dolbrace_state = DOLBRACE_WORD;
+        }
+
+      /* The big hammer.  Single quotes aren't special in double quotes.  The
+         problem is that Posix used to say the single quotes are semi-special:
+         within a double-quoted ${...} construct "an even number of
+         unescaped double-quotes or single-quotes, if any, shall occur." */
+      /* This was changed in Austin Group Interp 221 */
+      if MBTEST(posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE && (flags & P_DQUOTE) && (flags & P_DOLBRACE) && ch == '\'')
+       continue;
+
+      /* Could also check open == '`' if we want to parse grouping constructs
+        inside old-style command substitution. */
+      if (open != close)               /* a grouping construct */
+       {
+         if MBTEST(shellquote (ch))
+           {
+             /* '', ``, or "" inside $(...) or other grouping construct. */
+             push_delimiter (dstack, ch);
+             if MBTEST((tflags & LEX_WASDOL) && ch == '\'')    /* $'...' inside group */
+               nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags);
+             else
+               nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags);
+             pop_delimiter (dstack);
+             CHECK_NESTRET_ERROR ();
+
+             if MBTEST((tflags & LEX_WASDOL) && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0))
+               {
+                 /* Translate $'...' here. */
+                 ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen);
+                 xfree (nestret);
+
+                 /* If we're parsing a double-quoted brace expansion and we are
+                    not in a place where single quotes are treated specially,
+                    make sure we single-quote the results of the ansi
+                    expansion because quote removal should remove them later */
+                 /* FLAG POSIX INTERP 221 */
+                 if ((shell_compatibility_level > 42) && (rflags & P_DQUOTE) && (dolbrace_state == DOLBRACE_QUOTE2) && (flags & P_DOLBRACE))
+                   {
+                     nestret = sh_single_quote (ttrans);
+                     free (ttrans);
+                     nestlen = strlen (nestret);
+                   }
+                 else if ((rflags & P_DQUOTE) == 0)
+                   {
+                     nestret = sh_single_quote (ttrans);
+                     free (ttrans);
+                     nestlen = strlen (nestret);
+                   }
+                 else
+                   {
+                     nestret = ttrans;
+                     nestlen = ttranslen;
+                   }
+                 retind -= 2;          /* back up before the $' */
+               }
+             else if MBTEST((tflags & LEX_WASDOL) && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0))
+               {
+                 /* Locale expand $"..." here. */
+                 ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen);
+                 xfree (nestret);
+
+                 nestret = sh_mkdoublequoted (ttrans, ttranslen, 0);
+                 free (ttrans);
+                 nestlen = ttranslen + 2;
+                 retind -= 2;          /* back up before the $" */
+               }
+
+             APPEND_NESTRET ();
+             FREE (nestret);
+           }
+         else if ((flags & P_ARRAYSUB) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '['))      /* ) } ] */
+           goto parse_dollar_word;
+       }
+      /* Parse an old-style command substitution within double quotes as a
+        single word. */
+      /* XXX - sh and ksh93 don't do this - XXX */
+      else if MBTEST(open == '"' && ch == '`')
+       {
+         nestret = parse_matched_pair (0, '`', '`', &nestlen, rflags);
+
+         CHECK_NESTRET_ERROR ();
+         APPEND_NESTRET ();
+
+         FREE (nestret);
+       }
+      else if MBTEST(open != '`' && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '['))    /* ) } ] */
+       /* check for $(), $[], or ${} inside quoted string. */
+       {
+parse_dollar_word:
+         if (open == ch)       /* undo previous increment */
+           count--;
+         if (ch == '(')                /* ) */
+           nestret = parse_comsub (0, '(', ')', &nestlen, (rflags|P_COMMAND) & ~P_DQUOTE);
+         else if (ch == '{')           /* } */
+           nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
+         else if (ch == '[')           /* ] */
+           nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
+
+         CHECK_NESTRET_ERROR ();
+         APPEND_NESTRET ();
+
+         FREE (nestret);
+       }
+      if MBTEST(ch == '$')
+       tflags |= LEX_WASDOL;
+      else
+       tflags &= ~LEX_WASDOL;
+    }
+
+  ret[retind] = '\0';
+  if (lenp)
+    *lenp = retind;
+/*itrace("parse_matched_pair[%d]: returning %s", line_number, ret);*/
+  return ret;
+}
+
+/* Parse a $(...) command substitution.  This is messier than I'd like, and
+   reproduces a lot more of the token-reading code than I'd like. */
+static char *
+parse_comsub (qc, open, close, lenp, flags)
+     int qc;   /* `"' if this construct is within double quotes */
+     int open, close;
+     int *lenp, flags;
+{
+  int count, ch, peekc, tflags, lex_rwlen, lex_wlen, lex_firstind;
+  int nestlen, ttranslen, start_lineno;
+  char *ret, *nestret, *ttrans, *heredelim;
+  int retind, retsize, rflags, hdlen;
+
+  /* Posix interp 217 says arithmetic expressions have precedence, so
+     assume $(( introduces arithmetic expansion and parse accordingly. */
+  peekc = shell_getc (0);
+  shell_ungetc (peekc);
+  if (peekc == '(')
+    return (parse_matched_pair (qc, open, close, lenp, 0));
+
+/*itrace("parse_comsub: qc = `%c' open = %c close = %c", qc, open, close);*/
+  count = 1;
+  tflags = LEX_RESWDOK;
+
+  if ((flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0)
+    tflags |= LEX_CKCASE;
+  if ((tflags & LEX_CKCASE) && (interactive == 0 || interactive_comments))
+    tflags |= LEX_CKCOMMENT;
+
+  /* RFLAGS is the set of flags we want to pass to recursive calls. */
+  rflags = (flags & P_DQUOTE);
+
+  ret = (char *)xmalloc (retsize = 64);
+  retind = 0;
+
+  start_lineno = line_number;
+  lex_rwlen = lex_wlen = 0;
+
+  heredelim = 0;
+  lex_firstind = -1;
+
+  while (count)
+    {
+comsub_readchar:
+      ch = shell_getc (qc != '\'' && (tflags & (LEX_INCOMMENT|LEX_PASSNEXT)) == 0);
+
+      if (ch == EOF)
+       {
+eof_error:
+         free (ret);
+         FREE (heredelim);
+         parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
+         EOF_Reached = 1;      /* XXX */
+         return (&matched_pair_error);
+       }
+
+      /* If we hit the end of a line and are reading the contents of a here
+        document, and it's not the same line that the document starts on,
+        check for this line being the here doc delimiter.  Otherwise, if
+        we're in a here document, mark the next character as the beginning
+        of a line. */
+      if (ch == '\n')
+       {
+         if ((tflags & LEX_HEREDELIM) && heredelim)
+           {
+             tflags &= ~LEX_HEREDELIM;
+             tflags |= LEX_INHEREDOC;
+             lex_firstind = retind + 1;
+           }
+         else if (tflags & LEX_INHEREDOC)
+           {
+             int tind;
+             tind = lex_firstind;
+             while ((tflags & LEX_STRIPDOC) && ret[tind] == '\t')
+               tind++;
+             if (STREQN (ret + tind, heredelim, hdlen))
+               {
+                 tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC);
+/*itrace("parse_comsub:%d: found here doc end `%s'", line_number, ret + tind);*/
+                 free (heredelim);
+                 heredelim = 0;
+                 lex_firstind = -1;
+               }
+             else
+               lex_firstind = retind + 1;
+           }
+       }
+
+      /* Possible reprompting. */
+      if (ch == '\n' && SHOULD_PROMPT ())
+       prompt_again ();
+
+      /* XXX -- possibly allow here doc to be delimited by ending right
+        paren. */
+      if ((tflags & LEX_INHEREDOC) && ch == close && count == 1)
+       {
+         int tind;
+/*itrace("parse_comsub: in here doc, ch == close, retind - firstind = %d hdlen = %d retind = %d", retind-lex_firstind, hdlen, retind);*/
+         tind = lex_firstind;
+         while ((tflags & LEX_STRIPDOC) && ret[tind] == '\t')
+           tind++;
+         if (retind-tind == hdlen && STREQN (ret + tind, heredelim, hdlen))
+           {
+             tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC);
+/*itrace("parse_comsub:%d: found here doc end `%s'", line_number, ret + tind);*/
+             free (heredelim);
+             heredelim = 0;
+             lex_firstind = -1;
+           }
+       }
+
+      /* Don't bother counting parens or doing anything else if in a comment */
+      if (tflags & (LEX_INCOMMENT|LEX_INHEREDOC))
+       {
+         /* Add this character. */
+         RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
+         ret[retind++] = ch;
+
+         if ((tflags & LEX_INCOMMENT) && ch == '\n')
+           {
+/*itrace("parse_comsub:%d: lex_incomment -> 0 ch = `%c'", line_number, ch);*/
+             tflags &= ~LEX_INCOMMENT;
+           }
+
+         continue;
+       }
+
+      if (tflags & LEX_PASSNEXT)               /* last char was backslash */
+       {
+/*itrace("parse_comsub:%d: lex_passnext -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
+         tflags &= ~LEX_PASSNEXT;
+         if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
+           {
+             if (retind > 0)
+               retind--;       /* swallow previously-added backslash */
+             continue;
+           }
+
+         RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
+         if MBTEST(ch == CTLESC)
+           ret[retind++] = CTLESC;
+         ret[retind++] = ch;
+         continue;
+       }
+
+      /* If this is a shell break character, we are not in a word.  If not,
+        we either start or continue a word. */
+      if MBTEST(shellbreak (ch))
+       {
+         tflags &= ~LEX_INWORD;
+/*itrace("parse_comsub:%d: lex_inword -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
+       }
+      else
+       {
+         if (tflags & LEX_INWORD)
+           {
+             lex_wlen++;
+/*itrace("parse_comsub:%d: lex_inword == 1 ch = `%c' lex_wlen = %d (%d)", line_number, ch, lex_wlen, __LINE__);*/
+           }         
+         else
+           {
+/*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", line_number, ch, __LINE__);*/
+             tflags |= LEX_INWORD;
+             lex_wlen = 0;
+           }
+       }
+
+      /* Skip whitespace */
+      if MBTEST(shellblank (ch) && (tflags & LEX_HEREDELIM) == 0 && lex_rwlen == 0)
+        {
+         /* Add this character. */
+         RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
+         ret[retind++] = ch;
+         continue;
+        }
+
+      /* Either we are looking for the start of the here-doc delimiter
+        (lex_firstind == -1) or we are reading one (lex_firstind >= 0).
+        If this character is a shell break character and we are reading
+        the delimiter, save it and note that we are now reading a here
+        document.  If we've found the start of the delimiter, note it by
+        setting lex_firstind.  Backslashes can quote shell metacharacters
+        in here-doc delimiters. */
+      if (tflags & LEX_HEREDELIM)
+       {
+         if (lex_firstind == -1 && shellbreak (ch) == 0)
+           lex_firstind = retind;
+#if 0
+         else if (heredelim && (tflags & LEX_PASSNEXT) == 0 && ch == '\n')
+           {
+             tflags |= LEX_INHEREDOC;
+             tflags &= ~LEX_HEREDELIM;
+             lex_firstind = retind + 1;
+           }
+#endif
+         else if (lex_firstind >= 0 && (tflags & LEX_PASSNEXT) == 0 && shellbreak (ch))
+           {
+             if (heredelim == 0)
+               {
+                 nestret = substring (ret, lex_firstind, retind);
+                 heredelim = string_quote_removal (nestret, 0);
+                 free (nestret);
+                 hdlen = STRLEN(heredelim);
+/*itrace("parse_comsub:%d: found here doc delimiter `%s' (%d)", line_number, heredelim, hdlen);*/
+               }
+             if (ch == '\n')
+               {
+                 tflags |= LEX_INHEREDOC;
+                 tflags &= ~LEX_HEREDELIM;
+                 lex_firstind = retind + 1;
+               }
+             else
+               lex_firstind = -1;
+           }
+       }
+
+      /* Meta-characters that can introduce a reserved word.  Not perfect yet. */
+      if MBTEST((tflags & LEX_RESWDOK) == 0 && (tflags & LEX_CKCASE) && (tflags & LEX_INCOMMENT) == 0 && (shellmeta(ch) || ch == '\n'))
+       {
+         /* Add this character. */
+         RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
+         ret[retind++] = ch;
+         peekc = shell_getc (1);
+         if (ch == peekc && (ch == '&' || ch == '|' || ch == ';'))     /* two-character tokens */
+           {
+             RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
+             ret[retind++] = peekc;
+/*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
+             tflags |= LEX_RESWDOK;
+             lex_rwlen = 0;
+             continue;
+           }
+         else if (ch == '\n' || COMSUB_META(ch))
+           {
+             shell_ungetc (peekc);
+/*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
+             tflags |= LEX_RESWDOK;
+             lex_rwlen = 0;
+             continue;
+           }
+         else if (ch == EOF)
+           goto eof_error;
+         else
+           {
+             /* `unget' the character we just added and fall through */
+             retind--;
+             shell_ungetc (peekc);
+           }
+       }
+
+      /* If we can read a reserved word, try to read one. */
+      if (tflags & LEX_RESWDOK)
+       {
+         if MBTEST(islower (ch))
+           {
+             /* Add this character. */
+             RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
+             ret[retind++] = ch;
+             lex_rwlen++;
+             continue;
+           }
+         else if MBTEST(lex_rwlen == 4 && shellbreak (ch))
+           {
+             if (STREQN (ret + retind - 4, "case", 4))
+               {
+                 tflags |= LEX_INCASE;
+/*itrace("parse_comsub:%d: found `case', lex_incase -> 1 lex_reswdok -> 0", line_number);*/
+               }
+             else if (STREQN (ret + retind - 4, "esac", 4))
+               {
+                 tflags &= ~LEX_INCASE;
+/*itrace("parse_comsub:%d: found `esac', lex_incase -> 0 lex_reswdok -> 0", line_number);*/
+               }
+             tflags &= ~LEX_RESWDOK;
+           }
+         else if MBTEST((tflags & LEX_CKCOMMENT) && ch == '#' && (lex_rwlen == 0 || ((tflags & LEX_INWORD) && lex_wlen == 0)))
+           ;   /* don't modify LEX_RESWDOK if we're starting a comment */
+         /* Allow `do' followed by space, tab, or newline to preserve the
+            RESWDOK flag, but reset the reserved word length counter so we
+            can read another one. */
+         else if MBTEST(((tflags & LEX_INCASE) == 0) &&
+                         (isblank(ch) || ch == '\n') &&
+                         lex_rwlen == 2 &&
+                         STREQN (ret + retind - 2, "do", 2))
+           {
+/*itrace("parse_comsub:%d: lex_incase == 1 found `%c', found \"do\"", line_number, ch);*/
+             lex_rwlen = 0;
+           }
+         else if MBTEST((tflags & LEX_INCASE) && ch != '\n')
+           /* If we can read a reserved word and we're in case, we're at the
+              point where we can read a new pattern list or an esac.  We
+              handle the esac case above.  If we read a newline, we want to
+              leave LEX_RESWDOK alone.  If we read anything else, we want to
+              turn off LEX_RESWDOK, since we're going to read a pattern list. */
+           {
+             tflags &= ~LEX_RESWDOK;
+/*itrace("parse_comsub:%d: lex_incase == 1 found `%c', lex_reswordok -> 0", line_number, ch);*/
+           }
+         else if MBTEST(shellbreak (ch) == 0)
+           {
+             tflags &= ~LEX_RESWDOK;
+/*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/
+           }
+#if 0
+         /* If we find a space or tab but have read something and it's not
+            `do', turn off the reserved-word-ok flag */
+         else if MBTEST(isblank (ch) && lex_rwlen > 0)
+           {
+             tflags &= ~LEX_RESWDOK;
+/*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/
+           }
+#endif
+       }
+
+      /* Might be the start of a here-doc delimiter */
+      if MBTEST((tflags & LEX_INCOMMENT) == 0 && (tflags & LEX_CKCASE) && ch == '<')
+       {
+         /* Add this character. */
+         RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
+         ret[retind++] = ch;
+         peekc = shell_getc (1);
+         if (peekc == EOF)
+           goto eof_error;
+         if (peekc == ch)
+           {
+             RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
+             ret[retind++] = peekc;
+             peekc = shell_getc (1);
+             if (peekc == EOF)
+               goto eof_error;
+             if (peekc == '-')
+               {
+                 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
+                 ret[retind++] = peekc;
+                 tflags |= LEX_STRIPDOC;
+               }
+             else
+               shell_ungetc (peekc);
+             if (peekc != '<')
+               {
+                 tflags |= LEX_HEREDELIM;
+                 lex_firstind = -1;
+               }
+             continue;
+           }
+         else
+           ch = peekc;         /* fall through and continue XXX */
+       }
+      else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (((tflags & LEX_RESWDOK) && lex_rwlen == 0) || ((tflags & LEX_INWORD) && lex_wlen == 0)))
+       {
+/*itrace("parse_comsub:%d: lex_incomment -> 1 (%d)", line_number, __LINE__);*/
+         tflags |= LEX_INCOMMENT;
+       }
+
+      if MBTEST(ch == CTLESC || ch == CTLNUL)  /* special shell escapes */
+       {
+         RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
+         ret[retind++] = CTLESC;
+         ret[retind++] = ch;
+         continue;
+       }
+#if 0
+      else if MBTEST((tflags & LEX_INCASE) && ch == close && close == ')')
+        tflags &= ~LEX_INCASE;         /* XXX */
+#endif
+      else if MBTEST(ch == close && (tflags & LEX_INCASE) == 0)                /* ending delimiter */
+       {
+         count--;
+/*itrace("parse_comsub:%d: found close: count = %d", line_number, count);*/
+       }
+      else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && (tflags & LEX_INCASE) == 0 && ch == open)        /* nested begin */
+       {
+         count++;
+/*itrace("parse_comsub:%d: found open: count = %d", line_number, count);*/
+       }
+
+      /* Add this character. */
+      RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
+      ret[retind++] = ch;
+
+      /* If we just read the ending character, don't bother continuing. */
+      if (count == 0)
+       break;
+
+      if MBTEST(ch == '\\')                    /* backslashes */
+       tflags |= LEX_PASSNEXT;
+
+      if MBTEST(shellquote (ch))
+        {
+          /* '', ``, or "" inside $(...). */
+          push_delimiter (dstack, ch);
+          if MBTEST((tflags & LEX_WASDOL) && ch == '\'')       /* $'...' inside group */
+           nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags);
+         else
+           nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags);
+         pop_delimiter (dstack);
+         CHECK_NESTRET_ERROR ();
+
+         if MBTEST((tflags & LEX_WASDOL) && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0))
+           {
+             /* Translate $'...' here. */
+             ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen);
+             xfree (nestret);
+
+             if ((rflags & P_DQUOTE) == 0)
+               {
+                 nestret = sh_single_quote (ttrans);
+                 free (ttrans);
+                 nestlen = strlen (nestret);
+               }
+             else
+               {
+                 nestret = ttrans;
+                 nestlen = ttranslen;
+               }
+             retind -= 2;              /* back up before the $' */
+           }
+         else if MBTEST((tflags & LEX_WASDOL) && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0))
+           {
+             /* Locale expand $"..." here. */
+             ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen);
+             xfree (nestret);
+
+             nestret = sh_mkdoublequoted (ttrans, ttranslen, 0);
+             free (ttrans);
+             nestlen = ttranslen + 2;
+             retind -= 2;              /* back up before the $" */
+           }
+
+         APPEND_NESTRET ();
+         FREE (nestret);
+       }
+      else if MBTEST((tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '['))   /* ) } ] */
+       /* check for $(), $[], or ${} inside command substitution. */
+       {
+         if ((tflags & LEX_INCASE) == 0 && open == ch) /* undo previous increment */
+           count--;
+         if (ch == '(')                /* ) */
+           nestret = parse_comsub (0, '(', ')', &nestlen, (rflags|P_COMMAND) & ~P_DQUOTE);
+         else if (ch == '{')           /* } */
+           nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
+         else if (ch == '[')           /* ] */
+           nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
+
+         CHECK_NESTRET_ERROR ();
+         APPEND_NESTRET ();
+
+         FREE (nestret);
+       }
+      if MBTEST(ch == '$')
+       tflags |= LEX_WASDOL;
+      else
+       tflags &= ~LEX_WASDOL;
+    }
+
+  FREE (heredelim);
+  ret[retind] = '\0';
+  if (lenp)
+    *lenp = retind;
+/*itrace("parse_comsub:%d: returning `%s'", line_number, ret);*/
+  return ret;
+}
+
+/* Recursively call the parser to parse a $(...) command substitution. */
+char *
+xparse_dolparen (base, string, indp, flags)
+     char *base;
+     char *string;
+     int *indp;
+     int flags;
+{
+  sh_parser_state_t ps;
+  sh_input_line_state_t ls;
+  int orig_ind, nc, sflags;
+  char *ret, *s, *ep, *ostring;
+
+  /*yydebug = 1;*/
+  orig_ind = *indp;
+  ostring = string;
+
+/*itrace("xparse_dolparen: size = %d shell_input_line = `%s'", shell_input_line_size, shell_input_line);*/
+  sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
+  if (flags & SX_NOLONGJMP)
+    sflags |= SEVAL_NOLONGJMP;
+  save_parser_state (&ps);
+  save_input_line_state (&ls);
+
+  /*(*/
+  parser_state |= PST_CMDSUBST|PST_EOFTOKEN;   /* allow instant ')' */ /*(*/
+  shell_eof_token = ')';
+  parse_string (string, "command substitution", sflags, &ep);
+
+  restore_parser_state (&ps);
+  reset_parser ();
+  /* reset_parser clears shell_input_line and associated variables */
+  restore_input_line_state (&ls);
+  if (interactive)
+    token_to_read = 0;
+
+  /* Need to find how many characters parse_and_execute consumed, update
+     *indp, if flags != 0, copy the portion of the string parsed into RET
+     and return it.  If flags & 1 (EX_NOALLOC) we can return NULL. */
+
+  /*(*/
+  if (ep[-1] != ')')
+    {
+#if DEBUG
+      if (ep[-1] != '\n')
+       itrace("xparse_dolparen:%d: ep[-1] != RPAREN (%d), ep = `%s'", line_number, ep[-1], ep);
+#endif
+      while (ep > ostring && ep[-1] == '\n') ep--;
+    }
+
+  nc = ep - ostring;
+  *indp = ep - base - 1;
+
+  /*(*/
+#if DEBUG
+  if (base[*indp] != ')')
+    itrace("xparse_dolparen:%d: base[%d] != RPAREN (%d), base = `%s'", line_number, *indp, base[*indp], base);
+#endif
+
+  if (flags & SX_NOALLOC) 
+    return (char *)NULL;
+
+  if (nc == 0)
+    {
+      ret = xmalloc (1);
+      ret[0] = '\0';
+    }
+  else
+    ret = substring (ostring, 0, nc - 1);
+
+  return ret;
+}
+
+#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
+/* Parse a double-paren construct.  It can be either an arithmetic
+   command, an arithmetic `for' command, or a nested subshell.  Returns
+   the parsed token, -1 on error, or -2 if we didn't do anything and
+   should just go on. */
+static int
+parse_dparen (c)
+     int c;
+{
+  int cmdtyp, sline;
+  char *wval;
+  WORD_DESC *wd;
+
+#if defined (ARITH_FOR_COMMAND)
+  if (last_read_token == FOR)
+    {
+      arith_for_lineno = line_number;
+      cmdtyp = parse_arith_cmd (&wval, 0);
+      if (cmdtyp == 1)
+       {
+         wd = alloc_word_desc ();
+         wd->word = wval;
+         yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
+         return (ARITH_FOR_EXPRS);
+       }
+      else
+       return -1;              /* ERROR */
+    }
+#endif
+
+#if defined (DPAREN_ARITHMETIC)
+  if (reserved_word_acceptable (last_read_token))
+    {
+      sline = line_number;
+
+      cmdtyp = parse_arith_cmd (&wval, 0);
+      if (cmdtyp == 1) /* arithmetic command */
+       {
+         wd = alloc_word_desc ();
+         wd->word = wval;
+         wd->flags = W_QUOTED|W_NOSPLIT|W_NOGLOB|W_DQUOTE;
+         yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
+         return (ARITH_CMD);
+       }
+      else if (cmdtyp == 0)    /* nested subshell */
+       {
+         push_string (wval, 0, (alias_t *)NULL);
+         if ((parser_state & PST_CASEPAT) == 0)
+           parser_state |= PST_SUBSHELL;
+         return (c);
+       }
+      else                     /* ERROR */
+       return -1;
+    }
+#endif
+
+  return -2;                   /* XXX */
+}
+
+/* We've seen a `(('.  Look for the matching `))'.  If we get it, return 1.
+   If not, assume it's a nested subshell for backwards compatibility and
+   return 0.  In any case, put the characters we've consumed into a locally-
+   allocated buffer and make *ep point to that buffer.  Return -1 on an
+   error, for example EOF. */
+static int
+parse_arith_cmd (ep, adddq)
+     char **ep;
+     int adddq;
+{
+  int exp_lineno, rval, c;
+  char *ttok, *tokstr;
+  int ttoklen;
+
+  exp_lineno = line_number;
+  ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
+  rval = 1;
+  if (ttok == &matched_pair_error)
+    return -1;
+  /* Check that the next character is the closing right paren.  If
+     not, this is a syntax error. ( */
+  c = shell_getc (0);
+  if MBTEST(c != ')')
+    rval = 0;
+
+  tokstr = (char *)xmalloc (ttoklen + 4);
+
+  /* if ADDDQ != 0 then (( ... )) -> "..." */
+  if (rval == 1 && adddq)      /* arith cmd, add double quotes */
+    {
+      tokstr[0] = '"';
+      strncpy (tokstr + 1, ttok, ttoklen - 1);
+      tokstr[ttoklen] = '"';
+      tokstr[ttoklen+1] = '\0';
+    }
+  else if (rval == 1)          /* arith cmd, don't add double quotes */
+    {
+      strncpy (tokstr, ttok, ttoklen - 1);
+      tokstr[ttoklen-1] = '\0';
+    }
+  else                         /* nested subshell */
+    {
+      tokstr[0] = '(';
+      strncpy (tokstr + 1, ttok, ttoklen - 1);
+      tokstr[ttoklen] = ')';
+      tokstr[ttoklen+1] = c;
+      tokstr[ttoklen+2] = '\0';
+    }
+
+  *ep = tokstr;
+  FREE (ttok);
+  return rval;
+}
+#endif /* DPAREN_ARITHMETIC || ARITH_FOR_COMMAND */
+
+#if defined (COND_COMMAND)
+static void
+cond_error ()
+{
+  char *etext;
+
+  if (EOF_Reached && cond_token != COND_ERROR)         /* [[ */
+    parser_error (cond_lineno, _("unexpected EOF while looking for `]]'"));
+  else if (cond_token != COND_ERROR)
+    {
+      if (etext = error_token_from_token (cond_token))
+       {
+         parser_error (cond_lineno, _("syntax error in conditional expression: unexpected token `%s'"), etext);
+         free (etext);
+       }
+      else
+       parser_error (cond_lineno, _("syntax error in conditional expression"));
+    }
+}
+
+static COND_COM *
+cond_expr ()
+{
+  return (cond_or ());  
+}
+
+static COND_COM *
+cond_or ()
+{
+  COND_COM *l, *r;
+
+  l = cond_and ();
+  if (cond_token == OR_OR)
+    {
+      r = cond_or ();
+      l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r);
+    }
+  return l;
+}
+
+static COND_COM *
+cond_and ()
+{
+  COND_COM *l, *r;
+
+  l = cond_term ();
+  if (cond_token == AND_AND)
+    {
+      r = cond_and ();
+      l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r);
+    }
+  return l;
+}
+
+static int
+cond_skip_newlines ()
+{
+  while ((cond_token = read_token (READ)) == '\n')
+    {
+      if (SHOULD_PROMPT ())
+       prompt_again ();
+    }
+  return (cond_token);
+}
+
+#define COND_RETURN_ERROR() \
+  do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0)
+
+static COND_COM *
+cond_term ()
+{
+  WORD_DESC *op;
+  COND_COM *term, *tleft, *tright;
+  int tok, lineno;
+  char *etext;
+
+  /* Read a token.  It can be a left paren, a `!', a unary operator, or a
+     word that should be the first argument of a binary operator.  Start by
+     skipping newlines, since this is a compound command. */
+  tok = cond_skip_newlines ();
+  lineno = line_number;
+  if (tok == COND_END)
+    {
+      COND_RETURN_ERROR ();
+    }
+  else if (tok == '(')
+    {
+      term = cond_expr ();
+      if (cond_token != ')')
+       {
+         if (term)
+           dispose_cond_node (term);           /* ( */
+         if (etext = error_token_from_token (cond_token))
+           {
+             parser_error (lineno, _("unexpected token `%s', expected `)'"), etext);
+             free (etext);
+           }
+         else
+           parser_error (lineno, _("expected `)'"));
+         COND_RETURN_ERROR ();
+       }
+      term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL);
+      (void)cond_skip_newlines ();
+    }
+  else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
+    {
+      if (tok == WORD)
+       dispose_word (yylval.word);     /* not needed */
+      term = cond_term ();
+      if (term)
+       term->flags |= CMD_INVERT_RETURN;
+    }
+  else if (tok == WORD && yylval.word->word[0] == '-' && yylval.word->word[2] == 0 && test_unop (yylval.word->word))
+    {
+      op = yylval.word;
+      tok = read_token (READ);
+      if (tok == WORD)
+       {
+         tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
+         term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
+       }
+      else
+       {
+         dispose_word (op);
+         if (etext = error_token_from_token (tok))
+           {
+             parser_error (line_number, _("unexpected argument `%s' to conditional unary operator"), etext);
+             free (etext);
+           }
+         else
+           parser_error (line_number, _("unexpected argument to conditional unary operator"));
+         COND_RETURN_ERROR ();
+       }
+
+      (void)cond_skip_newlines ();
+    }
+  else if (tok == WORD)                /* left argument to binary operator */
+    {
+      /* lhs */
+      tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
+
+      /* binop */
+      tok = read_token (READ);
+      if (tok == WORD && test_binop (yylval.word->word))
+       {
+         op = yylval.word;
+         if (op->word[0] == '=' && (op->word[1] == '\0' || (op->word[1] == '=' && op->word[2] == '\0')))
+           parser_state |= PST_EXTPAT;
+         else if (op->word[0] == '!' && op->word[1] == '=' && op->word[2] == '\0')
+           parser_state |= PST_EXTPAT;
+       }
+#if defined (COND_REGEXP)
+      else if (tok == WORD && STREQ (yylval.word->word, "=~"))
+       {
+         op = yylval.word;
+         parser_state |= PST_REGEXP;
+       }
+#endif
+      else if (tok == '<' || tok == '>')
+       op = make_word_from_token (tok);  /* ( */
+      /* There should be a check before blindly accepting the `)' that we have
+        seen the opening `('. */
+      else if (tok == COND_END || tok == AND_AND || tok == OR_OR || tok == ')')
+       {
+         /* Special case.  [[ x ]] is equivalent to [[ -n x ]], just like
+            the test command.  Similarly for [[ x && expr ]] or
+            [[ x || expr ]] or [[ (x) ]]. */
+         op = make_word ("-n");
+         term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
+         cond_token = tok;
+         return (term);
+       }
+      else
+       {
+         if (etext = error_token_from_token (tok))
+           {
+             parser_error (line_number, _("unexpected token `%s', conditional binary operator expected"), etext);
+             free (etext);
+           }
+         else
+           parser_error (line_number, _("conditional binary operator expected"));
+         dispose_cond_node (tleft);
+         COND_RETURN_ERROR ();
+       }
+
+      /* rhs */
+      if (parser_state & PST_EXTPAT)
+       extended_glob = 1;
+      tok = read_token (READ);
+      if (parser_state & PST_EXTPAT)
+       extended_glob = global_extglob;
+      parser_state &= ~(PST_REGEXP|PST_EXTPAT);
+
+      if (tok == WORD)
+       {
+         tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
+         term = make_cond_node (COND_BINARY, op, tleft, tright);
+       }
+      else
+       {
+         if (etext = error_token_from_token (tok))
+           {
+             parser_error (line_number, _("unexpected argument `%s' to conditional binary operator"), etext);
+             free (etext);
+           }
+         else
+           parser_error (line_number, _("unexpected argument to conditional binary operator"));
+         dispose_cond_node (tleft);
+         dispose_word (op);
+         COND_RETURN_ERROR ();
+       }
+
+      (void)cond_skip_newlines ();
+    }
+  else
+    {
+      if (tok < 256)
+       parser_error (line_number, _("unexpected token `%c' in conditional command"), tok);
+      else if (etext = error_token_from_token (tok))
+       {
+         parser_error (line_number, _("unexpected token `%s' in conditional command"), etext);
+         free (etext);
+       }
+      else
+       parser_error (line_number, _("unexpected token %d in conditional command"), tok);
+      COND_RETURN_ERROR ();
+    }
+  return (term);
+}      
+
+/* This is kind of bogus -- we slip a mini recursive-descent parser in
+   here to handle the conditional statement syntax. */
+static COMMAND *
+parse_cond_command ()
+{
+  COND_COM *cexp;
+
+  global_extglob = extended_glob;
+  cexp = cond_expr ();
+  return (make_cond_command (cexp));
+}
+#endif
+
+#if defined (ARRAY_VARS)
+/* When this is called, it's guaranteed that we don't care about anything
+   in t beyond i.  We do save and restore the chars, though. */
+static int
+token_is_assignment (t, i)
+     char *t;
+     int i;
+{
+  unsigned char c, c1;
+  int r;
+
+  c = t[i]; c1 = t[i+1];
+  t[i] = '='; t[i+1] = '\0';
+  r = assignment (t, (parser_state & PST_COMPASSIGN) != 0);
+  t[i] = c; t[i+1] = c1;
+  return r;
+}
+
+/* XXX - possible changes here for `+=' */
+static int
+token_is_ident (t, i)
+     char *t;
+     int i;
+{
+  unsigned char c;
+  int r;
+
+  c = t[i];
+  t[i] = '\0';
+  r = legal_identifier (t);
+  t[i] = c;
+  return r;
+}
+#endif
+
+static int
+read_token_word (character)
+     int character;
+{
+  /* The value for YYLVAL when a WORD is read. */
+  WORD_DESC *the_word;
+
+  /* Index into the token that we are building. */
+  int token_index;
+
+  /* ALL_DIGITS becomes zero when we see a non-digit. */
+  int all_digit_token;
+
+  /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
+  int dollar_present;
+
+  /* COMPOUND_ASSIGNMENT becomes non-zero if we are parsing a compound
+     assignment. */
+  int compound_assignment;
+
+  /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
+  int quoted;
+
+  /* Non-zero means to ignore the value of the next character, and just
+     to add it no matter what. */
+ int pass_next_character;
+
+  /* The current delimiting character. */
+  int cd;
+  int result, peek_char;
+  char *ttok, *ttrans;
+  int ttoklen, ttranslen;
+  intmax_t lvalue;
+
+  if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
+    token = (char *)xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
+
+  token_index = 0;
+  all_digit_token = DIGIT (character);
+  dollar_present = quoted = pass_next_character = compound_assignment = 0;
+
+  for (;;)
+    {
+      if (character == EOF)
+       goto got_token;
+
+      if (pass_next_character)
+       {
+         pass_next_character = 0;
+         goto got_escaped_character;
+       }
+
+      cd = current_delimiter (dstack);
+
+      /* Handle backslashes.  Quote lots of things when not inside of
+        double-quotes, quote some things inside of double-quotes. */
+      if MBTEST(character == '\\')
+       {
+         peek_char = shell_getc (0);
+
+         /* Backslash-newline is ignored in all cases except
+            when quoted with single quotes. */
+         if (peek_char == '\n')
+           {
+             character = '\n';
+             goto next_character;
+           }
+         else
+           {
+             shell_ungetc (peek_char);
+
+             /* If the next character is to be quoted, note it now. */
+             if (cd == 0 || cd == '`' ||
+                 (cd == '"' && peek_char >= 0 && (sh_syntaxtab[peek_char] & CBSDQUOTE)))
+               pass_next_character++;
+
+             quoted = 1;
+             goto got_character;
+           }
+       }
+
+      /* Parse a matched pair of quote characters. */
+      if MBTEST(shellquote (character))
+       {
+         push_delimiter (dstack, character);
+         ttok = parse_matched_pair (character, character, character, &ttoklen, (character == '`') ? P_COMMAND : 0);
+         pop_delimiter (dstack);
+         if (ttok == &matched_pair_error)
+           return -1;          /* Bail immediately. */
+         RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
+                                 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
+         token[token_index++] = character;
+         strcpy (token + token_index, ttok);
+         token_index += ttoklen;
+         all_digit_token = 0;
+         quoted = 1;
+         dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
+         FREE (ttok);
+         goto next_character;
+       }
+
+#ifdef COND_REGEXP
+      /* When parsing a regexp as a single word inside a conditional command,
+        we need to special-case characters special to both the shell and
+        regular expressions.  Right now, that is only '(' and '|'. */ /*)*/
+      if MBTEST((parser_state & PST_REGEXP) && (character == '(' || character == '|'))         /*)*/
+       {
+         if (character == '|')
+           goto got_character;
+
+         push_delimiter (dstack, character);
+         ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
+         pop_delimiter (dstack);
+         if (ttok == &matched_pair_error)
+           return -1;          /* Bail immediately. */
+         RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
+                                 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
+         token[token_index++] = character;
+         strcpy (token + token_index, ttok);
+         token_index += ttoklen;
+         FREE (ttok);
+         dollar_present = all_digit_token = 0;
+         goto next_character;
+       }
+#endif /* COND_REGEXP */
+
+#ifdef EXTENDED_GLOB
+      /* Parse a ksh-style extended pattern matching specification. */
+      if MBTEST(extended_glob && PATTERN_CHAR (character))
+       {
+         peek_char = shell_getc (1);
+         if MBTEST(peek_char == '(')           /* ) */
+           {
+             push_delimiter (dstack, peek_char);
+             ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
+             pop_delimiter (dstack);
+             if (ttok == &matched_pair_error)
+               return -1;              /* Bail immediately. */
+             RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 3,
+                                     token_buffer_size,
+                                     TOKEN_DEFAULT_GROW_SIZE);
+             token[token_index++] = character;
+             token[token_index++] = peek_char;
+             strcpy (token + token_index, ttok);
+             token_index += ttoklen;
+             FREE (ttok);
+             dollar_present = all_digit_token = 0;
+             goto next_character;
+           }
+         else
+           shell_ungetc (peek_char);
+       }
+#endif /* EXTENDED_GLOB */
+
+      /* If the delimiter character is not single quote, parse some of
+        the shell expansions that must be read as a single word. */
+      if (shellexp (character))
+       {
+         peek_char = shell_getc (1);
+         /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
+         if MBTEST(peek_char == '(' ||
+               ((peek_char == '{' || peek_char == '[') && character == '$'))   /* ) ] } */
+           {
+             if (peek_char == '{')             /* } */
+               ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE|P_DOLBRACE);
+             else if (peek_char == '(')                /* ) */
+               {
+                 /* XXX - push and pop the `(' as a delimiter for use by
+                    the command-oriented-history code.  This way newlines
+                    appearing in the $(...) string get added to the
+                    history literally rather than causing a possibly-
+                    incorrect `;' to be added. ) */
+                 push_delimiter (dstack, peek_char);
+                 ttok = parse_comsub (cd, '(', ')', &ttoklen, P_COMMAND);
+                 pop_delimiter (dstack);
+               }
+             else
+               ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
+             if (ttok == &matched_pair_error)
+               return -1;              /* Bail immediately. */
+             RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 3,
+                                     token_buffer_size,
+                                     TOKEN_DEFAULT_GROW_SIZE);
+             token[token_index++] = character;
+             token[token_index++] = peek_char;
+             strcpy (token + token_index, ttok);
+             token_index += ttoklen;
+             FREE (ttok);
+             dollar_present = 1;
+             all_digit_token = 0;
+             goto next_character;
+           }
+         /* This handles $'...' and $"..." new-style quoted strings. */
+         else if MBTEST(character == '$' && (peek_char == '\'' || peek_char == '"'))
+           {
+             int first_line;
+
+             first_line = line_number;
+             push_delimiter (dstack, peek_char);
+             ttok = parse_matched_pair (peek_char, peek_char, peek_char,
+                                        &ttoklen,
+                                        (peek_char == '\'') ? P_ALLOWESC : 0);
+             pop_delimiter (dstack);
+             if (ttok == &matched_pair_error)
+               return -1;
+             if (peek_char == '\'')
+               {
+                 ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
+                 free (ttok);
+
+                 /* Insert the single quotes and correctly quote any
+                    embedded single quotes (allowed because P_ALLOWESC was
+                    passed to parse_matched_pair). */
+                 ttok = sh_single_quote (ttrans);
+                 free (ttrans);
+                 ttranslen = strlen (ttok);
+                 ttrans = ttok;
+               }
+             else
+               {
+                 /* Try to locale-expand the converted string. */
+                 ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen);
+                 free (ttok);
+
+                 /* Add the double quotes back */
+                 ttok = sh_mkdoublequoted (ttrans, ttranslen, 0);
+                 free (ttrans);
+                 ttranslen += 2;
+                 ttrans = ttok;
+               }
+
+             RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 1,
+                                     token_buffer_size,
+                                     TOKEN_DEFAULT_GROW_SIZE);
+             strcpy (token + token_index, ttrans);
+             token_index += ttranslen;
+             FREE (ttrans);
+             quoted = 1;
+             all_digit_token = 0;
+             goto next_character;
+           }
+         /* This could eventually be extended to recognize all of the
+            shell's single-character parameter expansions, and set flags.*/
+         else if MBTEST(character == '$' && peek_char == '$')
+           {
+             RESIZE_MALLOCED_BUFFER (token, token_index, 3,
+                                     token_buffer_size,
+                                     TOKEN_DEFAULT_GROW_SIZE);
+             token[token_index++] = '$';
+             token[token_index++] = peek_char;
+             dollar_present = 1;
+             all_digit_token = 0;
+             goto next_character;
+           }
+         else
+           shell_ungetc (peek_char);
+       }
+
+#if defined (ARRAY_VARS)
+      /* Identify possible array subscript assignment; match [...].  If
+        parser_state&PST_COMPASSIGN, we need to parse [sub]=words treating
+        `sub' as if it were enclosed in double quotes. */
+      else if MBTEST(character == '[' &&               /* ] */
+                    ((token_index > 0 && assignment_acceptable (last_read_token) && token_is_ident (token, token_index)) ||
+                     (token_index == 0 && (parser_state&PST_COMPASSIGN))))
+        {
+         ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARRAYSUB);
+         if (ttok == &matched_pair_error)
+           return -1;          /* Bail immediately. */
+         RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
+                                 token_buffer_size,
+                                 TOKEN_DEFAULT_GROW_SIZE);
+         token[token_index++] = character;
+         strcpy (token + token_index, ttok);
+         token_index += ttoklen;
+         FREE (ttok);
+         all_digit_token = 0;
+         goto next_character;
+        }
+      /* Identify possible compound array variable assignment. */
+      else if MBTEST(character == '=' && token_index > 0 && (assignment_acceptable (last_read_token) || (parser_state & PST_ASSIGNOK)) && token_is_assignment (token, token_index))
+       {
+         peek_char = shell_getc (1);
+         if MBTEST(peek_char == '(')           /* ) */
+           {
+             ttok = parse_compound_assignment (&ttoklen);
+
+             if (ttok == &compound_assignment_error)
+               { /*(*/
+                 report_syntax_error (_("unexpected token `)' while parsing compound assignment"));
+                 return -1;
+               }
+
+             RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 4,
+                                     token_buffer_size,
+                                     TOKEN_DEFAULT_GROW_SIZE);
+
+             token[token_index++] = '=';
+             token[token_index++] = '(';
+             if (ttok)
+               {
+                 strcpy (token + token_index, ttok);
+                 token_index += ttoklen;
+               }
+             token[token_index++] = ')';
+             FREE (ttok);
+             all_digit_token = 0;
+             compound_assignment = 1;
+#if 1
+             goto next_character;
+#else
+             goto got_token;           /* ksh93 seems to do this */
+#endif
+           }
+         else
+           shell_ungetc (peek_char);
+       }
+#endif
+
+      /* When not parsing a multi-character word construct, shell meta-
+        characters break words. */
+      if MBTEST(shellbreak (character))
+       {
+         shell_ungetc (character);
+         goto got_token;
+       }
+
+got_character:
+
+      if (character == CTLESC || character == CTLNUL)
+       {
+         RESIZE_MALLOCED_BUFFER (token, token_index, 2, token_buffer_size,
+                                 TOKEN_DEFAULT_GROW_SIZE);
+         token[token_index++] = CTLESC;
+       }
+      else
+got_escaped_character:
+       RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
+                               TOKEN_DEFAULT_GROW_SIZE);
+
+      token[token_index++] = character;
+
+      all_digit_token &= DIGIT (character);
+      dollar_present |= character == '$';
+
+    next_character:
+      if (character == '\n' && SHOULD_PROMPT ())
+       prompt_again ();
+
+      /* We want to remove quoted newlines (that is, a \<newline> pair)
+        unless we are within single quotes or pass_next_character is
+        set (the shell equivalent of literal-next). */
+      cd = current_delimiter (dstack);
+      character = shell_getc (cd != '\'' && pass_next_character == 0);
+    }  /* end for (;;) */
+
+got_token:
+
+  /* Calls to RESIZE_MALLOCED_BUFFER ensure there is sufficient room. */
+  token[token_index] = '\0';
+
+  /* Check to see what thing we should return.  If the last_read_token
+     is a `<', or a `&', or the character which ended this token is
+     a '>' or '<', then, and ONLY then, is this input token a NUMBER.
+     Otherwise, it is just a word, and should be returned as such. */
+  if MBTEST(all_digit_token && (character == '<' || character == '>' ||
+                   last_read_token == LESS_AND ||
+                   last_read_token == GREATER_AND))
+      {
+       if (legal_number (token, &lvalue) && (int)lvalue == lvalue)
+         {
+           yylval.number = lvalue;
+           return (NUMBER);
+         }
+      }
+
+  /* Check for special case tokens. */
+  result = (last_shell_getc_is_singlebyte) ? special_case_tokens (token) : -1;
+  if (result >= 0)
+    return result;
+
+#if defined (ALIAS)
+  /* Posix.2 does not allow reserved words to be aliased, so check for all
+     of them, including special cases, before expanding the current token
+     as an alias. */
+  if MBTEST(posixly_correct)
+    CHECK_FOR_RESERVED_WORD (token);
+
+  /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
+     inhibits alias expansion. */
+  if (expand_aliases && quoted == 0)
+    {
+      result = alias_expand_token (token);
+      if (result == RE_READ_TOKEN)
+       return (RE_READ_TOKEN);
+      else if (result == NO_EXPANSION)
+       parser_state &= ~PST_ALEXPNEXT;
+    }
+
+  /* If not in Posix.2 mode, check for reserved words after alias
+     expansion. */
+  if MBTEST(posixly_correct == 0)
+#endif
+    CHECK_FOR_RESERVED_WORD (token);
+
+  the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
+  the_word->word = (char *)xmalloc (1 + token_index);
+  the_word->flags = 0;
+  strcpy (the_word->word, token);
+  if (dollar_present)
+    the_word->flags |= W_HASDOLLAR;
+  if (quoted)
+    the_word->flags |= W_QUOTED;               /*(*/
+  if (compound_assignment && token[token_index-1] == ')')
+    the_word->flags |= W_COMPASSIGN;
+  /* A word is an assignment if it appears at the beginning of a
+     simple command, or after another assignment word.  This is
+     context-dependent, so it cannot be handled in the grammar. */
+  if (assignment (token, (parser_state & PST_COMPASSIGN) != 0))
+    {
+      the_word->flags |= W_ASSIGNMENT;
+      /* Don't perform word splitting on assignment statements. */
+      if (assignment_acceptable (last_read_token) || (parser_state & PST_COMPASSIGN) != 0)
+       {
+         the_word->flags |= W_NOSPLIT;
+         if (parser_state & PST_COMPASSIGN)
+           the_word->flags |= W_NOGLOB;        /* XXX - W_NOBRACE? */
+       }
+    }
+
+  if (command_token_position (last_read_token))
+    {
+      struct builtin *b;
+      b = builtin_address_internal (token, 0);
+      if (b && (b->flags & ASSIGNMENT_BUILTIN))
+       parser_state |= PST_ASSIGNOK;
+      else if (STREQ (token, "eval") || STREQ (token, "let"))
+       parser_state |= PST_ASSIGNOK;
+    }
+
+  yylval.word = the_word;
+
+  if (token[0] == '{' && token[token_index-1] == '}' &&
+      (character == '<' || character == '>'))
+    {
+      /* can use token; already copied to the_word */
+      token[token_index-1] = '\0';
+#if defined (ARRAY_VARS)
+      if (legal_identifier (token+1) || valid_array_reference (token+1))
+#else
+      if (legal_identifier (token+1))
+#endif
+       {
+         strcpy (the_word->word, token+1);
+/*itrace("read_token_word: returning REDIR_WORD for %s", the_word->word);*/
+         return (REDIR_WORD);
+       }
+    }
+
+  result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
+               ? ASSIGNMENT_WORD : WORD;
+
+  switch (last_read_token)
+    {
+    case FUNCTION:
+      parser_state |= PST_ALLOWOPNBRC;
+      function_dstart = line_number;
+      break;
+    case CASE:
+    case SELECT:
+    case FOR:
+      if (word_top < MAX_CASE_NEST)
+       word_top++;
+      word_lineno[word_top] = line_number;
+      break;
+    }
+
+  return (result);
+}
+
+/* Return 1 if TOKSYM is a token that after being read would allow
+   a reserved word to be seen, else 0. */
+static int
+reserved_word_acceptable (toksym)
+     int toksym;
+{
+  switch (toksym)
+    {
+    case '\n':
+    case ';':
+    case '(':
+    case ')':
+    case '|':
+    case '&':
+    case '{':
+    case '}':          /* XXX */
+    case AND_AND:
+    case BANG:
+    case BAR_AND:
+    case DO:
+    case DONE:
+    case ELIF:
+    case ELSE:
+    case ESAC:
+    case FI:
+    case IF:
+    case OR_OR:
+    case SEMI_SEMI:
+    case SEMI_AND:
+    case SEMI_SEMI_AND:
+    case THEN:
+    case TIME:
+    case TIMEOPT:
+    case TIMEIGN:
+    case COPROC:
+    case UNTIL:
+    case WHILE:
+    case 0:
+      return 1;
+    default:
+#if defined (COPROCESS_SUPPORT)
+      if (last_read_token == WORD && token_before_that == COPROC)
+       return 1;
+#endif
+      if (last_read_token == WORD && token_before_that == FUNCTION)
+       return 1;
+      return 0;
+    }
+}
+    
+/* Return the index of TOKEN in the alist of reserved words, or -1 if
+   TOKEN is not a shell reserved word. */
+int
+find_reserved_word (tokstr)
+     char *tokstr;
+{
+  int i;
+  for (i = 0; word_token_alist[i].word; i++)
+    if (STREQ (tokstr, word_token_alist[i].word))
+      return i;
+  return -1;
+}
+
+/* An interface to let the rest of the shell (primarily the completion
+   system) know what the parser is expecting. */
+int
+parser_in_command_position ()
+{
+  return (command_token_position (last_read_token));
+}
+
+#if 0
+#if defined (READLINE)
+/* Called after each time readline is called.  This insures that whatever
+   the new prompt string is gets propagated to readline's local prompt
+   variable. */
+static void
+reset_readline_prompt ()
+{
+  char *temp_prompt;
+
+  if (prompt_string_pointer)
+    {
+      temp_prompt = (*prompt_string_pointer)
+                       ? decode_prompt_string (*prompt_string_pointer)
+                       : (char *)NULL;
+
+      if (temp_prompt == 0)
+       {
+         temp_prompt = (char *)xmalloc (1);
+         temp_prompt[0] = '\0';
+       }
+
+      FREE (current_readline_prompt);
+      current_readline_prompt = temp_prompt;
+    }
+}
+#endif /* READLINE */
+#endif /* 0 */
+
+#if defined (HISTORY)
+/* A list of tokens which can be followed by newlines, but not by
+   semi-colons.  When concatenating multiple lines of history, the
+   newline separator for such tokens is replaced with a space. */
+static const int no_semi_successors[] = {
+  '\n', '{', '(', ')', ';', '&', '|',
+  CASE, DO, ELSE, IF, SEMI_SEMI, SEMI_AND, SEMI_SEMI_AND, THEN, UNTIL,
+  WHILE, AND_AND, OR_OR, IN,
+  0
+};
+
+/* If we are not within a delimited expression, try to be smart
+   about which separators can be semi-colons and which must be
+   newlines.  Returns the string that should be added into the
+   history entry.  LINE is the line we're about to add; it helps
+   make some more intelligent decisions in certain cases. */
+char *
+history_delimiting_chars (line)
+     const char *line;
+{
+  static int last_was_heredoc = 0;     /* was the last entry the start of a here document? */
+  register int i;
+
+  if ((parser_state & PST_HEREDOC) == 0)
+    last_was_heredoc = 0;
+
+  if (dstack.delimiter_depth != 0)
+    return ("\n");
+
+  /* We look for current_command_line_count == 2 because we are looking to
+     add the first line of the body of the here document (the second line
+     of the command).  We also keep LAST_WAS_HEREDOC as a private sentinel
+     variable to note when we think we added the first line of a here doc
+     (the one with a "<<" somewhere in it) */
+  if (parser_state & PST_HEREDOC)
+    {
+      if (last_was_heredoc)
+       {
+         last_was_heredoc = 0;
+         return "\n";
+       }
+      return (current_command_line_count == 2 ? "\n" : "");
+    }
+
+  if (parser_state & PST_COMPASSIGN)
+    return (" ");
+
+  /* First, handle some special cases. */
+  /*(*/
+  /* If we just read `()', assume it's a function definition, and don't
+     add a semicolon.  If the token before the `)' was not `(', and we're
+     not in the midst of parsing a case statement, assume it's a
+     parenthesized command and add the semicolon. */
+  /*)(*/
+  if (token_before_that == ')')
+    {
+      if (two_tokens_ago == '(')       /*)*/   /* function def */
+       return " ";
+      /* This does not work for subshells inside case statement
+        command lists.  It's a suboptimal solution. */
+      else if (parser_state & PST_CASESTMT)    /* case statement pattern */
+       return " ";
+      else     
+       return "; ";                            /* (...) subshell */
+    }
+  else if (token_before_that == WORD && two_tokens_ago == FUNCTION)
+    return " ";                /* function def using `function name' without `()' */
+
+  /* If we're not in a here document, but we think we're about to parse one,
+     and we would otherwise return a `;', return a newline to delimit the
+     line with the here-doc delimiter */
+  else if ((parser_state & PST_HEREDOC) == 0 && current_command_line_count > 1 && last_read_token == '\n' && strstr (line, "<<"))
+    {
+      last_was_heredoc = 1;
+      return "\n";
+    }
+
+  else if (token_before_that == WORD && two_tokens_ago == FOR)
+    {
+      /* Tricky.  `for i\nin ...' should not have a semicolon, but
+        `for i\ndo ...' should.  We do what we can. */
+      for (i = shell_input_line_index; whitespace (shell_input_line[i]); i++)
+       ;
+      if (shell_input_line[i] && shell_input_line[i] == 'i' && shell_input_line[i+1] == 'n')
+       return " ";
+      return ";";
+    }
+  else if (two_tokens_ago == CASE && token_before_that == WORD && (parser_state & PST_CASESTMT))
+    return " ";
+
+  for (i = 0; no_semi_successors[i]; i++)
+    {
+      if (token_before_that == no_semi_successors[i])
+       return (" ");
+    }
+
+  return ("; ");
+}
+#endif /* HISTORY */
+
+/* Issue a prompt, or prepare to issue a prompt when the next character
+   is read. */
+static void
+prompt_again ()
+{
+  char *temp_prompt;
+
+  if (interactive == 0 || expanding_alias ())  /* XXX */
+    return;
+
+  ps1_prompt = get_string_value ("PS1");
+  ps2_prompt = get_string_value ("PS2");
+
+  if (!prompt_string_pointer)
+    prompt_string_pointer = &ps1_prompt;
+
+  temp_prompt = *prompt_string_pointer
+                       ? decode_prompt_string (*prompt_string_pointer)
+                       : (char *)NULL;
+
+  if (temp_prompt == 0)
+    {
+      temp_prompt = (char *)xmalloc (1);
+      temp_prompt[0] = '\0';
+    }
+
+  current_prompt_string = *prompt_string_pointer;
+  prompt_string_pointer = &ps2_prompt;
+
+#if defined (READLINE)
+  if (!no_line_editing)
+    {
+      FREE (current_readline_prompt);
+      current_readline_prompt = temp_prompt;
+    }
+  else
+#endif /* READLINE */
+    {
+      FREE (current_decoded_prompt);
+      current_decoded_prompt = temp_prompt;
+    }
+}
+
+int
+get_current_prompt_level ()
+{
+  return ((current_prompt_string && current_prompt_string == ps2_prompt) ? 2 : 1);
+}
+
+void
+set_current_prompt_level (x)
+     int x;
+{
+  prompt_string_pointer = (x == 2) ? &ps2_prompt : &ps1_prompt;
+  current_prompt_string = *prompt_string_pointer;
+}
+      
+static void
+print_prompt ()
+{
+  fprintf (stderr, "%s", current_decoded_prompt);
+  fflush (stderr);
+}
+
+/* Return a string which will be printed as a prompt.  The string
+   may contain special characters which are decoded as follows:
+
+       \a      bell (ascii 07)
+       \d      the date in Day Mon Date format
+       \e      escape (ascii 033)
+       \h      the hostname up to the first `.'
+       \H      the hostname
+       \j      the number of active jobs
+       \l      the basename of the shell's tty device name
+       \n      CRLF
+       \r      CR
+       \s      the name of the shell
+       \t      the time in 24-hour hh:mm:ss format
+       \T      the time in 12-hour hh:mm:ss format
+       \@      the time in 12-hour hh:mm am/pm format
+       \A      the time in 24-hour hh:mm format
+       \D{fmt} the result of passing FMT to strftime(3)
+       \u      your username
+       \v      the version of bash (e.g., 2.00)
+       \V      the release of bash, version + patchlevel (e.g., 2.00.0)
+       \w      the current working directory
+       \W      the last element of $PWD
+       \!      the history number of this command
+       \#      the command number of this command
+       \$      a $ or a # if you are root
+       \nnn    character code nnn in octal
+       \\      a backslash
+       \[      begin a sequence of non-printing chars
+       \]      end a sequence of non-printing chars
+*/
+#define PROMPT_GROWTH 48
+char *
+decode_prompt_string (string)
+     char *string;
+{
+  WORD_LIST *list;
+  char *result, *t;
+  struct dstack save_dstack;
+  int last_exit_value, last_comsub_pid;
+#if defined (PROMPT_STRING_DECODE)
+  int result_size, result_index;
+  int c, n, i;
+  char *temp, octal_string[4];
+  struct tm *tm;  
+  time_t the_time;
+  char timebuf[128];
+  char *timefmt;
+
+  result = (char *)xmalloc (result_size = PROMPT_GROWTH);
+  result[result_index = 0] = 0;
+  temp = (char *)NULL;
+
+  while (c = *string++)
+    {
+      if (posixly_correct && c == '!')
+       {
+         if (*string == '!')
+           {
+             temp = savestring ("!");
+             goto add_string;
+           }
+         else
+           {
+#if !defined (HISTORY)
+               temp = savestring ("1");
+#else /* HISTORY */
+               temp = itos (history_number ());
+#endif /* HISTORY */
+               string--;       /* add_string increments string again. */
+               goto add_string;
+           }
+       }
+      if (c == '\\')
+       {
+         c = *string;
+
+         switch (c)
+           {
+           case '0':
+           case '1':
+           case '2':
+           case '3':
+           case '4':
+           case '5':
+           case '6':
+           case '7':
+             strncpy (octal_string, string, 3);
+             octal_string[3] = '\0';
+
+             n = read_octal (octal_string);
+             temp = (char *)xmalloc (3);
+
+             if (n == CTLESC || n == CTLNUL)
+               {
+                 temp[0] = CTLESC;
+                 temp[1] = n;
+                 temp[2] = '\0';
+               }
+             else if (n == -1)
+               {
+                 temp[0] = '\\';
+                 temp[1] = '\0';
+               }
+             else
+               {
+                 temp[0] = n;
+                 temp[1] = '\0';
+               }
+
+             for (c = 0; n != -1 && c < 3 && ISOCTAL (*string); c++)
+               string++;
+
+             c = 0;            /* tested at add_string: */
+             goto add_string;
+
+           case 'd':
+           case 't':
+           case 'T':
+           case '@':
+           case 'A':
+             /* Make the current time/date into a string. */
+             (void) time (&the_time);
+#if defined (HAVE_TZSET)
+             sv_tz ("TZ");             /* XXX -- just make sure */
+#endif
+             tm = localtime (&the_time);
+
+             if (c == 'd')
+               n = strftime (timebuf, sizeof (timebuf), "%a %b %d", tm);
+             else if (c == 't')
+               n = strftime (timebuf, sizeof (timebuf), "%H:%M:%S", tm);
+             else if (c == 'T')
+               n = strftime (timebuf, sizeof (timebuf), "%I:%M:%S", tm);
+             else if (c == '@')
+               n = strftime (timebuf, sizeof (timebuf), "%I:%M %p", tm);
+             else if (c == 'A')
+               n = strftime (timebuf, sizeof (timebuf), "%H:%M", tm);
+
+             if (n == 0)
+               timebuf[0] = '\0';
+             else
+               timebuf[sizeof(timebuf) - 1] = '\0';
+
+             temp = savestring (timebuf);
+             goto add_string;
+
+           case 'D':           /* strftime format */
+             if (string[1] != '{')             /* } */
+               goto not_escape;
+
+             (void) time (&the_time);
+             tm = localtime (&the_time);
+             string += 2;                      /* skip { */
+             timefmt = xmalloc (strlen (string) + 3);
+             for (t = timefmt; *string && *string != '}'; )
+               *t++ = *string++;
+             *t = '\0';
+             c = *string;      /* tested at add_string */
+             if (timefmt[0] == '\0')
+               {
+                 timefmt[0] = '%';
+                 timefmt[1] = 'X';     /* locale-specific current time */
+                 timefmt[2] = '\0';
+               }
+             n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
+             free (timefmt);
+
+             if (n == 0)
+               timebuf[0] = '\0';
+             else
+               timebuf[sizeof(timebuf) - 1] = '\0';
+
+             if (promptvars || posixly_correct)
+               /* Make sure that expand_prompt_string is called with a
+                  second argument of Q_DOUBLE_QUOTES if we use this
+                  function here. */
+               temp = sh_backslash_quote_for_double_quotes (timebuf);
+             else
+               temp = savestring (timebuf);
+             goto add_string;
+             
+           case 'n':
+             temp = (char *)xmalloc (3);
+             temp[0] = no_line_editing ? '\n' : '\r';
+             temp[1] = no_line_editing ? '\0' : '\n';
+             temp[2] = '\0';
+             goto add_string;
+
+           case 's':
+             temp = base_pathname (shell_name);
+             temp = savestring (temp);
+             goto add_string;
+
+           case 'v':
+           case 'V':
+             temp = (char *)xmalloc (16);
+             if (c == 'v')
+               strcpy (temp, dist_version);
+             else
+               sprintf (temp, "%s.%d", dist_version, patch_level);
+             goto add_string;
+
+           case 'w':
+           case 'W':
+             {
+               /* Use the value of PWD because it is much more efficient. */
+               char t_string[PATH_MAX];
+               int tlen;
+
+               temp = get_string_value ("PWD");
+
+               if (temp == 0)
+                 {
+                   if (getcwd (t_string, sizeof(t_string)) == 0)
+                     {
+                       t_string[0] = '.';
+                       tlen = 1;
+                     }
+                   else
+                     tlen = strlen (t_string);
+                 }
+               else
+                 {
+                   tlen = sizeof (t_string) - 1;
+                   strncpy (t_string, temp, tlen);
+                 }
+               t_string[tlen] = '\0';
+
+#if defined (MACOSX)
+               /* Convert from "fs" format to "input" format */
+               temp = fnx_fromfs (t_string, strlen (t_string));
+               if (temp != t_string)
+                 strcpy (t_string, temp);
+#endif
+
+#define ROOT_PATH(x)   ((x)[0] == '/' && (x)[1] == 0)
+#define DOUBLE_SLASH_ROOT(x)   ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0)
+               /* Abbreviate \W as ~ if $PWD == $HOME */
+               if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || STREQ (t, t_string) == 0))
+                 {
+                   if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT (t_string) == 0)
+                     {
+                       t = strrchr (t_string, '/');
+                       if (t)
+                         memmove (t_string, t + 1, strlen (t));        /* strlen(t) to copy NULL */
+                     }
+                 }
+#undef ROOT_PATH
+#undef DOUBLE_SLASH_ROOT
+               else
+                 {
+                   /* polite_directory_format is guaranteed to return a string
+                      no longer than PATH_MAX - 1 characters. */
+                   temp = polite_directory_format (t_string);
+                   if (temp != t_string)
+                     strcpy (t_string, temp);
+                 }
+
+               temp = trim_pathname (t_string, PATH_MAX - 1);
+               /* If we're going to be expanding the prompt string later,
+                  quote the directory name. */
+               if (promptvars || posixly_correct)
+                 /* Make sure that expand_prompt_string is called with a
+                    second argument of Q_DOUBLE_QUOTES if we use this
+                    function here. */
+                 temp = sh_backslash_quote_for_double_quotes (t_string);
+               else
+                 temp = savestring (t_string);
+
+               goto add_string;
+             }
+
+           case 'u':
+             if (current_user.user_name == 0)
+               get_current_user_info ();
+             temp = savestring (current_user.user_name);
+             goto add_string;
+
+           case 'h':
+           case 'H':
+             temp = savestring (current_host_name);
+             if (c == 'h' && (t = (char *)strchr (temp, '.')))
+               *t = '\0';
+             goto add_string;
+
+           case '#':
+             temp = itos (current_command_number);
+             goto add_string;
+
+           case '!':
+#if !defined (HISTORY)
+             temp = savestring ("1");
+#else /* HISTORY */
+             temp = itos (history_number ());
+#endif /* HISTORY */
+             goto add_string;
+
+           case '$':
+             t = temp = (char *)xmalloc (3);
+             if ((promptvars || posixly_correct) && (current_user.euid != 0))
+               *t++ = '\\';
+             *t++ = current_user.euid == 0 ? '#' : '$';
+             *t = '\0';
+             goto add_string;
+
+           case 'j':
+             temp = itos (count_all_jobs ());
+             goto add_string;
+
+           case 'l':
+#if defined (HAVE_TTYNAME)
+             temp = (char *)ttyname (fileno (stdin));
+             t = temp ? base_pathname (temp) : "tty";
+             temp = savestring (t);
+#else
+             temp = savestring ("tty");
+#endif /* !HAVE_TTYNAME */
+             goto add_string;
+
+#if defined (READLINE)
+           case '[':
+           case ']':
+             if (no_line_editing)
+               {
+                 string++;
+                 break;
+               }
+             temp = (char *)xmalloc (3);
+             n = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
+             i = 0;
+             if (n == CTLESC || n == CTLNUL)
+               temp[i++] = CTLESC;
+             temp[i++] = n;
+             temp[i] = '\0';
+             goto add_string;
+#endif /* READLINE */
+
+           case '\\':
+           case 'a':
+           case 'e':
+           case 'r':
+             temp = (char *)xmalloc (2);
+             if (c == 'a')
+               temp[0] = '\07';
+             else if (c == 'e')
+               temp[0] = '\033';
+             else if (c == 'r')
+               temp[0] = '\r';
+             else                      /* (c == '\\') */
+               temp[0] = c;
+             temp[1] = '\0';
+             goto add_string;
+
+           default:
+not_escape:
+             temp = (char *)xmalloc (3);
+             temp[0] = '\\';
+             temp[1] = c;
+             temp[2] = '\0';
+
+           add_string:
+             if (c)
+               string++;
+             result =
+               sub_append_string (temp, result, &result_index, &result_size);
+             temp = (char *)NULL; /* Freed in sub_append_string (). */
+             result[result_index] = '\0';
+             break;
+           }
+       }
+      else
+       {
+         RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
+         result[result_index++] = c;
+         result[result_index] = '\0';
+       }
+    }
+#else /* !PROMPT_STRING_DECODE */
+  result = savestring (string);
+#endif /* !PROMPT_STRING_DECODE */
+
+  /* Save the delimiter stack and point `dstack' to temp space so any
+     command substitutions in the prompt string won't result in screwing
+     up the parser's quoting state. */
+  save_dstack = dstack;
+  dstack = temp_dstack;
+  dstack.delimiter_depth = 0;
+
+  /* Perform variable and parameter expansion and command substitution on
+     the prompt string. */
+  if (promptvars || posixly_correct)
+    {
+      last_exit_value = last_command_exit_value;
+      last_comsub_pid = last_command_subst_pid;
+      list = expand_prompt_string (result, Q_DOUBLE_QUOTES, 0);
+      free (result);
+      result = string_list (list);
+      dispose_words (list);
+      last_command_exit_value = last_exit_value;
+      last_command_subst_pid = last_comsub_pid;
+    }
+  else
+    {
+      t = dequote_string (result);
+      free (result);
+      result = t;
+    }
+
+  dstack = save_dstack;
+
+  return (result);
+}
+
+/************************************************
+ *                                             *
+ *             ERROR HANDLING                  *
+ *                                             *
+ ************************************************/
+
+/* Report a syntax error, and restart the parser.  Call here for fatal
+   errors. */
+int
+yyerror (msg)
+     const char *msg;
+{
+  report_syntax_error ((char *)NULL);
+  reset_parser ();
+  return (0);
+}
+
+static char *
+error_token_from_token (tok)
+     int tok;
+{
+  char *t;
+
+  if (t = find_token_in_alist (tok, word_token_alist, 0))
+    return t;
+
+  if (t = find_token_in_alist (tok, other_token_alist, 0))
+    return t;
+
+  t = (char *)NULL;
+  /* This stuff is dicy and needs closer inspection */
+  switch (current_token)
+    {
+    case WORD:
+    case ASSIGNMENT_WORD:
+      if (yylval.word)
+       t = savestring (yylval.word->word);
+      break;
+    case NUMBER:
+      t = itos (yylval.number);
+      break;
+    case ARITH_CMD:
+      if (yylval.word_list)
+        t = string_list (yylval.word_list);
+      break;
+    case ARITH_FOR_EXPRS:
+      if (yylval.word_list)
+       t = string_list_internal (yylval.word_list, " ; ");
+      break;
+    case COND_CMD:
+      t = (char *)NULL;                /* punt */
+      break;
+    }
+
+  return t;
+}
+
+static char *
+error_token_from_text ()
+{
+  char *msg, *t;
+  int token_end, i;
+
+  t = shell_input_line;
+  i = shell_input_line_index;
+  token_end = 0;
+  msg = (char *)NULL;
+
+  if (i && t[i] == '\0')
+    i--;
+
+  while (i && (whitespace (t[i]) || t[i] == '\n'))
+    i--;
+
+  if (i)
+    token_end = i + 1;
+
+  while (i && (member (t[i], " \n\t;|&") == 0))
+    i--;
+
+  while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
+    i++;
+
+  /* Return our idea of the offending token. */
+  if (token_end || (i == 0 && token_end == 0))
+    {
+      if (token_end)
+       msg = substring (t, i, token_end);
+      else     /* one-character token */
+       {
+         msg = (char *)xmalloc (2);
+         msg[0] = t[i];
+         msg[1] = '\0';
+       }
+    }
+
+  return (msg);
+}
+
+static void
+print_offending_line ()
+{
+  char *msg;
+  int token_end;
+
+  msg = savestring (shell_input_line);
+  token_end = strlen (msg);
+  while (token_end && msg[token_end - 1] == '\n')
+    msg[--token_end] = '\0';
+
+  parser_error (line_number, "`%s'", msg);
+  free (msg);
+}
+
+/* Report a syntax error with line numbers, etc.
+   Call here for recoverable errors.  If you have a message to print,
+   then place it in MESSAGE, otherwise pass NULL and this will figure
+   out an appropriate message for you. */
+static void
+report_syntax_error (message)
+     char *message;
+{
+  char *msg, *p;
+
+  if (message)
+    {
+      parser_error (line_number, "%s", message);
+      if (interactive && EOF_Reached)
+       EOF_Reached = 0;
+      last_command_exit_value = parse_and_execute_level ? EX_BADSYNTAX : EX_BADUSAGE;
+      return;
+    }
+
+  /* If the line of input we're reading is not null, try to find the
+     objectionable token.  First, try to figure out what token the
+     parser's complaining about by looking at current_token. */
+  if (current_token != 0 && EOF_Reached == 0 && (msg = error_token_from_token (current_token)))
+    {
+      if (ansic_shouldquote (msg))
+       {
+         p = ansic_quote (msg, 0, NULL);
+         free (msg);
+         msg = p;
+       }
+      parser_error (line_number, _("syntax error near unexpected token `%s'"), msg);
+      free (msg);
+
+      if (interactive == 0)
+       print_offending_line ();
+
+      last_command_exit_value = parse_and_execute_level ? EX_BADSYNTAX : EX_BADUSAGE;
+      return;
+    }
+
+  /* If looking at the current token doesn't prove fruitful, try to find the
+     offending token by analyzing the text of the input line near the current
+     input line index and report what we find. */
+  if (shell_input_line && *shell_input_line)
+    {
+      msg = error_token_from_text ();
+      if (msg)
+       {
+         parser_error (line_number, _("syntax error near `%s'"), msg);
+         free (msg);
+       }
+
+      /* If not interactive, print the line containing the error. */
+      if (interactive == 0)
+        print_offending_line ();
+    }
+  else
+    {
+      msg = EOF_Reached ? _("syntax error: unexpected end of file") : _("syntax error");
+      parser_error (line_number, "%s", msg);
+      /* When the shell is interactive, this file uses EOF_Reached
+        only for error reporting.  Other mechanisms are used to
+        decide whether or not to exit. */
+      if (interactive && EOF_Reached)
+       EOF_Reached = 0;
+    }
+
+  last_command_exit_value = parse_and_execute_level ? EX_BADSYNTAX : EX_BADUSAGE;
+}
+
+/* ??? Needed function. ??? We have to be able to discard the constructs
+   created during parsing.  In the case of error, we want to return
+   allocated objects to the memory pool.  In the case of no error, we want
+   to throw away the information about where the allocated objects live.
+   (dispose_command () will actually free the command.) */
+static void
+discard_parser_constructs (error_p)
+     int error_p;
+{
+}
+
+/************************************************
+ *                                             *
+ *             EOF HANDLING                    *
+ *                                             *
+ ************************************************/
+
+/* Do that silly `type "bye" to exit' stuff.  You know, "ignoreeof". */
+
+/* A flag denoting whether or not ignoreeof is set. */
+int ignoreeof = 0;
+
+/* The number of times that we have encountered an EOF character without
+   another character intervening.  When this gets above the limit, the
+   shell terminates. */
+int eof_encountered = 0;
+
+/* The limit for eof_encountered. */
+int eof_encountered_limit = 10;
+
+/* If we have EOF as the only input unit, this user wants to leave
+   the shell.  If the shell is not interactive, then just leave.
+   Otherwise, if ignoreeof is set, and we haven't done this the
+   required number of times in a row, print a message. */
+static void
+handle_eof_input_unit ()
+{
+  if (interactive)
+    {
+      /* shell.c may use this to decide whether or not to write out the
+        history, among other things.  We use it only for error reporting
+        in this file. */
+      if (EOF_Reached)
+       EOF_Reached = 0;
+
+      /* If the user wants to "ignore" eof, then let her do so, kind of. */
+      if (ignoreeof)
+       {
+         if (eof_encountered < eof_encountered_limit)
+           {
+             fprintf (stderr, _("Use \"%s\" to leave the shell.\n"),
+                      login_shell ? "logout" : "exit");
+             eof_encountered++;
+             /* Reset the parsing state. */
+             last_read_token = current_token = '\n';
+             /* Reset the prompt string to be $PS1. */
+             prompt_string_pointer = (char **)NULL;
+             prompt_again ();
+             return;
+           }
+       }
+
+      /* In this case EOF should exit the shell.  Do it now. */
+      reset_parser ();
+      exit_builtin ((WORD_LIST *)NULL);
+    }
+  else
+    {
+      /* We don't write history files, etc., for non-interactive shells. */
+      EOF_Reached = 1;
+    }
+}
+
+/************************************************
+ *                                             *
+ *     STRING PARSING FUNCTIONS                *
+ *                                             *
+ ************************************************/
+
+/* It's very important that these two functions treat the characters
+   between ( and ) identically. */
+
+static WORD_LIST parse_string_error;
+
+/* Take a string and run it through the shell parser, returning the
+   resultant word list.  Used by compound array assignment. */
+WORD_LIST *
+parse_string_to_word_list (s, flags, whom)
+     char *s;
+     int flags;
+     const char *whom;
+{
+  WORD_LIST *wl;
+  int tok, orig_current_token, orig_line_number, orig_input_terminator;
+  int orig_line_count;
+  int old_echo_input, old_expand_aliases;
+#if defined (HISTORY)
+  int old_remember_on_history, old_history_expansion_inhibited;
+#endif
+
+#if defined (HISTORY)
+  old_remember_on_history = remember_on_history;
+#  if defined (BANG_HISTORY)
+  old_history_expansion_inhibited = history_expansion_inhibited;
+#  endif
+  bash_history_disable ();
+#endif
+
+  orig_line_number = line_number;
+  orig_line_count = current_command_line_count;
+  orig_input_terminator = shell_input_line_terminator;
+  old_echo_input = echo_input_at_read;
+  old_expand_aliases = expand_aliases;
+
+  push_stream (1);
+  last_read_token = WORD;              /* WORD to allow reserved words here */
+  current_command_line_count = 0;
+  echo_input_at_read = expand_aliases = 0;
+
+  with_input_from_string (s, whom);
+  wl = (WORD_LIST *)NULL;
+
+  if (flags & 1)
+    parser_state |= PST_COMPASSIGN|PST_REPARSE;
+
+  while ((tok = read_token (READ)) != yacc_EOF)
+    {
+      if (tok == '\n' && *bash_input.location.string == '\0')
+       break;
+      if (tok == '\n')         /* Allow newlines in compound assignments */
+       continue;
+      if (tok != WORD && tok != ASSIGNMENT_WORD)
+       {
+         line_number = orig_line_number + line_number - 1;
+         orig_current_token = current_token;
+         current_token = tok;
+         yyerror (NULL);       /* does the right thing */
+         current_token = orig_current_token;
+         if (wl)
+           dispose_words (wl);
+         wl = &parse_string_error;
+         break;
+       }
+      wl = make_word_list (yylval.word, wl);
+    }
+  
+  last_read_token = '\n';
+  pop_stream ();
+
+#if defined (HISTORY)
+  remember_on_history = old_remember_on_history;
+#  if defined (BANG_HISTORY)
+  history_expansion_inhibited = old_history_expansion_inhibited;
+#  endif /* BANG_HISTORY */
+#endif /* HISTORY */
+
+  echo_input_at_read = old_echo_input;
+  expand_aliases = old_expand_aliases;
+
+  current_command_line_count = orig_line_count;
+  shell_input_line_terminator = orig_input_terminator;
+
+  if (flags & 1)
+    parser_state &= ~(PST_COMPASSIGN|PST_REPARSE);
+
+  if (wl == &parse_string_error)
+    {
+      last_command_exit_value = EXECUTION_FAILURE;
+      if (interactive_shell == 0 && posixly_correct)
+       jump_to_top_level (FORCE_EOF);
+      else
+       jump_to_top_level (DISCARD);
+    }
+
+  return (REVERSE_LIST (wl, WORD_LIST *));
+}
+
+static char *
+parse_compound_assignment (retlenp)
+     int *retlenp;
+{
+  WORD_LIST *wl, *rl;
+  int tok, orig_line_number, orig_token_size, orig_last_token, assignok;
+  int peekc;
+  char *saved_token, *ret;
+
+  saved_token = token;
+  orig_token_size = token_buffer_size;
+  orig_line_number = line_number;
+  orig_last_token = last_read_token;
+
+  last_read_token = WORD;      /* WORD to allow reserved words here */
+
+  token = (char *)NULL;
+  token_buffer_size = 0;
+
+  assignok = parser_state&PST_ASSIGNOK;                /* XXX */
+
+  wl = (WORD_LIST *)NULL;      /* ( */
+  parser_state |= PST_COMPASSIGN;
+
+  while ((tok = read_token (READ)) != ')')
+    {
+      if (tok == '\n')                 /* Allow newlines in compound assignments */
+       {
+         if (SHOULD_PROMPT ())
+           prompt_again ();
+         continue;
+       }
+      if (tok != WORD && tok != ASSIGNMENT_WORD)
+       {
+         current_token = tok;  /* for error reporting */
+         if (tok == yacc_EOF)  /* ( */
+           parser_error (orig_line_number, _("unexpected EOF while looking for matching `)'"));
+         else
+           yyerror(NULL);      /* does the right thing */
+         if (wl)
+           dispose_words (wl);
+         wl = &parse_string_error;
+         break;
+       }
+      wl = make_word_list (yylval.word, wl);
+    }
+
+  FREE (token);
+  token = saved_token;
+  token_buffer_size = orig_token_size;
+
+  parser_state &= ~PST_COMPASSIGN;
+
+  if (wl == &parse_string_error)
+    {
+      last_command_exit_value = EXECUTION_FAILURE;
+      last_read_token = '\n';  /* XXX */
+      if (interactive_shell == 0 && posixly_correct)
+       jump_to_top_level (FORCE_EOF);
+      else
+       jump_to_top_level (DISCARD);
+    }
+
+  last_read_token = orig_last_token;           /* XXX - was WORD? */
+
+  if (wl)
+    {
+      rl = REVERSE_LIST (wl, WORD_LIST *);
+      ret = string_list (rl);
+      dispose_words (rl);
+    }
+  else
+    ret = (char *)NULL;
+
+  if (retlenp)
+    *retlenp = (ret && *ret) ? strlen (ret) : 0;
+
+  if (assignok)
+    parser_state |= PST_ASSIGNOK;
+
+  return ret;
+}
+
+/************************************************
+ *                                             *
+ *   SAVING AND RESTORING PARTIAL PARSE STATE   *
+ *                                             *
+ ************************************************/
+
+sh_parser_state_t *
+save_parser_state (ps)
+     sh_parser_state_t *ps;
+{
+  if (ps == 0)
+    ps = (sh_parser_state_t *)xmalloc (sizeof (sh_parser_state_t));
+  if (ps == 0)
+    return ((sh_parser_state_t *)NULL);
+
+  ps->parser_state = parser_state;
+  ps->token_state = save_token_state ();
+
+  ps->input_line_terminator = shell_input_line_terminator;
+  ps->eof_encountered = eof_encountered;
+
+  ps->prompt_string_pointer = prompt_string_pointer;
+
+  ps->current_command_line_count = current_command_line_count;
+
+#if defined (HISTORY)
+  ps->remember_on_history = remember_on_history;
+#  if defined (BANG_HISTORY)
+  ps->history_expansion_inhibited = history_expansion_inhibited;
+#  endif
+#endif
+
+  ps->last_command_exit_value = last_command_exit_value;
+#if defined (ARRAY_VARS)
+  ps->pipestatus = save_pipestatus_array ();
+#endif
+    
+  ps->last_shell_builtin = last_shell_builtin;
+  ps->this_shell_builtin = this_shell_builtin;
+
+  ps->expand_aliases = expand_aliases;
+  ps->echo_input_at_read = echo_input_at_read;
+
+  ps->token = token;
+  ps->token_buffer_size = token_buffer_size;
+  /* Force reallocation on next call to read_token_word */
+  token = 0;
+  token_buffer_size = 0;
+
+  return (ps);
+}
+
+void
+restore_parser_state (ps)
+     sh_parser_state_t *ps;
+{
+  if (ps == 0)
+    return;
+
+  parser_state = ps->parser_state;
+  if (ps->token_state)
+    {
+      restore_token_state (ps->token_state);
+      free (ps->token_state);
+    }
+
+  shell_input_line_terminator = ps->input_line_terminator;
+  eof_encountered = ps->eof_encountered;
+
+  prompt_string_pointer = ps->prompt_string_pointer;
+
+  current_command_line_count = ps->current_command_line_count;
+
+#if defined (HISTORY)
+  remember_on_history = ps->remember_on_history;
+#  if defined (BANG_HISTORY)
+  history_expansion_inhibited = ps->history_expansion_inhibited;
+#  endif
+#endif
+
+  last_command_exit_value = ps->last_command_exit_value;
+#if defined (ARRAY_VARS)
+  restore_pipestatus_array (ps->pipestatus);
+#endif
+
+  last_shell_builtin = ps->last_shell_builtin;
+  this_shell_builtin = ps->this_shell_builtin;
+
+  expand_aliases = ps->expand_aliases;
+  echo_input_at_read = ps->echo_input_at_read;
+
+  FREE (token);
+  token = ps->token;
+  token_buffer_size = ps->token_buffer_size;
+}
+
+sh_input_line_state_t *
+save_input_line_state (ls)
+     sh_input_line_state_t *ls;
+{
+  if (ls == 0)
+    ls = (sh_input_line_state_t *)xmalloc (sizeof (sh_input_line_state_t));
+  if (ls == 0)
+    return ((sh_input_line_state_t *)NULL);
+
+  ls->input_line = shell_input_line;
+  ls->input_line_size = shell_input_line_size;
+  ls->input_line_len = shell_input_line_len;
+  ls->input_line_index = shell_input_line_index;
+
+  /* force reallocation */
+  shell_input_line = 0;
+  shell_input_line_size = shell_input_line_len = shell_input_line_index = 0;
+
+  return ls;
+}
+
+void
+restore_input_line_state (ls)
+     sh_input_line_state_t *ls;
+{
+  FREE (shell_input_line);
+  shell_input_line = ls->input_line;
+  shell_input_line_size = ls->input_line_size;
+  shell_input_line_len = ls->input_line_len;
+  shell_input_line_index = ls->input_line_index;
+
+  set_line_mbstate ();
+}
+
+/************************************************
+ *                                             *
+ *     MULTIBYTE CHARACTER HANDLING            *
+ *                                             *
+ ************************************************/
+
+#if defined (HANDLE_MULTIBYTE)
+static void
+set_line_mbstate ()
+{
+  int c;
+  size_t i, previ, len;
+  mbstate_t mbs, prevs;
+  size_t mbclen;
+
+  if (shell_input_line == NULL)
+    return;
+  len = strlen (shell_input_line);     /* XXX - shell_input_line_len ? */
+  FREE (shell_input_line_property);
+  shell_input_line_property = (char *)xmalloc (len + 1);
+
+  memset (&prevs, '\0', sizeof (mbstate_t));
+  for (i = previ = 0; i < len; i++)
+    {
+      mbs = prevs;
+
+      c = shell_input_line[i];
+      if (c == EOF)
+       {
+         size_t j;
+         for (j = i; j < len; j++)
+           shell_input_line_property[j] = 1;
+         break;
+       }
+
+      mbclen = mbrlen (shell_input_line + previ, i - previ + 1, &mbs);
+      if (mbclen == 1 || mbclen == (size_t)-1)
+       {
+         mbclen = 1;
+         previ = i + 1;
+       }
+      else if (mbclen == (size_t)-2)
+        mbclen = 0;
+      else if (mbclen > 1)
+       {
+         mbclen = 0;
+         previ = i + 1;
+         prevs = mbs;
+       }
+      else
+       {
+         /* XXX - what to do if mbrlen returns 0? (null wide character) */
+         size_t j;
+         for (j = i; j < len; j++)
+           shell_input_line_property[j] = 1;
+         break;
+       }
+
+      shell_input_line_property[i] = mbclen;
+    }
+}
+#endif /* HANDLE_MULTIBYTE */
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
 
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